28 Sets

A very important mathematical concept, maybe the most important of all, are sets. Mathematically a set is an abstract object such that each object is either an element of the set or it is not. So a set is a collection like a list, and in fact GAP3 uses lists to represent sets. Note that this of course implies that GAP3 only deals with finite sets.

Unlike a list a set must not contain an element several times. It simply makes no sense to say that an object is twice an element of a set, because an object is either an element of a set, or it is not. Therefore the list that is used to represent a set has no duplicates, that is, no two elements of such a list are equal.

Also unlike a list a set does not impose any ordering on the elements. Again it simply makes no sense to say that an object is the first or second etc. element of a set, because, again, an object is either an element of a set, or it is not. Since ordering is not defined for a set we can put the elements in any order into the list used to represent the set. We put the elements sorted into the list, because this ordering is very practical. For example if we convert a list into a set we have to remove duplicates, which is very easy to do after we have sorted the list, since then equal elements will be next to each other.

In short sets are represented by sorted lists without holes and duplicates in GAP3. Such a list is in this document called a proper set. Note that we guarantee this representation, so you may make use of the fact that a set is represented by a sorted list in your functions.

In some contexts (for example see Combinatorics), we also want to talk about multisets. A multiset is like a set, except that an element may appear several times in a multiset. Such multisets are represented by sorted lists with holes that may have duplicates.

The first section in this chapter describes the functions to test if an object is a set and to convert objects to sets (see IsSet and Set).

The next section describes the function that tests if two sets are equal (see IsEqualSet).

The next sections describe the destructive functions that compute the standard set operations for sets (see AddSet, RemoveSet, UniteSet, IntersectSet, and SubtractSet).

The last section tells you more about sets and their internal representation (see More about Sets).

All set theoretic functions, especially Intersection and Union, also accept sets as arguments. Thus all functions described in chapter Domains are applicable to sets (see Set Functions for Sets).

Since sets are just a special case of lists, all the operations and functions for lists, especially the membership test (see In), can be used for sets just as well (see Lists).

Subsections

  1. IsSet
  2. Set
  3. IsEqualSet
  4. AddSet
  5. RemoveSet
  6. UniteSet
  7. IntersectSet
  8. SubtractSet
  9. Set Functions for Sets
  10. More about Sets

28.1 IsSet

IsSet( obj )

IsSet returns true if the object obj is a set and false otherwise. An object is a set if it is a sorted lists without holes or duplicates. Will cause an error if evaluation of obj is an unbound variable.

    gap> IsSet( [] );
    true
    gap> IsSet( [ 2, 3, 5, 7, 11 ] );
    true
    gap> IsSet( [, 2, 3,, 5,, 7,,,, 11 ] );
    false        # this list contains holes
    gap> IsSet( [ 11, 7, 5, 3, 2 ] );
    false        # this list is not sorted
    gap> IsSet( [ 2, 2, 3, 5, 5, 7, 11, 11 ] );
    false        # this list contains duplicates
    gap> IsSet( 235711 );
    false        # this argument is not even a list 

28.2 Set

Set( list )

Set returns a new proper set, which is represented as a sorted list without holes or duplicates, containing the elements of the list list.

Set returns a new list even if the list list is already a proper set, in this case it is equivalent to ShallowCopy (see ShallowCopy). Thus the result is a new list that is not identical to any other list. The elements of the result are however identical to elements of list. If list contains equal elements, it is not specified to which of those the element of the result is identical (see Identical Lists).

    gap> Set( [3,2,11,7,2,,5] );
    [ 2, 3, 5, 7, 11 ]
    gap> Set( [] );
    [  ] 

28.3 IsEqualSet

IsEqualSet( list1, list2 )

IsEqualSet returns true if the two lists list1 and list2 are equal when viewed as sets, and false otherwise. list1 and list2 are equal if every element of list1 is also an element of list2 and if every element of list2 is also an element of list1.

If both lists are proper sets then they are of course equal if and only if they are also equal as lists. Thus IsEqualSet( list1, list2 ) is equivalent to Set( list1 ) = Set( list2 ) (see Set), but the former is more efficient.

    gap> IsEqualSet( [2,3,5,7,11], [11,7,5,3,2] );
    true
    gap> IsEqualSet( [2,3,5,7,11], [2,3,5,7,11,13] );
    false 

28.4 AddSet

AddSet( set, elm )

AddSet adds elm, which may be an elment of an arbitrary type, to the set set, which must be a proper set, otherwise an error will be signalled. If elm is already an element of the set set, the set is not changed. Otherwise elm is inserted at the correct position such that set is again a set afterwards.

    gap> s := [2,3,7,11];;
    gap> AddSet( s, 5 );  s;
    [ 2, 3, 5, 7, 11 ]
    gap> AddSet( s, 13 );  s;
    [ 2, 3, 5, 7, 11, 13 ]
    gap> AddSet( s, 3 );  s;
    [ 2, 3, 5, 7, 11, 13 ] 

RemoveSet (see RemoveSet) is the counterpart of AddSet.

28.5 RemoveSet

RemoveSet( set, elm )

RemoveSet removes the element elm, which may be an object of arbitrary type, from the set set, which must be a set, otherwise an error will be signalled. If elm is not an element of set nothing happens. If elm is an element it is removed and all the following elements in the list are moved one position forward.

    gap> s := [ 2, 3, 4, 5, 6, 7 ];;
    gap> RemoveSet( s, 6 );
    gap> s;
    [ 2, 3, 4, 5, 7 ]
    gap> RemoveSet( s, 10 );
    gap> s;
    [ 2, 3, 4, 5, 7 ] 

AddSet (see AddSet) is the counterpart of RemoveSet.

28.6 UniteSet

UniteSet( set1, set2 )

UniteSet unites the set set1 with the set set2. This is equivalent to adding all the elements in set2 to set1 (see AddSet). set1 must be a proper set, otherwise an error is signalled. set2 may also be list that is not a proper set, in which case UniteSet silently applies Set to it first (see Set). UniteSet returns nothing, it is only called to change set1.

    gap> set := [ 2, 3, 5, 7, 11 ];;
    gap> UniteSet( set, [ 4, 8, 9 ] );  set;
    [ 2, 3, 4, 5, 7, 8, 9, 11 ]
    gap> UniteSet( set, [ 16, 9, 25, 13, 16 ] );  set;
    [ 2, 3, 4, 5, 7, 8, 9, 11, 13, 16, 25 ] 

The function UnionSet (see Set Functions for Sets) is the nondestructive counterpart to the destructive procedure UniteSet.

28.7 IntersectSet

IntersectSet( set1, set2 )

IntersectSet intersects the set set1 with the set set2. This is equivalent to removing all the elements that are not in set2 from set1 (see RemoveSet). set1 must be a set, otherwise an error is signalled. set2 may be a list that is not a proper set, in which case IntersectSet silently applies Set to it first (see Set). IntersectSet returns nothing, it is only called to change set1.

    gap> set := [ 2, 3, 4, 5, 7, 8, 9, 11, 13, 16 ];;
    gap> IntersectSet( set, [ 3, 5, 7, 9, 11, 13, 15, 17 ] );  set;
    [ 3, 5, 7, 9, 11, 13 ]
    gap> IntersectSet( set, [ 9, 4, 6, 8 ] );  set;
    [ 9 ] 

The function IntersectionSet (see Set Functions for Sets) is the nondestructive counterpart to the destructive procedure IntersectSet.

28.8 SubtractSet

SubtractSet( set1, set2 )

SubtractSet subtracts the set set2 from the set set1. This is equivalent to removing all the elements in set2 from set1 (see RemoveSet). set1 must be a proper set, otherwise an error is signalled. set2 may be a list that is not a proper set, in which case SubtractSet applies Set to it first (see Set). SubtractSet returns nothing, it is only called to change set1.

    gap> set := [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];;
    gap> SubtractSet( set, [ 6, 10 ] );  set;
    [ 2, 3, 4, 5, 7, 8, 9, 11 ]
    gap> SubtractSet( set, [ 9, 4, 6, 8 ] );  set;
    [ 2, 3, 5, 7, 11 ] 

The function Difference (see Difference) is the nondestructive counterpart to destructive the procedure SubtractSet.

28.9 Set Functions for Sets

As was already mentioned in the introduction to this chapter all domain functions also accept sets as arguments. Thus all functions described in the chapter Domains are applicable to sets. This section describes those functions where it might be helpful to know the implementation of those functions for sets.

IsSubset( set1, set2 )

This is implemented by IsSubsetSet, which you can call directly to save a little bit of time. Either argument to IsSubsetSet may also be a list that is not a proper set, in which case IsSubset silently applies Set (see Set) to it first.

Union( set1, set2 )

This is implemented by UnionSet, which you can call directly to save a little bit of time. Note that UnionSet only accepts two sets, unlike Union, which accepts several sets or a list of sets. The result of UnionSet is a new set, represented as a sorted list without holes or duplicates. Each argument to UnionSet may also be a list that is not a proper set, in which case UnionSet silently applies Set (see Set) to this argument. UnionSet is implemented in terms of its destructive counterpart UniteSet (see UniteSet).

Intersection( set1, set2 )

This is implemented by IntersectionSet, which you can call directly to save a little bit of time. Note that IntersectionSet only accepts two sets, unlike Intersection, which accepts several sets or a list of sets. The result of IntersectionSet is a new set, represented as a sorted list without holes or duplicates. Each argument to IntersectionSet may also be a list that is not a proper set, in which case IntersectionSet silently applies Set (see Set) to this argument. IntersectionSet is implemented in terms of its destructive counterpart IntersectSet (see IntersectSet).

The result of IntersectionSet and UnionSet is always a new list, that is not identical to any other list. The elements of that list however are identical to the corresponding elements of set1. If set1 is not a proper list it is not specified to which of a number of equal elements in set1 the element in the result is identical (see Identical Lists).

28.10 More about Sets

In the previous section we defined a proper set as a sorted list without holes or duplicates. This representation is not only nice to use, it is also a good internal representation supporting efficient algorithms. For example the in operator can use binary instead of a linear search since a set is sorted. For another example Union only has to merge the sets.

However, all those set functions also allow lists that are not proper sets, silently making a copy of it and converting this copy to a set. Suppose all the functions would have to test their arguments every time, comparing each element with its successor, to see if they are proper sets. This would chew up most of the performance advantage again. For example suppose in would have to run over the whole list, to see if it is a proper set, so it could use the binary search. That would be ridiculous.

To avoid this a list that is a proper set may, but need not, have an internal flag set that tells those functions that this list is indeed a proper set. Those functions do not have to check this argument then, and can use the more efficient algorithms. This section tells you when a proper set obtains this flag, so you can write your functions in such a way that you make best use of the algorithms.

The results of Set, Difference, Intersection and Union are known to be sets by construction, and thus have the flag set upon creation.

If an argument to IsSet, IsEqualSet, IsSubset, Set, Difference, Intersection or Union is a proper set, that does not yet have the flag set, those functions will notice that and set the flag for this set. Note that in will use linear search if the right operand does not have the flag set, will therefore not detect if it is a proper set and will, unlike the functions above, never set the flag.

If you change a proper set, that does have this flag set, by assignment, Add or Append the set will generally lose it flag, even if the change is such that the resulting list is still a proper set. However if the set has more than 100 elements and the value assigned or added is not a list and not a record and the resulting list is still a proper set than it will keep the flag. Note that changing a list that is not a proper set will never set the flag, even if the resulting list is a proper set. Such a set will obtain the flag only if it is passed to a set function.

Suppose you have built a proper set in such a way that it does not have the flag set, and that you now want to perform lots of membership tests. Then you should call IsSet with that set as an argument. If it is indeed a proper set IsSet will set the flag, and the subsequent in operations will use the more efficient binary search. You can think of the call to IsSet as a hint to GAP3 that this list is a proper set.

There is no way you can set the flag for an ordinary list without going through the checking in IsSet. The internal functions depend so much on the fact that a list with this flag set is indeed sorted and without holes and duplicates that the risk would be too high to allow setting the flag without such a check.

Previous Up Next
Index

gap3-jm
27 Nov 2023