克隆、复制序言列表
Cloning,Copying prolog list
我发现这段代码到处都是复制列表或克隆列表。
代码无处不在:
clone([],[]).
clone([H|T],[H|Z]):- clone(T,Z).
?-clone([1,2,3],Z).
Z=[1,2,3]
?-clone(2,Z).
false
除了lists
,这不会复制任何东西。上面代码的时间复杂度是O(n)
。
但是 Prolog 试图统一右侧和提升侧,对吗?这可以用更简单的方式来写,对吧?
喜欢clone1(Z,Z).
:
clone1(Z,Z).
?-clone1([1,2,3],Z).
Z=[1,2,3]
?-clone1(1,Z).
Z=1
?-clone1(!,Z).
Z =!
?-clone1(@,Z).
Z=(@)
我觉得 clone1(X, X).
更通用,几乎复制了传递给它的所有内容。它没有克隆 %
、(
、)
、()
。 clone1(%,Z)
失败,消息 % - used for commenting
。clone1
的时间复杂度是 O(1)
我可能错了。 clone1
各方面都比clone
好很多。
为什么这个 clone/copy 不是这样写的,即 clone(X, X).
我错过了什么?请向我解释我上面提供的两个代码之间的区别。如果两者都做同样的事情,为什么 clone1(X, X).
没有被使用并且没有人发布过它。
调用 clone1(Z,Z2)
与调用 Z = Z2
相同。哪个更基础。
区别在于,正如您自己指出的那样,clone/2
仅适用于列表,而 =/2
适用于所有有效的 Prolog 术语。
代码的另一点是学习Prolog中的列表处理;以便它作为您可能想要编写的其他递归列表处理任务的基础。比如映射、过滤、计数等
Sterling 和 Shapiro 的书将此类代码称为特定数据类型的骨架代码。
要记住的一件事是 "clone" 或 "copy" 的确切含义。变量会怎样?
例如,如果您使用统一进行克隆,则:
| ?- L1 = [1,2,X], L2 = L1.
L1 = [1,2,X]
L2 = [1,2,X]
yes
| ?- L1 = [1,2,X], L2 = L1, X = a.
L1 = [1,2,a]
L2 = [1,2,a]
X = a
yes
| ?-
换句话说,通过统一,任何以这种方式 "copied" 或 "cloned" 的相应变量保持统一(因为术语统一)。
如果在 "clone" 或 "copy" 时需要新变量,则需要使用 Prolog 的 copy_term/2
:
| ?- L1 = [1,2,X], copy_term(L1, L2), X = a.
L1 = [1,2,a]
L2 = [1,2,_]
X = a
yes
| ?-
所以现在 L2
是 L1
的副本,它在列表的第 3 个位置有自己的变量。
我发现这段代码到处都是复制列表或克隆列表。
代码无处不在:
clone([],[]).
clone([H|T],[H|Z]):- clone(T,Z).
?-clone([1,2,3],Z).
Z=[1,2,3]
?-clone(2,Z).
false
除了lists
,这不会复制任何东西。上面代码的时间复杂度是O(n)
。
但是 Prolog 试图统一右侧和提升侧,对吗?这可以用更简单的方式来写,对吧?
喜欢clone1(Z,Z).
:
clone1(Z,Z).
?-clone1([1,2,3],Z).
Z=[1,2,3]
?-clone1(1,Z).
Z=1
?-clone1(!,Z).
Z =!
?-clone1(@,Z).
Z=(@)
我觉得 clone1(X, X).
更通用,几乎复制了传递给它的所有内容。它没有克隆 %
、(
、)
、()
。 clone1(%,Z)
失败,消息 % - used for commenting
。clone1
的时间复杂度是 O(1)
我可能错了。 clone1
各方面都比clone
好很多。
为什么这个 clone/copy 不是这样写的,即 clone(X, X).
我错过了什么?请向我解释我上面提供的两个代码之间的区别。如果两者都做同样的事情,为什么 clone1(X, X).
没有被使用并且没有人发布过它。
调用 clone1(Z,Z2)
与调用 Z = Z2
相同。哪个更基础。
区别在于,正如您自己指出的那样,clone/2
仅适用于列表,而 =/2
适用于所有有效的 Prolog 术语。
代码的另一点是学习Prolog中的列表处理;以便它作为您可能想要编写的其他递归列表处理任务的基础。比如映射、过滤、计数等
Sterling 和 Shapiro 的书将此类代码称为特定数据类型的骨架代码。
要记住的一件事是 "clone" 或 "copy" 的确切含义。变量会怎样?
例如,如果您使用统一进行克隆,则:
| ?- L1 = [1,2,X], L2 = L1.
L1 = [1,2,X]
L2 = [1,2,X]
yes
| ?- L1 = [1,2,X], L2 = L1, X = a.
L1 = [1,2,a]
L2 = [1,2,a]
X = a
yes
| ?-
换句话说,通过统一,任何以这种方式 "copied" 或 "cloned" 的相应变量保持统一(因为术语统一)。
如果在 "clone" 或 "copy" 时需要新变量,则需要使用 Prolog 的 copy_term/2
:
| ?- L1 = [1,2,X], copy_term(L1, L2), X = a.
L1 = [1,2,a]
L2 = [1,2,_]
X = a
yes
| ?-
所以现在 L2
是 L1
的副本,它在列表的第 3 个位置有自己的变量。