doc-src/AxClass/Group/Group.thy
changeset 9146 dde1affac73e
parent 8907 813fabceec00
child 9306 d0ef4a41ae63
equal deleted inserted replaced
9145:9f7b8de5bfaf 9146:dde1affac73e
     1 
     1 
     2 header {* Basic group theory *};
     2 header {* Basic group theory *}
     3 
     3 
     4 theory Group = Main:;
     4 theory Group = Main:
     5 
     5 
     6 text {*
     6 text {*
     7  \medskip\noindent The meta-type system of Isabelle supports
     7  \medskip\noindent The meta-type system of Isabelle supports
     8  \emph{intersections} and \emph{inclusions} of type classes. These
     8  \emph{intersections} and \emph{inclusions} of type classes. These
     9  directly correspond to intersections and inclusions of type
     9  directly correspond to intersections and inclusions of type
    10  predicates in a purely set theoretic sense. This is sufficient as a
    10  predicates in a purely set theoretic sense. This is sufficient as a
    11  means to describe simple hierarchies of structures.  As an
    11  means to describe simple hierarchies of structures.  As an
    12  illustration, we use the well-known example of semigroups, monoids,
    12  illustration, we use the well-known example of semigroups, monoids,
    13  general groups and Abelian groups.
    13  general groups and Abelian groups.
    14 *};
    14 *}
    15 
    15 
    16 subsection {* Monoids and Groups *};
    16 subsection {* Monoids and Groups *}
    17 
    17 
    18 text {*
    18 text {*
    19  First we declare some polymorphic constants required later for the
    19  First we declare some polymorphic constants required later for the
    20  signature parts of our structures.
    20  signature parts of our structures.
    21 *};
    21 *}
    22 
    22 
    23 consts
    23 consts
    24   times :: "'a => 'a => 'a"    (infixl "\<Otimes>" 70)
    24   times :: "'a => 'a => 'a"    (infixl "\<Otimes>" 70)
    25   inverse :: "'a => 'a"        ("(_\<inv>)" [1000] 999)
    25   inverse :: "'a => 'a"        ("(_\<inv>)" [1000] 999)
    26   one :: 'a                    ("\<unit>");
    26   one :: 'a                    ("\<unit>")
    27 
    27 
    28 text {*
    28 text {*
    29  \noindent Next we define class $monoid$ of monoids with operations
    29  \noindent Next we define class $monoid$ of monoids with operations
    30  $\TIMES$ and $1$.  Note that multiple class axioms are allowed for
    30  $\TIMES$ and $1$.  Note that multiple class axioms are allowed for
    31  user convenience --- they simply represent the conjunction of their
    31  user convenience --- they simply represent the conjunction of their
    32  respective universal closures.
    32  respective universal closures.
    33 *};
    33 *}
    34 
    34 
    35 axclass
    35 axclass
    36   monoid < "term"
    36   monoid < "term"
    37   assoc:      "(x \<Otimes> y) \<Otimes> z = x \<Otimes> (y \<Otimes> z)"
    37   assoc:      "(x \<Otimes> y) \<Otimes> z = x \<Otimes> (y \<Otimes> z)"
    38   left_unit:  "\<unit> \<Otimes> x = x"
    38   left_unit:  "\<unit> \<Otimes> x = x"
    39   right_unit: "x \<Otimes> \<unit> = x";
    39   right_unit: "x \<Otimes> \<unit> = x"
    40 
    40 
    41 text {*
    41 text {*
    42  \noindent So class $monoid$ contains exactly those types $\tau$ where
    42  \noindent So class $monoid$ contains exactly those types $\tau$ where
    43  $\TIMES :: \tau \To \tau \To \tau$ and $1 :: \tau$ are specified
    43  $\TIMES :: \tau \To \tau \To \tau$ and $1 :: \tau$ are specified
    44  appropriately, such that $\TIMES$ is associative and $1$ is a left
    44  appropriately, such that $\TIMES$ is associative and $1$ is a left
    45  and right unit element for $\TIMES$.
    45  and right unit element for $\TIMES$.
    46 *};
    46 *}
    47 
    47 
    48 text {*
    48 text {*
    49  \medskip Independently of $monoid$, we now define a linear hierarchy
    49  \medskip Independently of $monoid$, we now define a linear hierarchy
    50  of semigroups, general groups and Abelian groups.  Note that the
    50  of semigroups, general groups and Abelian groups.  Note that the
    51  names of class axioms are automatically qualified with each class
    51  names of class axioms are automatically qualified with each class
    52  name, so we may re-use common names such as $assoc$.
    52  name, so we may re-use common names such as $assoc$.
    53 *};
    53 *}
    54 
    54 
    55 axclass
    55 axclass
    56   semigroup < "term"
    56   semigroup < "term"
    57   assoc: "(x \<Otimes> y) \<Otimes> z = x \<Otimes> (y \<Otimes> z)";
    57   assoc: "(x \<Otimes> y) \<Otimes> z = x \<Otimes> (y \<Otimes> z)"
    58 
    58 
    59 axclass
    59 axclass
    60   group < semigroup
    60   group < semigroup
    61   left_unit:    "\<unit> \<Otimes> x = x"
    61   left_unit:    "\<unit> \<Otimes> x = x"
    62   left_inverse: "x\<inv> \<Otimes> x = \<unit>";
    62   left_inverse: "x\<inv> \<Otimes> x = \<unit>"
    63 
    63 
    64 axclass
    64 axclass
    65   agroup < group
    65   agroup < group
    66   commute: "x \<Otimes> y = y \<Otimes> x";
    66   commute: "x \<Otimes> y = y \<Otimes> x"
    67 
    67 
    68 text {*
    68 text {*
    69  \noindent Class $group$ inherits associativity of $\TIMES$ from
    69  \noindent Class $group$ inherits associativity of $\TIMES$ from
    70  $semigroup$ and adds two further group axioms. Similarly, $agroup$
    70  $semigroup$ and adds two further group axioms. Similarly, $agroup$
    71  is defined as the subset of $group$ such that for all of its elements
    71  is defined as the subset of $group$ such that for all of its elements
    72  $\tau$, the operation $\TIMES :: \tau \To \tau \To \tau$ is even
    72  $\tau$, the operation $\TIMES :: \tau \To \tau \To \tau$ is even
    73  commutative.
    73  commutative.
    74 *};
    74 *}
    75 
    75 
    76 
    76 
    77 subsection {* Abstract reasoning *};
    77 subsection {* Abstract reasoning *}
    78 
    78 
    79 text {*
    79 text {*
    80  In a sense, axiomatic type classes may be viewed as \emph{abstract
    80  In a sense, axiomatic type classes may be viewed as \emph{abstract
    81  theories}.  Above class definitions gives rise to abstract axioms
    81  theories}.  Above class definitions gives rise to abstract axioms
    82  $assoc$, $left_unit$, $left_inverse$, $commute$, where any of these
    82  $assoc$, $left_unit$, $left_inverse$, $commute$, where any of these
    90  \medskip From a technical point of view, abstract axioms are just
    90  \medskip From a technical point of view, abstract axioms are just
    91  ordinary Isabelle theorems, which may be used in proofs without
    91  ordinary Isabelle theorems, which may be used in proofs without
    92  special treatment.  Such ``abstract proofs'' usually yield new
    92  special treatment.  Such ``abstract proofs'' usually yield new
    93  ``abstract theorems''.  For example, we may now derive the following
    93  ``abstract theorems''.  For example, we may now derive the following
    94  well-known laws of general groups.
    94  well-known laws of general groups.
    95 *};
    95 *}
    96 
    96 
    97 theorem group_right_inverse: "x \<Otimes> x\<inv> = (\<unit>\\<Colon>'a\\<Colon>group)";
    97 theorem group_right_inverse: "x \<Otimes> x\<inv> = (\<unit>\\<Colon>'a\\<Colon>group)"
    98 proof -;
    98 proof -
    99   have "x \<Otimes> x\<inv> = \<unit> \<Otimes> (x \<Otimes> x\<inv>)";
    99   have "x \<Otimes> x\<inv> = \<unit> \<Otimes> (x \<Otimes> x\<inv>)"
   100     by (simp only: group.left_unit);
   100     by (simp only: group.left_unit)
   101   also; have "... = \<unit> \<Otimes> x \<Otimes> x\<inv>";
   101   also have "... = \<unit> \<Otimes> x \<Otimes> x\<inv>"
   102     by (simp only: semigroup.assoc);
   102     by (simp only: semigroup.assoc)
   103   also; have "... = (x\<inv>)\<inv> \<Otimes> x\<inv> \<Otimes> x \<Otimes> x\<inv>";
   103   also have "... = (x\<inv>)\<inv> \<Otimes> x\<inv> \<Otimes> x \<Otimes> x\<inv>"
   104     by (simp only: group.left_inverse);
   104     by (simp only: group.left_inverse)
   105   also; have "... = (x\<inv>)\<inv> \<Otimes> (x\<inv> \<Otimes> x) \<Otimes> x\<inv>";
   105   also have "... = (x\<inv>)\<inv> \<Otimes> (x\<inv> \<Otimes> x) \<Otimes> x\<inv>"
   106     by (simp only: semigroup.assoc);
   106     by (simp only: semigroup.assoc)
   107   also; have "... = (x\<inv>)\<inv> \<Otimes> \<unit> \<Otimes> x\<inv>";
   107   also have "... = (x\<inv>)\<inv> \<Otimes> \<unit> \<Otimes> x\<inv>"
   108     by (simp only: group.left_inverse);
   108     by (simp only: group.left_inverse)
   109   also; have "... = (x\<inv>)\<inv> \<Otimes> (\<unit> \<Otimes> x\<inv>)";
   109   also have "... = (x\<inv>)\<inv> \<Otimes> (\<unit> \<Otimes> x\<inv>)"
   110     by (simp only: semigroup.assoc);
   110     by (simp only: semigroup.assoc)
   111   also; have "... = (x\<inv>)\<inv> \<Otimes> x\<inv>";
   111   also have "... = (x\<inv>)\<inv> \<Otimes> x\<inv>"
   112     by (simp only: group.left_unit);
   112     by (simp only: group.left_unit)
   113   also; have "... = \<unit>";
   113   also have "... = \<unit>"
   114     by (simp only: group.left_inverse);
   114     by (simp only: group.left_inverse)
   115   finally; show ?thesis; .;
   115   finally show ?thesis .
   116 qed;
   116 qed
   117 
   117 
   118 text {*
   118 text {*
   119  \noindent With $group_right_inverse$ already available,
   119  \noindent With $group_right_inverse$ already available,
   120  $group_right_unit$\label{thm:group-right-unit} is now established
   120  $group_right_unit$\label{thm:group-right-unit} is now established
   121  much easier.
   121  much easier.
   122 *};
   122 *}
   123 
   123 
   124 theorem group_right_unit: "x \<Otimes> \<unit> = (x\\<Colon>'a\\<Colon>group)";
   124 theorem group_right_unit: "x \<Otimes> \<unit> = (x\\<Colon>'a\\<Colon>group)"
   125 proof -;
   125 proof -
   126   have "x \<Otimes> \<unit> = x \<Otimes> (x\<inv> \<Otimes> x)";
   126   have "x \<Otimes> \<unit> = x \<Otimes> (x\<inv> \<Otimes> x)"
   127     by (simp only: group.left_inverse);
   127     by (simp only: group.left_inverse)
   128   also; have "... = x \<Otimes> x\<inv> \<Otimes> x";
   128   also have "... = x \<Otimes> x\<inv> \<Otimes> x"
   129     by (simp only: semigroup.assoc);
   129     by (simp only: semigroup.assoc)
   130   also; have "... = \<unit> \<Otimes> x";
   130   also have "... = \<unit> \<Otimes> x"
   131     by (simp only: group_right_inverse);
   131     by (simp only: group_right_inverse)
   132   also; have "... = x";
   132   also have "... = x"
   133     by (simp only: group.left_unit);
   133     by (simp only: group.left_unit)
   134   finally; show ?thesis; .;
   134   finally show ?thesis .
   135 qed;
   135 qed
   136 
   136 
   137 text {*
   137 text {*
   138  \medskip Abstract theorems may be instantiated to only those types
   138  \medskip Abstract theorems may be instantiated to only those types
   139  $\tau$ where the appropriate class membership $\tau :: c$ is known at
   139  $\tau$ where the appropriate class membership $\tau :: c$ is known at
   140  Isabelle's type signature level.  Since we have $agroup \subseteq
   140  Isabelle's type signature level.  Since we have $agroup \subseteq
   141  group \subseteq semigroup$ by definition, all theorems of $semigroup$
   141  group \subseteq semigroup$ by definition, all theorems of $semigroup$
   142  and $group$ are automatically inherited by $group$ and $agroup$.
   142  and $group$ are automatically inherited by $group$ and $agroup$.
   143 *};
   143 *}
   144 
   144 
   145 
   145 
   146 subsection {* Abstract instantiation *};
   146 subsection {* Abstract instantiation *}
   147 
   147 
   148 text {*
   148 text {*
   149  From the definition, the $monoid$ and $group$ classes have been
   149  From the definition, the $monoid$ and $group$ classes have been
   150  independent.  Note that for monoids, $right_unit$ had to be included
   150  independent.  Note that for monoids, $right_unit$ had to be included
   151  as an axiom, but for groups both $right_unit$ and $right_inverse$ are
   151  as an axiom, but for groups both $right_unit$ and $right_inverse$ are
   179      \end{picture}
   179      \end{picture}
   180      \caption{Monoids and groups: according to definition, and by proof}
   180      \caption{Monoids and groups: according to definition, and by proof}
   181      \label{fig:monoid-group}
   181      \label{fig:monoid-group}
   182    \end{center}
   182    \end{center}
   183  \end{figure}
   183  \end{figure}
   184 *};
   184 *}
   185 
   185 
   186 instance monoid < semigroup;
   186 instance monoid < semigroup
   187 proof intro_classes;
   187 proof intro_classes
   188   fix x y z :: "'a\\<Colon>monoid";
   188   fix x y z :: "'a\\<Colon>monoid"
   189   show "x \<Otimes> y \<Otimes> z = x \<Otimes> (y \<Otimes> z)";
   189   show "x \<Otimes> y \<Otimes> z = x \<Otimes> (y \<Otimes> z)"
   190     by (rule monoid.assoc);
   190     by (rule monoid.assoc)
   191 qed;
   191 qed
   192 
   192 
   193 instance group < monoid;
   193 instance group < monoid
   194 proof intro_classes;
   194 proof intro_classes
   195   fix x y z :: "'a\\<Colon>group";
   195   fix x y z :: "'a\\<Colon>group"
   196   show "x \<Otimes> y \<Otimes> z = x \<Otimes> (y \<Otimes> z)";
   196   show "x \<Otimes> y \<Otimes> z = x \<Otimes> (y \<Otimes> z)"
   197     by (rule semigroup.assoc);
   197     by (rule semigroup.assoc)
   198   show "\<unit> \<Otimes> x = x";
   198   show "\<unit> \<Otimes> x = x"
   199     by (rule group.left_unit);
   199     by (rule group.left_unit)
   200   show "x \<Otimes> \<unit> = x";
   200   show "x \<Otimes> \<unit> = x"
   201     by (rule group_right_unit);
   201     by (rule group_right_unit)
   202 qed;
   202 qed
   203 
   203 
   204 text {*
   204 text {*
   205  \medskip The $\isakeyword{instance}$ command sets up an appropriate
   205  \medskip The $\isakeyword{instance}$ command sets up an appropriate
   206  goal that represents the class inclusion (or type arity, see
   206  goal that represents the class inclusion (or type arity, see
   207  \secref{sec:inst-arity}) to be proven
   207  \secref{sec:inst-arity}) to be proven
   209  method does back-chaining of class membership statements wrt.\ the
   209  method does back-chaining of class membership statements wrt.\ the
   210  hierarchy of any classes defined in the current theory; the effect is
   210  hierarchy of any classes defined in the current theory; the effect is
   211  to reduce to the initial statement to a number of goals that directly
   211  to reduce to the initial statement to a number of goals that directly
   212  correspond to any class axioms encountered on the path upwards
   212  correspond to any class axioms encountered on the path upwards
   213  through the class hierarchy.
   213  through the class hierarchy.
   214 *};
   214 *}
   215 
   215 
   216 
   216 
   217 subsection {* Concrete instantiation \label{sec:inst-arity} *};
   217 subsection {* Concrete instantiation \label{sec:inst-arity} *}
   218 
   218 
   219 text {*
   219 text {*
   220  So far we have covered the case of the form
   220  So far we have covered the case of the form
   221  $\isakeyword{instance}~c@1 < c@2$, namely \emph{abstract
   221  $\isakeyword{instance}~c@1 < c@2$, namely \emph{abstract
   222  instantiation} --- $c@1$ is more special than $c@2$ and thus an
   222  instantiation} --- $c@1$ is more special than $c@2$ and thus an
   227  transferred to Isabelle's type signature level.
   227  transferred to Isabelle's type signature level.
   228 
   228 
   229  \medskip As a typical example, we show that type $bool$ with
   229  \medskip As a typical example, we show that type $bool$ with
   230  exclusive-or as operation $\TIMES$, identity as $\isasyminv$, and
   230  exclusive-or as operation $\TIMES$, identity as $\isasyminv$, and
   231  $False$ as $1$ forms an Abelian group.
   231  $False$ as $1$ forms an Abelian group.
   232 *};
   232 *}
   233 
   233 
   234 defs
   234 defs
   235   times_bool_def:   "x \<Otimes> y \\<equiv> x \\<noteq> (y\\<Colon>bool)"
   235   times_bool_def:   "x \<Otimes> y \\<equiv> x \\<noteq> (y\\<Colon>bool)"
   236   inverse_bool_def: "x\<inv> \\<equiv> x\\<Colon>bool"
   236   inverse_bool_def: "x\<inv> \\<equiv> x\\<Colon>bool"
   237   unit_bool_def:    "\<unit> \\<equiv> False";
   237   unit_bool_def:    "\<unit> \\<equiv> False"
   238 
   238 
   239 text {*
   239 text {*
   240  \medskip It is important to note that above $\DEFS$ are just
   240  \medskip It is important to note that above $\DEFS$ are just
   241  overloaded meta-level constant definitions, where type classes are
   241  overloaded meta-level constant definitions, where type classes are
   242  not yet involved at all.  This form of constant definition with
   242  not yet involved at all.  This form of constant definition with
   247  best applied in the context of type classes.
   247  best applied in the context of type classes.
   248 
   248 
   249  \medskip Since we have chosen above $\DEFS$ of the generic group
   249  \medskip Since we have chosen above $\DEFS$ of the generic group
   250  operations on type $bool$ appropriately, the class membership $bool
   250  operations on type $bool$ appropriately, the class membership $bool
   251  :: agroup$ may be now derived as follows.
   251  :: agroup$ may be now derived as follows.
   252 *};
   252 *}
   253 
   253 
   254 instance bool :: agroup;
   254 instance bool :: agroup
   255 proof (intro_classes,
   255 proof (intro_classes,
   256     unfold times_bool_def inverse_bool_def unit_bool_def);
   256     unfold times_bool_def inverse_bool_def unit_bool_def)
   257   fix x y z;
   257   fix x y z
   258   show "((x \\<noteq> y) \\<noteq> z) = (x \\<noteq> (y \\<noteq> z))"; by blast;
   258   show "((x \\<noteq> y) \\<noteq> z) = (x \\<noteq> (y \\<noteq> z))" by blast
   259   show "(False \\<noteq> x) = x"; by blast;
   259   show "(False \\<noteq> x) = x" by blast
   260   show "(x \\<noteq> x) = False"; by blast;
   260   show "(x \\<noteq> x) = False" by blast
   261   show "(x \\<noteq> y) = (y \\<noteq> x)"; by blast;
   261   show "(x \\<noteq> y) = (y \\<noteq> x)" by blast
   262 qed;
   262 qed
   263 
   263 
   264 text {*
   264 text {*
   265  The result of an $\isakeyword{instance}$ statement is both expressed
   265  The result of an $\isakeyword{instance}$ statement is both expressed
   266  as a theorem of Isabelle's meta-logic, and as a type arity of the
   266  as a theorem of Isabelle's meta-logic, and as a type arity of the
   267  type signature.  The latter enables type-inference system to take
   267  type signature.  The latter enables type-inference system to take
   272  defining $\TIMES$ as addition, $\isasyminv$ as negation and $1$ as
   272  defining $\TIMES$ as addition, $\isasyminv$ as negation and $1$ as
   273  zero) or $list :: (term)semigroup$ (e.g.\ if $\TIMES$ is defined as
   273  zero) or $list :: (term)semigroup$ (e.g.\ if $\TIMES$ is defined as
   274  list append).  Thus, the characteristic constants $\TIMES$,
   274  list append).  Thus, the characteristic constants $\TIMES$,
   275  $\isasyminv$, $1$ really become overloaded, i.e.\ have different
   275  $\isasyminv$, $1$ really become overloaded, i.e.\ have different
   276  meanings on different types.
   276  meanings on different types.
   277 *};
   277 *}
   278 
   278 
   279 
   279 
   280 subsection {* Lifting and Functors *};
   280 subsection {* Lifting and Functors *}
   281 
   281 
   282 text {*
   282 text {*
   283  As already mentioned above, overloading in the simply-typed HOL
   283  As already mentioned above, overloading in the simply-typed HOL
   284  systems may include recursion over the syntactic structure of types.
   284  systems may include recursion over the syntactic structure of types.
   285  That is, definitional equations $c^\tau \equiv t$ may also contain
   285  That is, definitional equations $c^\tau \equiv t$ may also contain
   287  that are structurally simpler than $\tau$.
   287  that are structurally simpler than $\tau$.
   288 
   288 
   289  This feature enables us to \emph{lift operations}, say to Cartesian
   289  This feature enables us to \emph{lift operations}, say to Cartesian
   290  products, direct sums or function spaces.  Subsequently we lift
   290  products, direct sums or function spaces.  Subsequently we lift
   291  $\TIMES$ component-wise to binary products $\alpha \times \beta$.
   291  $\TIMES$ component-wise to binary products $\alpha \times \beta$.
   292 *};
   292 *}
   293 
   293 
   294 defs
   294 defs
   295   times_prod_def: "p \<Otimes> q \\<equiv> (fst p \<Otimes> fst q, snd p \<Otimes> snd q)";
   295   times_prod_def: "p \<Otimes> q \\<equiv> (fst p \<Otimes> fst q, snd p \<Otimes> snd q)"
   296 
   296 
   297 text {*
   297 text {*
   298  It is very easy to see that associativity of $\TIMES^\alpha$ and
   298  It is very easy to see that associativity of $\TIMES^\alpha$ and
   299  $\TIMES^\beta$ transfers to ${\TIMES}^{\alpha \times \beta}$.  Hence
   299  $\TIMES^\beta$ transfers to ${\TIMES}^{\alpha \times \beta}$.  Hence
   300  the binary type constructor $\times$ maps semigroups to semigroups.
   300  the binary type constructor $\times$ maps semigroups to semigroups.
   301  This may be established formally as follows.
   301  This may be established formally as follows.
   302 *};
   302 *}
   303 
   303 
   304 instance * :: (semigroup, semigroup) semigroup;
   304 instance * :: (semigroup, semigroup) semigroup
   305 proof (intro_classes, unfold times_prod_def);
   305 proof (intro_classes, unfold times_prod_def)
   306   fix p q r :: "'a\\<Colon>semigroup \\<times> 'b\\<Colon>semigroup";
   306   fix p q r :: "'a\\<Colon>semigroup \\<times> 'b\\<Colon>semigroup"
   307   show
   307   show
   308     "(fst (fst p \<Otimes> fst q, snd p \<Otimes> snd q) \<Otimes> fst r,
   308     "(fst (fst p \<Otimes> fst q, snd p \<Otimes> snd q) \<Otimes> fst r,
   309       snd (fst p \<Otimes> fst q, snd p \<Otimes> snd q) \<Otimes> snd r) =
   309       snd (fst p \<Otimes> fst q, snd p \<Otimes> snd q) \<Otimes> snd r) =
   310        (fst p \<Otimes> fst (fst q \<Otimes> fst r, snd q \<Otimes> snd r),
   310        (fst p \<Otimes> fst (fst q \<Otimes> fst r, snd q \<Otimes> snd r),
   311         snd p \<Otimes> snd (fst q \<Otimes> fst r, snd q \<Otimes> snd r))";
   311         snd p \<Otimes> snd (fst q \<Otimes> fst r, snd q \<Otimes> snd r))"
   312     by (simp add: semigroup.assoc);
   312     by (simp add: semigroup.assoc)
   313 qed;
   313 qed
   314 
   314 
   315 text {*
   315 text {*
   316  Thus, if we view class instances as ``structures'', then overloaded
   316  Thus, if we view class instances as ``structures'', then overloaded
   317  constant definitions with recursion over types indirectly provide
   317  constant definitions with recursion over types indirectly provide
   318  some kind of ``functors'' --- i.e.\ mappings between abstract
   318  some kind of ``functors'' --- i.e.\ mappings between abstract
   319  theories.
   319  theories.
   320 *};
   320 *}
   321 
   321 
   322 end;
   322 end