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
GAP 3.4.4