2

我是 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 的答案。

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

4

1 回答 1

2

编辑:正如错误指出的那样: 您找不到答案的原因是您的规则 numberpair/1 不会终止。您找不到答案的原因是 Prolog 以首先列出 A 的所有可能性然后列出 B 的可能性的方式枚举您的答案(请注意,两者都有无限的可能性)。Prolog 尝试首先为子句 numberpair(pair(A,B)) 找到答案,然后为以下子句 A=s(s(0)) 和 B=s(s(s(0))) . 但是由于 numberpair 已经不会终止,所以到目前为止它不会“到来”。

如果您更改子句目标的顺序并在 numberpair(pair(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,还提供一个版本,它将以“公平”的方式枚举!

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 .
于 2017-11-12T13:35:55.220 回答