Prolog 为什么可以';我的规则不能在一个简单的代数方程中解X吗?
我不熟悉Prolog,所以请温柔一点 这是我的规则:Prolog 为什么可以';我的规则不能在一个简单的代数方程中解X吗?,prolog,constraint-programming,Prolog,Constraint Programming,我不熟悉Prolog,所以请温柔一点 这是我的规则: solve(X) :- A = B, A is (7 * (X - 2)), B is (3 * (X + 4)). 显然,这里的正确答案是6.5。如果我将其交给Prolog,它将确认: | ?- solve(6.5). yes 但是,如果我让Prolog做脏活,它会抛出一个错误: | ?- solve(X). uncaught exception: error(instantiation_error,(is)/2) 我完全承认这里发
solve(X) :- A = B, A is (7 * (X - 2)), B is (3 * (X + 4)).
显然,这里的正确答案是6.5
。如果我将其交给Prolog,它将确认:
| ?- solve(6.5).
yes
但是,如果我让Prolog做脏活,它会抛出一个错误:
| ?- solve(X).
uncaught exception: error(instantiation_error,(is)/2)
我完全承认这里发生的一切都是由于我对序言的误解。有人能给我解释一下我该如何使它工作或者为什么它不工作吗?在序言中,
是一个算术求值操作符。它计算表达式右侧的结果,并将其分配给左侧的变量
要计算的表达式必须仅包含数字和算术运算符/函数。换句话说,要计算表达式,is
必须已经知道其中的所有数字
另一种说法是,与双向的=
不同。这正是你所期望的。这就是你所犯错误的意义
解决这样的方程-约束-是一个工程师的工作 Prolog通过统一工作。它试图使结构相同
例如,如果我尝试将[3,X,5]
与[3,4,5]
统一起来,这很好,并且X=4
在代码中,您首先说的是A=B
。这很好,因为最初的A
和B
没有实例化,所以基本上是将它们的命运联系在一起-如果A
后来被实例化,那么B
也会自动实例化,反之亦然
然后你继续问A是(7*(X-2))
。现在,如果您已经将X
与6.5
统一,则可以对其进行评估-A
然后与7*(6.5-2)
或31.5
统一。但是请记住,A
已经与B
统一,因此B
现在也是31.5
现在你说B是(3*(X+4))
。因此,使用X
统一到6.5
和B
统一到31.5
,这与31.5是(3*(6.5+4))
相同。右侧是31.5
,因此这是31.5是31.5
,这是正确的
因此,求解solve(6.5)
是可行的
但是,如果您尝试求解
X
,那么第一个谓词就可以正常工作。但是第二个没有。这就像我问“比我想的数字少2的7倍数字是多少?”除非我告诉你我想的数字,否则你不能给我答案。Prolog也是如此。它卡住并报告错误。您可以为此使用库,至少在SWI Prolog中提供:库(clpr)和库(clpq)
以下是Reals的顶层:
?- use_module(library(clpr)).
true.
?- {7 * (X - 2) = 3 * (X + 4)}.
X = 6.5 ;
false.
或者,如果你使用理性:
?- use_module(library(clpq)).
true.
?- {7 * (X - 2) = 3 * (X + 4)}, R is float(X).
X = 13 rdiv 2,
R = 6.5.
如果你想自己做这件事,那当然要做更多的工作。您必须像这样编写代码
...,
( ground(X)
-> 7 * (X - 2) =:= 3 * (X + 4)
; X is (3*4 + 2*7) / (7 - 3)
),
...
顺便说一句,你在做什么:A=B,A是…,B是…
。
这有点危险,例如:
?- A = B, A is 3 - 2, B is sin(pi/2).
false.
?- 3 - 2 =:= sin(pi/2).
true.
3-2
计算为整数1;然后,sin(pi/2)
计算为浮点数1.0,这与整数1不一致。因此,第一个查询失败
?- 1 = 1.0.
false.
请考虑使用CLP(Q)代替CLP(R):我们不能相信CLP(R)的结果。