【问题标题】:Not understanding The Reasoned Schemer Chapter 5 frame 62不理解 The Reasoned Schemer 第 5 章 62
【发布时间】:2018-04-03 16:27:39
【问题描述】:
我目前正在通过学习 The Reasoned Schemer 来学习 miniKanren。
我被困在第 5 章第 62 帧的一个练习中:(run* (x) (flatten_o (a) x)),为什么输出中有三个列表?
【问题讨论】:
标签:
logic-programming
minikanren
reasoned-schemer
【解决方案1】:
好问题!这些额外的列表是从哪里来的???
问题出在flatteno 定义的else 子句中。 else 子句处理s 是符号的情况(此处为符号a)。但是,该子句还允许s 是空列表或一对!这就是为什么我们看到三个列表而不是一个的原因——额外的两个列表是由递归调用产生的,由于else 子句接受s 的非符号值而成功。
在以后的 miniKanren 版本中,我们添加了特殊的约束,例如 symbolo 和 =/= 来防止此类行为。比如这里是同一个查询,还有flatteno,写成faster-miniKanren (https://github.com/webyrd/faster-miniKanren):
(define flatteno
(lambda (s out)
(conde
((== '() s) (== '() out))
((fresh (a d res-a res-d)
(== (cons a d) s)
(flatteno a res-a)
(flatteno d res-d)
(appendo res-a res-d out)))
((symbolo s) (== (cons s '()) out)))))
(run* (x)
(flatteno '(a) x))
=>
((a))
注意在flatteno 中使用symbolo 约束以确保s 是一个符号。
您可以在本文中找到这些约束的非“小书”解释:
http://webyrd.net/quines/quines.pdf
我们正试图弄清楚如何在小书格式中包含对这些约束的描述。约束的实现有点牵强,很难放在一本小书中!
希望这会有所帮助!
干杯,
--会