Prolog 不会终止带有 2 个参数的查询
Prolog does not terminate on query with 2 arguments
我是 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 的答案。
任何人都可以给我提示,如何解决这个问题?
编辑: 正如 false 指出的那样:
您找不到答案的原因是您的规则 numberpair/1 不会终止。您找不到答案的原因是 Prolog 在它首先列出 A 的所有可能性,然后列出 B 的可能性(请注意,两者都有无限的可能性)。 Prolog 尝试首先为子句 numberpair(pair(A,B)) 找到答案,然后为以下子句 A=s(s(0)) 和 B=s(s(s(0))) .但由于 numberpair 已经不会终止,所以目前不会 "come"。
如果您更改 子句 目标的顺序并简单地在 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,也提供一个版本,它将以 "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 .
我是 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 的答案。
任何人都可以给我提示,如何解决这个问题?
编辑: 正如 false 指出的那样:
您找不到答案的原因是您的规则 numberpair/1 不会终止。您找不到答案的原因是 Prolog 在它首先列出 A 的所有可能性,然后列出 B 的可能性(请注意,两者都有无限的可能性)。 Prolog 尝试首先为子句 numberpair(pair(A,B)) 找到答案,然后为以下子句 A=s(s(0)) 和 B=s(s(s(0))) .但由于 numberpair 已经不会终止,所以目前不会 "come"。
如果您更改 子句 目标的顺序并简单地在 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,也提供一个版本,它将以 "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 .