# HG changeset patch # User haftmann # Date 1142601624 -3600 # Node ID b411f25fff25dd08691e9e69012c0a267783fe34 # Parent 5091dc43817b8f6726061acdcea778a5a88be182 added example for operational classes and code generator diff -r 5091dc43817b -r b411f25fff25 src/HOL/ex/Classpackage.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/ex/Classpackage.thy Fri Mar 17 14:20:24 2006 +0100 @@ -0,0 +1,323 @@ +(* ID: $Id$ + Author: Florian Haftmann, TU Muenchen +*) + +header {* Test and Examples for Pure/Tools/class_package.ML *} + +theory Classpackage +imports Main +begin + +class semigroup = + fixes mult :: "'a \ 'a \ 'a" (infixl "\<^loc>\" 70) + assumes assoc: "x \<^loc>\ y \<^loc>\ z = x \<^loc>\ (y \<^loc>\ z)" + +instance nat :: semigroup + "m \ n == (m::nat) + n" +proof + fix m n q :: nat + from semigroup_nat_def show "m \ n \ q = m \ (n \ q)" by simp +qed + +instance int :: semigroup + "k \ l == (k::int) + l" +proof + fix k l j :: int + from semigroup_int_def show "k \ l \ j = k \ (l \ j)" by simp +qed + +instance (type) list :: semigroup + "xs \ ys == xs @ ys" +proof + fix xs ys zs :: "'a list" + show "xs \ ys \ zs = xs \ (ys \ zs)" + proof - + from semigroup_list_def have "\xs ys::'a list. xs \ ys == xs @ ys". + thus ?thesis by simp + qed +qed + +class monoidl = semigroup + + fixes one :: 'a ("\<^loc>\") + assumes neutl: "\<^loc>\ \<^loc>\ x = x" + +instance nat :: monoidl + "\ == (0::nat)" +proof + fix n :: nat + from semigroup_nat_def monoidl_nat_def show "\ \ n = n" by simp +qed + +instance int :: monoidl + "\ == (0::int)" +proof + fix k :: int + from semigroup_int_def monoidl_int_def show "\ \ k = k" by simp +qed + +instance (type) list :: monoidl + "\ == []" +proof + fix xs :: "'a list" + show "\ \ xs = xs" + proof - + from semigroup_list_def have "\xs ys::'a list. xs \ ys == xs @ ys". + moreover from monoidl_list_def have "\ == []::'a list". + ultimately show ?thesis by simp + qed +qed + +class monoid = monoidl + + assumes neutr: "x \<^loc>\ \<^loc>\ = x" + +instance (type) list :: monoid +proof + fix xs :: "'a list" + show "xs \ \ = xs" + proof - + from semigroup_list_def have "\xs ys::'a list. xs \ ys == xs @ ys". + moreover from monoidl_list_def have "\ == []::'a list". + ultimately show ?thesis by simp + qed +qed + +class monoid_comm = monoid + + assumes comm: "x \<^loc>\ y = y \<^loc>\ x" + +instance nat :: monoid_comm +proof + fix n :: nat + from semigroup_nat_def monoidl_nat_def show "n \ \ = n" by simp +next + fix n m :: nat + from semigroup_nat_def monoidl_nat_def show "n \ m = m \ n" by simp +qed + +instance int :: monoid_comm +proof + fix k :: int + from semigroup_int_def monoidl_int_def show "k \ \ = k" by simp +next + fix k l :: int + from semigroup_int_def monoidl_int_def show "k \ l = l \ k" by simp +qed + +definition (in monoid) + units :: "'a set" + units_def: "units = { y. \x. x \<^loc>\ y = \<^loc>\ \ y \<^loc>\ x = \<^loc>\ }" + +lemma (in monoid) inv_obtain: + assumes ass: "x \ units" + obtains y where "y \<^loc>\ x = \<^loc>\" and "x \<^loc>\ y = \<^loc>\" +proof - + from ass units_def obtain y + where "y \<^loc>\ x = \<^loc>\" and "x \<^loc>\ y = \<^loc>\" by auto + thus ?thesis .. +qed + +lemma (in monoid) inv_unique: + assumes eq: "y \<^loc>\ x = \<^loc>\" "x \<^loc>\ y' = \<^loc>\" + shows "y = y'" +proof - + from eq neutr have "y = y \<^loc>\ (x \<^loc>\ y')" by simp + also with assoc have "... = (y \<^loc>\ x) \<^loc>\ y'" by simp + also with eq neutl have "... = y'" by simp + finally show ?thesis . +qed + +lemma (in monoid) units_inv_comm: + assumes inv: "x \<^loc>\ y = \<^loc>\" + and G: "x \ units" + shows "y \<^loc>\ x = \<^loc>\" +proof - + from G inv_obtain obtain z + where z_choice: "z \<^loc>\ x = \<^loc>\" by blast + from inv neutl neutr have "x \<^loc>\ y \<^loc>\ x = x \<^loc>\ \<^loc>\" by simp + with assoc have "z \<^loc>\ x \<^loc>\ y \<^loc>\ x = z \<^loc>\ x \<^loc>\ \<^loc>\" by simp + with neutl z_choice show ?thesis by simp +qed + +consts + reduce :: "('a \ 'a \ 'a) \ 'a \ nat \ 'a \ 'a" + +primrec + "reduce f g 0 x = g" + "reduce f g (Suc n) x = f x (reduce f g n x)" + +definition (in monoid) + npow :: "nat \ 'a \ 'a" + npow_def_prim: "npow n x = reduce (op \<^loc>\) \<^loc>\ n x" + +abbreviation (in monoid) + abbrev_npow :: "'a \ nat \ 'a" (infix "\<^loc>\" 75) + "(x \<^loc>\ n) = npow n x" + +lemma (in monoid) npow_def: + "x \<^loc>\ 0 = \<^loc>\" + "x \<^loc>\ Suc n = x \<^loc>\ x \<^loc>\ n" +using npow_def_prim by simp_all + +lemma (in monoid) nat_pow_one: + "\<^loc>\ \<^loc>\ n = \<^loc>\" +using npow_def neutl by (induct n) simp_all + +lemma (in monoid) nat_pow_mult: + "npow n x \<^loc>\ npow m x = npow (n + m) x" +proof (induct n) + case 0 with neutl npow_def show ?case by simp +next + case (Suc n) with prems assoc npow_def show ?case by simp +qed + +lemma (in monoid) nat_pow_pow: + "npow n (npow m x) = npow (n * m) x" +using npow_def nat_pow_mult by (induct n) simp_all + +class group = monoidl + + fixes inv :: "'a \ 'a" ("\<^loc>\
_" [81] 80) + assumes invl: "\<^loc>\
x \<^loc>\ x = \<^loc>\" + +class group_comm = group + monoid_comm + +instance int :: group_comm + "\
k == - (k::int)" +proof + fix k :: int + from semigroup_int_def monoidl_int_def group_comm_int_def show "\
k \ k = \" by simp +qed + +lemma (in group) cancel: + "(x \<^loc>\ y = x \<^loc>\ z) = (y = z)" +proof + fix x y z :: 'a + assume eq: "x \<^loc>\ y = x \<^loc>\ z" + hence "\<^loc>\
x \<^loc>\ (x \<^loc>\ y) = \<^loc>\
x \<^loc>\ (x \<^loc>\ z)" by simp + with assoc have "\<^loc>\
x \<^loc>\ x \<^loc>\ y = \<^loc>\
x \<^loc>\ x \<^loc>\ z" by simp + with neutl invl show "y = z" by simp +next + fix x y z :: 'a + assume eq: "y = z" + thus "x \<^loc>\ y = x \<^loc>\ z" by simp +qed + +lemma (in group) neutr: + "x \<^loc>\ \<^loc>\ = x" +proof - + from invl have "\<^loc>\
x \<^loc>\ x = \<^loc>\" by simp + with assoc [symmetric] neutl invl have "\<^loc>\
x \<^loc>\ (x \<^loc>\ \<^loc>\) = \<^loc>\
x \<^loc>\ x" by simp + with cancel show ?thesis by simp +qed + +lemma (in group) invr: + "x \<^loc>\ \<^loc>\
x = \<^loc>\" +proof - + from neutl invl have "\<^loc>\
x \<^loc>\ x \<^loc>\ \<^loc>\
x = \<^loc>\
x" by simp + with neutr have "\<^loc>\
x \<^loc>\ x \<^loc>\ \<^loc>\
x = \<^loc>\
x \<^loc>\ \<^loc>\ " by simp + with assoc have "\<^loc>\
x \<^loc>\ (x \<^loc>\ \<^loc>\
x) = \<^loc>\
x \<^loc>\ \<^loc>\ " by simp + with cancel show ?thesis .. +qed + +interpretation group < monoid +proof + fix x :: "'a" + from neutr show "x \<^loc>\ \<^loc>\ = x" . +qed + +instance group < monoid +proof + fix x :: "'a::group" + from group.mult_one.neutr [standard] show "x \ \ = x" . +qed + +lemma (in group) all_inv [intro]: + "(x::'a) \ monoid.units (op \<^loc>\) \<^loc>\" + unfolding units_def +proof - + fix x :: "'a" + from invl invr have "\<^loc>\
x \<^loc>\ x = \<^loc>\" and "x \<^loc>\ \<^loc>\
x = \<^loc>\" . + then obtain y where "y \<^loc>\ x = \<^loc>\" and "x \<^loc>\ y = \<^loc>\" .. + hence "\y\'a. y \<^loc>\ x = \<^loc>\ \ x \<^loc>\ y = \<^loc>\" by blast + thus "x \ {y\'a. \x\'a. x \<^loc>\ y = \<^loc>\ \ y \<^loc>\ x = \<^loc>\}" by simp +qed + +lemma (in group) cancer: + "(y \<^loc>\ x = z \<^loc>\ x) = (y = z)" +proof + assume eq: "y \<^loc>\ x = z \<^loc>\ x" + with assoc [symmetric] have "y \<^loc>\ (x \<^loc>\ \<^loc>\
x) = z \<^loc>\ (x \<^loc>\ \<^loc>\
x)" by (simp del: invr) + with invr neutr show "y = z" by simp +next + assume eq: "y = z" + thus "y \<^loc>\ x = z \<^loc>\ x" by simp +qed + +lemma (in group) inv_one: + "\<^loc>\
\<^loc>\ = \<^loc>\" +proof - + from neutl have "\<^loc>\
\<^loc>\ = \<^loc>\ \<^loc>\ (\<^loc>\
\<^loc>\)" .. + moreover from invr have "... = \<^loc>\" by simp + finally show ?thesis . +qed + +lemma (in group) inv_inv: + "\<^loc>\
(\<^loc>\
x) = x" +proof - + from invl invr neutr + have "\<^loc>\
(\<^loc>\
x) \<^loc>\ \<^loc>\
x \<^loc>\ x = x \<^loc>\ \<^loc>\
x \<^loc>\ x" by simp + with assoc [symmetric] + have "\<^loc>\
(\<^loc>\
x) \<^loc>\ (\<^loc>\
x \<^loc>\ x) = x \<^loc>\ (\<^loc>\
x \<^loc>\ x)" by simp + with invl neutr show ?thesis by simp +qed + +lemma (in group) inv_mult_group: + "\<^loc>\
(x \<^loc>\ y) = \<^loc>\
y \<^loc>\ \<^loc>\
x" +proof - + from invl have "\<^loc>\
(x \<^loc>\ y) \<^loc>\ (x \<^loc>\ y) = \<^loc>\" by simp + with assoc have "\<^loc>\
(x \<^loc>\ y) \<^loc>\ x \<^loc>\ y = \<^loc>\" by simp + with neutl have "\<^loc>\
(x \<^loc>\ y) \<^loc>\ x \<^loc>\ y \<^loc>\ \<^loc>\
y \<^loc>\ \<^loc>\
x = \<^loc>\
y \<^loc>\ \<^loc>\
x" by simp + with assoc have "\<^loc>\
(x \<^loc>\ y) \<^loc>\ (x \<^loc>\ (y \<^loc>\ \<^loc>\
y) \<^loc>\ \<^loc>\
x) = \<^loc>\
y \<^loc>\ \<^loc>\
x" by simp + with invr neutr show ?thesis by simp +qed + +lemma (in group) inv_comm: + "x \<^loc>\ \<^loc>\
x = \<^loc>\
x \<^loc>\ x" +using invr invl by simp + +definition (in group) + pow :: "int \ 'a \ 'a" + pow_def: "pow k x = (if k < 0 then \<^loc>\
(monoid.npow (op \<^loc>\) \<^loc>\ (nat (-k)) x) + else (monoid.npow (op \<^loc>\) \<^loc>\ (nat k) x))" + +abbreviation (in group) + abbrev_pow :: "'a \ int \ 'a" (infix "\<^loc>\" 75) + "(x \<^loc>\ k) = pow k x" + +lemma (in group) int_pow_zero: + "x \<^loc>\ (0::int) = \<^loc>\" +using npow_def pow_def by simp + +lemma (in group) int_pow_one: + "\<^loc>\ \<^loc>\ (k::int) = \<^loc>\" +using pow_def nat_pow_one inv_one by simp + +instance group_prod_def: (group, group) * :: group + mult_prod_def: "x \ y == let (x1, x2) = x in (let (y1, y2) = y in + (x1 \ y1, x2 \ y2))" + mult_one_def: "\ == (\, \)" + mult_inv_def: "\
x == let (x1, x2) = x in (\
x1, \
x2)" +by default (simp_all add: split_paired_all group_prod_def semigroup.assoc monoidl.neutl group.invl) + +instance group_comm_prod_def: (group_comm, group_comm) * :: group_comm +by default (simp_all add: split_paired_all group_prod_def semigroup.assoc monoidl.neutl group.invl monoid_comm.comm) + +definition + "x = ((2::nat) \ \ \ 3, (2::int) \ \ \ \
3, [1::nat, 2] \ \ \ [1, 2, 3])" + "y = (2 :: int, \
2 :: int) \ \ \ (3, \
3)" + +code_generate "op \" "\" "inv" +code_generate x +code_generate y + +code_serialize ml (-) + +end diff -r 5091dc43817b -r b411f25fff25 src/HOL/ex/Codegenerator.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/ex/Codegenerator.thy Fri Mar 17 14:20:24 2006 +0100 @@ -0,0 +1,133 @@ +(* ID: $Id$ + Author: Florian Haftmann, TU Muenchen +*) + +header {* Test and Examples for Code Generator *} + +theory Codegenerator +imports Main +begin + +subsection {* booleans *} + +definition + xor :: "bool \ bool \ bool" + "xor p q = ((p | q) & \ (p & q))" + +code_generate xor + +subsection {* natural numbers *} + +definition + one :: nat + "one = 1" + n :: nat + "n = 42" + +code_generate + "0::nat" "one" n + "op + :: nat \ nat \ nat" + "op - :: nat \ nat \ nat" + "op * :: nat \ nat \ nat" + "op < :: nat \ nat \ bool" + "op <= :: nat \ nat \ bool" + +subsection {* pairs *} + +definition + swap :: "'a * 'b \ 'b * 'a" + "swap p = (let (x, y) = p in (y, x))" + swapp :: "'a * 'b \ 'c * 'd \ ('a * 'c) * ('b * 'd)" + "swapp = (\(x, y) (z, w). ((x, z), (y, w)))" + appl :: "('a \ 'b) * 'a \ 'b" + "appl p = (let (f, x) = p in f x)" + +code_generate Pair fst snd Let split swap swapp appl + +definition + k :: "int" + "k = 42" + +consts + fac :: "int => int" + +recdef fac "measure nat" + "fac j = (if j <= 0 then 1 else j * (fac (j - 1)))" + +code_generate + "0::int" "1::int" k + "op + :: int \ int \ int" + "op - :: int \ int \ int" + "op * :: int \ int \ int" + "op < :: int \ int \ bool" + "op <= :: int \ int \ bool" + fac + +subsection {* sums *} + +code_generate Inl Inr + +subsection {* options *} + +code_generate None Some + +subsection {* lists *} + +definition + ps :: "nat list" + "ps = [2, 3, 5, 7, 11]" + qs :: "nat list" + "qs == rev ps" + +code_generate hd tl "op @" ps qs + +subsection {* mutual datatypes *} + +datatype mut1 = Tip | Top mut2 + and mut2 = Tip | Top mut1 + +consts + mut1 :: "mut1 \ mut1" + mut2 :: "mut2 \ mut2" + +primrec + "mut1 mut1.Tip = mut1.Tip" + "mut1 (mut1.Top x) = mut1.Top (mut2 x)" + "mut2 mut2.Tip = mut2.Tip" + "mut2 (mut2.Top x) = mut2.Top (mut1 x)" + +code_generate mut1 mut2 + +subsection {* equalities *} + +code_generate + "op = :: bool \ bool \ bool" + "op = :: nat \ nat \ bool" + "op = :: int \ int \ bool" + "op = :: 'a * 'b \ 'a * 'b \ bool" + "op = :: 'a + 'b \ 'a + 'b \ bool" + "op = :: 'a option \ 'a option \ bool" + "op = :: 'a list \ 'a list \ bool" + "op = :: mut1 \ mut1 \ bool" + "op = :: mut2 \ mut2 \ bool" + +subsection {* heavy use of names *} + +definition + f :: nat + "f = 2" + g :: nat + "g = f" + h :: nat + "h = g" + +code_alias + "Codegenerator.f" "Mymod.f" + "Codegenerator.g" "Mymod.A.f" + "Codegenerator.h" "Mymod.A.B.f" + +code_generate f g h + +code_serialize ml (-) + +end \ No newline at end of file diff -r 5091dc43817b -r b411f25fff25 src/HOL/ex/ROOT.ML --- a/src/HOL/ex/ROOT.ML Fri Mar 17 14:19:24 2006 +0100 +++ b/src/HOL/ex/ROOT.ML Fri Mar 17 14:20:24 2006 +0100 @@ -57,6 +57,8 @@ time_use_thy "Refute_Examples"; time_use_thy "Quickcheck_Examples"; +no_document time_use_thy "Classpackage"; +no_document time_use_thy "Codegenerator"; no_document time_use_thy "nbe"; no_document use_thy "Word";