core.logic CLP(FD) with ClojureScript

454 views Asked by At

I'm trying to use core.logic to figure out answer to the following equations:

x + y = W
x - y = V

W and V are both given, while x and y are the values I'm trying to compute.

I've tried approaches like (I substituted W with 60 and V with 10):

(logic/run* [q]
          (logic/fresh [x y]
                       (logic/== q [x y])
                       (logic/project [x y]
                                      ; x + y = 60
                                      ; x - y = 10
                                      (logic/== y (- 60 x))
                                      (logic/== x (+ 10 y)))))

But it returns (["10<lvar:y_6>" NaN]) (I would expect 35 and 25).

How do I approach that? I don't want to use clojure.core.logic.fd because I'm using ClojureScript - is that possible at all? Would it be possible with fd?


Note that those equations are an example only. In my real-world scenario I want to solve something more like that:

x + H + y = W
x / y * 100 = V

For now I simplified those to get the most basic example running, but the solution to the above is also welcome :)

1

There are 1 answers

0
nberger On

The cljs version of core.async cannot solve this kind of problem yet, because the fd namespace has not been migrated from the clj version.

Using the clojure version, we can solve it this way:

(require '[clojure.core.logic :as logic]
         '[clojure.core.logic.fd :as fd])

(logic/run* [q]
  (logic/fresh [x y]
    (logic/== q [x y])
    (fd/in x y (fd/interval 0 100))
    (fd/eq (= 60 (+ x y)))
    (fd/eq (= 10 (- x y)))))

Result: ([35 25])

Instead of using logic/project we use fd/eq to express the relation between the LVars, and fd/interval to constrain their values into that interval.

In this answer @dnolen explains that "you cannot project finite domain vars that haven't been constrained to single value".