如何使用core.logic求解数学方程

时间:2012-09-25 22:36:47

标签: clojure clojure-core.logic

我尝试在core.logic中输入一个查询:

(run* [q] (== 0 (+ (* q q) (* 4 q) 4)))

提示说,

error: lvar cannot be cast to a number

如果我没有完全误解逻辑编程是什么,有没有办法使用core.logic来解决这个问题?

3 个答案:

答案 0 :(得分:5)

到目前为止,我发现core.logic不能用代数来解决这个等式。虽然数学的输入需要是实际值而不是LVar s,因为数学函数不能对这些数据进行操作,它可以进行基本数学运算:

user> (run* [q]
   (fresh [x]
        (== x 1)
       (project [x] (== q (+ (* x x) 4)))))
(5)

在x具有清除值时有效,在x不具有时失败:

user> (run* [q]
   (fresh [x]
        (== x q)
        (project [x] (== q (+ (* x x) 4)))))
ClassCastException clojure.core.logic.LVar cannot be cast to java.lang.Number

答案 1 :(得分:5)

你应该阅读The Reasoned Schemer的想法。基本上,在逻辑程序中进行数学运算的方法是创建基于列表的数字编码,逻辑引擎可以根据需要增长以进行尝试。我没有这本书很方便,但它将整数编码为一个位列表,以某种奇怪的方式我不记得:可能(1)代表0,(0)是非法的,而MSB列表中的最后一个?

无论如何,这是很多工作; David Nolen最近还在core.logic中介绍了有限域的内容。我不知道这些是如何工作的,但我认为它们可以通过指定哪些类型的数字作为解决问题的方法来为您简化问题。

答案 2 :(得分:2)

当前形式的

core.logic并非设计为数值方程求解器 - 它更适合于求解逻辑和关系表达式。

你基本上有两条解决数学方程式的实用路线:

  • 分析解算器 - 对于简单的情况,可以很容易地找到解决方案,例如像上面那样的二次方程式,但开始变得越来越复杂,然后变得不可能/不可用于许多方程式。这是一个巨大的开放研究课题。
  • 数值解算器 - 这些技术更加通用,几乎可用于任何类型的方程式。然而,结果并不准确,如果方程具有“令人讨厌的”特征(不连续性,奇数梯度,复杂的局部最小值集等),算法可能无法找到正确的解决方案。

方程求解器需要特殊的智能来理解数学方程的“规则”,例如:如何计算多项式表达式(对于解析解)或如何估计导数(对于数值解)。

一些可能有趣的链接: