Modifying distinct lists in GAP when their values are equal

48 Views Asked by At

I am making some functions in GAP and am having weird issues with lists and variables. It seems like whenever two variables have the same value at a given point, any changes made to one will change the other even though I have defined them separately.

Here's a simple example illustrating my main problem. Suppose I write the code:

list:=[1,2,3];
list2:=list;
Add(list2,4);

Using this code, I would want to add 4 to list2, which would make list2=[1,2,3,4]. This part is fine. The unintended consequence here is that this also changes list to list=[1,2,3,4].

In this example, my question is: how do I change list2 without changing list?

2

There are 2 best solutions below

0
On BEST ANSWER

When assigning objects in GAP, the assignment is always a pointer to the objects. For objects that do not have the ability to change stored information that does not matter, but for lists or records it means that a change to the entries of the one object also changes the other.

To avoid this happening, there are two kinds of copy functions" ShallowCopy duplicates the top-level object, but changes the entries. StructuralCopy duplicates the whole structure (which is often wasting memory). If an object has no further substructures, both functions do the same. For example:

gap> l:=[[1,[2]],[3],4];
[ [ 1, [ 2 ] ], [ 3 ], 4 ]
gap> a:=l;
[ [ 1, [ 2 ] ], [ 3 ], 4 ]
gap> b:=ShallowCopy(l);
[ [ 1, [ 2 ] ], [ 3 ], 4 ]
gap> c:=StructuralCopy(l);
[ [ 1, [ 2 ] ], [ 3 ], 4 ]
gap> l[1][1];
1
gap> l[1][1]:=5;l;
5
[ [ 5, [ 2 ] ], [ 3 ], 4 ]
gap> a;b;c;
[ [ 5, [ 2 ] ], [ 3 ], 4 ]
[ [ 5, [ 2 ] ], [ 3 ], 4 ]
[ [ 1, [ 2 ] ], [ 3 ], 4 ]
gap> l[4]:=6;l;
6
[ [ 5, [ 2 ] ], [ 3 ], 4, 6 ]
gap> a;b;c;
[ [ 5, [ 2 ] ], [ 3 ], 4, 6 ]
[ [ 5, [ 2 ] ], [ 3 ], 4 ]
[ [ 1, [ 2 ] ], [ 3 ], 4 ]
gap> Add(l[1][2],7);l;
[ [ 5, [ 2, 7 ] ], [ 3 ], 4, 6 ]
gap> a;b;c;
[ [ 5, [ 2, 7 ] ], [ 3 ], 4, 6 ]
[ [ 5, [ 2, 7 ] ], [ 3 ], 4 ]
[ [ 1, [ 2 ] ], [ 3 ], 4 ]
0
On

I seem to have found an answer. One can define list2:=StructuralCopy(list) to make a "structural copy" of list, and then changes to list2 are not made to list. See here.

I'll leave the question open for a bit in case anyone has any other nice solutions.