在Prolog中解决极其简单的方程:A = B + C?

5

我有一个非常简单的方程式,希望能在prolog中解决:

A = B + C

我想写一个谓词来表达这个关系,可以处理任何一个参数未被实例化的情况。不需要推广到更复杂的关系或方程。

myEquation(A, B, C) :-
...something...

我可以使用以下语义来调用它:
myEquation(A,1,2).
>    A = 3.
myEquation(3,B,2).
>    B = 1.
myEquation(3,1,C).
>    C = 2.

有什么想法吗?使用算术运算符会导致很多“Arguments are not sufficiently instantiated”错误。看起来解决任意方程组超出了大多数Prolog实现的范围,但我希望这个极其简单的方程是可处理的。


这并不超出大多数Prolog实现的范围。你只需要稍微阅读一下。 ;) 你看过CLP(约束逻辑编程)库吗? - lurker
2
请查看plus/3。 - CapelliC
感谢lurker和CapelliC。我正在一个非常小的golang prolog环境中工作,而CLP库有点过于庞大(虽然很棒!感谢指引)。看到plus/3的实现让我开始了这个项目。 - yurbles
1
你也可以“长手写”你的谓词(不使用plus/3),通过检查给定的变量来实现。例如,如果A是一个整数,那么integer(A)将返回true。只需要几个子句或if-then-else结构来检查每种情况。 - lurker
2个回答

5

虽然不是特别花哨,但这就是它。如果您不是绝对的初学者,您也可以做到这一点:

myEquation(A, B, C):- 
    var(A),number(B),number(C) -> A is B+C;
    var(B),number(A),number(C) -> B is A-C;
    var(C),number(A),number(B) -> C is A-B;
    A =:= B + C.

更新: 与约束逻辑编程相同:
:- use_module(library(clpq)).

myEquation(A, B, C):-
    {A = B + C}.

2
你的第一个版本是错误的。可靠消息告诉我,myEquation(0,0,0) 应该成功,但是你的版本失败了。测试 var(A) 等通常容易出错。相反,只测试 nonvar(X) 并在最后一种情况下使用未经检查的 (is)/2 - false
@zslevi:请删除错误的版本,这样我们就可以给您正确的解决方案投票了! - mat
@false:现在已经修复了。但我并没有看到var与nonvar之间的问题。 - zslevi
2
你目前的解决方案也是可行的,但需要额外的努力。此外,你有很多不对称性:myEquation(A,0+0,0)会产生一个实例化错误 - 它应该要么成功,要么产生类型错误。 - false

3
如果你的域是整数,使用
:- use_module(library(clpfd)).

:- assert(clpfd:full_answer).       % for SICStus Prolog

myEquation(A,B,C) :-
   A #= B+C.

以下是使用 4.3.2 版本的一些示例查询:

?- myEquation(A,B,C).
B+C#=A,A在inf..sup范围内,B在inf..sup范围内,C在inf..sup范围内?;
否
?- myEquation(A,2,C). 2+C#=A,A在inf..sup范围内,C在inf..sup范围内?; 否 ?- myEquation(X,X,X). X+X#=X,X在inf..sup范围内?; 否

让我们使用 7.3.3 版本运行相同的查询:

?- myEquation(A,B,C).
B+C#=A。
?- myEquation(A,2,C). 2+C#=A。 ?- myEquation(X,X,X). X = 0. % 成功确定

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接