How to rewrite the core.logic snippet? - clojure

I'm trying to rewrite the below piece of core.logic code.
(run* [x y]
(fd/in x (fd/domain 1 2))
(fd/in y (fd/domain 1 2)))
o/p,
([1 1] [2 1] [1 2] [2 2])
I tried the below versions but none of them works,
(run* [x y]
(fresh [dom (fd/domain 1 2)])
(fd/in x dom)
(fd/in y dom)))
;; Error Unsupported binding form: (fd/domain 1 2)
(run* [x y]
(fresh [dom]
(== dom (fd/domain 1 2))
(fd/in x dom)
(fd/in y dom)))
O/P:
([1 1])
(run* [x y]
(let [dom (fd/domain 1 2)]
(fd/in x dom)
(fd/in y dom)))
O/P:
([_0 1] [_0 2])
What's the rationale for the 3 versions that I tried? Any help would be greatly appreciated.

fd/domain returns a concrete value that can be used with other goals/relations in the fd namespace — you can define it once and use it inside run* more than once:
(let [dom (fd/domain 1 2)]
(run* [x y]
(fd/in x dom)
(fd/in y dom)))
=> ([1 1] [2 1] [1 2] [2 2])
What's the rationale for the 3 versions that I tried?
The first refactoring doesn't work because fresh is being used like let, but it doesn't work like that; fresh simply allows you to give names to some fresh logic variables.
The second refactoring doesn't work because the domain value is being bound to a logic variable, and fd/in wants a concrete domain value as its second argument — not a (fresh) logic variable.
The third refactoring doesn't work (I assume) because let bindings aren't going to work like that inside the run* macro, which only wants a sequence of goals in its body.

Related

Why does this implementation of sorto does not terminate?

I'm a beginner with logic programming.
I'm trying to implement a sorting relation like this:
(sorto [3 2 1][1 2 3]) -> #s
I'am using clojure and core.logic:
I don't understand why this can not terminate in most cases.
Any idea would be helpful, thank you.
(require '[clojure.core.logic :refer :all]
'[clojure.core.logic.fd :as fd])
First I define several little helpers:
A simple count relation: (counto [a b] 2) -> #s
(defne counto [list n]
([() 0])
([[fl . rl] _]
(fresh [nnxt]
(fd/- n 1 nnxt)
(counto rl nnxt))))
reduce and every? relational equivalents:
(defne reduceo [rel acc x y]
([_ _ () _] (== acc y))
([_ _ [fx . rx] _]
(fresh [nacc]
(rel acc fx nacc)
(reduceo rel nacc rx y))))
(defne everyo [g list]
([_ ()])
([_ [fl . rl]]
(g fl)
(everyo g rl)))
min relation: (mino 1 2 1) -> #s
(defn mino [x y z]
(conde
[(fd/<= x y) (== x z)]
[(fd/> x y) (== y z)]))
relation between a list and its minimum element: (mino* [1 2 3 0] 0) -> #s
(defne mino* [xs y]
([[fxs . rxs] _]
(reduceo mino fxs rxs y)))
The main relation: (sorto [2 3 1 4] [1 2 3 4]) -> #s
(defne sorto [x y]
([() ()])
([[fx . rx] [fy . ry]]
(fresh [x* c]
(counto rx c)
(counto ry c)
(mino* x fy)
(rembero fy x x*)
(sorto x* ry))))
The below runs doesn't terminate, I would like to understand why.
(run* [q]
(sorto q [1 2]))
; does not terminate
(run* [q]
(sorto [2 1] q))
; does not terminate
(run* [a b]
(everyo #(fd/in % (fd/interval 10)) a)
(everyo #(fd/in % (fd/interval 10)) b)
(sorto a b))
;neither
The high level answer is because conjunction are tried in order. Reordering them may sometimes make a program to terminate -- however in the general case there may not exist a "good" order.
Have a look at Chapter 5 in https://scholarworks.iu.edu/dspace/bitstream/handle/2022/8777/Byrd_indiana_0093A_10344.pdf

Clojure - Unknown number of arguments in a function

I have a function
(defn x [w]
(let [[w1 w2 w3] w]
(println w1)
(println w2)
(println w3)))
If I call the function
(x [[1 1] [2 2] [3 3]])
=> [1 1]
[2 2]
[3 3]
which is what I expect
Is there a way to generalise this? In this case I knew that w was a vector containing 3 vectors so I know to have [w1 w2 w3] If w was then a vector of 4 vectors, the last vector would not be set to anything
What I want is where w is a vector of n vectors and then in the let of the function set them to [w1 w2 w3 ... wn]? (note doesn't necessarily have to be w1, w2, ... wn)
The println are just there for debugging so not that important for the function
Any help would be much appreciated.
(defn x [ws]
(dorun (map println ws)))
For example,
(x [[1 1] [2 2] [3 3]])
[1 1]
[2 2]
[3 3]
=> nil
The map applies println to each of the ws in turn, returning
the nil results as a sequence, on demand (lazily).
The dorun demands the whole sequence, discarding it as it goes,
returning nil.
If you want to see the sequence, replace dorun with doall:
(defn x [ws]
(doall (map println ws)))
=> (x [[1 1] [2 2] [3 3]])
[1 1]
[2 2]
[3 3]
=> (nil nil nil)
A more concise alternative to the former is
(defn x [ws]
(doseq [w ws] (println w)))
... and to the latter is
(defn x [ws]
(for [w ws] (println w)))

Clojure: understaning the binding in a doseq

I understand the following snippet of code and its corresponding output
(let [ [x y] (map list [1 2] [3 4])] (prn x) (prn y))
(1 3)
(2 4)
nil
Now the following output confuses me:
(doseq [ [x y] (map list [1 2] [3 4])] (prn x y))
1 3
2 4
nil
I think in the above snippet x will get bound to [1 3] and y will get bound to [2 4] so the output should be"
1 2
3 4
nil
The binding is pulling out the individual elements inside the larger single element in the nesting. The map creates a list ((1 3) (2 4) so the element 1 3 is first and thus that is what the doseq outputs: this is "destructuring" and the x and y are both bound from inside a single element of the list. Thus x and y are 1 and 3, and then 2 and 4.
Note also that this is the same binding that occurs in a for and the destructuring works for all sequence types.
Let's isolate the source of your confusion.
(map list [1 2] [3 4])
evaluates to
((1 3) (2 4))
So your first example
(let [[x y] (map list [1 2] [3 4])] (prn x) (prn y))
... is equivalent to
(let [[x y] [[1 3] [2 4]]] (prn x) (prn y))
... or, printing slightly differently
(let [[x y] [[1 3] [2 4]]] (prn [x y]))
... which simplifies to
(let [z [[1 3] [2 4]]] (prn z))
... producing, as expected,
; [[1 3] [2 4]]
; nil
So far, so good.
If we boil down the confusing example,
(doseq [ [x y] (map list [1 2] [3 4])] (prn x y))
... in the same way, we get, taking the liberty of printing each z whole,
(doseq [z [[1 3] [2 4]]] (prn z))
which fairly clearly produces the observed order:
[1 3]
[2 4]
nil
The difference is that the doseq binds z to each successive vector in [[1 3] [2 4]], so we don't see an enclosing [ ... ], whereas the let binds z once to the whole thing.

Translating the insert fact from Prolog to core.logic

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)))
The solution is to make the recursive insert clause last:
(defn insert [x l nl]
(conde
[(conso x l nl)]
[(fresh [h t]
(conso h t l)
(conso h l nl)
(insert x t l))]))
The Prolog code can be transcribed almost verbatim as core.logic also supports matching.
(defne inserto [L, X, L*]
([L, X, (X . L)])
([(H . T), X, (H . L)] (inserto T, X, L)))
Note that I've kept the order of the Prolog version, rather than the inverted order of the first two logical variables in your version.
user=> (run* [q] (inserto [2] 1 q))
((1 2))
user=> (run* [q] (inserto [2 3] 1 q))
((1 2 3))
user=> (run* [q] (inserto [2] q [1 2]))
(1)
user=> (run* [q] (inserto q 1 [1 2]))
((2))

distincto vs. fd/distinct in core.logic

What is the advantage of using fd/distinct in cases where the elements will be in a finite domain instead of distincto?
The following all return ([0 1] [1 0]).
;;; With distincto
(run* [q]
(fresh [x y]
(fd/in x y (fd/interval 1))
(distincto [x y])
(== q [x y])))
;;; With fd/distinct
(run* [q]
(fresh [x y]
(fd/in x y (fd/interval 1))
(fd/distinct [x y])
(== q [x y])))
;;; Without fd at all.
(let [interval [0 1]]
(run* [q]
(fresh [x y]
(membero x interval)
(membero y interval)
(distincto [x y])
(== q [x y]))))
Notably, although it appears you may use distincto in any place where you may use fd/distinct (but not the other way around), the same cannot be said for membero and fd/in.
fd/distinct is much more highly optimized than distincto which must receive any kind of value. fd/distinct under the hood deals with efficient representations of constrained variables all at once using sets, distincto uses the disequality operator != in a pretty simple manner.