我正在玩弄 core.logic 并尝试翻译一些 Prolog 代码并陷入对insert
事实的无休止递归(取自 RAO'Keefe 的“Prolog 工艺”):
insert(L, X, [X|L]).
insert([H|T], X, [H|L]) :-
insert(T,X,L).
这是我到目前为止提出的(请注意,前两个参数被交换以匹配conso
参数列表):
(defn insert [x l nl]
(conde
[(conso x l nl)]
[(fresh [h t]
(conso h t l)
(insert x t l)
(conso h l nl))]))
我遇到的问题是,这些 midje 测试的最后两个事实永远不会返回。第一个按预期工作得很好,因为这只需要第一个conso
子句。
(fact "Inserting works"
(run* [q] (insert 1 [2] q)) => '((1 2)))
(run* [q] (insert 1 [2 3] q)) => '((1 2 3)))
(fact "We can retrieve the inserted data"
(run* [q] (insert q [2] '(1 2))) => '(1))
(fact "We can retrieve the list data, too"
(run* [q] (insert 1 q '(1 2))) => '((2))))
我想我忽略了一些明显的东西,但是什么?
编辑:事实不能正确反映 Prolog 代码的行为。正确的行为是这样的:
?- insert([2,3], 1, Q).
Q = [1, 2, 3] ;
Q = [2, 1, 3] ;
Q = [2, 3, 1].
所以,第二个检查实际上应该是
(fact "Inserting works"
(run* [q] (insert 1 [2 3] q)) => '((1 2 3) (2 1 3) (2 3 1)))