如何重写core.logic代码段?

时间:2019-07-17 18:42:58

标签: clojure clojure-core.logic

我正在尝试重写下面的core.logic代码。

(run* [x y]
    (fd/in x (fd/domain 1 2))
    (fd/in y (fd/domain 1 2)))

o / p

  

([1 1] [2 1] [1 2] [2 2])

我尝试了以下版本,但没有一个起作用,

(run* [x y]
    (fresh [dom (fd/domain 1 2)])
        (fd/in x dom)
        (fd/in y dom)))

;;错误不支持的绑定形式:(fd / domain 1 2)

(run* [x y]
 (fresh [dom]
    (== dom  (fd/domain 1 2))
    (fd/in x dom)
    (fd/in y dom)))

O / P:

  

([[1 1])

(run* [x y]
  (let [dom (fd/domain 1 2)]
  (fd/in x dom)
  (fd/in y dom)))

O / P:

  

([_ 0 1] [_0 2])

我尝试过3个版本的理由是什么?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

fd/domain返回一个具体的值,该值可以与fd命名空间中的其他目标/关系一起使用-您可以定义一次并在run*内多次使用它:

(let [dom (fd/domain 1 2)]
  (run* [x y]
    (fd/in x dom)
    (fd/in y dom)))
=> ([1 1] [2 1] [1 2] [2 2])
  

我尝试过的3个版本的依据是什么?

第一次重构无法正常工作,因为fresh的使用方式与let类似,但它并非如此。 fresh仅允许您为一些新的逻辑变量命名。

第二个重构不起作用,因为域值已绑定到逻辑变量,并且fd/in想要一个具体的域值作为其第二个参数—而不是(新的)逻辑变量。

第三种重构不起作用(我认为)是因为let绑定不会像run*宏那样在 inside 内部工作,该宏只需要一个序列目标中的目标。