Prolog不会在带有2个参数的查询中终止

Prolog不会在带有2个参数的查询中终止,prolog,successor-arithmetics,Prolog,Successor Arithmetics,我是Prolog新手,对编程练习有一个问题: 我有一个程序,大部分时间我的意见都是有效的,但是有一个具体的问题,我没有得到答案 is_number(0). is_number(s(N)) :- is_number(N). numberpair(pair(X,Y)) :- is_number(X), is_number(Y). ?- numberpair(pair(A,B)), A=s(s(0)), B=s(s(s(0))). 所以我理解,Prolog现在尝试A和B的每一个可能的

我是Prolog新手,对编程练习有一个问题:

我有一个程序,大部分时间我的意见都是有效的,但是有一个具体的问题,我没有得到答案

is_number(0).
is_number(s(N)) :-
  is_number(N).

numberpair(pair(X,Y)) :-
  is_number(X),
  is_number(Y).

?- numberpair(pair(A,B)), A=s(s(0)), B=s(s(s(0))).
所以我理解,Prolog现在尝试A和B的每一个可能的数字->[0,s(0),s(0)),s(s(0)),…]但是如果它找到了A的答案(即
s(0))
),它在B失败,在下一次调用中,它尝试A的下一个答案(即
s(0))
)等等。 现在的问题是,我希望Prolog停止,如果它找到A的答案,现在只搜索B的答案


谁能给我一个提示,如何解决这个问题?

编辑:正如false所指出的: 您找不到答案的原因是您的规则编号pair/1不会终止。你找不到答案的原因是Prolog以一种方式列举你的答案,它首先列出a的所有可能性,然后列出B的可能性(注意两者都有无限的可能性)。Prolog试图首先为子句numberpair(对(A,B))找到答案,然后为下面的子句A=s(s(0))和B=s(s(0))找到答案。但既然numberpair已经不会终止,它也不会“到来”

如果您更改子句目标的顺序,只需在numberpair(pair(A,B))之前调用A=s(s(0)),它将列出关于B可能性的所有答案(请注意,这仍然不会终止!)

编辑2,同时提供一个版本,该版本将以“公平”的方式枚举

这将为我们提供

?- numberpair(pair(A,B)).
A = B, B = 0 ;
A = 0,
B = s(0) ;
A = s(0),
B = 0 ;
A = 0,
B = s(s(0)) ;
A = B, B = s(0) ;
A = s(s(0)),
B = 0 ;
A = 0,
B = s(s(s(0))) ;
A = s(0),
B = s(s(0)) ;
A = s(s(0)),
B = s(0) ;
A = s(s(s(0))),
B = 0 .

打字错误:
numberpairD
-->
numberpair
?啊,是的,对不起……这没有答案,因为您的查询没有意义。您要求Prolog以某种方式神奇地看到查询的未来。它一次只能为一个目标成功。你不能让它在第三个目标(
B=s(s(0))
)上失败,并让它返回到第一个目标(
numberpair(pair(A,B))
),而是在返回时跳过第二个目标(
A=s(s(0))
)。你需要重新定义你的查询,这样它才有意义。@潜伏者:不是。
D
是如何解决这个问题的一个非常广泛的提示。@Enigmativity:这个查询确实有意义。它是这样写的:当被问及所有的解决方案时,这个特定的解决方案也会被找到。换句话说,枚举是公平的还是不公平的。好吧,对我来说是合乎逻辑的。»你找不到答案的原因是你的规则numberpair/1不会终止。«这不是原因——正如你在最后承认的那样。原因是无穷多个数对以一种非常不公平的方式枚举。这里的目标是为numberpair/1找到一个公平枚举。公平枚举是这样的吗:a=0,B=0a=s(0),B=0a=0,B=s(0)a=s(s(0)),B=0a=s(0),B=s(0)a=0,B=s(s(0))。。。还有更具体的:我尝试通过“广度优先搜索”而不是“深度优先搜索”来移动搜索树很好!请注意,你必须为此付出代价!
is_number(0).
is_number(s(N)) :-
  is_number(N).

number_number_sum(0,A,A).
number_number_sum(s(A),B,s(C)) :-
    number_number_sum(A,B,C).

numberpair(pair(X,Y)) :-
    is_number(Z),
    number_number_sum(X,Y,Z).
?- numberpair(pair(A,B)).
A = B, B = 0 ;
A = 0,
B = s(0) ;
A = s(0),
B = 0 ;
A = 0,
B = s(s(0)) ;
A = B, B = s(0) ;
A = s(s(0)),
B = 0 ;
A = 0,
B = s(s(s(0))) ;
A = s(0),
B = s(s(0)) ;
A = s(s(0)),
B = s(0) ;
A = s(s(s(0))),
B = 0 .