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

时间:2017-11-12 12:06:37

标签: 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的所有可能数字 - > [0,s(0),s(s(0)),s(s(s(0))),...]但是如果它找到A的答案(即s(s(0))),它就会失败B并在下一次调用中,它尝试A的下一个答案(即s(s(s(0)))),依此类推。 现在问题是,我希望Prolog停止,如果它找到A的答案,现在只搜索B的答案。

任何人都可以给我一个提示,如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

编辑:正如虚假所指出: 您找不到答案的原因是您的规则编号对/ 1不会终止。您找不到答案的原因是Prolog列举了您的答案一种方式,它首先列出A的所有可能性,然后列出B的可能性(注意两者都有无限的可能性)。 Prolog尝试的是首先为子句numberpair(对(A,B))找到答案,然后对于以下从句A = s(s(0))和B = s(s(s(0))) 。但由于数字对已经终止,但它不会来#34;到目前为止。

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

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

A = s(s(0)),
B = 0 ;
A = s(s(0)),
B = s(0) ;
A = B, B = s(s(0)) ;
A = s(s(0)),
B = s(s(s(0))) .

编辑2 ,还提供一个版本,该版本将在" fair"中进行枚举。方式!

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 .