2015-06-08 2 views
1

Я пытаюсь использовать core.logic, чтобы выяснить ответ на следующие уравнения:core.logic CLP (FD) с ClojureScript

x + y = W 
x - y = V 

W и V оба данных, в то время как x и y являются значения I Я пытаюсь вычислить.

Я пробовал подходы, как (я заменял W с 60 и V с 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))))) 

Но она возвращает (["10<lvar:y_6>" NaN]) (я бы ожидать, 35 и 25).

Как подойти к этому? Я не хочу использовать clojure.core.logic.fd, потому что я использую ClojureScript - это вообще возможно? Можно ли с fd?


Обратите внимание, что эти уравнения являются только примером. В моей реальной ситуации я хочу, чтобы решить что-то еще как то:

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

Сейчас я упрощена тем, чтобы получить наиболее простой пример работает, но решение выше также приветствуется :)

+0

Почему бы просто не использовать обратную матрицу, чтобы решить эту проблему? Если это целые числа, тогда вы можете использовать форму Эрмита. – ClojureMostly

+0

@ Andre. Одна из причин, по которым я оцениваю core.logic, - иметь возможность четко выражать ограничения в моем коде - для удобочитаемости/ремонтопригодности. Поэтому, если для данной проблемы я бы интуитивно (используя математические обозначения) использовал пару уравнений для описания моей проблемы, я хотел бы передать эти уравнения в core.logic, чтобы получить неизвестные. – kamituel

+0

Gotcha, я прочитал ваше последнее предложение как «решение проблемы выше (математика) также приветствуется». Извини за это. – ClojureMostly

ответ

0

Версия cljs core.async еще не может решить эту проблему, поскольку пространство имен fd не было перенесено из версии clj.

Используя версию Clojure, мы можем решить это следующим образом:

(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))))) 

Результат: ([35 25])

Вместо использования logic/project мы используем fd/eq, чтобы выразить свое отношение между LVars и fd/interval, чтобы ограничить их значения в этот интервал.

В this answer @dnolen объясняет, что «вы не можете проецировать конечные области vars, которые не были ограничены одним значением».