如何避免整数基本情况的非终止?
How can I avoid nontermination with an integer base case?
我想写一个递归到 0 的谓词,但它总是无法终止。我使用故障切片将其缩小为:
f(a, 0).
f(b, 0).
f(X, Y) :- false.
当我将文件加载为 swipl -f test.pl
时,然后在提示中 运行 f(X, 0).
,我得到输出 X = a
但我没有看到 X = b
或获得新提示。我希望它表现得像 A is 1 + 1
,在那里我得到 A = 2.
和一个新的 ?-
提示符。
我可以用这样的东西让它工作,但它看起来不太干净:
f(X, 0) :- X = x.
f(X, Y) :- Y == 0 -> false; (NewY is Y - 1, f(X, NewY)).
对于列表,我可以将更一般的情况写成 f(X, [A|B])
以确保它仅适用于列表至少有一个元素的情况。我可以做一些类似的事情来确保这里更一般的情况只适用于 Y
不为 0 的情况吗?
我看过 this question,虽然它暗示了正确的方向,但这也不起作用:
:- use_module(library(clpfd)).
int_int_prod(_, 0, 0).
int_int_prod(Num1, Num2, Result) :-
Num2 #> 0,
NewNum2 #= Num2 - 1,
int_int_prod(Num1, NewNum2, NewResult),
Result #= Num1 + NewResult.
?- int_int_prod(0, 0, X).
运行 f(X,0)
,你得到 X = a
回来。注意白色 space。系统等待您的命令。
如果您在键盘上按 ;
,它会响应 X = b
。这是你不想发生的事情吗? (另一种选择是:按 .
)。毕竟,您的定义确实为该查询提供 两个 解决方案,X=a
和 X=b
。为什么 Prolog 应该跳过第二个?不应该。
另一件事是,它仍然等待(在 SWI 中测试,通过 [user]
从提示加载)第二个结果后的用户响应。要删除 that,只需删除第三个子句。无论如何,这完全是多余的:明确失败与找不到更多匹配子句时失败的效果相同。
没有第三个子句 f(X,Y) :- false.
,终止改进:
6 ?- f(X,0).
X = a ;
X = b.
% ^^ no white space, no waiting, immediate termination.
我想写一个递归到 0 的谓词,但它总是无法终止。我使用故障切片将其缩小为:
f(a, 0).
f(b, 0).
f(X, Y) :- false.
当我将文件加载为 swipl -f test.pl
时,然后在提示中 运行 f(X, 0).
,我得到输出 X = a
但我没有看到 X = b
或获得新提示。我希望它表现得像 A is 1 + 1
,在那里我得到 A = 2.
和一个新的 ?-
提示符。
我可以用这样的东西让它工作,但它看起来不太干净:
f(X, 0) :- X = x.
f(X, Y) :- Y == 0 -> false; (NewY is Y - 1, f(X, NewY)).
对于列表,我可以将更一般的情况写成 f(X, [A|B])
以确保它仅适用于列表至少有一个元素的情况。我可以做一些类似的事情来确保这里更一般的情况只适用于 Y
不为 0 的情况吗?
我看过 this question,虽然它暗示了正确的方向,但这也不起作用:
:- use_module(library(clpfd)).
int_int_prod(_, 0, 0).
int_int_prod(Num1, Num2, Result) :-
Num2 #> 0,
NewNum2 #= Num2 - 1,
int_int_prod(Num1, NewNum2, NewResult),
Result #= Num1 + NewResult.
?- int_int_prod(0, 0, X).
运行 f(X,0)
,你得到 X = a
回来。注意白色 space。系统等待您的命令。
如果您在键盘上按 ;
,它会响应 X = b
。这是你不想发生的事情吗? (另一种选择是:按 .
)。毕竟,您的定义确实为该查询提供 两个 解决方案,X=a
和 X=b
。为什么 Prolog 应该跳过第二个?不应该。
另一件事是,它仍然等待(在 SWI 中测试,通过 [user]
从提示加载)第二个结果后的用户响应。要删除 that,只需删除第三个子句。无论如何,这完全是多余的:明确失败与找不到更多匹配子句时失败的效果相同。
没有第三个子句 f(X,Y) :- false.
,终止改进:
6 ?- f(X,0).
X = a ;
X = b.
% ^^ no white space, no waiting, immediate termination.