I found this piece of code everywhere for copying a list or cloning a list.
Code found everywhere:
clone([],[]).
clone([H|T],[H|Z]):- clone(T,Z).
?-clone([1,2,3],Z).
Z=[1,2,3]
?-clone(2,Z).
false
This doesn't copy anything other than lists
.The time complexity of the above code is O(n)
.
But Prolog tries to unify right and lift side, right? This can be written in a much simpler way, right?
Like 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=(@)
I feel clone1(X, X).
is much more generic and cloned almost everything passed to it. It did not clone %
,(
, )
, ()
. clone1(%,Z)
failed with the message % - used for commenting
.The time complexity of clone1
is O(1)
I may be wrong. In every aspect, clone1
is much better than clone
.
Why is this clone/copy written not like this, i.e. clone(X, X).
What am I missing? Please explain to me the difference between both codes I provided above. If both do the same why is clone1(X, X).
not used and no one had posted about it.
Calling clone1(Z,Z2)
is the same as calling Z = Z2
. Which is even more basic.
The difference is, as you've pointed out yourself, that clone/2
works only for lists, while =/2
works for all valid Prolog terms.
Another point to the code is to learn about list handling in Prolog; for it to serve as the basis for other recursive list-handling tasks you might want to write. Like mapping, filtering, counting, etc.
Sterling and Shapiro book calls such code a skeleton code for a certain data type.