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 useL
instead ofR
there,L
is already used as an argument. – Will Ness