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 |
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>. |