不理解Reasoned Schemer第5章框架62

时间:2017-10-23 07:30:55

标签: logic-programming minikanren seasoned-schemer

我目前正在学习The Reasoned Schemer学习miniKanren。

我陷入了第5章第62帧的练习:(run* (x) (flatten_o (a) x)),为什么输出中有三个列表?

提前多多感谢。

1 个答案:

答案 0 :(得分:3)

好问题!这些额外的清单来自哪里?

问题出在else定义的flatteno子句中。 else子句处理s是符号(此处为符号a)的情况。但是,该子句还允许s为空列表或一对!这就是我们看到三个列表而不是一个列表的原因---额外的两个列表是由递归调用生成的,这些调用由于else子句接受s的非符号值而成功。

在miniKanren的更高版本中,我们添加了特殊约束,例如symbolo=/=,以防止此类行为。例如,以下是相同的查询,flatteno,用fast-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))

请注意在symbolo中使用flatteno约束以确保s是符号。

您可以在本文中找到这些约束的非“小书”解释:

http://webyrd.net/quines/quines.pdf

我们正试图弄清楚如何以Little Book格式包含这些约束的描述。约束的实现有点涉及,这使得很难适应Little Book!

希望这有帮助!

干杯,

- 威尔