hi. i have ported one prolog example to core.logic:
% P07 (**) Flatten a nested list structure.
my_flatten(X,[X]) :- \+ is_list(X).
my_flatten([],[]).
my_flatten([X|Xs],Zs) :- my_flatten(X,Y), my_flatten(Xs,Ys), append(Y,Ys,Zs).
(defne flatteno [l1 l2]
([x [x]] (pred x (comp not seq?)))
([[] []])
([[x . xs] zs]
(fresh [y ys]
(flatteno x y)
(flatteno xs ys)
(appendo y ys zs))))
can someone tell me why the clojure version produces multiple results:
([[1 [2]]] (1 [2]) (1 2))
and the prolog version only one:
[1 2]
?(defna flatteno [l1 l2]
([[] []])
([[x . xs] zs]
(fresh [y ys]
(flatteno x y)
(flatteno xs ys)
(appendo y ys zs)))
([x [x]]))
i think this is the best solution. it got rid of pred
as @hiredman suggested and uses defna
. the arrangement of the clauses still matters, but it makes sense.I assume some rearrangement of the clauses and use of defna
or defnu
..
yes, my assumption was right:
(defna flatteno [l1 l2]
([[x . xs] zs]
(fresh [y ys]
(flatteno x y)
(flatteno xs ys)
(appendo y ys zs)))
([x [x]] (pred x (comp not seq?)))
([[] []]))
both defna
and defnu
do the job and clauses have to be rearranged.
Someone who knows prolog can tell me why this kind of cut is necessary in clojure and not in prolog?the \+ negation in prolog also does a cut: http://cs.union.edu/~striegnk/learn-prolog-now/html/node90.html#sec.l10.negation.as.failure
I would strongly recommend against using pred, and seq? is likely the wrong predicate there
the re-arrangement of the clauses and using defna or defna are both consequences of seq? being the wrong predicate
user=> (seq? [])
false
user=>
but using defna you should be able to get rid of the pred usage altogether