Clojure core.logic 中的阶乘
Posted
技术标签:
【中文标题】Clojure core.logic 中的阶乘【英文标题】:Factorial in Clojure core.logic 【发布时间】:2012-08-23 11:49:30 【问题描述】:我想使用 core.logic 编写阶乘。我找到了这个 prolog sn-p
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 中编写阶乘的正确方法是什么?
【问题讨论】:
这是一个假设性问题,还是有充分的理由不直接用 Clojure 编写它? 目的是学习逻辑编程和core.logic库提供的可能性。 【参考方案1】: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))
请注意,变量的域必须明确,但我们不再需要为投影而烦恼。然而,这项工作还处于 alpha 阶段,未来的解决方案可能会发生变化。
【讨论】:
太棒了!感谢您的详尽解释。我真的很喜欢学习逻辑编程以及如何使用 core.logic。继续努力!以上是关于Clojure core.logic 中的阶乘的主要内容,如果未能解决你的问题,请参考以下文章
core.logic lvars 上的算术和 clojure 函数
使用 clojure 的 core.logic / minikanren 查找相似的集合