Prolog中割的使用

Prolog中割的使用,prolog,prolog-cut,Prolog,Prolog Cut,我正在Prolog中重新编写以下函数: V1: f(X,Y):-X

我正在Prolog中重新编写以下函数:

V1:

f(X,Y):-X<2,Y是X+1。
f(X,3):-2=
作为V2:

f(X,Y) :-
    X < 2,
    Y is X + 1. 
f(X,Y) :-
    X >= 2,
    X < 5,
    Y is 3.
f(X,Y) :-
    X >= 5,
    Y is 8-X.
f(X,Y):-
X<2,
Y是X+1。
f(X,Y):-
X>=2,
X<5,
Y是3。
f(X,Y):-
X>=5,
Y是8-X。
然后我想尝试切割。对于绿色切割(V3):

f(X,Y):-
X<2!,
Y是X+1。
f(X,Y):-
X>=2,
X<5!,
Y是3。
f(X,Y):-
X>=5,
Y是8-X。
对于红色切割(V4):

f(X,Y):-
X<2!,
Y是X+1。
f(X,Y):-
X<5!,
Y是3。
f(X,Y):-
Y是8-X。

然而,我不理解它们的优点,因为删除剪切将允许代码的相同行为。。。有什么帮助吗?

如您所述,第一个版本显示绿色切割,第二个显示红色切割。 没有必要让你感觉到这两个版本之间的差异

a) 一个原因可能是效率,但对于快速机器的玩具代码,你几乎没有注意到

b) 在绿色剪切的情况下,规则的混乱不应该改变代码的行为,对于第一个代码也是如此。但在第二个代码中,如果将第二个子句放在第一个子句之前,则行为会发生变化:f(0,3)为true,但最初为false。因此,如果你改变规则,你会感到不同


洗牌的优点是,您不关心顺序,而关心内容——这是声明式编程的要点之一

您的所有版本V1..V4在观测上都是等效的,因此您的推理是正确的。尽管如此,还是存在差异

避免多余的选择点 在许多实现中,V1和V2的效率可能特别低,因为在内部,它们“留下了一个选择点”。之所以如此,是因为这些开场白没有进一步考虑其他规则。因此,每个目标
f(1,X)
都会消耗一些内存,这些内存只能在回溯(或使用!)时释放。下面是一个自己尝试的简单方法:

loop(Goal) :-
   Goal,
   loop(Goal).
以下是我在SWI中得到的信息:

?- time(loop(f1(1,2))).
% 5,991,554 inferences, 81.282 CPU in 81.443 seconds (100% CPU, 73713 Lips)
ERROR: Out of local stack
?- time(loop(f2(1,2))).
% 5,991,553 inferences, 85.032 CPU in 85.212 seconds (100% CPU, 70462 Lips)
ERROR: Out of local stack
而V3和V4似乎无限期地运行——至少比85秒长得多。像这样的实验对于非常小的程序来说很有趣,但对于较大的程序来说却不太实用。幸运的是,在许多序言中,有一种简单的方法可以判断查询是否是确定执行的。要查看您的系统是否执行此操作,请输入:

?- X = 1.
X = 1.
对于您的变体:

?- f1(1,2).
true ;        % <== Prolog asked for another answer
false.        % <== only to conclude that there is none.

?- f2(1,2).
true ;        % same again
false.

?- f3(1,2).
true.         % <== Prolog knows there will be no further answer

?- f4(1,2).
true.
?-f1(1,2)。

正确;%只是一个注释:您不想使用算术表达式求值谓词
is/2
来统一变量。使用
=/2
统一运算符。因此
Y=3
而不是
Y是3
。你好@louger谢谢,在一个在线教程中,我被告知不要使用is/2。。。有什么具体原因吗?
is/2
在这种情况下有效,但它的作用实际上是从算术表达式中赋值。在更一般的情况下,如果
右侧的术语为/2
有任何变量,则会产生错误。统一的任务是统一两个术语。所以你可以说,
Y=3
3=Y
,两者都可以工作。当你有一个谓词头
f(X,3)
并且你查询
f(a,B)
时,prolog在
B
3
之间执行统一,而不是
B隐式地是3
?- time(loop(f1(1,2))).
% 5,991,554 inferences, 81.282 CPU in 81.443 seconds (100% CPU, 73713 Lips)
ERROR: Out of local stack
?- time(loop(f2(1,2))).
% 5,991,553 inferences, 85.032 CPU in 85.212 seconds (100% CPU, 70462 Lips)
ERROR: Out of local stack
?- X = 1.
X = 1.
?- f1(1,2).
true ;        % <== Prolog asked for another answer
false.        % <== only to conclude that there is none.

?- f2(1,2).
true ;        % same again
false.

?- f3(1,2).
true.         % <== Prolog knows there will be no further answer

?- f4(1,2).
true.