--- a/src/FOL/ex/LocaleTest.thy Mon Jul 23 13:47:48 2007 +0200
+++ b/src/FOL/ex/LocaleTest.thy Mon Jul 23 13:48:30 2007 +0200
@@ -798,6 +798,9 @@
text {* Naming convention for global objects: prefixes D and d *}
+
+subsection {* Simple examples *}
+
locale Da = fixes a :: o
assumes true: a
@@ -807,7 +810,7 @@
apply simp apply (rule true) done
interpretation D1: Da ["True"]
- where "~ True" = "False"
+ where "~ True == False"
apply -
apply unfold_locales [1] apply rule
by simp
@@ -816,7 +819,7 @@
lemma "False <-> False" apply (rule D1.not_false) done
interpretation D2: Da ["x | ~ x"]
- where "~ (x | ~ x)" = "~ x & x"
+ where "~ (x | ~ x) <-> ~ x & x"
apply -
apply unfold_locales [1] apply fast
by simp
--- a/src/HOL/ex/LocaleTest2.thy Mon Jul 23 13:47:48 2007 +0200
+++ b/src/HOL/ex/LocaleTest2.thy Mon Jul 23 13:48:30 2007 +0200
@@ -5,26 +5,635 @@
More regression tests for locales.
Definitions are less natural in FOL, since there is no selection operator.
-Hence we do them in HOL, not in the main test suite for locales:
-FOL/ex/LocaleTest.thy
+Hence we do them here in HOL, not in the main test suite for locales,
+which is FOL/ex/LocaleTest.thy
*)
header {* Test of Locale Interpretation *}
theory LocaleTest2
-imports Main
+imports GCD
begin
-ML {* set quick_and_dirty *} (* allow for thm command in batch mode *)
-ML {* set show_hyps *}
-ML {* set show_sorts *}
-
-
-subsection {* Interpretation of Defined Concepts *}
+section {* Interpretation of Defined Concepts *}
text {* Naming convention for global objects: prefixes D and d *}
-(* Group example with defined operation inv *)
+
+subsection {* Lattices *}
+
+text {* Much of the lattice proofs are from HOL/Lattice. *}
+
+
+subsubsection {* Definitions *}
+
+locale dpo =
+ fixes le :: "['a, 'a] => bool" (infixl "\<sqsubseteq>" 50)
+ assumes refl [intro, simp]: "x \<sqsubseteq> x"
+ and anti_sym [intro]: "[| x \<sqsubseteq> y; y \<sqsubseteq> x |] ==> x = y"
+ and trans [trans]: "[| x \<sqsubseteq> y; y \<sqsubseteq> z |] ==> x \<sqsubseteq> z"
+
+begin
+
+theorem circular:
+ "[| x \<sqsubseteq> y; y \<sqsubseteq> z; z \<sqsubseteq> x |] ==> x = y & y = z"
+ by (blast intro: trans)
+
+definition
+ less :: "['a, 'a] => bool" (infixl "\<sqsubset>" 50)
+ where "(x \<sqsubset> y) = (x \<sqsubseteq> y & x ~= y)"
+
+theorem abs_test:
+ "op \<sqsubset> = (%x y. x \<sqsubset> y)"
+ by simp
+
+definition
+ is_inf :: "['a, 'a, 'a] => bool"
+ where "is_inf x y i = (i \<sqsubseteq> x \<and> i \<sqsubseteq> y \<and> (\<forall>z. z \<sqsubseteq> x \<and> z \<sqsubseteq> y \<longrightarrow> z \<sqsubseteq> i))"
+
+definition
+ is_sup :: "['a, 'a, 'a] => bool"
+ where "is_sup x y s = (x \<sqsubseteq> s \<and> y \<sqsubseteq> s \<and> (\<forall>z. x \<sqsubseteq> z \<and> y \<sqsubseteq> z \<longrightarrow> s \<sqsubseteq> z))"
+
+end
+
+locale dlat = dpo +
+ assumes ex_inf: "EX inf. dpo.is_inf le x y inf"
+ and ex_sup: "EX sup. dpo.is_sup le x y sup"
+
+begin
+
+definition
+ meet :: "['a, 'a] => 'a" (infixl "\<sqinter>" 70)
+ where "x \<sqinter> y = (THE inf. is_inf x y inf)"
+
+definition
+ join :: "['a, 'a] => 'a" (infixl "\<squnion>" 65)
+ where "x \<squnion> y = (THE sup. is_sup x y sup)"
+
+lemma is_infI [intro?]: "i \<sqsubseteq> x \<Longrightarrow> i \<sqsubseteq> y \<Longrightarrow>
+ (\<And>z. z \<sqsubseteq> x \<Longrightarrow> z \<sqsubseteq> y \<Longrightarrow> z \<sqsubseteq> i) \<Longrightarrow> is_inf x y i"
+ by (unfold is_inf_def) blast
+
+lemma is_inf_lower [elim?]:
+ "is_inf x y i \<Longrightarrow> (i \<sqsubseteq> x \<Longrightarrow> i \<sqsubseteq> y \<Longrightarrow> C) \<Longrightarrow> C"
+ by (unfold is_inf_def) blast
+
+lemma is_inf_greatest [elim?]:
+ "is_inf x y i \<Longrightarrow> z \<sqsubseteq> x \<Longrightarrow> z \<sqsubseteq> y \<Longrightarrow> z \<sqsubseteq> i"
+ by (unfold is_inf_def) blast
+
+theorem is_inf_uniq: "is_inf x y i \<Longrightarrow> is_inf x y i' \<Longrightarrow> i = i'"
+proof -
+ assume inf: "is_inf x y i"
+ assume inf': "is_inf x y i'"
+ show ?thesis
+ proof (rule anti_sym)
+ from inf' show "i \<sqsubseteq> i'"
+ proof (rule is_inf_greatest)
+ from inf show "i \<sqsubseteq> x" ..
+ from inf show "i \<sqsubseteq> y" ..
+ qed
+ from inf show "i' \<sqsubseteq> i"
+ proof (rule is_inf_greatest)
+ from inf' show "i' \<sqsubseteq> x" ..
+ from inf' show "i' \<sqsubseteq> y" ..
+ qed
+ qed
+qed
+
+theorem is_inf_related [elim?]: "x \<sqsubseteq> y \<Longrightarrow> is_inf x y x"
+proof -
+ assume "x \<sqsubseteq> y"
+ show ?thesis
+ proof
+ show "x \<sqsubseteq> x" ..
+ show "x \<sqsubseteq> y" by fact
+ fix z assume "z \<sqsubseteq> x" and "z \<sqsubseteq> y" show "z \<sqsubseteq> x" by fact
+ qed
+qed
+
+lemma meet_equality [elim?]: "is_inf x y i \<Longrightarrow> x \<sqinter> y = i"
+proof (unfold meet_def)
+ assume "is_inf x y i"
+ then show "(THE i. is_inf x y i) = i"
+ by (rule the_equality) (rule is_inf_uniq [OF _ `is_inf x y i`])
+qed
+
+lemma meetI [intro?]:
+ "i \<sqsubseteq> x \<Longrightarrow> i \<sqsubseteq> y \<Longrightarrow> (\<And>z. z \<sqsubseteq> x \<Longrightarrow> z \<sqsubseteq> y \<Longrightarrow> z \<sqsubseteq> i) \<Longrightarrow> x \<sqinter> y = i"
+ by (rule meet_equality, rule is_infI) blast+
+
+lemma is_inf_meet [intro?]: "is_inf x y (x \<sqinter> y)"
+proof (unfold meet_def)
+ from ex_inf obtain i where "is_inf x y i" ..
+ then show "is_inf x y (THE i. is_inf x y i)"
+ by (rule theI) (rule is_inf_uniq [OF _ `is_inf x y i`])
+qed
+
+lemma meet_left [intro?]:
+ "x \<sqinter> y \<sqsubseteq> x"
+ by (rule is_inf_lower) (rule is_inf_meet)
+
+lemma meet_right [intro?]:
+ "x \<sqinter> y \<sqsubseteq> y"
+ by (rule is_inf_lower) (rule is_inf_meet)
+
+lemma meet_le [intro?]:
+ "[| z \<sqsubseteq> x; z \<sqsubseteq> y |] ==> z \<sqsubseteq> x \<sqinter> y"
+ by (rule is_inf_greatest) (rule is_inf_meet)
+
+lemma is_supI [intro?]: "x \<sqsubseteq> s \<Longrightarrow> y \<sqsubseteq> s \<Longrightarrow>
+ (\<And>z. x \<sqsubseteq> z \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> s \<sqsubseteq> z) \<Longrightarrow> is_sup x y s"
+ by (unfold is_sup_def) blast
+
+lemma is_sup_least [elim?]:
+ "is_sup x y s \<Longrightarrow> x \<sqsubseteq> z \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> s \<sqsubseteq> z"
+ by (unfold is_sup_def) blast
+
+lemma is_sup_upper [elim?]:
+ "is_sup x y s \<Longrightarrow> (x \<sqsubseteq> s \<Longrightarrow> y \<sqsubseteq> s \<Longrightarrow> C) \<Longrightarrow> C"
+ by (unfold is_sup_def) blast
+
+theorem is_sup_uniq: "is_sup x y s \<Longrightarrow> is_sup x y s' \<Longrightarrow> s = s'"
+proof -
+ assume sup: "is_sup x y s"
+ assume sup': "is_sup x y s'"
+ show ?thesis
+ proof (rule anti_sym)
+ from sup show "s \<sqsubseteq> s'"
+ proof (rule is_sup_least)
+ from sup' show "x \<sqsubseteq> s'" ..
+ from sup' show "y \<sqsubseteq> s'" ..
+ qed
+ from sup' show "s' \<sqsubseteq> s"
+ proof (rule is_sup_least)
+ from sup show "x \<sqsubseteq> s" ..
+ from sup show "y \<sqsubseteq> s" ..
+ qed
+ qed
+qed
+
+theorem is_sup_related [elim?]: "x \<sqsubseteq> y \<Longrightarrow> is_sup x y y"
+proof -
+ assume "x \<sqsubseteq> y"
+ show ?thesis
+ proof
+ show "x \<sqsubseteq> y" by fact
+ show "y \<sqsubseteq> y" ..
+ fix z assume "x \<sqsubseteq> z" and "y \<sqsubseteq> z"
+ show "y \<sqsubseteq> z" by fact
+ qed
+qed
+
+lemma join_equality [elim?]: "is_sup x y s \<Longrightarrow> x \<squnion> y = s"
+proof (unfold join_def)
+ assume "is_sup x y s"
+ then show "(THE s. is_sup x y s) = s"
+ by (rule the_equality) (rule is_sup_uniq [OF _ `is_sup x y s`])
+qed
+
+lemma joinI [intro?]: "x \<sqsubseteq> s \<Longrightarrow> y \<sqsubseteq> s \<Longrightarrow>
+ (\<And>z. x \<sqsubseteq> z \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> s \<sqsubseteq> z) \<Longrightarrow> x \<squnion> y = s"
+ by (rule join_equality, rule is_supI) blast+
+
+lemma is_sup_join [intro?]: "is_sup x y (x \<squnion> y)"
+proof (unfold join_def)
+ from ex_sup obtain s where "is_sup x y s" ..
+ then show "is_sup x y (THE s. is_sup x y s)"
+ by (rule theI) (rule is_sup_uniq [OF _ `is_sup x y s`])
+qed
+
+lemma join_left [intro?]:
+ "x \<sqsubseteq> x \<squnion> y"
+ by (rule is_sup_upper) (rule is_sup_join)
+
+lemma join_right [intro?]:
+ "y \<sqsubseteq> x \<squnion> y"
+ by (rule is_sup_upper) (rule is_sup_join)
+
+lemma join_le [intro?]:
+ "[| x \<sqsubseteq> z; y \<sqsubseteq> z |] ==> x \<squnion> y \<sqsubseteq> z"
+ by (rule is_sup_least) (rule is_sup_join)
+
+theorem meet_assoc: "(x \<sqinter> y) \<sqinter> z = x \<sqinter> (y \<sqinter> z)"
+proof (rule meetI)
+ show "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> x \<sqinter> y"
+ proof
+ show "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> x" ..
+ show "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> y"
+ proof -
+ have "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> y \<sqinter> z" ..
+ also have "\<dots> \<sqsubseteq> y" ..
+ finally show ?thesis .
+ qed
+ qed
+ show "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> z"
+ proof -
+ have "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> y \<sqinter> z" ..
+ also have "\<dots> \<sqsubseteq> z" ..
+ finally show ?thesis .
+ qed
+ fix w assume "w \<sqsubseteq> x \<sqinter> y" and "w \<sqsubseteq> z"
+ show "w \<sqsubseteq> x \<sqinter> (y \<sqinter> z)"
+ proof
+ show "w \<sqsubseteq> x"
+ proof -
+ have "w \<sqsubseteq> x \<sqinter> y" by fact
+ also have "\<dots> \<sqsubseteq> x" ..
+ finally show ?thesis .
+ qed
+ show "w \<sqsubseteq> y \<sqinter> z"
+ proof
+ show "w \<sqsubseteq> y"
+ proof -
+ have "w \<sqsubseteq> x \<sqinter> y" by fact
+ also have "\<dots> \<sqsubseteq> y" ..
+ finally show ?thesis .
+ qed
+ show "w \<sqsubseteq> z" by fact
+ qed
+ qed
+qed
+
+theorem meet_commute: "x \<sqinter> y = y \<sqinter> x"
+proof (rule meetI)
+ show "y \<sqinter> x \<sqsubseteq> x" ..
+ show "y \<sqinter> x \<sqsubseteq> y" ..
+ fix z assume "z \<sqsubseteq> y" and "z \<sqsubseteq> x"
+ then show "z \<sqsubseteq> y \<sqinter> x" ..
+qed
+
+theorem meet_join_absorb: "x \<sqinter> (x \<squnion> y) = x"
+proof (rule meetI)
+ show "x \<sqsubseteq> x" ..
+ show "x \<sqsubseteq> x \<squnion> y" ..
+ fix z assume "z \<sqsubseteq> x" and "z \<sqsubseteq> x \<squnion> y"
+ show "z \<sqsubseteq> x" by fact
+qed
+
+theorem join_assoc: "(x \<squnion> y) \<squnion> z = x \<squnion> (y \<squnion> z)"
+proof (rule joinI)
+ show "x \<squnion> y \<sqsubseteq> x \<squnion> (y \<squnion> z)"
+ proof
+ show "x \<sqsubseteq> x \<squnion> (y \<squnion> z)" ..
+ show "y \<sqsubseteq> x \<squnion> (y \<squnion> z)"
+ proof -
+ have "y \<sqsubseteq> y \<squnion> z" ..
+ also have "... \<sqsubseteq> x \<squnion> (y \<squnion> z)" ..
+ finally show ?thesis .
+ qed
+ qed
+ show "z \<sqsubseteq> x \<squnion> (y \<squnion> z)"
+ proof -
+ have "z \<sqsubseteq> y \<squnion> z" ..
+ also have "... \<sqsubseteq> x \<squnion> (y \<squnion> z)" ..
+ finally show ?thesis .
+ qed
+ fix w assume "x \<squnion> y \<sqsubseteq> w" and "z \<sqsubseteq> w"
+ show "x \<squnion> (y \<squnion> z) \<sqsubseteq> w"
+ proof
+ show "x \<sqsubseteq> w"
+ proof -
+ have "x \<sqsubseteq> x \<squnion> y" ..
+ also have "\<dots> \<sqsubseteq> w" by fact
+ finally show ?thesis .
+ qed
+ show "y \<squnion> z \<sqsubseteq> w"
+ proof
+ show "y \<sqsubseteq> w"
+ proof -
+ have "y \<sqsubseteq> x \<squnion> y" ..
+ also have "... \<sqsubseteq> w" by fact
+ finally show ?thesis .
+ qed
+ show "z \<sqsubseteq> w" by fact
+ qed
+ qed
+qed
+
+theorem join_commute: "x \<squnion> y = y \<squnion> x"
+proof (rule joinI)
+ show "x \<sqsubseteq> y \<squnion> x" ..
+ show "y \<sqsubseteq> y \<squnion> x" ..
+ fix z assume "y \<sqsubseteq> z" and "x \<sqsubseteq> z"
+ then show "y \<squnion> x \<sqsubseteq> z" ..
+qed
+
+theorem join_meet_absorb: "x \<squnion> (x \<sqinter> y) = x"
+proof (rule joinI)
+ show "x \<sqsubseteq> x" ..
+ show "x \<sqinter> y \<sqsubseteq> x" ..
+ fix z assume "x \<sqsubseteq> z" and "x \<sqinter> y \<sqsubseteq> z"
+ show "x \<sqsubseteq> z" by fact
+qed
+
+theorem meet_idem: "x \<sqinter> x = x"
+proof -
+ have "x \<sqinter> (x \<squnion> (x \<sqinter> x)) = x" by (rule meet_join_absorb)
+ also have "x \<squnion> (x \<sqinter> x) = x" by (rule join_meet_absorb)
+ finally show ?thesis .
+qed
+
+theorem meet_related [elim?]: "x \<sqsubseteq> y \<Longrightarrow> x \<sqinter> y = x"
+proof (rule meetI)
+ assume "x \<sqsubseteq> y"
+ show "x \<sqsubseteq> x" ..
+ show "x \<sqsubseteq> y" by fact
+ fix z assume "z \<sqsubseteq> x" and "z \<sqsubseteq> y"
+ show "z \<sqsubseteq> x" by fact
+qed
+
+theorem meet_related2 [elim?]: "y \<sqsubseteq> x \<Longrightarrow> x \<sqinter> y = y"
+ by (drule meet_related) (simp add: meet_commute)
+
+theorem join_related [elim?]: "x \<sqsubseteq> y \<Longrightarrow> x \<squnion> y = y"
+proof (rule joinI)
+ assume "x \<sqsubseteq> y"
+ show "y \<sqsubseteq> y" ..
+ show "x \<sqsubseteq> y" by fact
+ fix z assume "x \<sqsubseteq> z" and "y \<sqsubseteq> z"
+ show "y \<sqsubseteq> z" by fact
+qed
+
+theorem join_related2 [elim?]: "y \<sqsubseteq> x \<Longrightarrow> x \<squnion> y = x"
+ by (drule join_related) (simp add: join_commute)
+
+
+text {* Additional theorems *}
+
+theorem meet_connection: "(x \<sqsubseteq> y) = (x \<sqinter> y = x)"
+proof
+ assume "x \<sqsubseteq> y"
+ then have "is_inf x y x" ..
+ then show "x \<sqinter> y = x" ..
+next
+ have "x \<sqinter> y \<sqsubseteq> y" ..
+ also assume "x \<sqinter> y = x"
+ finally show "x \<sqsubseteq> y" .
+qed
+
+theorem meet_connection2: "(x \<sqsubseteq> y) = (y \<sqinter> x = x)"
+ using meet_commute meet_connection by simp
+
+theorem join_connection: "(x \<sqsubseteq> y) = (x \<squnion> y = y)"
+proof
+ assume "x \<sqsubseteq> y"
+ then have "is_sup x y y" ..
+ then show "x \<squnion> y = y" ..
+next
+ have "x \<sqsubseteq> x \<squnion> y" ..
+ also assume "x \<squnion> y = y"
+ finally show "x \<sqsubseteq> y" .
+qed
+
+theorem join_connection2: "(x \<sqsubseteq> y) = (x \<squnion> y = y)"
+ using join_commute join_connection by simp
+
+
+text {* Naming according to Jacobson I, p.\ 459. *}
+
+lemmas L1 = join_commute meet_commute
+lemmas L2 = join_assoc meet_assoc
+(*lemmas L3 = join_idem meet_idem*)
+lemmas L4 = join_meet_absorb meet_join_absorb
+
+end
+
+locale ddlat = dlat +
+ assumes meet_distr:
+ "dlat.meet le x (dlat.join le y z) =
+ dlat.join le (dlat.meet le x y) (dlat.meet le x z)"
+
+begin
+
+lemma join_distr:
+ "x \<squnion> (y \<sqinter> z) = (x \<squnion> y) \<sqinter> (x \<squnion> z)"
+ txt {* Jacobson I, p.\ 462 *}
+proof -
+ have "x \<squnion> (y \<sqinter> z) = (x \<squnion> (x \<sqinter> z)) \<squnion> (y \<sqinter> z)" by (simp add: L4)
+ also have "... = x \<squnion> ((x \<sqinter> z) \<squnion> (y \<sqinter> z))" by (simp add: L2)
+ also have "... = x \<squnion> ((x \<squnion> y) \<sqinter> z)" by (simp add: L1 meet_distr)
+ also have "... = ((x \<squnion> y) \<sqinter> x) \<squnion> ((x \<squnion> y) \<sqinter> z)" by (simp add: L1 L4)
+ also have "... = (x \<squnion> y) \<sqinter> (x \<squnion> z)" by (simp add: meet_distr)
+ finally show ?thesis .
+qed
+
+end
+
+locale dlo = dpo +
+ assumes total: "x \<sqsubseteq> y | y \<sqsubseteq> x"
+
+begin
+
+lemma less_total: "x \<sqsubset> y | x = y | y \<sqsubset> x"
+ using total
+ by (unfold less_def) blast
+
+end
+
+
+interpretation dlo < dlat
+(* TODO: definition syntax is unavailable *)
+proof unfold_locales
+ fix x y
+ from total have "is_inf x y (if x \<sqsubseteq> y then x else y)" by (auto simp: is_inf_def)
+ then show "EX inf. is_inf x y inf" by blast
+next
+ fix x y
+ from total have "is_sup x y (if x \<sqsubseteq> y then y else x)" by (auto simp: is_sup_def)
+ then show "EX sup. is_sup x y sup" by blast
+qed
+
+interpretation dlo < ddlat
+proof unfold_locales
+ fix x y z
+ show "x \<sqinter> (y \<squnion> z) = x \<sqinter> y \<squnion> x \<sqinter> z" (is "?l = ?r")
+ txt {* Jacobson I, p.\ 462 *}
+ proof -
+ { assume c: "y \<sqsubseteq> x" "z \<sqsubseteq> x"
+ from c have "?l = y \<squnion> z"
+ by (metis c (*join_commute*) join_connection2 join_related2 (*meet_commute*) meet_connection meet_related2 total)
+ also from c have "... = ?r" by (metis (*c*) (*join_commute*) meet_related2)
+ finally have "?l = ?r" . }
+ moreover
+ { assume c: "x \<sqsubseteq> y | x \<sqsubseteq> z"
+ from c have "?l = x"
+ by (metis (*anti_sym*) (*c*) (*circular*) (*join_assoc*)(* join_commute *) join_connection2 (*join_left*) join_related2 meet_connection(* meet_related2*) total trans)
+ also from c have "... = ?r"
+ by (metis join_commute join_related2 meet_connection meet_related2 total)
+ finally have "?l = ?r" . }
+ moreover note total
+ ultimately show ?thesis by blast
+ qed
+qed
+
+subsubsection {* Total order @{text "<="} on @{typ int} *}
+
+interpretation int: dpo ["op <= :: [int, int] => bool"]
+ where "(dpo.less (op <=) (x::int) y) = (x < y)"
+ txt {* We give interpretation for less, but not is\_inf and is\_sub. *}
+proof -
+ show "dpo (op <= :: [int, int] => bool)"
+ by unfold_locales auto
+ then interpret int: dpo ["op <= :: [int, int] => bool"] .
+ txt {* Gives interpreted version of less\_def (without condition). *}
+ show "(dpo.less (op <=) (x::int) y) = (x < y)"
+ by (unfold int.less_def) auto
+qed
+
+thm int.circular
+lemma "\<lbrakk> (x::int) \<le> y; y \<le> z; z \<le> x\<rbrakk> \<Longrightarrow> x = y \<and> y = z"
+ apply (rule int.circular) apply assumption apply assumption apply assumption done
+thm int.abs_test
+lemma "(op < :: [int, int] => bool) = op <"
+ apply (rule int.abs_test) done
+
+interpretation int: dlat ["op <= :: [int, int] => bool"]
+ where "dlat.meet (op <=) (x::int) y = min x y"
+ and "dlat.join (op <=) (x::int) y = max x y"
+proof -
+ show "dlat (op <= :: [int, int] => bool)"
+ apply unfold_locales
+ apply (unfold int.is_inf_def int.is_sup_def)
+ apply arith+
+ done
+ then interpret int: dlat ["op <= :: [int, int] => bool"] .
+ txt {* Interpretation to ease use of definitions, which are
+ conditional in general but unconditional after interpretation. *}
+ show "dlat.meet (op <=) (x::int) y = min x y"
+ apply (unfold int.meet_def)
+ apply (rule the_equality)
+ apply (unfold int.is_inf_def)
+ by auto
+ show "dlat.join (op <=) (x::int) y = max x y"
+ apply (unfold int.join_def)
+ apply (rule the_equality)
+ apply (unfold int.is_sup_def)
+ by auto
+qed
+
+interpretation int: dlo ["op <= :: [int, int] => bool"]
+ by unfold_locales arith
+
+text {* Interpreted theorems from the locales, involving defined terms. *}
+
+thm int.less_def text {* from dpo *}
+thm int.meet_left text {* from dlat *}
+thm int.meet_distr text {* from ddlat *}
+thm int.less_total text {* from dlo *}
+
+
+subsubsection {* Total order @{text "<="} on @{typ nat} *}
+
+interpretation nat: dpo ["op <= :: [nat, nat] => bool"]
+ where "dpo.less (op <=) (x::nat) y = (x < y)"
+ txt {* We give interpretation for less, but not is\_inf and is\_sub. *}
+proof -
+ show "dpo (op <= :: [nat, nat] => bool)"
+ by unfold_locales auto
+ then interpret nat: dpo ["op <= :: [nat, nat] => bool"] .
+ txt {* Gives interpreted version of less\_def (without condition). *}
+ show "dpo.less (op <=) (x::nat) y = (x < y)"
+ apply (unfold nat.less_def)
+ apply auto
+ done
+qed
+
+interpretation nat: dlat ["op <= :: [nat, nat] => bool"]
+ where "dlat.meet (op <=) (x::nat) y = min x y"
+ and "dlat.join (op <=) (x::nat) y = max x y"
+proof -
+ show "dlat (op <= :: [nat, nat] => bool)"
+ apply unfold_locales
+ apply (unfold nat.is_inf_def nat.is_sup_def)
+ apply arith+
+ done
+ then interpret nat: dlat ["op <= :: [nat, nat] => bool"] .
+ txt {* Interpretation to ease use of definitions, which are
+ conditional in general but unconditional after interpretation. *}
+ show "dlat.meet (op <=) (x::nat) y = min x y"
+ apply (unfold nat.meet_def)
+ apply (rule the_equality)
+ apply (unfold nat.is_inf_def)
+ by auto
+ show "dlat.join (op <=) (x::nat) y = max x y"
+ apply (unfold nat.join_def)
+ apply (rule the_equality)
+ apply (unfold nat.is_sup_def)
+ by auto
+qed
+
+interpretation nat: dlo ["op <= :: [nat, nat] => bool"]
+ by unfold_locales arith
+
+text {* Interpreted theorems from the locales, involving defined terms. *}
+
+thm nat.less_def text {* from dpo *}
+thm nat.meet_left text {* from dlat *}
+thm nat.meet_distr text {* from ddlat *}
+thm nat.less_total text {* from ldo *}
+
+
+subsubsection {* Lattice @{text "dvd"} on @{typ nat} *}
+
+interpretation nat_dvd: dpo ["op dvd :: [nat, nat] => bool"]
+ where "dpo.less (op dvd) (x::nat) y = (x dvd y & x ~= y)"
+ txt {* We give interpretation for less, but not is\_inf and is\_sub. *}
+proof -
+ show "dpo (op dvd :: [nat, nat] => bool)"
+ by unfold_locales (auto simp: dvd_def)
+ then interpret nat_dvd: dpo ["op dvd :: [nat, nat] => bool"] .
+ txt {* Gives interpreted version of less\_def (without condition). *}
+ show "dpo.less (op dvd) (x::nat) y = (x dvd y & x ~= y)"
+ apply (unfold nat_dvd.less_def)
+ apply auto
+ done
+qed
+
+interpretation nat_dvd: dlat ["op dvd :: [nat, nat] => bool"]
+ where "dlat.meet (op dvd) (x::nat) y = gcd (x, y)"
+ and "dlat.join (op dvd) (x::nat) y = lcm (x, y)"
+proof -
+ show "dlat (op dvd :: [nat, nat] => bool)"
+ apply unfold_locales
+ apply (unfold nat_dvd.is_inf_def nat_dvd.is_sup_def)
+ apply (rule_tac x = "gcd (x, y)" in exI)
+ apply auto [1]
+ apply (rule_tac x = "lcm (x, y)" in exI)
+ apply (auto intro: lcm_dvd1 lcm_dvd2 lcm_lowest)
+ done
+ then interpret nat_dvd: dlat ["op dvd :: [nat, nat] => bool"] .
+ txt {* Interpretation to ease use of definitions, which are
+ conditional in general but unconditional after interpretation. *}
+ show "dlat.meet (op dvd) (x::nat) y = gcd (x, y)"
+ apply (unfold nat_dvd.meet_def)
+ apply (rule the_equality)
+ apply (unfold nat_dvd.is_inf_def)
+ by auto
+ show "dlat.join (op dvd) (x::nat) y = lcm (x, y)"
+ apply (unfold nat_dvd.join_def)
+ apply (rule the_equality)
+ apply (unfold nat_dvd.is_sup_def)
+ by (auto intro: lcm_dvd1 lcm_dvd2 lcm_lowest)
+qed
+
+text {* Interpreted theorems from the locales, involving defined terms. *}
+
+thm nat_dvd.less_def text {* from dpo *}
+lemma "((x::nat) dvd y & x ~= y) = (x dvd y & x ~= y)"
+ apply (rule nat_dvd.less_def) done
+thm nat_dvd.meet_left text {* from dlat *}
+lemma "gcd (x, y) dvd x"
+ apply (rule nat_dvd.meet_left) done
+
+print_interps dpo
+print_interps dlat
+
+
+subsection {* Group example with defined operations @{text inv} and @{text unit} *}
+
+subsubsection {* Locale declarations and lemmas *}
locale Dsemi =
fixes prod (infixl "**" 65)
@@ -32,128 +641,279 @@
locale Dmonoid = Dsemi +
fixes one
- assumes lone: "one ** x = x"
- and rone: "x ** one = x"
+ assumes l_one [simp]: "one ** x = x"
+ and r_one [simp]: "x ** one = x"
+
+begin
-definition (in Dmonoid)
- inv where "inv(x) == THE y. x ** y = one & y ** x = one"
+definition
+ inv where "inv x = (THE y. x ** y = one & y ** x = one)"
+definition
+ unit where "unit x = (EX y. x ** y = one & y ** x = one)"
-lemma (in Dmonoid) inv_unique:
+lemma inv_unique:
assumes eq: "y ** x = one" "x ** y' = one"
shows "y = y'"
proof -
- from eq have "y = y ** (x ** y')" by (simp add: rone)
+ from eq have "y = y ** (x ** y')" by (simp add: r_one)
also have "... = (y ** x) ** y'" by (simp add: assoc)
- also from eq have "... = y'" by (simp add: lone)
+ also from eq have "... = y'" by (simp add: l_one)
finally show ?thesis .
qed
-locale Dgrp = Dmonoid +
- assumes linv_ex: "EX y. y ** x = one"
- and rinv_ex: "EX y. x ** y = one"
+lemma unit_one [intro, simp]:
+ "unit one"
+ by (unfold unit_def) auto
+
+lemma unit_l_inv_ex:
+ "unit x ==> \<exists>y. y ** x = one"
+ by (unfold unit_def) auto
+
+lemma unit_r_inv_ex:
+ "unit x ==> \<exists>y. x ** y = one"
+ by (unfold unit_def) auto
+
+lemma unit_l_inv:
+ "unit x ==> inv x ** x = one"
+ apply (simp add: unit_def inv_def) apply (erule exE)
+ apply (rule theI2, fast)
+ apply (rule inv_unique)
+ apply fast+
+ done
-lemma (in Dgrp) linv:
- "inv x ** x = one"
-apply (unfold inv_def)
-apply (insert rinv_ex [where x = x])
-apply (insert linv_ex [where x = x])
-apply (erule exE) apply (erule exE)
-apply (rule theI2)
-apply rule apply assumption
-apply (frule inv_unique, assumption)
-apply simp
-apply (rule inv_unique)
-apply fast+
-done
+lemma unit_r_inv:
+ "unit x ==> x ** inv x = one"
+ apply (simp add: unit_def inv_def) apply (erule exE)
+ apply (rule theI2, fast)
+ apply (rule inv_unique)
+ apply fast+
+ done
+
+lemma unit_inv_unit [intro, simp]:
+ "unit x ==> unit (inv x)"
+proof -
+ assume x: "unit x"
+ show "unit (inv x)"
+ by (auto simp add: unit_def
+ intro: unit_l_inv unit_r_inv x)
+qed
+
+lemma unit_l_cancel [simp]:
+ "unit x ==> (x ** y = x ** z) = (y = z)"
+proof
+ assume eq: "x ** y = x ** z"
+ and G: "unit x"
+ then have "(inv x ** x) ** y = (inv x ** x) ** z"
+ by (simp add: assoc)
+ with G show "y = z" by (simp add: unit_l_inv)
+next
+ assume eq: "y = z"
+ and G: "unit x"
+ then show "x ** y = x ** z" by simp
+qed
-lemma (in Dgrp) rinv:
+lemma unit_inv_inv [simp]:
+ "unit x ==> inv (inv x) = x"
+proof -
+ assume x: "unit x"
+ then have "inv x ** inv (inv x) = inv x ** x"
+ by (simp add: unit_l_inv unit_r_inv)
+ with x show ?thesis by simp
+qed
+
+lemma inv_inj_on_unit:
+ "inj_on inv {x. unit x}"
+proof (rule inj_onI, simp)
+ fix x y
+ assume G: "unit x" "unit y" and eq: "inv x = inv y"
+ then have "inv (inv x) = inv (inv y)" by simp
+ with G show "x = y" by simp
+qed
+
+lemma unit_inv_comm:
+ assumes inv: "x ** y = one"
+ and G: "unit x" "unit y"
+ shows "y ** x = one"
+proof -
+ from G have "x ** y ** x = x ** one" by (auto simp add: inv)
+ with G show ?thesis by (simp del: r_one add: assoc)
+qed
+
+end
+
+
+locale Dgrp = Dmonoid +
+ assumes unit [intro, simp]: "Dmonoid.unit (op **) one x"
+
+begin
+
+lemma l_inv_ex [simp]:
+ "\<exists>y. y ** x = one"
+ using unit_l_inv_ex by simp
+
+lemma r_inv_ex [simp]:
+ "\<exists>y. x ** y = one"
+ using unit_r_inv_ex by simp
+
+lemma l_inv [simp]:
+ "inv x ** x = one"
+ using unit_l_inv by simp
+
+lemma l_cancel [simp]:
+ "(x ** y = x ** z) = (y = z)"
+ using unit_l_inv by simp
+
+lemma r_inv [simp]:
"x ** inv x = one"
-apply (unfold inv_def)
-apply (insert rinv_ex [where x = x])
-apply (insert linv_ex [where x = x])
-apply (erule exE) apply (erule exE)
-apply (rule theI2)
-apply rule apply assumption
-apply (frule inv_unique, assumption)
-apply simp
-apply (rule inv_unique)
-apply fast+
-done
+proof -
+ have "inv x ** (x ** inv x) = inv x ** one"
+ by (simp add: assoc [symmetric] l_inv)
+ then show ?thesis by (simp del: r_one)
+qed
-lemma (in Dgrp) lcancel:
- "x ** y = x ** z <-> y = z"
+lemma r_cancel [simp]:
+ "(y ** x = z ** x) = (y = z)"
proof
- assume "x ** y = x ** z"
- then have "inv(x) ** x ** y = inv(x) ** x ** z" by (simp add: assoc)
- then show "y = z" by (simp add: lone linv)
+ assume eq: "y ** x = z ** x"
+ then have "y ** (x ** inv x) = z ** (x ** inv x)"
+ by (simp add: assoc [symmetric] del: r_inv)
+ then show "y = z" by simp
qed simp
-interpretation Dint: Dmonoid ["op +" "0::int"]
- where "Dmonoid.inv (op +) (0::int)" = "uminus"
+lemma inv_one [simp]:
+ "inv one = one"
proof -
- show "Dmonoid (op +) (0::int)" by unfold_locales auto
- note Dint = this (* should have this as an assumption in further goals *)
- {
- fix x
- have "Dmonoid.inv (op +) (0::int) x = - x"
- by (auto simp: Dmonoid.inv_def [OF Dint])
- }
- then show "Dmonoid.inv (op +) (0::int) == uminus"
- by (rule_tac eq_reflection) (fast intro: ext)
+ have "inv one = one ** (inv one)" by (simp del: r_inv)
+ moreover have "... = one" by simp
+ finally show ?thesis .
qed
-thm Dmonoid.inv_def Dint.inv_def
+lemma inv_inv [simp]:
+ "inv (inv x) = x"
+ using unit_inv_inv by simp
-lemma "- x \<equiv> THE y. x + y = 0 \<and> y + x = (0::int)"
- apply (rule Dint.inv_def) done
+lemma inv_inj:
+ "inj_on inv UNIV"
+ using inv_inj_on_unit by simp
-interpretation Dclass: Dmonoid ["op +" "0::'a::ab_group_add"]
- where "Dmonoid.inv (op +) (0::'a::ab_group_add)" = "uminus"
+lemma inv_mult_group:
+ "inv (x ** y) = inv y ** inv x"
proof -
- show "Dmonoid (op +) (0::'a::ab_group_add)" by unfold_locales auto
- note Dclass = this (* should have this as an assumption in further goals *)
- {
- fix x
- have "Dmonoid.inv (op +) (0::'a::ab_group_add) x = - x"
- by (auto simp: Dmonoid.inv_def [OF Dclass] equals_zero_I [symmetric])
- }
- then show "Dmonoid.inv (op +) (0::'a::ab_group_add) == uminus"
- by (rule_tac eq_reflection) (fast intro: ext)
+ have "inv (x ** y) ** (x ** y) = (inv y ** inv x) ** (x ** y)"
+ by (simp add: assoc l_inv) (simp add: assoc [symmetric])
+ then show ?thesis by (simp del: l_inv)
+qed
+
+lemma inv_comm:
+ "x ** y = one ==> y ** x = one"
+ by (rule unit_inv_comm) auto
+
+lemma inv_equality:
+ "y ** x = one ==> inv x = y"
+ apply (simp add: inv_def)
+ apply (rule the_equality)
+ apply (simp add: inv_comm [of y x])
+ apply (rule r_cancel [THEN iffD1], auto)
+ done
+
+end
+
+
+locale Dhom = Dgrp prod (infixl "**" 65) one + Dgrp sum (infixl "+++" 60) zero +
+ fixes hom
+ assumes hom_mult [simp]: "hom (x ** y) = hom x +++ hom y"
+
+begin
+
+lemma hom_one [simp]:
+ "hom one = zero"
+proof -
+ have "hom one +++ zero = hom one +++ hom one"
+ by (simp add: hom_mult [symmetric] del: hom_mult)
+ then show ?thesis by (simp del: r_one)
qed
-interpretation Dclass: Dgrp ["op +" "0::'a::ring"]
-apply unfold_locales
-apply (rule_tac x="-x" in exI) apply simp
-apply (rule_tac x="-x" in exI) apply simp
-done
+end
-(* Equation for inverse from Dclass: Dmonoid effective. *)
-thm Dclass.linv
-lemma "-x + x = (0::'a::ring)" apply (rule Dclass.linv) done
-
-(* Equations have effect in "subscriptions" *)
-
-(* In the same module *)
+subsubsection {* Interpretation of Functions *}
-lemma (in Dmonoid) trivial:
- "inv one = inv one"
- by rule
-
-thm Dclass.trivial
-
-(* Inherited: interpretation *)
-
-lemma (in Dgrp) inv_inv:
- "inv (inv x) = x"
+interpretation Dfun: Dmonoid ["op o" "id :: 'a => 'a"]
+ where "Dmonoid.unit (op o) id f = bij (f::'a => 'a)"
+(* and "Dmonoid.inv (op o) id" = "inv :: ('a => 'a) => ('a => 'a)" *)
proof -
- have "inv x ** inv (inv x) = inv x ** x"
- by (simp add: linv rinv)
- then show ?thesis by (simp add: lcancel)
+ show "Dmonoid op o (id :: 'a => 'a)" by unfold_locales (simp_all add: o_assoc)
+ note Dmonoid = this
+(*
+ from this interpret Dmonoid ["op o" "id :: 'a => 'a"] .
+*)
+ show "Dmonoid.unit (op o) (id :: 'a => 'a) f = bij f"
+ apply (unfold Dmonoid.unit_def [OF Dmonoid])
+ apply rule apply clarify
+ proof -
+ fix f g
+ assume id1: "f o g = id" and id2: "g o f = id"
+ show "bij f"
+ proof (rule bijI)
+ show "inj f"
+ proof (rule inj_onI)
+ fix x y
+ assume "f x = f y"
+ then have "(g o f) x = (g o f) y" by simp
+ with id2 show "x = y" by simp
+ qed
+ next
+ show "surj f"
+ proof (rule surjI)
+ fix x
+ from id1 have "(f o g) x = x" by simp
+ then show "f (g x) = x" by simp
+ qed
+ qed
+ next
+ fix f
+ assume bij: "bij f"
+ then
+ have inv: "f o Hilbert_Choice.inv f = id & Hilbert_Choice.inv f o f = id"
+ by (simp add: bij_def surj_iff inj_iff)
+ show "EX g. f o g = id & g o f = id" by rule (rule inv)
+ qed
qed
-thm Dclass.inv_inv
-lemma "- (- x) = (x::'a::ring)"
- apply (rule Dclass.inv_inv) done
+thm Dmonoid.unit_def Dfun.unit_def
+
+thm Dmonoid.inv_inj_on_unit Dfun.inv_inj_on_unit
+
+lemma unit_id:
+ "(f :: unit => unit) = id"
+ by rule simp
+
+interpretation Dfun: Dgrp ["op o" "id :: unit => unit"]
+ where "Dmonoid.inv (op o) id f = inv (f :: unit => unit)"
+proof -
+ have "Dmonoid op o (id :: 'a => 'a)" by unfold_locales (simp_all add: o_assoc)
+ note Dmonoid = this
+
+ show "Dgrp (op o) (id :: unit => unit)"
+apply unfold_locales
+apply (unfold Dmonoid.unit_def [OF Dmonoid])
+apply (insert unit_id)
+apply simp
+done
+ show "Dmonoid.inv (op o) id f = inv (f :: unit => unit)"
+apply (unfold Dmonoid.inv_def [OF Dmonoid] inv_def)
+apply (insert unit_id)
+apply simp
+apply (rule the_equality)
+apply rule
+apply rule
+apply simp
+done
+qed
+
+thm Dfun.unit_l_inv Dfun.l_inv
+
+thm Dfun.inv_equality
+thm Dfun.inv_equality
end
--- a/src/Pure/Isar/spec_parse.ML Mon Jul 23 13:47:48 2007 +0200
+++ b/src/Pure/Isar/spec_parse.ML Mon Jul 23 13:48:30 2007 +0200
@@ -24,7 +24,7 @@
val locale_mixfix: token list -> mixfix * token list
val locale_fixes: token list -> (string * string option * mixfix) list * token list
val locale_insts: token list ->
- (string option list * (string * string) list) * token list
+ (string option list * string list) * token list
val locale_expr: token list -> Locale.expr * token list
val locale_expr_unless: (token list -> 'a * token list) ->
token list -> Locale.expr * token list
@@ -88,7 +88,7 @@
val locale_insts =
Scan.optional (P.$$$ "[" |-- P.!!! (Scan.repeat1 (P.maybe P.term) --| P.$$$ "]")) []
- -- Scan.optional (P.$$$ "where" |-- P.and_list1 (P.term -- (P.$$$ "=" |-- P.!!! P.term))) [];
+ -- Scan.optional (P.$$$ "where" |-- P.and_list1 P.term) [];
local
--- a/src/Pure/Tools/class_package.ML Mon Jul 23 13:47:48 2007 +0200
+++ b/src/Pure/Tools/class_package.ML Mon Jul 23 13:48:30 2007 +0200
@@ -637,7 +637,7 @@
val def' = symmetric def
val tac = (ALLGOALS o ProofContext.fact_tac) [def'];
val name_locale = (#locale o the_class_data thy) class;
- val def_eq = (Logic.dest_equals o Thm.prop_of) def';
+ val def_eq = Thm.prop_of def';
val (params, consts) = split_list (param_map thy [class]);
in
prove_interpretation tac ((false, prfx), []) (Locale.Locale name_locale)