调试 APL 代码:如何同时使用 `@`(index) 和 `⊢` (right tack)?

Debugging APL code: how to use `@`(index) and `⊢` (right tack) together?

我正在尝试阅读 Aaron Hsu 关于 A data parallel compiler hosted on the GPU 的论文,在那里我遇到了一些我无法修复的 APL 代码。我附上了违规页面的屏幕截图(根据底部的论文编号,页码 74):

转载代码如下:

d ← 0 1 2 3 1 2 3 3 4 1 2 3 4 5 6 5 5 6 3 4 5 6 5 5 6 3 4

这是有道理的:创建一个名为 d 的数组。

⍳≢d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

这也很有道理。计算 d 中的元素数量并创建一个序列 那个长度。

⍉↑d,¨⍳≢d
0 1 2 3 1 2 3 3 4  1  2  3  4  5  6  5  5  6  3  4  5  6  5  5  6  3  4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

这有点挑战性,但让我分解一下:

现在是大人物:

(⍳≢d)@(d,¨⍳≢d)⊢7 27⍴' '
INDEX ERROR
      (⍳≢d)@(d,¨⍳≢d)⊢7 27⍴' '

正在尝试分解:

我认为它被解析为:

(⍳≢d)@((d,¨⍳≢d)⊢(7 27⍴' '))

我认为应该评价为:

(⍳≢d)@((d,¨⍳≢d)⊢(7 27⍴' '))
=  (⍳≢d)@((7 27⍴' ')) [using a⊢b = b]
=  not the right thing

当我写下这篇文章时,我完全靠运气修复了这个错误:如果我们将 d 递增为 d + 1 所以我们是 1-indexed,错误不再出现:

d ← d + 1
d
1 2 3 4 2 3 4 4 5 2 3 4 5 6 7 6 6 7 4 5 6 7 6 6 7 4 5

然后:

(⍳≢d)@(d,¨⍳≢d)⊢7 27⍴' '
1                                                                      
  2     5         10                                                   
    3     6          11                                                
      4     7 8         12                   19                   26   
                9          13                   20                   27
                              14    16 17          21    23 24         
                                 15       18          22       25      

但是,我还是不明白这是怎么回事!我认为上下文会很有用 对于其他试图离开论文的人,所以我将把它的其余部分留在上面。

请解释一下 (⍳≢d)@(d,¨⍳≢d)⊢7 27⍴' ' 的作用!

我附上了原始屏幕截图以确保我没有遗漏任何内容:

我很高兴看到您发现了差一错误。它源于 Aaron Hsu 使用 index origin 0。如果你设置 ⎕IO←0 那么他的代码将起作用。


一些二元运算符可以采用数组操作数,给出序列 OPERATOR operand argument,例如在 -@(1 2 3)(4 5 6 7)。这带来了一个问题,因为操作数和参数都是数组,并且数组的并置通过称为 stranding 的过程形成一个新数组,这些数组作为元素。比较:

      (1 2 3)(4 5 6 7)
┌─────┬───┐
│1 2 3│4 5│
└─────┴───┘

但是,在运算符及其数组操作数的情况下,我们希望 "break" 这个链,以便左侧部分可以作为操作数,而右侧部分可以作为参数。打破搁浅的一种方法是对参数应用一个函数,给出序列 OPERATOR operand Function argument。现在,我们实际上 不需要 参数的任何转换,所以 identity function 就可以了:-@(1 2 3)⊢(4 5 6 7).


至于(⍳≢d)@(d,¨⍳≢d)⊢7 27⍴' '实际做了什么:

7 27⍴' ' 创建空白矩阵。

(⍳≢d) 是要插入到矩阵中指定位置的索引。

@(d,¨⍳≢d) 表示 上面矩阵中的哪些位置应该替换现有值

仅用于将 (d,¨⍳≢d)7 27⍴' ' 分开。代码也可以写成 ((⍳≢d)@(d,¨⍳≢d))7 27⍴' ',括号用于 "bind" 运算符的操作数。