src/Doc/Classes/Classes.thy
changeset 78664 d052d61da398
parent 76987 4c275405faae
equal deleted inserted replaced
78663:3032bc7d613d 78664:d052d61da398
    99   Depending on an arbitrary type \<open>\<alpha>\<close>, class \<open>semigroup\<close> introduces a binary operator \<open>(\<otimes>)\<close> that is
    99   Depending on an arbitrary type \<open>\<alpha>\<close>, class \<open>semigroup\<close> introduces a binary operator \<open>(\<otimes>)\<close> that is
   100   assumed to be associative:
   100   assumed to be associative:
   101 \<close>
   101 \<close>
   102 
   102 
   103 class %quote semigroup =
   103 class %quote semigroup =
   104   fixes mult :: "\<alpha> \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>"    (infixl "\<otimes>" 70)
   104   fixes mult :: \<open>\<alpha> \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>\<close>   (infixl \<open>\<otimes>\<close> 70)
   105   assumes assoc: "(x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"
   105   assumes assoc: \<open>(x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)\<close>
   106 
   106 
   107 text \<open>
   107 text \<open>
   108   \<^noindent> This @{command class} specification consists of two parts:
   108   \<^noindent> This @{command class} specification consists of two parts:
   109   the \qn{operational} part names the class parameter (@{element
   109   the \qn{operational} part names the class parameter (@{element
   110   "fixes"}), the \qn{logical} part specifies properties on them
   110   "fixes"}), the \qn{logical} part specifies properties on them
   111   (@{element "assumes"}).  The local @{element "fixes"} and @{element
   111   (@{element "assumes"}).  The local @{element "fixes"} and @{element
   112   "assumes"} are lifted to the theory toplevel, yielding the global
   112   "assumes"} are lifted to the theory toplevel, yielding the global
   113   parameter @{term [source] "mult :: \<alpha>::semigroup \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>"} and the
   113   parameter @{term [source] \<open>mult :: \<alpha>::semigroup \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>\<close>} and the
   114   global theorem @{fact "semigroup.assoc:"}~@{prop [source] "\<And>x y z ::
   114   global theorem @{fact "semigroup.assoc:"}~@{prop [source] \<open>\<And>x y z ::
   115   \<alpha>::semigroup. (x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"}.
   115   \<alpha>::semigroup. (x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)\<close>}.
   116 \<close>
   116 \<close>
   117 
   117 
   118 
   118 
   119 subsection \<open>Class instantiation \label{sec:class_inst}\<close>
   119 subsection \<open>Class instantiation \label{sec:class_inst}\<close>
   120 
   120 
   126 
   126 
   127 instantiation %quote int :: semigroup
   127 instantiation %quote int :: semigroup
   128 begin
   128 begin
   129 
   129 
   130 definition %quote
   130 definition %quote
   131   mult_int_def: "i \<otimes> j = i + (j::int)"
   131   mult_int_def: \<open>i \<otimes> j = i + (j::int)\<close>
   132 
   132 
   133 instance %quote proof
   133 instance %quote proof
   134   fix i j k :: int have "(i + j) + k = i + (j + k)" by simp
   134   fix i j k :: int have \<open>(i + j) + k = i + (j + k)\<close> by simp
   135   then show "(i \<otimes> j) \<otimes> k = i \<otimes> (j \<otimes> k)"
   135   then show \<open>(i \<otimes> j) \<otimes> k = i \<otimes> (j \<otimes> k)\<close>
   136     unfolding mult_int_def .
   136     unfolding mult_int_def .
   137 qed
   137 qed
   138 
   138 
   139 end %quote
   139 end %quote
   140 
   140 
   158 
   158 
   159 instantiation %quote nat :: semigroup
   159 instantiation %quote nat :: semigroup
   160 begin
   160 begin
   161 
   161 
   162 primrec %quote mult_nat where
   162 primrec %quote mult_nat where
   163   "(0::nat) \<otimes> n = n"
   163   \<open>(0::nat) \<otimes> n = n\<close>
   164   | "Suc m \<otimes> n = Suc (m \<otimes> n)"
   164   | \<open>Suc m \<otimes> n = Suc (m \<otimes> n)\<close>
   165 
   165 
   166 instance %quote proof
   166 instance %quote proof
   167   fix m n q :: nat 
   167   fix m n q :: nat 
   168   show "m \<otimes> n \<otimes> q = m \<otimes> (n \<otimes> q)"
   168   show \<open>m \<otimes> n \<otimes> q = m \<otimes> (n \<otimes> q)\<close>
   169     by (induct m) auto
   169     by (induct m) auto
   170 qed
   170 qed
   171 
   171 
   172 end %quote
   172 end %quote
   173 
   173 
   189 
   189 
   190 instantiation %quote prod :: (semigroup, semigroup) semigroup
   190 instantiation %quote prod :: (semigroup, semigroup) semigroup
   191 begin
   191 begin
   192 
   192 
   193 definition %quote
   193 definition %quote
   194   mult_prod_def: "p\<^sub>1 \<otimes> p\<^sub>2 = (fst p\<^sub>1 \<otimes> fst p\<^sub>2, snd p\<^sub>1 \<otimes> snd p\<^sub>2)"
   194   mult_prod_def: \<open>p\<^sub>1 \<otimes> p\<^sub>2 = (fst p\<^sub>1 \<otimes> fst p\<^sub>2, snd p\<^sub>1 \<otimes> snd p\<^sub>2)\<close>
   195 
   195 
   196 instance %quote proof
   196 instance %quote proof
   197   fix p\<^sub>1 p\<^sub>2 p\<^sub>3 :: "\<alpha>::semigroup \<times> \<beta>::semigroup"
   197   fix p\<^sub>1 p\<^sub>2 p\<^sub>3 :: \<open>\<alpha>::semigroup \<times> \<beta>::semigroup\<close>
   198   show "p\<^sub>1 \<otimes> p\<^sub>2 \<otimes> p\<^sub>3 = p\<^sub>1 \<otimes> (p\<^sub>2 \<otimes> p\<^sub>3)"
   198   show \<open>p\<^sub>1 \<otimes> p\<^sub>2 \<otimes> p\<^sub>3 = p\<^sub>1 \<otimes> (p\<^sub>2 \<otimes> p\<^sub>3)\<close>
   199     unfolding mult_prod_def by (simp add: assoc)
   199     unfolding mult_prod_def by (simp add: assoc)
   200 qed      
   200 qed      
   201 
   201 
   202 end %quote
   202 end %quote
   203 
   203 
   218   neutral) by extending \<^class>\<open>semigroup\<close> with one additional
   218   neutral) by extending \<^class>\<open>semigroup\<close> with one additional
   219   parameter \<open>neutral\<close> together with its characteristic property:
   219   parameter \<open>neutral\<close> together with its characteristic property:
   220 \<close>
   220 \<close>
   221 
   221 
   222 class %quote monoidl = semigroup +
   222 class %quote monoidl = semigroup +
   223   fixes neutral :: "\<alpha>" ("\<one>")
   223   fixes neutral :: \<open>\<alpha>\<close> (\<open>\<one>\<close>)
   224   assumes neutl: "\<one> \<otimes> x = x"
   224   assumes neutl: \<open>\<one> \<otimes> x = x\<close>
   225 
   225 
   226 text \<open>
   226 text \<open>
   227   \<^noindent> Again, we prove some instances, by providing suitable
   227   \<^noindent> Again, we prove some instances, by providing suitable
   228   parameter definitions and proofs for the additional specifications.
   228   parameter definitions and proofs for the additional specifications.
   229   Observe that instantiations for types with the same arity may be
   229   Observe that instantiations for types with the same arity may be
   232 
   232 
   233 instantiation %quote nat and int :: monoidl
   233 instantiation %quote nat and int :: monoidl
   234 begin
   234 begin
   235 
   235 
   236 definition %quote
   236 definition %quote
   237   neutral_nat_def: "\<one> = (0::nat)"
   237   neutral_nat_def: \<open>\<one> = (0::nat)\<close>
   238 
   238 
   239 definition %quote
   239 definition %quote
   240   neutral_int_def: "\<one> = (0::int)"
   240   neutral_int_def: \<open>\<one> = (0::int)\<close>
   241 
   241 
   242 instance %quote proof
   242 instance %quote proof
   243   fix n :: nat
   243   fix n :: nat
   244   show "\<one> \<otimes> n = n"
   244   show \<open>\<one> \<otimes> n = n\<close>
   245     unfolding neutral_nat_def by simp
   245     unfolding neutral_nat_def by simp
   246 next
   246 next
   247   fix k :: int
   247   fix k :: int
   248   show "\<one> \<otimes> k = k"
   248   show \<open>\<one> \<otimes> k = k\<close>
   249     unfolding neutral_int_def mult_int_def by simp
   249     unfolding neutral_int_def mult_int_def by simp
   250 qed
   250 qed
   251 
   251 
   252 end %quote
   252 end %quote
   253 
   253 
   254 instantiation %quote prod :: (monoidl, monoidl) monoidl
   254 instantiation %quote prod :: (monoidl, monoidl) monoidl
   255 begin
   255 begin
   256 
   256 
   257 definition %quote
   257 definition %quote
   258   neutral_prod_def: "\<one> = (\<one>, \<one>)"
   258   neutral_prod_def: \<open>\<one> = (\<one>, \<one>)\<close>
   259 
   259 
   260 instance %quote proof
   260 instance %quote proof
   261   fix p :: "\<alpha>::monoidl \<times> \<beta>::monoidl"
   261   fix p :: \<open>\<alpha>::monoidl \<times> \<beta>::monoidl\<close>
   262   show "\<one> \<otimes> p = p"
   262   show \<open>\<one> \<otimes> p = p\<close>
   263     unfolding neutral_prod_def mult_prod_def by (simp add: neutl)
   263     unfolding neutral_prod_def mult_prod_def by (simp add: neutl)
   264 qed
   264 qed
   265 
   265 
   266 end %quote
   266 end %quote
   267 
   267 
   269   \<^noindent> Fully-fledged monoids are modelled by another subclass,
   269   \<^noindent> Fully-fledged monoids are modelled by another subclass,
   270   which does not add new parameters but tightens the specification:
   270   which does not add new parameters but tightens the specification:
   271 \<close>
   271 \<close>
   272 
   272 
   273 class %quote monoid = monoidl +
   273 class %quote monoid = monoidl +
   274   assumes neutr: "x \<otimes> \<one> = x"
   274   assumes neutr: \<open>x \<otimes> \<one> = x\<close>
   275 
   275 
   276 instantiation %quote nat and int :: monoid 
   276 instantiation %quote nat and int :: monoid 
   277 begin
   277 begin
   278 
   278 
   279 instance %quote proof
   279 instance %quote proof
   280   fix n :: nat
   280   fix n :: nat
   281   show "n \<otimes> \<one> = n"
   281   show \<open>n \<otimes> \<one> = n\<close>
   282     unfolding neutral_nat_def by (induct n) simp_all
   282     unfolding neutral_nat_def by (induct n) simp_all
   283 next
   283 next
   284   fix k :: int
   284   fix k :: int
   285   show "k \<otimes> \<one> = k"
   285   show \<open>k \<otimes> \<one> = k\<close>
   286     unfolding neutral_int_def mult_int_def by simp
   286     unfolding neutral_int_def mult_int_def by simp
   287 qed
   287 qed
   288 
   288 
   289 end %quote
   289 end %quote
   290 
   290 
   291 instantiation %quote prod :: (monoid, monoid) monoid
   291 instantiation %quote prod :: (monoid, monoid) monoid
   292 begin
   292 begin
   293 
   293 
   294 instance %quote proof 
   294 instance %quote proof 
   295   fix p :: "\<alpha>::monoid \<times> \<beta>::monoid"
   295   fix p :: \<open>\<alpha>::monoid \<times> \<beta>::monoid\<close>
   296   show "p \<otimes> \<one> = p"
   296   show \<open>p \<otimes> \<one> = p\<close>
   297     unfolding neutral_prod_def mult_prod_def by (simp add: neutr)
   297     unfolding neutral_prod_def mult_prod_def by (simp add: neutr)
   298 qed
   298 qed
   299 
   299 
   300 end %quote
   300 end %quote
   301 
   301 
   302 text \<open>
   302 text \<open>
   303   \<^noindent> To finish our small algebra example, we add a \<open>group\<close> class with a corresponding instance:
   303   \<^noindent> To finish our small algebra example, we add a \<open>group\<close> class with a corresponding instance:
   304 \<close>
   304 \<close>
   305 
   305 
   306 class %quote group = monoidl +
   306 class %quote group = monoidl +
   307   fixes inverse :: "\<alpha> \<Rightarrow> \<alpha>"    ("(_\<div>)" [1000] 999)
   307   fixes inverse :: \<open>\<alpha> \<Rightarrow> \<alpha>\<close>    (\<open>(_\<div>)\<close> [1000] 999)
   308   assumes invl: "x\<div> \<otimes> x = \<one>"
   308   assumes invl: \<open>x\<div> \<otimes> x = \<one>\<close>
   309 
   309 
   310 instantiation %quote int :: group
   310 instantiation %quote int :: group
   311 begin
   311 begin
   312 
   312 
   313 definition %quote
   313 definition %quote
   314   inverse_int_def: "i\<div> = - (i::int)"
   314   inverse_int_def: \<open>i\<div> = - (i::int)\<close>
   315 
   315 
   316 instance %quote proof
   316 instance %quote proof
   317   fix i :: int
   317   fix i :: int
   318   have "-i + i = 0" by simp
   318   have \<open>-i + i = 0\<close> by simp
   319   then show "i\<div> \<otimes> i = \<one>"
   319   then show \<open>i\<div> \<otimes> i = \<one>\<close>
   320     unfolding mult_int_def neutral_int_def inverse_int_def .
   320     unfolding mult_int_def neutral_int_def inverse_int_def .
   321 qed
   321 qed
   322 
   322 
   323 end %quote
   323 end %quote
   324 
   324 
   333   link to Isar's locale system.  Indeed, the logical core of a class
   333   link to Isar's locale system.  Indeed, the logical core of a class
   334   is nothing other than a locale:
   334   is nothing other than a locale:
   335 \<close>
   335 \<close>
   336 
   336 
   337 class %quote idem =
   337 class %quote idem =
   338   fixes f :: "\<alpha> \<Rightarrow> \<alpha>"
   338   fixes f :: \<open>\<alpha> \<Rightarrow> \<alpha>\<close>
   339   assumes idem: "f (f x) = f x"
   339   assumes idem: \<open>f (f x) = f x\<close>
   340 
   340 
   341 text \<open>
   341 text \<open>
   342   \<^noindent> essentially introduces the locale
   342   \<^noindent> essentially introduces the locale
   343 \<close> (*<*)setup %invisible \<open>Sign.add_path "foo"\<close>
   343 \<close> (*<*)setup %invisible \<open>Sign.add_path "foo"\<close>
   344 (*>*)
   344 (*>*)
   345 locale %quote idem =
   345 locale %quote idem =
   346   fixes f :: "\<alpha> \<Rightarrow> \<alpha>"
   346   fixes f :: \<open>\<alpha> \<Rightarrow> \<alpha>\<close>
   347   assumes idem: "f (f x) = f x"
   347   assumes idem: \<open>f (f x) = f x\<close>
   348 
   348 
   349 text \<open>\<^noindent> together with corresponding constant(s):\<close>
   349 text \<open>\<^noindent> together with corresponding constant(s):\<close>
   350 
   350 
   351 consts %quote f :: "\<alpha> \<Rightarrow> \<alpha>"
   351 consts %quote f :: \<open>\<alpha> \<Rightarrow> \<alpha>\<close>
   352 
   352 
   353 text \<open>
   353 text \<open>
   354   \<^noindent> The connection to the type system is done by means of a
   354   \<^noindent> The connection to the type system is done by means of a
   355   primitive type class \<open>idem\<close>, together with a corresponding
   355   primitive type class \<open>idem\<close>, together with a corresponding
   356   interpretation:
   356   interpretation:
   357 \<close>
   357 \<close>
   358 
   358 
   359 interpretation %quote idem_class:
   359 interpretation %quote idem_class:
   360   idem "f :: (\<alpha>::idem) \<Rightarrow> \<alpha>"
   360   idem \<open>f :: (\<alpha>::idem) \<Rightarrow> \<alpha>\<close>
   361 (*<*)sorry(*>*)
   361 (*<*)sorry(*>*)
   362 
   362 
   363 text \<open>
   363 text \<open>
   364   \<^noindent> This gives you the full power of the Isabelle module system;
   364   \<^noindent> This gives you the full power of the Isabelle module system;
   365   conclusions in locale \<open>idem\<close> are implicitly propagated
   365   conclusions in locale \<open>idem\<close> are implicitly propagated
   373   are implicitly transferred to all instances.  For example, we can
   373   are implicitly transferred to all instances.  For example, we can
   374   now establish the \<open>left_cancel\<close> lemma for groups, which
   374   now establish the \<open>left_cancel\<close> lemma for groups, which
   375   states that the function \<open>(x \<otimes>)\<close> is injective:
   375   states that the function \<open>(x \<otimes>)\<close> is injective:
   376 \<close>
   376 \<close>
   377 
   377 
   378 lemma %quote (in group) left_cancel: "x \<otimes> y = x \<otimes> z \<longleftrightarrow> y = z"
   378 lemma %quote (in group) left_cancel: \<open>x \<otimes> y = x \<otimes> z \<longleftrightarrow> y = z\<close>
   379 proof
   379 proof
   380   assume "x \<otimes> y = x \<otimes> z"
   380   assume \<open>x \<otimes> y = x \<otimes> z\<close>
   381   then have "x\<div> \<otimes> (x \<otimes> y) = x\<div> \<otimes> (x \<otimes> z)" by simp
   381   then have \<open>x\<div> \<otimes> (x \<otimes> y) = x\<div> \<otimes> (x \<otimes> z)\<close> by simp
   382   then have "(x\<div> \<otimes> x) \<otimes> y = (x\<div> \<otimes> x) \<otimes> z" using assoc by simp
   382   then have \<open>(x\<div> \<otimes> x) \<otimes> y = (x\<div> \<otimes> x) \<otimes> z\<close> using assoc by simp
   383   then show "y = z" using neutl and invl by simp
   383   then show \<open>y = z\<close> using neutl and invl by simp
   384 next
   384 next
   385   assume "y = z"
   385   assume \<open>y = z\<close>
   386   then show "x \<otimes> y = x \<otimes> z" by simp
   386   then show \<open>x \<otimes> y = x \<otimes> z\<close> by simp
   387 qed
   387 qed
   388 
   388 
   389 text \<open>
   389 text \<open>
   390   \<^noindent> Here the \qt{@{keyword "in"} \<^class>\<open>group\<close>} target
   390   \<^noindent> Here the \qt{@{keyword "in"} \<^class>\<open>group\<close>} target
   391   specification indicates that the result is recorded within that
   391   specification indicates that the result is recorded within that
   392   context for later use.  This local theorem is also lifted to the
   392   context for later use.  This local theorem is also lifted to the
   393   global one @{fact "group.left_cancel:"} @{prop [source] "\<And>x y z ::
   393   global one @{fact "group.left_cancel:"} @{prop [source] \<open>\<And>x y z ::
   394   \<alpha>::group. x \<otimes> y = x \<otimes> z \<longleftrightarrow> y = z"}.  Since type \<open>int\<close> has been
   394   \<alpha>::group. x \<otimes> y = x \<otimes> z \<longleftrightarrow> y = z\<close>}.  Since type \<open>int\<close> has been
   395   made an instance of \<open>group\<close> before, we may refer to that
   395   made an instance of \<open>group\<close> before, we may refer to that
   396   fact as well: @{prop [source] "\<And>x y z :: int. x \<otimes> y = x \<otimes> z \<longleftrightarrow> y =
   396   fact as well: @{prop [source] \<open>\<And>x y z :: int. x \<otimes> y = x \<otimes> z \<longleftrightarrow> y =
   397   z"}.
   397   z\<close>}.
   398 \<close>
   398 \<close>
   399 
   399 
   400 
   400 
   401 subsection \<open>Derived definitions\<close>
   401 subsection \<open>Derived definitions\<close>
   402 
   402 
   403 text \<open>
   403 text \<open>
   404   Isabelle locales are targets which support local definitions:
   404   Isabelle locales are targets which support local definitions:
   405 \<close>
   405 \<close>
   406 
   406 
   407 primrec %quote (in monoid) pow_nat :: "nat \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>" where
   407 primrec %quote (in monoid) pow_nat :: \<open>nat \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>\<close> where
   408   "pow_nat 0 x = \<one>"
   408   \<open>pow_nat 0 x = \<one>\<close>
   409   | "pow_nat (Suc n) x = x \<otimes> pow_nat n x"
   409   | \<open>pow_nat (Suc n) x = x \<otimes> pow_nat n x\<close>
   410 
   410 
   411 text \<open>
   411 text \<open>
   412   \<^noindent> If the locale \<open>group\<close> is also a class, this local
   412   \<^noindent> If the locale \<open>group\<close> is also a class, this local
   413   definition is propagated onto a global definition of @{term [source]
   413   definition is propagated onto a global definition of @{term [source]
   414   "pow_nat :: nat \<Rightarrow> \<alpha>::monoid \<Rightarrow> \<alpha>::monoid"} with corresponding theorems
   414   \<open>pow_nat :: nat \<Rightarrow> \<alpha>::monoid \<Rightarrow> \<alpha>::monoid\<close>} with corresponding theorems
   415 
   415 
   416   @{thm pow_nat.simps [no_vars]}.
   416   @{thm pow_nat.simps [no_vars]}.
   417 
   417 
   418   \<^noindent> As you can see from this example, for local definitions
   418   \<^noindent> As you can see from this example, for local definitions
   419   you may use any specification tool which works together with
   419   you may use any specification tool which works together with
   436   lists the same operations as for genuinely algebraic types.  In such
   436   lists the same operations as for genuinely algebraic types.  In such
   437   a case, we can simply make a particular interpretation of monoids
   437   a case, we can simply make a particular interpretation of monoids
   438   for lists:
   438   for lists:
   439 \<close>
   439 \<close>
   440 
   440 
   441 interpretation %quote list_monoid: monoid append "[]"
   441 interpretation %quote list_monoid: monoid append \<open>[]\<close>
   442   proof qed auto
   442   proof qed auto
   443 
   443 
   444 text \<open>
   444 text \<open>
   445   \<^noindent> This enables us to apply facts on monoids
   445   \<^noindent> This enables us to apply facts on monoids
   446   to lists, e.g. @{thm list_monoid.neutl [no_vars]}.
   446   to lists, e.g. @{thm list_monoid.neutl [no_vars]}.
   447 
   447 
   448   When using this interpretation pattern, it may also
   448   When using this interpretation pattern, it may also
   449   be appropriate to map derived definitions accordingly:
   449   be appropriate to map derived definitions accordingly:
   450 \<close>
   450 \<close>
   451 
   451 
   452 primrec %quote replicate :: "nat \<Rightarrow> \<alpha> list \<Rightarrow> \<alpha> list" where
   452 primrec %quote replicate :: \<open>nat \<Rightarrow> \<alpha> list \<Rightarrow> \<alpha> list\<close> where
   453   "replicate 0 _ = []"
   453   \<open>replicate 0 _ = []\<close>
   454   | "replicate (Suc n) xs = xs @ replicate n xs"
   454   | \<open>replicate (Suc n) xs = xs @ replicate n xs\<close>
   455 
   455 
   456 interpretation %quote list_monoid: monoid append "[]" rewrites
   456 interpretation %quote list_monoid: monoid append \<open>[]\<close> rewrites
   457   "monoid.pow_nat append [] = replicate"
   457   \<open>monoid.pow_nat append [] = replicate\<close>
   458 proof -
   458 proof -
   459   interpret monoid append "[]" ..
   459   interpret monoid append \<open>[]\<close> ..
   460   show "monoid.pow_nat append [] = replicate"
   460   show \<open>monoid.pow_nat append [] = replicate\<close>
   461   proof
   461   proof
   462     fix n
   462     fix n
   463     show "monoid.pow_nat append [] n = replicate n"
   463     show \<open>monoid.pow_nat append [] n = replicate n\<close>
   464       by (induct n) auto
   464       by (induct n) auto
   465   qed
   465   qed
   466 qed intro_locales
   466 qed intro_locales
   467 
   467 
   468 text \<open>
   468 text \<open>
   484 \<close>
   484 \<close>
   485 
   485 
   486 subclass %quote (in group) monoid
   486 subclass %quote (in group) monoid
   487 proof
   487 proof
   488   fix x
   488   fix x
   489   from invl have "x\<div> \<otimes> x = \<one>" by simp
   489   from invl have \<open>x\<div> \<otimes> x = \<one>\<close> by simp
   490   with assoc [symmetric] neutl invl have "x\<div> \<otimes> (x \<otimes> \<one>) = x\<div> \<otimes> x" by simp
   490   with assoc [symmetric] neutl invl have \<open>x\<div> \<otimes> (x \<otimes> \<one>) = x\<div> \<otimes> x\<close> by simp
   491   with left_cancel show "x \<otimes> \<one> = x" by simp
   491   with left_cancel show \<open>x \<otimes> \<one> = x\<close> by simp
   492 qed
   492 qed
   493 
   493 
   494 text \<open>
   494 text \<open>
   495   The logical proof is carried out on the locale level.  Afterwards it
   495   The logical proof is carried out on the locale level.  Afterwards it
   496   is propagated to the type system, making \<open>group\<close> an instance
   496   is propagated to the type system, making \<open>group\<close> an instance
   528   \end{figure}
   528   \end{figure}
   529 
   529 
   530   For illustration, a derived definition in \<open>group\<close> using \<open>pow_nat\<close>
   530   For illustration, a derived definition in \<open>group\<close> using \<open>pow_nat\<close>
   531 \<close>
   531 \<close>
   532 
   532 
   533 definition %quote (in group) pow_int :: "int \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>" where
   533 definition %quote (in group) pow_int :: \<open>int \<Rightarrow> \<alpha> \<Rightarrow> \<alpha>\<close> where
   534   "pow_int k x = (if k >= 0
   534   \<open>pow_int k x = (if k \<ge> 0
   535     then pow_nat (nat k) x
   535     then pow_nat (nat k) x
   536     else (pow_nat (nat (- k)) x)\<div>)"
   536     else (pow_nat (nat (- k)) x)\<div>)\<close>
   537 
   537 
   538 text \<open>
   538 text \<open>
   539   \<^noindent> yields the global definition of @{term [source] "pow_int ::
   539   \<^noindent> yields the global definition of @{term [source] \<open>pow_int ::
   540   int \<Rightarrow> \<alpha>::group \<Rightarrow> \<alpha>::group"} with the corresponding theorem @{thm
   540   int \<Rightarrow> \<alpha>::group \<Rightarrow> \<alpha>::group\<close>} with the corresponding theorem @{thm
   541   pow_int_def [no_vars]}.
   541   pow_int_def [no_vars]}.
   542 \<close>
   542 \<close>
   543 
   543 
   544 subsection \<open>A note on syntax\<close>
   544 subsection \<open>A note on syntax\<close>
   545 
   545 
   550 \<close>
   550 \<close>
   551 
   551 
   552 context %quote semigroup
   552 context %quote semigroup
   553 begin
   553 begin
   554 
   554 
   555 term %quote "x \<otimes> y" \<comment> \<open>example 1\<close>
   555 term %quote \<open>x \<otimes> y\<close> \<comment> \<open>example 1\<close>
   556 term %quote "(x::nat) \<otimes> y" \<comment> \<open>example 2\<close>
   556 term %quote \<open>(x::nat) \<otimes> y\<close> \<comment> \<open>example 2\<close>
   557 
   557 
   558 end  %quote
   558 end  %quote
   559 
   559 
   560 term %quote "x \<otimes> y" \<comment> \<open>example 3\<close>
   560 term %quote \<open>x \<otimes> y\<close> \<comment> \<open>example 3\<close>
   561 
   561 
   562 text \<open>
   562 text \<open>
   563   \<^noindent> Here in example 1, the term refers to the local class
   563   \<^noindent> Here in example 1, the term refers to the local class
   564   operation \<open>mult [\<alpha>]\<close>, whereas in example 2 the type
   564   operation \<open>mult [\<alpha>]\<close>, whereas in example 2 the type
   565   constraint enforces the global class operation \<open>mult [nat]\<close>.
   565   constraint enforces the global class operation \<open>mult [nat]\<close>.
   581   an explicit dictionary construction.  As example, let's go back to
   581   an explicit dictionary construction.  As example, let's go back to
   582   the power function:
   582   the power function:
   583 \<close>
   583 \<close>
   584 
   584 
   585 definition %quote example :: int where
   585 definition %quote example :: int where
   586   "example = pow_int 10 (-2)"
   586   \<open>example = pow_int 10 (-2)\<close>
   587 
   587 
   588 text \<open>
   588 text \<open>
   589   \<^noindent> This maps to Haskell as follows:
   589   \<^noindent> This maps to Haskell as follows:
   590 \<close>
   590 \<close>
   591 text %quote \<open>
   591 text %quote \<open>
   626 
   626 
   627   \end{description}
   627   \end{description}
   628 \<close>
   628 \<close>
   629 
   629 
   630 end
   630 end
   631