我目前正在通过学习推理图谋来学习miniKanren。
我被困在第5章第62帧的练习中:(run* (x) (flatten_o (a) x)),为什么输出中有三个列表?
发布于 2017-10-24 12:24:26
问得好!这些额外的列表是从哪里来的?
问题出在flatteno定义的else子句中。else子句处理s是符号的情况(这里是符号a )。但是,该子句还允许s为空列表或空对!这就是为什么我们看到三个列表而不是一个-额外的两个列表是由于else子句接受s的非符号值而成功的递归调用产生的。
在更高版本的miniKanren中,我们添加了symbolo和=/=等特殊约束,以防止此类行为。例如,下面是用faster-miniKanren (https://github.com/webyrd/faster-miniKanren)编写的相同的查询和flatteno:
(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
我们正在试图弄清楚如何在小书格式中包含对这些约束的描述。约束的实现有点复杂,这使得它很难适合一本小书!
希望这能有所帮助!
干杯,
--威尔
https://stackoverflow.com/questions/46884010
复制相似问题