45.4 Comparisons of Records

rec1 = rec2
rec1 < rec2

The equality operator = returns true if the record rec1 is equal to the record rec2 and false otherwise. The inequality operator < returns true if the record rec1 is not equal to rec2 and false otherwise.

Usually two records are considered equal, if for each component of one record the other record has a component of the same name with an equal value and vice versa. You can also compare records with other objects, they are of course different, unless the record has a special comparison function (see below) that says otherwise.

    gap> rec( a := 1, b := 2 ) = rec( b := 2, a := 1 );
    true
    gap> rec( a := 1, b := 2 ) = rec( a := 2, b := 1 );
    false
    gap> rec( a := 1 ) = rec( a := 1, b := 2 );
    false
    gap> rec( a := 1 ) = 1;
    false 

However a record may contain a special operations record that contains a function that is called when this record is an operand of a comparison. The precise mechanism is as follows. If the operand of the equality operator = is a record, and if this record has an element with the name operations that is a record, and if this record has an element with the name = that is a function, then this function is called with the operands of = as arguments, and the value of the operation is the result returned by this function. In this case a record may also be equal to an object of another type if this function says so. It is probably not a good idea to define a comparison function in such a way that the resulting relation is not an equivalence relation, i.e., not reflexive, symmetric, and transitive. Note that there is no corresponding < function, because left < right is implemented as not left = right.

The following example shows one piece of the definition of residue classes, using record operations. Of course this is far from a complete implementation (see About Defining New Group Elements). Note that the = must be quoted, so that it is taken as an identifier (see Identifiers).

    gap> ResidueClassOps := rec( );;
    gap> ResidueClassOps.\= := function ( l, r )
    >   return (l.modulus = r.modulus)
    >     and (l.representative-r.representative) mod l.modulus = 0;
    > end;;
    gap> ResidueClass := function ( representative, modulus )
    >   return rec(
    >     representative := representative,
    >     modulus        := modulus,
    >     operations     := ResidueClassOps );
    > end;;
    gap> l := ResidueClass( 13, 23 );;
    gap> r := ResidueClass( -10, 23 );;
    gap> l = r;
    true
    gap> l = ResidueClass( 10, 23 );
    false 

rec1 < rec2
rec1 <= rec2
rec1 rec2
rec1 = rec2

The operators <, <=, , and = evaluate to true if the record rec1 is less than, less than or equal to, greater than, and greater than or equal to the record rec2, and to false otherwise.

To compare records we imagine that the components of both records are sorted according to their names. Then the records are compared lexicographically with unbound elements considered smaller than anything else. Precisely one record rec1 is considered less than another record rec2 if rec2 has a component with name name2 and either rec1 has no component with this name or rec1.name2 < rec2.name2 and for each component of rec1 with name name1 < name2 rec2 has a component with this name and rec1.name1 = rec2.name1. Records may also be compared with objects of other types, they are greater than anything else, unless the record has a special comparison function (see below) that says otherwise.

    gap> rec( a := 1, b := 2 ) < rec( b := 2, a := 1 );
    false    # they are equal
    gap> rec( a := 1, b := 2 ) < rec( a := 2, b := 0 );
    true    # the 'a' elements are compared first and 1 is less than 2
    gap> rec( a := 1 ) < rec( a := 1, b := 2 );
    true    # unbound is less than 2
    gap> rec( a := 1 ) < rec( a := 0, b := 2 );
    false    # the 'a' elements are compared first and 0 is less than 1
    gap> rec( b := 1 ) < rec( b := 0, a := 2 );
    true    # the 'a'-s are compared first and unbound is less than 2
    gap> rec( a := 1 ) < 1;
    false    # other objects are less than records 

However a record may contain a special operations record that contains a function that is called when this record is an operand of a comparison. The precise mechanism is as follows. If the operand of the equality operator < is a record, and if this record has an element with the name operations that is a record, and if this record has an element with the name < that is a function, then this function is called with the operands of < as arguments, and the value of the operation is the result returned by this function. In this case a record may also be smaller than an object of another type if this function says so. It is probably not a good idea to define a comparison function in such a way that the resulting relation is not an ordering relation, i.e., not antisymmetric, and transitive. Note that there are no corresponding <=, , and = functions, since those operations are implemented as not right < left, right < left, and not left < right respectively.

The following example shows one piece of the definition of residue classes, using record operations. Of course this is far from a complete implementation (see About Defining New Group Elements). Note that the < must be quoted, so that it is taken as an identifier (see Identifiers).

    gap> ResidueClassOps := rec( );;
    gap> ResidueClassOps.\< := function ( l, r )
    >   if l.modulus <> r.modulus  then
    >     Error("<l> and <r> must have the same modulus");
    >   fi;
    >   return   l.representative mod l.modulus
    >          < r.representative mod r.modulus;
    > end;;
    gap> ResidueClass := function ( representative, modulus )
    >   return rec(
    >     representative := representative,
    >     modulus        := modulus,
    >     operations     := ResidueClassOps );
    > end;;
    gap> l := ResidueClass( 13, 23 );;
    gap> r := ResidueClass( -1, 23 );;
    gap> l < r;
    true    # 13 is less than 22
    gap> l < ResidueClass( 10, 23 );
    false    # 10 is less than 13 

Previous Up Top Next
Index

GAP 3.4.4
April 1997