有两种切割方式;绿色切割和红色切割。插入绿色切割只是为了提高效率并且不改变程序的语义。另一方面,红色切割可以。根据定义,绿色削减不会造成任何问题。
那么,如果没有削减,有没有办法改变行为?
让我们来看看; 对于要匹配的第一个子句,L1 应该与 [] 一致,L2 与 L 和 L3 与 L 一致,或者换句话说,L2 与 L3 一致。
当 L1 为 [] 时,第二个子句不能匹配;所以切割没有任何效果
当 L1 未实例化时:如果此时 L2 和 L3 的长度已知,则它们必须相等,否则第一个子句将不匹配;因此,第二个子句无法匹配,因为在每一步 L3 的长度都会减少 1,并且终止的唯一方法需要 L2=L3
如果 L3 或 L2 的长度未知:那么我们有一个问题,因为第二个子句可能会产生解决方案。
确实:
3 ?- append2(L1,L2,[1,2,3]).
L1 = [],
L2 = [1, 2, 3].
4 ?- append2(L1,[1,2,3],L3).
L1 = [],
L3 = [1, 2, 3].
5 ?- append2(L1,L2,L3).
L1 = [],
L2 = L3.
6 ?- append2(L1,[E1,E2],L3).
L1 = [],
L2 = [E1, E2].
7 ?- append2(L1,L2,[E1,E2]).
L1 = [],
L2 = [E1, E2].
虽然我们期望:
8 ?- append(L1,L2,[1,2,3]).
L1 = [],
L2 = [1, 2, 3] ;
L1 = [1],
L2 = [2, 3] ;
L1 = [1, 2],
L2 = [3] ;
L1 = [1, 2, 3],
L2 = [] ;
false.
9 ?- append(L1,[1,2,3],L3).
L1 = [],
L3 = [1, 2, 3] ;
L1 = [_G24],
L3 = [_G24, 1, 2, 3] ;
L1 = [_G24, _G30],
L3 = [_G24, _G30, 1, 2, 3] ;
L1 = [_G24, _G30, _G36],
L3 = [_G24, _G30, _G36, 1, 2, 3] ;
L1 = [_G24, _G30, _G36, _G42],
L3 = [_G24, _G30, _G36, _G42, 1, 2, 3] ;
...
10 ?- append(L1,L2,L3).
L1 = [],
L2 = L3 ;
L1 = [_G22],
L3 = [_G22|L2] ;
L1 = [_G22, _G28],
L3 = [_G22, _G28|L2] ;
....
11 ?- append(L1,[E1,E2],L3).
L1 = [],
L3 = [E1, E2] ;
L1 = [_G78],
L3 = [_G78, E1, E2] ;
L1 = [_G78, _G84],
L3 = [_G78, _G84, E1, E2] ;
L1 = [_G78, _G84, _G90],
L3 = [_G78, _G84, _G90, E1, E2] ;
...
12 ?- append(L1,L2,[E1,E2]).
L1 = [],
L2 = [E1, E2] ;
L1 = [E1],
L2 = [E2] ;
L1 = [E1, E2],
L2 = [] ;
false.