Skip to content

Commit

Permalink
[docs] 反应网编程 -- 完成 mul 的讲解
Browse files Browse the repository at this point in the history
  • Loading branch information
xieyuheng committed Sep 5, 2023
1 parent 3bbc35a commit d36fa67
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 3 deletions.
1 change: 0 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# articles

[docs] 反应网编程 -- 完成 `mul` 的讲解
[docs] 反应网编程 -- 完成 `List` 的讲解
[docs] 反应网编程 -- 完成 `DiffList` 的讲解

Expand Down
110 changes: 109 additions & 1 deletion docs/articles/反应网编程.md
Original file line number Diff line number Diff line change
Expand Up @@ -711,8 +711,116 @@ three two max

# 10

TODO `mul`, `nat_erase`, `nat_dup` -- 零返回值和多返回值。
我们已经分析了代表加法的节点 `(add)`
下面我们来分析代表乘法的节点 `(mul)`

我们将会发现,为了定义 `(mul)``(zero)``(add1)` 之间的反应规则,
我们又要引入两个新的辅助节点:

- `(nat_erase)` 删除一个自然数。
- `(nat_dup)` 复制一个自然数。

这两个节点与之前的所有节点都不一样,
之前的所有节点都有一个输出节点,
然而:

- `(nat_erase)` 有零个输出节点。
- `(nat_dup)` 有两个输出节点。

这其实是我们使用栈来构造网的主要原因。

使用栈的好处之一是,
可以自然地处理零个返回值和多个返回值的节点,
而不必为它们设计新的特殊的语法。

决定使用栈来构造网之后,就进而决定使用纯粹的后缀表达式作为语法。
这样的零一个好处是,词之间复合具有结合性,
因此当我们想要把一个词的定义中的一部分切分出来,定义成新的词时,
不用考虑那么多语法上相互影响的地方。

下面我们就不用 ASCII 画图了,
点开去演算场的连接,
就可以看到自动渲染出来的图。

在下面的代码中,我们用了一个新的语法关键词 `import` 来从其他模块中引入定义。

- 一个文件对应一个模块。
-`.i` 作为文件名后缀。
- 可以使用完整的 URL `https//...` 来指定文件,
也可以使用相对路径 `./...` 来指定文件。

我们还用了一种新的词 `$local` 来将栈顶的值保存到名为 `local` 的局部变量中。

-`$local` 保存一个值之后,可以通过调用 `local` 来取出这个值。
- 取出之后,`$local` 就空了,就又可以用于保存新的值了。


[去 `Nat` 与 `(mul)` 的演算场](https://inet.run/playground/aW1wb3J0CiAgTmF0LCB6ZXJvLCBhZGQxLCBhZGQsCiAgb25lLCB0d28sIHRocmVlLApmcm9tICJodHRwczovL2Nkbi5pbmV0LnJ1bi90ZXN0cy9kYXRhdHlwZS9OYXQuaSIKCm5vZGUgbmF0X2VyYXNlCiAgTmF0IDp0YXJnZXQhCiAgLS0tLS0tLS0KZW5kCgpydWxlIHplcm8gbmF0X2VyYXNlIGVuZAoKcnVsZSBhZGQxIG5hdF9lcmFzZQogIChhZGQxKS1wcmV2IG5hdF9lcmFzZQplbmQKCm5vZGUgbmF0X2R1cAogIE5hdCA6dGFyZ2V0IQogIC0tLS0tLS0tCiAgTmF0IDpzZWNvbmQKICBOYXQgOmZpcnN0CmVuZAoKcnVsZSB6ZXJvIG5hdF9kdXAKICB6ZXJvIGZpcnN0LShuYXRfZHVwKQogIHplcm8gc2Vjb25kLShuYXRfZHVwKQplbmQKCnJ1bGUgYWRkMSBuYXRfZHVwCiAgKGFkZDEpLXByZXYgbmF0X2R1cCAkZmlyc3QgJHNlY29uZAogIGZpcnN0IGFkZDEgZmlyc3QtKG5hdF9kdXApCiAgc2Vjb25kIGFkZDEgc2Vjb25kLShuYXRfZHVwKQplbmQKCm5vZGUgbXVsCiAgTmF0IDp0YXJnZXQhCiAgTmF0IDptdWxlbmQKICAtLS0tLS0tLQogIE5hdCA6cmV0dXJuCmVuZAoKcnVsZSB6ZXJvIG11bAogIChtdWwpLW11bGVuZCBuYXRfZXJhc2UKICB6ZXJvIHJldHVybi0obXVsKQplbmQKCnJ1bGUgYWRkMSBtdWwKICAobXVsKS1tdWxlbmQgbmF0X2R1cCAkZmlyc3QgJHNlY29uZAogIChhZGQxKS1wcmV2IGZpcnN0IG11bCBzZWNvbmQgYWRkCiAgcmV0dXJuLShtdWwpCmVuZAoKdHdvIG5hdF9kdXAgJGZpcnN0ICRzZWNvbmQKCnR3byB0d28gbXVsCgp0aHJlZSB0aHJlZSBtdWw)

```
import
Nat, zero, add1, add,
one, two, three,
from "https://cdn.inet.run/tests/datatype/Nat.i"
node nat_erase
Nat :target!
--------
end
rule zero nat_erase end
rule add1 nat_erase
(add1)-prev nat_erase
end
node nat_dup
Nat :target!
--------
Nat :second
Nat :first
end
rule zero nat_dup
zero first-(nat_dup)
zero second-(nat_dup)
end
rule add1 nat_dup
(add1)-prev nat_dup $first $second
first add1 first-(nat_dup)
second add1 second-(nat_dup)
end
node mul
Nat :target!
Nat :mulend
--------
Nat :return
end
rule zero mul
(mul)-mulend nat_erase
zero return-(mul)
end
rule add1 mul
(mul)-mulend nat_dup $first $second
(add1)-prev first mul second add
return-(mul)
end
two nat_dup $first $second
two two mul
three three mul
```

# 11

TODO `List` -- `append` 如何与 `add` 类似。

# 12

TODO `DiffList` -- 对表达式与图的反思 -- 简单的图也是双线连接的表达式。
5 changes: 4 additions & 1 deletion tests/datatype/Nat.i
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ node nat_erase
end

rule zero nat_erase end
rule add1 nat_erase (add1)-prev nat_erase end

rule add1 nat_erase
(add1)-prev nat_erase
end

node nat_dup
Nat :target!
Expand Down

0 comments on commit d36fa67

Please sign in to comment.