Факториал в Clojure core.logic

Я хотел бы написать факториал, используя core.logic. Я нашел этот фрагмент пролога

factorial(0, 1).
factorial(N, M):- N1 is N - 1, factorial (N1, M1), M is N*M1.

и попытался перевести его в core.logic следующим образом

(defne factorialo [n m]
  ([0 1])
  ([n m] (fresh [n1 m1]
            (== (- n 1) n1)
            (== (* n m1) m)
            (factorialo n1 m1))))

(run* [q]
  (factorialo 3 q))

который терпит неудачу с сообщением

clojure.core.logic.LVar cannot be cast to java.lang.Number
  [Thrown class java.lang.ClassCastException]

Как правильно писать факториал в core.logic?


person mchlstckl    schedule 28.08.2012    source источник
comment
Это гипотетический вопрос или есть веская причина не писать его просто на Clojure?   -  person Bill    schedule 30.08.2012
comment
Цель состоит в том, чтобы изучить логическое программирование и возможности, предоставляемые библиотекой core.logic.   -  person mchlstckl    schedule 31.08.2012


Ответы (1)


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

(defne factorialo [n m]
  ([0 1])
  ([n m]
     (fresh [n1 m1]
       (project [n]
         (== n1 (- n 1)))
       (factorialo n1 m1)
       (project [n m1]
         (== m (* n m1))))))

(run 1 [q]
  (factorialo 3 q))

В альфа-версии core.logic 0.8.0 есть поддержка логического программирования с ограничениями в конечных доменах. Это улучшает арифметическую историю для Пролога:

(defne factorialfd [n m]
  ([0 1])
  ([n m]
     (fresh [n1 m1]
       (infd n1 m1 (interval 0 Integer/MAX_VALUE))
       (+fd n1 1 n)
       (factorialfd n1 m1)
       (*fd n m1 m))))

(run 1 [q]
  (infd q (interval 0 Integer/MAX_VALUE))
  (factorialfd 3 q))

Обратите внимание, что домены переменных должны быть указаны явно, но нам больше не нужно возиться с проекцией. Однако эта работа находится в очень альфа-статусе, и то, как эти решения будут выглядеть в будущем, может измениться.

person dnolen    schedule 30.08.2012
comment
Здорово! Спасибо за подробное объяснение. Мне очень нравится изучать логическое программирование и использовать core.logic. Продолжайте хорошую работу! - person mchlstckl; 31.08.2012