Fork me on GitHub
#core-logic
<
2020-11-05
>
nitaai14:11:21

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]` ?

nitaai14:11:15

I assume some rearrangement of the clauses and use of `defna` or `defnu`..

nitaai15:11:18

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?

hiredman18:11:21

I would strongly recommend against using pred, and seq? is likely the wrong predicate there

hiredman18:11:59

the re-arrangement of the clauses and using defna or defna are both consequences of seq? being the wrong predicate

hiredman18:11:19

``````user=> (seq? [])
false
user=>``````

hiredman18:11:59

but using defna you should be able to get rid of the pred usage altogether

nitaai18:11:23

Great and interesting hints. Thanks @UCPGSBNQ4 and @U0NCTKEV8. Will look into that…

nitaai08:11:13

``````(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 @U0NCTKEV8 suggested and uses `defna`. the arrangement of the clauses still matters, but it makes sense.