我想使用core.logic编写factorial。我找到了这个prolog片段
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中编写阶乘的正确方法是什么?
答案 0 :(得分:4)
Prolog中的算术通常意味着隐式投影 - 您不再与逻辑变量有关系,而是与它们绑定的实际值有关。在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 alphas中,支持有限域上的约束逻辑编程。这改善了Prolog的算术故事:
(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))
请注意,必须明确变量的域,但我们不再需要打扰投影。然而,这项工作是非常阿尔法的状态,未来这个解决方案的样子可能会发生变化。