Арифметические и clojure функции на core.logic lvars - PullRequest
8 голосов
/ 06 октября 2011

Два связанных вопроса в одном:

Может ли модуль Clojure core.logic выполнять арифметику, логическое сравнение и т. Д., Как обычный пролог?Я предполагаю что-то вроде следующего:

(defrel points person n) 
(fact :bob 2)
(fact :charlie 3)
(run* [q] (fresh [x y] 
   (points :bob x) 
   (points :charlie y) 
   (< x y) 
   (== q (+ x y))))

=> (5)

В этом примере ни логическое сравнение (< x y), ни попытка привязки q к (+ x y) не работают.Я предполагаю, что это потому, что я работаю с LVar s, а не с целыми числами, и я не могу сделать эти сравнения, потому что символы еще не связаны.Но это работает в прологе:

points(bob, 2).
points(charlie, 3).
?- points(bob, X), points(charlie, Y), Result is X + Y.

=> Result = 5.

Аналогичным образом, могу ли я каким-то образом использовать функции Clojure (которые возвращают логические или другие «истинные» значения) в качестве логических предикатов?Другими словами, использовать функции, чтобы указать Minikanren, какие термины объединять или нет.Что-то вроде:

(defmagic startswithhi-o [v]
  (.startsWith v "hi"))
(defrel person n)
(fact person "bob")
(fact person "hillary")
(run* [q] 
   (fresh [n]
     (person n)
     (startswithhi-o n)
     (== q n)))

=> ("hillary")

Если я пытаюсь сделать что-то подобное, я получаю ошибки, также жалуюсь, что LVars не связаны.Есть ли способ сделать это?

И наконец, если кто-нибудь прочитал это далеко, я мог бы также спросить: есть ли планы по включению вероятностной логики в core.logic, например:

http://dtai.cs.kuleuven.be/problog/?

Я не задерживаю дыхание, но это было бы здорово!

Ответы [ 2 ]

10 голосов
/ 06 октября 2011

Нереляционная арифметика возможна через project.

(run 1 [q]
   (fresh [x y]
        (== x 1)
        (== y 2)
        (project [x y]
                 (== q (+ x y)))))
(3)

Я полагаю, что приведенный пример Пролога также нереляционный.

Вторую половину вашего вопроса также можно решить с помощью project, но вы должны быть осторожны, всегда вводя значение заземления.

(defn startwith [x]
    (project [x]
         (== true (.startsWith x "hi"))))

PS: задержите дыхание, чтобы программирование логики ограничений появилось на core.logic!

2 голосов
/ 06 октября 2011

Я полагаю, что вам необходимо "спроецировать" (не относиться к / проектировать) логическую переменную для ее привязки, прежде чем вы сможете применить к ней функцию:

(defrel points person n) 
(fact points :bob 2)
(fact points :charlie 3)
(run* [q] 
  (exist [x y] 
    (points :bob x) 
    (points :charlie y) 
    (project [x y]
      (== true (< x y)) 
      (== q (+ x y)))))

Обратите внимание, что существующий заменитель fresh в исходном фрагменте и дополнительный аргумент для объявлений фактов.

...