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

zca*_*ate 8 clojure clojure-core.logic

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

(run* [q] (== 0 (+ (* q q) (* 4 q) 4)))
Run Code Online (Sandbox Code Playgroud)

提示说,

error: lvar cannot be cast to a number
Run Code Online (Sandbox Code Playgroud)

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

Art*_*ldt 5

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

user> (run* [q]
   (fresh [x]
        (== x 1)
       (project [x] (== q (+ (* x x) 4)))))
(5)
Run Code Online (Sandbox Code Playgroud)

当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
Run Code Online (Sandbox Code Playgroud)


ama*_*loy 5

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

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


mik*_*era 5

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

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

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

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

一些可能有趣的链接: