对于特定的剪辑,我遇到过非常奇怪的行为(对我而言)。从我的理解,一旦执行通过削减,它不能回溯到它上面。但这正是这段代码的作用。有人可以解释为什么会这样做吗?
以下是代码:
example([],[]).
example([X,Y,Z|Tail],[Z|NewTail]) :-
X < Y,
example(Tail,NewTail).
example([X,Y,Z|Tail],[X|NewTail]) :-
Y < Z,
example(Tail,NewTail).
example([X,Y,Z|Tail],[Y|NewTail]) :-
X < Z,
example(Tail,NewTail).
现在没有剪切,此特定输入的输出如下:
example([1,3,2,4,5,6],L).
L = [2, 6] ;
L = [2, 4] ;
L = [2, 5] ;
L = [3, 6] ;
L = [3, 4] ;
L = [3, 5].
现在,如果我添加以下剪辑:
example([],[]).
example([X,Y,Z|Tail],[Z|NewTail]) :-
X < Y,
example(Tail,NewTail).
example([X,Y,Z|Tail],[X|NewTail]) :-
Y < Z,
!, <---- cut here
example(Tail,NewTail).
example([X,Y,Z|Tail],[Y|NewTail]) :-
X < Z,
example(Tail,NewTail).
我希望它能够回归
L = [2,6] ;
L - [2,4].
一旦它通过了第三个条款的剪切,它就不能再回溯了。
相反,它返回:
L = [2, 6] ;
L = [2, 4] ;
L = [3, 6] ;
L = [3, 4]
为什么会这样?它实际上跳过了切口并开始执行第4条,为什么?
为什么它执行第4条,如果我将切割移动到第2条:
example([],[]).
example([X,Y,Z|Tail],[Z|NewTail]) :-
X < Y,
!, <---- cut here
example(Tail,NewTail).
example([X,Y,Z|Tail],[X|NewTail]) :-
Y < Z,
example(Tail,NewTail).
example([X,Y,Z|Tail],[Y|NewTail]) :-
X < Z,
example(Tail,NewTail).
它只产生:
L = [2, 6].
为什么裁员在第2条中有效,但在第3条中却没有?这对我来说毫无意义。
答案 0 :(得分:2)
最后一个代码段的剪辑工作两次,从而阻止了预期的替代方案:
?- leash(-all).
true.
?- trace.
true.
[trace] ?- example([1,3,2,4,5,6],L).
Call: (6) example([1, 3, 2, 4, 5, 6], _G6183)
Call: (7) 1<3
Exit: (7) 1<3
Call: (7) example([4, 5, 6], _G6267)
Call: (8) 4<5
Exit: (8) 4<5
Call: (8) example([], _G6270)
Exit: (8) example([], [])
Exit: (7) example([4, 5, 6], [6])
Exit: (6) example([1, 3, 2, 4, 5, 6], [2, 6])
L = [2, 6].