Reputation: 20689
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.
Upvotes: 2
Views: 749
Reputation: 58324
One thing to keep in mind is what you exactly mean by "clone" or "copy". What happens to variables?
For example, if you use unification for cloning, then:
| ?- 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
| ?-
In other words, with unification, any corresponding variables that are "copied" or "cloned" in this way remain unified (since the terms are unified).
If you want new variables when you "clone" or "copy", you would want to use Prolog's copy_term/2
:
| ?- L1 = [1,2,X], copy_term(L1, L2), X = a.
L1 = [1,2,a]
L2 = [1,2,_]
X = a
yes
| ?-
So now L2
is a copy of L1
with it's own variable in the 3rd position in the list.
Upvotes: 7
Reputation: 71119
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.
Upvotes: 2