diff -r 46cc6708c3b3 -r fa810f01f7b5 Quot/Nominal/Nominal2_Atoms.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Quot/Nominal/Nominal2_Atoms.thy Tue Jan 26 20:07:50 2010 +0100 @@ -0,0 +1,221 @@ +(* Title: Nominal2_Atoms + Authors: Brian Huffman, Christian Urban + + Definitions for concrete atom types. +*) +theory Nominal2_Atoms +imports Nominal2_Base +uses ("atom_decl.ML") +begin + +section {* Concrete atom types *} + +text {* + Class @{text at_base} allows types containing multiple sorts of atoms. + Class @{text at} only allows types with a single sort. +*} + +class at_base = pt + + fixes atom :: "'a \ atom" + assumes atom_eq_iff [simp]: "atom a = atom b \ a = b" + assumes atom_eqvt: "p \ (atom a) = atom (p \ a)" + +class at = at_base + + assumes sort_of_atom_eq [simp]: "sort_of (atom a) = sort_of (atom b)" + +instance at < at_base .. + +lemma supp_at_base: + fixes a::"'a::at_base" + shows "supp a = {atom a}" + by (simp add: supp_atom [symmetric] supp_def atom_eqvt) + +lemma fresh_at: + shows "a \ b \ a \ atom b" + unfolding fresh_def by (simp add: supp_at_base) + +instance at_base < fs +proof qed (simp add: supp_at_base) + + +lemma at_base_infinite [simp]: + shows "infinite (UNIV :: 'a::at_base set)" (is "infinite ?U") +proof + obtain a :: 'a where "True" by auto + assume "finite ?U" + hence "finite (atom ` ?U)" + by (rule finite_imageI) + then obtain b where b: "b \ atom ` ?U" "sort_of b = sort_of (atom a)" + by (rule obtain_atom) + from b(2) have "b = atom ((atom a \ b) \ a)" + unfolding atom_eqvt [symmetric] + by (simp add: swap_atom) + hence "b \ atom ` ?U" by simp + with b(1) show "False" by simp +qed + +lemma swap_at_base_simps [simp]: + fixes x y::"'a::at_base" + shows "sort_of (atom x) = sort_of (atom y) \ (atom x \ atom y) \ x = y" + and "sort_of (atom x) = sort_of (atom y) \ (atom x \ atom y) \ y = x" + and "atom x \ a \ atom x \ b \ (a \ b) \ x = x" + unfolding atom_eq_iff [symmetric] + unfolding atom_eqvt [symmetric] + by simp_all + +lemma obtain_at_base: + assumes X: "finite X" + obtains a::"'a::at_base" where "atom a \ X" +proof - + have "inj (atom :: 'a \ atom)" + by (simp add: inj_on_def) + with X have "finite (atom -` X :: 'a set)" + by (rule finite_vimageI) + with at_base_infinite have "atom -` X \ (UNIV :: 'a set)" + by auto + then obtain a :: 'a where "atom a \ X" + by auto + thus ?thesis .. +qed + + +section {* A swapping operation for concrete atoms *} + +definition + flip :: "'a::at_base \ 'a \ perm" ("'(_ \ _')") +where + "(a \ b) = (atom a \ atom b)" + +lemma flip_self [simp]: "(a \ a) = 0" + unfolding flip_def by (rule swap_self) + +lemma flip_commute: "(a \ b) = (b \ a)" + unfolding flip_def by (rule swap_commute) + +lemma minus_flip [simp]: "- (a \ b) = (a \ b)" + unfolding flip_def by (rule minus_swap) + +lemma add_flip_cancel: "(a \ b) + (a \ b) = 0" + unfolding flip_def by (rule swap_cancel) + +lemma permute_flip_cancel [simp]: "(a \ b) \ (a \ b) \ x = x" + unfolding permute_plus [symmetric] add_flip_cancel by simp + +lemma permute_flip_cancel2 [simp]: "(a \ b) \ (b \ a) \ x = x" + by (simp add: flip_commute) + +lemma flip_eqvt: + fixes a b c::"'a::at_base" + shows "p \ (a \ b) = (p \ a \ p \ b)" + unfolding flip_def + by (simp add: swap_eqvt atom_eqvt) + +lemma flip_at_base_simps [simp]: + shows "sort_of (atom a) = sort_of (atom b) \ (a \ b) \ a = b" + and "sort_of (atom a) = sort_of (atom b) \ (a \ b) \ b = a" + and "\a \ c; b \ c\ \ (a \ b) \ c = c" + and "sort_of (atom a) \ sort_of (atom b) \ (a \ b) \ x = x" + unfolding flip_def + unfolding atom_eq_iff [symmetric] + unfolding atom_eqvt [symmetric] + by simp_all + +text {* the following two lemmas do not hold for at_base, + only for single sort atoms from at *} + +lemma permute_flip_at: + fixes a b c::"'a::at" + shows "(a \ b) \ c = (if c = a then b else if c = b then a else c)" + unfolding flip_def + apply (rule atom_eq_iff [THEN iffD1]) + apply (subst atom_eqvt [symmetric]) + apply (simp add: swap_atom) + done + +lemma flip_at_simps [simp]: + fixes a b::"'a::at" + shows "(a \ b) \ a = b" + and "(a \ b) \ b = a" + unfolding permute_flip_at by simp_all + + +subsection {* Syntax for coercing at-elements to the atom-type *} + +syntax + "_atom_constrain" :: "logic \ type \ logic" ("_:::_" [4, 0] 3) + +translations + "_atom_constrain a t" => "atom (_constrain a t)" + + +subsection {* A lemma for proving instances of class @{text at}. *} + +setup {* Sign.add_const_constraint (@{const_name "permute"}, NONE) *} +setup {* Sign.add_const_constraint (@{const_name "atom"}, NONE) *} + +text {* + New atom types are defined as subtypes of @{typ atom}. +*} + +lemma exists_eq_sort: + shows "\a. a \ {a. sort_of a = s}" + by (rule_tac x="Atom s 0" in exI, simp) + +lemma at_base_class: + fixes s :: atom_sort + fixes Rep :: "'a \ atom" and Abs :: "atom \ 'a" + assumes type: "type_definition Rep Abs {a. P (sort_of a)}" + assumes atom_def: "\a. atom a = Rep a" + assumes permute_def: "\p a. p \ a = Abs (p \ Rep a)" + shows "OFCLASS('a, at_base_class)" +proof + interpret type_definition Rep Abs "{a. P (sort_of a)}" by (rule type) + have sort_of_Rep: "\a. P (sort_of (Rep a))" using Rep by simp + fix a b :: 'a and p p1 p2 :: perm + show "0 \ a = a" + unfolding permute_def by (simp add: Rep_inverse) + show "(p1 + p2) \ a = p1 \ p2 \ a" + unfolding permute_def by (simp add: Abs_inverse sort_of_Rep) + show "atom a = atom b \ a = b" + unfolding atom_def by (simp add: Rep_inject) + show "p \ atom a = atom (p \ a)" + unfolding permute_def atom_def by (simp add: Abs_inverse sort_of_Rep) +qed + +lemma at_class: + fixes s :: atom_sort + fixes Rep :: "'a \ atom" and Abs :: "atom \ 'a" + assumes type: "type_definition Rep Abs {a. sort_of a = s}" + assumes atom_def: "\a. atom a = Rep a" + assumes permute_def: "\p a. p \ a = Abs (p \ Rep a)" + shows "OFCLASS('a, at_class)" +proof + interpret type_definition Rep Abs "{a. sort_of a = s}" by (rule type) + have sort_of_Rep: "\a. sort_of (Rep a) = s" using Rep by simp + fix a b :: 'a and p p1 p2 :: perm + show "0 \ a = a" + unfolding permute_def by (simp add: Rep_inverse) + show "(p1 + p2) \ a = p1 \ p2 \ a" + unfolding permute_def by (simp add: Abs_inverse sort_of_Rep) + show "sort_of (atom a) = sort_of (atom b)" + unfolding atom_def by (simp add: sort_of_Rep) + show "atom a = atom b \ a = b" + unfolding atom_def by (simp add: Rep_inject) + show "p \ atom a = atom (p \ a)" + unfolding permute_def atom_def by (simp add: Abs_inverse sort_of_Rep) +qed + +setup {* Sign.add_const_constraint + (@{const_name "permute"}, SOME @{typ "perm \ 'a::pt \ 'a"}) *} +setup {* Sign.add_const_constraint + (@{const_name "atom"}, SOME @{typ "'a::at_base \ atom"}) *} + + +section {* Automation for creating concrete atom types *} + +text {* at the moment only single-sort concrete atoms are supported *} + +use "atom_decl.ML" + + +end