I'm toying around with core.logic and trying to translate some Prolog code and run into an endless recursion for the insert facts (taken from R.A.O'Keefe's "Craft of Prolog"):
insert(L, X, [X|L]).
insert([H|T], X, [H|L]) :-
insert(T,X,L).
This is what I've come up so far (please note that the first two arguments are exchanged to match up with conso parameter list):
(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))]))
The problem I have is that the last two facts from these midje tests will never return.
The first one works just fine as is expected since this only requires the first conso clause.
(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))))
I guess I'm overlooking something obvious, but what?
Edit: The facts don't reflect the behavior of the Prolog code correctly. The right behavior is like this:
?- insert([2,3], 1, Q).
Q = [1, 2, 3] ;
Q = [2, 1, 3] ;
Q = [2, 3, 1].
So, the second checkable should actually be
(fact "Inserting works"
(run* [q] (insert 1 [2 3] q)) => '((1 2 3) (2 1 3) (2 3 1)))
NL=[H|R]. can't useLinstead ofRthere,Lis already used as an argument. - Will Ness