Ch3steR
Ch3steR

Reputation: 20689

Cloning,Copying prolog list

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

Answers (2)

lurker
lurker

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

Will Ness
Will Ness

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

Related Questions