我正在尝试重写下面的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个版本的理由是什么?任何帮助将不胜感激。
答案 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 内部工作,该宏只需要一个序列目标中的目标。