9

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

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

提示说,

error: lvar cannot be cast to a number

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

4

3 回答 3

7

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

无论如何,这是很多工作;David Nolen 最近还在 core.logic 中引入了一些关于有限域的内容。我不知道它们是如何工作的,但我认为它们通过让您指定要考虑哪些类型的数字来解决您的问题,从而为您简化了很多问题。

于 2012-09-25T23:44:11.353 回答
6

据我所知,core.logic 不能用代数来求解这个方程。它可以进行基本数学运算,尽管该数学运算的输入需要是实际值而不是LVars,因为数学函数不能对这些进行运算:

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
于 2012-09-25T23:20:05.303 回答
4

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

您基本上有两种实用的方法来求解数学方程:

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

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

一些可能有趣的链接:

于 2012-09-27T03:21:14.030 回答