File: proto.gi

package info (click to toggle)
gap 4.15.1-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 110,212 kB
  • sloc: ansic: 97,261; xml: 48,343; cpp: 13,946; sh: 4,900; perl: 1,650; javascript: 255; makefile: 252; ruby: 9
file content (168 lines) | stat: -rw-r--r-- 5,409 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#############################################################################
##
##  This file is part of GAP, a system for computational discrete algebra.
##  This file's authors include Andrew Solomon.
##
##  Copyright of GAP belongs to its developers, whose names are too numerous
##  to list here. Please refer to the COPYRIGHT file for details.
##
##  SPDX-License-Identifier: GPL-2.0-or-later
##
##  Declarations of utilities for fast prototyping of new GAP objects.
##


##########################################################################
##
#F  ArithmeticElementCreator(<spec>)
##
InstallGlobalFunction(ArithmeticElementCreator,
function(spec)
  local
    makeelt,        # the function returned
    inst_str,
    inst_str_bin,   # method installation strings
    repfilters,     # filters for representation
    mathfilters,    # filters for categories and properties
    cat, rep,       # the category and representation of the new elts
    allfilters,     # category and representation
    eFam, eType;    # the element family and element type

  # first check to see this hasn't already been done
  if not REREADING and IsBoundGlobal(Concatenation("Is",spec.ElementName)) then
    Error(Concatenation(spec.ElementName," already defined"));
  fi;

  # What mathematical filters can we deduce?
  mathfilters := IsObject;

  if IsBound(spec.Multiplication) then
    mathfilters :=  mathfilters and IsMultiplicativeElement;
  fi;

  if IsBound(spec.One) then
    mathfilters :=  mathfilters and IsMultiplicativeElementWithOne;
  fi;

  if IsBound(spec.Inverse) then
    mathfilters :=  mathfilters and IsMultiplicativeElementWithInverse;
  fi;

  if IsBound(spec.Addition) then
    mathfilters :=  mathfilters and IsNearAdditiveElement;
  fi;

  if IsBound(spec.Zero) then
    mathfilters :=  mathfilters and IsNearAdditiveElementWithZero;
  fi;

  if IsBound(spec.AdditiveInverse) then
    mathfilters :=  mathfilters and IsNearAdditiveElementWithInverse;
  fi;

  # what mathematical filters are explicitly asserted?
  if IsBound(spec.MathInfo) then
    mathfilters :=  mathfilters and spec.MathInfo;
  fi;

  # declare the elements category and collections category
  cat := NewCategory(Concatenation("Is",spec.ElementName), mathfilters);
  BindGlobal(Concatenation("Is",spec.ElementName), cat);
  DeclareCategoryCollections(Concatenation("Is",spec.ElementName));

  # See what representation specific filters we have.
  repfilters := IsComponentObjectRep;
  if IsBound(spec.RepInfo) then
    repfilters := repfilters and spec.RepInfo;
  fi;

  # declare the representastion with the single "data" component
  rep := NewRepresentation(Concatenation(spec.ElementName,"Rep"),
    repfilters, ["data"]);
  BindGlobal(Concatenation(spec.ElementName,"Rep"), rep);

  allfilters := cat and rep;

  # create the family
  eFam := NewFamily(Concatenation("Element family of ", spec.ElementName),
    cat);

  # create the type
  eType := NewType(eFam, allfilters);

  # the creation function
  makeelt := x->Objectify(eType, rec(data := x));
  ##
  ## Install the methods
  ##
  inst_str := Concatenation("for ", spec.ElementName);
  inst_str_bin := Concatenation("for ",spec.ElementName,
    " and ",spec.ElementName);

  if IsBound(spec.Multiplication) then
    InstallOtherMethod(\*, inst_str_bin, IsIdenticalObj,
    [allfilters, allfilters], 0,
    function(x, y) return makeelt(spec.Multiplication(x!.data, y!.data)); end);
  fi;

  if IsBound(spec.One) then
    InstallOtherMethod(OneOp, inst_str, true, [allfilters], 0,
    function(x) return makeelt(spec.One(x!.data)); end);
  fi;

  if IsBound(spec.Inverse) then
    InstallOtherMethod(InverseOp, inst_str, true, [allfilters], 0,
    function(x) return makeelt(spec.Inverse(x!.data)); end);
  fi;

  if IsBound(spec.Addition) then
    InstallOtherMethod(\+, inst_str_bin, IsIdenticalObj,
    [allfilters, allfilters], 0,
    function(x,y) return makeelt(spec.Addition(x!.data, y!.data)); end);
  fi;

  if IsBound(spec.Zero) then
    InstallOtherMethod(ZeroOp, inst_str, true, [allfilters], 0,
    function(x) return makeelt(spec.Zero(x!.data)); end);
  fi;

  if IsBound(spec.AdditiveInverse) then
    InstallOtherMethod(AdditiveInverseOp, inst_str,true, [allfilters], 0,
    function(x) return makeelt(spec.AdditiveInverse(x!.data)); end);
  fi;

  if IsBound(spec.Equality) then
    InstallOtherMethod(\=, inst_str_bin, IsIdenticalObj,
      [allfilters, allfilters], 0,
      function(x,y) return spec!.Equality(x!.data, y!.data); end);
  else
  InstallOtherMethod(\=, inst_str_bin, IsIdenticalObj,
    [allfilters, allfilters], 0,
    function(x,y) return x!.data = y!.data; end);
  fi;

  if IsBound(spec.LessThan) then
    InstallOtherMethod(\<, inst_str_bin, IsIdenticalObj,
      [allfilters, allfilters], 0,
      function(x,y) return spec!.LessThan(x!.data, y!.data); end);
  else
    InstallOtherMethod(\<, inst_str_bin, IsIdenticalObj,
      [allfilters, allfilters], 0,
      function(x,y) return x!.data < y!.data; end);
  fi;

  if IsBound(spec.Print) then
    InstallOtherMethod(PrintObj, inst_str,true, [allfilters], 0,
    function(x) spec.Print(x!.data); end);
  else
    InstallOtherMethod(PrintObj, inst_str,true, [allfilters], 0,
    function(x) Print(x!.data); end);
  fi;

  InstallOtherMethod(UnderlyingElement, inst_str, true,
    [allfilters], 0,
    function(x) return x!.data; end);

  return makeelt;

end);