diff -r c0eac04ae3b4 -r c34347ec7ab3 Nominal/Nominal2_Base.thy --- a/Nominal/Nominal2_Base.thy Sat Apr 03 22:31:11 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1062 +0,0 @@ -(* Title: Nominal2_Base - Authors: Brian Huffman, Christian Urban - - Basic definitions and lemma infrastructure for - Nominal Isabelle. -*) -theory Nominal2_Base -imports Main Infinite_Set -begin - -section {* Atoms and Sorts *} - -text {* A simple implementation for atom_sorts is strings. *} -(* types atom_sort = string *) - -text {* To deal with Church-like binding we use trees of - strings as sorts. *} - -datatype atom_sort = Sort "string" "atom_sort list" - -datatype atom = Atom atom_sort nat - - -text {* Basic projection function. *} - -primrec - sort_of :: "atom \ atom_sort" -where - "sort_of (Atom s i) = s" - - -text {* There are infinitely many atoms of each sort. *} -lemma INFM_sort_of_eq: - shows "INFM a. sort_of a = s" -proof - - have "INFM i. sort_of (Atom s i) = s" by simp - moreover have "inj (Atom s)" by (simp add: inj_on_def) - ultimately show "INFM a. sort_of a = s" by (rule INFM_inj) -qed - -lemma infinite_sort_of_eq: - shows "infinite {a. sort_of a = s}" - using INFM_sort_of_eq unfolding INFM_iff_infinite . - -lemma atom_infinite [simp]: - shows "infinite (UNIV :: atom set)" - using subset_UNIV infinite_sort_of_eq - by (rule infinite_super) - -lemma obtain_atom: - fixes X :: "atom set" - assumes X: "finite X" - obtains a where "a \ X" "sort_of a = s" -proof - - from X have "MOST a. a \ X" - unfolding MOST_iff_cofinite by simp - with INFM_sort_of_eq - have "INFM a. sort_of a = s \ a \ X" - by (rule INFM_conjI) - then obtain a where "a \ X" "sort_of a = s" - by (auto elim: INFM_E) - then show ?thesis .. -qed - -section {* Sort-Respecting Permutations *} - -typedef perm = - "{f. bij f \ finite {a. f a \ a} \ (\a. sort_of (f a) = sort_of a)}" -proof - show "id \ ?perm" by simp -qed - -lemma permI: - assumes "bij f" and "MOST x. f x = x" and "\a. sort_of (f a) = sort_of a" - shows "f \ perm" - using assms unfolding perm_def MOST_iff_cofinite by simp - -lemma perm_is_bij: "f \ perm \ bij f" - unfolding perm_def by simp - -lemma perm_is_finite: "f \ perm \ finite {a. f a \ a}" - unfolding perm_def by simp - -lemma perm_is_sort_respecting: "f \ perm \ sort_of (f a) = sort_of a" - unfolding perm_def by simp - -lemma perm_MOST: "f \ perm \ MOST x. f x = x" - unfolding perm_def MOST_iff_cofinite by simp - -lemma perm_id: "id \ perm" - unfolding perm_def by simp - -lemma perm_comp: - assumes f: "f \ perm" and g: "g \ perm" - shows "(f \ g) \ perm" -apply (rule permI) -apply (rule bij_comp) -apply (rule perm_is_bij [OF g]) -apply (rule perm_is_bij [OF f]) -apply (rule MOST_rev_mp [OF perm_MOST [OF g]]) -apply (rule MOST_rev_mp [OF perm_MOST [OF f]]) -apply (simp) -apply (simp add: perm_is_sort_respecting [OF f]) -apply (simp add: perm_is_sort_respecting [OF g]) -done - -lemma perm_inv: - assumes f: "f \ perm" - shows "(inv f) \ perm" -apply (rule permI) -apply (rule bij_imp_bij_inv) -apply (rule perm_is_bij [OF f]) -apply (rule MOST_mono [OF perm_MOST [OF f]]) -apply (erule subst, rule inv_f_f) -apply (rule bij_is_inj [OF perm_is_bij [OF f]]) -apply (rule perm_is_sort_respecting [OF f, THEN sym, THEN trans]) -apply (simp add: surj_f_inv_f [OF bij_is_surj [OF perm_is_bij [OF f]]]) -done - -lemma bij_Rep_perm: "bij (Rep_perm p)" - using Rep_perm [of p] unfolding perm_def by simp - -lemma finite_Rep_perm: "finite {a. Rep_perm p a \ a}" - using Rep_perm [of p] unfolding perm_def by simp - -lemma sort_of_Rep_perm: "sort_of (Rep_perm p a) = sort_of a" - using Rep_perm [of p] unfolding perm_def by simp - -lemma Rep_perm_ext: - "Rep_perm p1 = Rep_perm p2 \ p1 = p2" - by (simp add: expand_fun_eq Rep_perm_inject [symmetric]) - - -subsection {* Permutations form a group *} - -instantiation perm :: group_add -begin - -definition - "0 = Abs_perm id" - -definition - "- p = Abs_perm (inv (Rep_perm p))" - -definition - "p + q = Abs_perm (Rep_perm p \ Rep_perm q)" - -definition - "(p1::perm) - p2 = p1 + - p2" - -lemma Rep_perm_0: "Rep_perm 0 = id" - unfolding zero_perm_def - by (simp add: Abs_perm_inverse perm_id) - -lemma Rep_perm_add: - "Rep_perm (p1 + p2) = Rep_perm p1 \ Rep_perm p2" - unfolding plus_perm_def - by (simp add: Abs_perm_inverse perm_comp Rep_perm) - -lemma Rep_perm_uminus: - "Rep_perm (- p) = inv (Rep_perm p)" - unfolding uminus_perm_def - by (simp add: Abs_perm_inverse perm_inv Rep_perm) - -instance -apply default -unfolding Rep_perm_inject [symmetric] -unfolding minus_perm_def -unfolding Rep_perm_add -unfolding Rep_perm_uminus -unfolding Rep_perm_0 -by (simp_all add: o_assoc inv_o_cancel [OF bij_is_inj [OF bij_Rep_perm]]) - -end - - -section {* Implementation of swappings *} - -definition - swap :: "atom \ atom \ perm" ("'(_ \ _')") -where - "(a \ b) = - Abs_perm (if sort_of a = sort_of b - then (\c. if a = c then b else if b = c then a else c) - else id)" - -lemma Rep_perm_swap: - "Rep_perm (a \ b) = - (if sort_of a = sort_of b - then (\c. if a = c then b else if b = c then a else c) - else id)" -unfolding swap_def -apply (rule Abs_perm_inverse) -apply (rule permI) -apply (auto simp add: bij_def inj_on_def surj_def)[1] -apply (rule MOST_rev_mp [OF MOST_neq(1) [of a]]) -apply (rule MOST_rev_mp [OF MOST_neq(1) [of b]]) -apply (simp) -apply (simp) -done - -lemmas Rep_perm_simps = - Rep_perm_0 - Rep_perm_add - Rep_perm_uminus - Rep_perm_swap - -lemma swap_different_sorts [simp]: - "sort_of a \ sort_of b \ (a \ b) = 0" - by (rule Rep_perm_ext) (simp add: Rep_perm_simps) - -lemma swap_cancel: - "(a \ b) + (a \ b) = 0" -by (rule Rep_perm_ext) - (simp add: Rep_perm_simps expand_fun_eq) - -lemma swap_self [simp]: - "(a \ a) = 0" - by (rule Rep_perm_ext, simp add: Rep_perm_simps expand_fun_eq) - -lemma minus_swap [simp]: - "- (a \ b) = (a \ b)" - by (rule minus_unique [OF swap_cancel]) - -lemma swap_commute: - "(a \ b) = (b \ a)" - by (rule Rep_perm_ext) - (simp add: Rep_perm_swap expand_fun_eq) - -lemma swap_triple: - assumes "a \ b" and "c \ b" - assumes "sort_of a = sort_of b" "sort_of b = sort_of c" - shows "(a \ c) + (b \ c) + (a \ c) = (a \ b)" - using assms - by (rule_tac Rep_perm_ext) - (auto simp add: Rep_perm_simps expand_fun_eq) - - -section {* Permutation Types *} - -text {* - Infix syntax for @{text permute} has higher precedence than - addition, but lower than unary minus. -*} - -class pt = - fixes permute :: "perm \ 'a \ 'a" ("_ \ _" [76, 75] 75) - assumes permute_zero [simp]: "0 \ x = x" - assumes permute_plus [simp]: "(p + q) \ x = p \ (q \ x)" -begin - -lemma permute_diff [simp]: - shows "(p - q) \ x = p \ - q \ x" - unfolding diff_minus by simp - -lemma permute_minus_cancel [simp]: - shows "p \ - p \ x = x" - and "- p \ p \ x = x" - unfolding permute_plus [symmetric] by simp_all - -lemma permute_swap_cancel [simp]: - shows "(a \ b) \ (a \ b) \ x = x" - unfolding permute_plus [symmetric] - by (simp add: swap_cancel) - -lemma permute_swap_cancel2 [simp]: - shows "(a \ b) \ (b \ a) \ x = x" - unfolding permute_plus [symmetric] - by (simp add: swap_commute) - -lemma inj_permute [simp]: - shows "inj (permute p)" - by (rule inj_on_inverseI) - (rule permute_minus_cancel) - -lemma surj_permute [simp]: - shows "surj (permute p)" - by (rule surjI, rule permute_minus_cancel) - -lemma bij_permute [simp]: - shows "bij (permute p)" - by (rule bijI [OF inj_permute surj_permute]) - -lemma inv_permute: - shows "inv (permute p) = permute (- p)" - by (rule inv_equality) (simp_all) - -lemma permute_minus: - shows "permute (- p) = inv (permute p)" - by (simp add: inv_permute) - -lemma permute_eq_iff [simp]: - shows "p \ x = p \ y \ x = y" - by (rule inj_permute [THEN inj_eq]) - -end - -subsection {* Permutations for atoms *} - -instantiation atom :: pt -begin - -definition - "p \ a = Rep_perm p a" - -instance -apply(default) -apply(simp_all add: permute_atom_def Rep_perm_simps) -done - -end - -lemma sort_of_permute [simp]: - shows "sort_of (p \ a) = sort_of a" - unfolding permute_atom_def by (rule sort_of_Rep_perm) - -lemma swap_atom: - shows "(a \ b) \ c = - (if sort_of a = sort_of b - then (if c = a then b else if c = b then a else c) else c)" - unfolding permute_atom_def - by (simp add: Rep_perm_swap) - -lemma swap_atom_simps [simp]: - "sort_of a = sort_of b \ (a \ b) \ a = b" - "sort_of a = sort_of b \ (a \ b) \ b = a" - "c \ a \ c \ b \ (a \ b) \ c = c" - unfolding swap_atom by simp_all - -lemma expand_perm_eq: - fixes p q :: "perm" - shows "p = q \ (\a::atom. p \ a = q \ a)" - unfolding permute_atom_def - by (metis Rep_perm_ext ext) - - -subsection {* Permutations for permutations *} - -instantiation perm :: pt -begin - -definition - "p \ q = p + q - p" - -instance -apply default -apply (simp add: permute_perm_def) -apply (simp add: permute_perm_def diff_minus minus_add add_assoc) -done - -end - -lemma permute_self: "p \ p = p" -unfolding permute_perm_def by (simp add: diff_minus add_assoc) - -lemma permute_eqvt: - shows "p \ (q \ x) = (p \ q) \ (p \ x)" - unfolding permute_perm_def by simp - -lemma zero_perm_eqvt: - shows "p \ (0::perm) = 0" - unfolding permute_perm_def by simp - -lemma add_perm_eqvt: - fixes p p1 p2 :: perm - shows "p \ (p1 + p2) = p \ p1 + p \ p2" - unfolding permute_perm_def - by (simp add: expand_perm_eq) - -lemma swap_eqvt: - shows "p \ (a \ b) = (p \ a \ p \ b)" - unfolding permute_perm_def - by (auto simp add: swap_atom expand_perm_eq) - - -subsection {* Permutations for functions *} - -instantiation "fun" :: (pt, pt) pt -begin - -definition - "p \ f = (\x. p \ (f (- p \ x)))" - -instance -apply default -apply (simp add: permute_fun_def) -apply (simp add: permute_fun_def minus_add) -done - -end - -lemma permute_fun_app_eq: - shows "p \ (f x) = (p \ f) (p \ x)" -unfolding permute_fun_def by simp - - -subsection {* Permutations for booleans *} - -instantiation bool :: pt -begin - -definition "p \ (b::bool) = b" - -instance -apply(default) -apply(simp_all add: permute_bool_def) -done - -end - -lemma Not_eqvt: - shows "p \ (\ A) = (\ (p \ A))" -by (simp add: permute_bool_def) - -lemma permute_boolE: - fixes P::"bool" - shows "p \ P \ P" - by (simp add: permute_bool_def) - -lemma permute_boolI: - fixes P::"bool" - shows "P \ p \ P" - by(simp add: permute_bool_def) - -subsection {* Permutations for sets *} - -lemma permute_set_eq: - fixes x::"'a::pt" - and p::"perm" - shows "(p \ X) = {p \ x | x. x \ X}" - apply(auto simp add: permute_fun_def permute_bool_def mem_def) - apply(rule_tac x="- p \ x" in exI) - apply(simp) - done - -lemma permute_set_eq_image: - shows "p \ X = permute p ` X" -unfolding permute_set_eq by auto - -lemma permute_set_eq_vimage: - shows "p \ X = permute (- p) -` X" -unfolding permute_fun_def permute_bool_def -unfolding vimage_def Collect_def mem_def .. - -lemma swap_set_not_in: - assumes a: "a \ S" "b \ S" - shows "(a \ b) \ S = S" - using a by (auto simp add: permute_set_eq swap_atom) - -lemma swap_set_in: - assumes a: "a \ S" "b \ S" "sort_of a = sort_of b" - shows "(a \ b) \ S \ S" - using a by (auto simp add: permute_set_eq swap_atom) - - -subsection {* Permutations for units *} - -instantiation unit :: pt -begin - -definition "p \ (u::unit) = u" - -instance proof -qed (simp_all add: permute_unit_def) - -end - - -subsection {* Permutations for products *} - -instantiation "*" :: (pt, pt) pt -begin - -primrec - permute_prod -where - Pair_eqvt: "p \ (x, y) = (p \ x, p \ y)" - -instance -by default auto - -end - -subsection {* Permutations for sums *} - -instantiation "+" :: (pt, pt) pt -begin - -primrec - permute_sum -where - "p \ (Inl x) = Inl (p \ x)" -| "p \ (Inr y) = Inr (p \ y)" - -instance proof -qed (case_tac [!] x, simp_all) - -end - -subsection {* Permutations for lists *} - -instantiation list :: (pt) pt -begin - -primrec - permute_list -where - "p \ [] = []" -| "p \ (x # xs) = p \ x # p \ xs" - -instance proof -qed (induct_tac [!] x, simp_all) - -end - -subsection {* Permutations for options *} - -instantiation option :: (pt) pt -begin - -primrec - permute_option -where - "p \ None = None" -| "p \ (Some x) = Some (p \ x)" - -instance proof -qed (induct_tac [!] x, simp_all) - -end - -subsection {* Permutations for @{typ char}, @{typ nat}, and @{typ int} *} - -instantiation char :: pt -begin - -definition "p \ (c::char) = c" - -instance proof -qed (simp_all add: permute_char_def) - -end - -instantiation nat :: pt -begin - -definition "p \ (n::nat) = n" - -instance proof -qed (simp_all add: permute_nat_def) - -end - -instantiation int :: pt -begin - -definition "p \ (i::int) = i" - -instance proof -qed (simp_all add: permute_int_def) - -end - - -section {* Pure types *} - -text {* Pure types will have always empty support. *} - -class pure = pt + - assumes permute_pure: "p \ x = x" - -text {* Types @{typ unit} and @{typ bool} are pure. *} - -instance unit :: pure -proof qed (rule permute_unit_def) - -instance bool :: pure -proof qed (rule permute_bool_def) - -text {* Other type constructors preserve purity. *} - -instance "fun" :: (pure, pure) pure -by default (simp add: permute_fun_def permute_pure) - -instance "*" :: (pure, pure) pure -by default (induct_tac x, simp add: permute_pure) - -instance "+" :: (pure, pure) pure -by default (induct_tac x, simp_all add: permute_pure) - -instance list :: (pure) pure -by default (induct_tac x, simp_all add: permute_pure) - -instance option :: (pure) pure -by default (induct_tac x, simp_all add: permute_pure) - - -subsection {* Types @{typ char}, @{typ nat}, and @{typ int} *} - -instance char :: pure -proof qed (rule permute_char_def) - -instance nat :: pure -proof qed (rule permute_nat_def) - -instance int :: pure -proof qed (rule permute_int_def) - - -subsection {* Supp, Freshness and Supports *} - -context pt -begin - -definition - supp :: "'a \ atom set" -where - "supp x = {a. infinite {b. (a \ b) \ x \ x}}" - -end - -definition - fresh :: "atom \ 'a::pt \ bool" ("_ \ _" [55, 55] 55) -where - "a \ x \ a \ supp x" - -lemma supp_conv_fresh: - shows "supp x = {a. \ a \ x}" - unfolding fresh_def by simp - -lemma swap_rel_trans: - assumes "sort_of a = sort_of b" - assumes "sort_of b = sort_of c" - assumes "(a \ c) \ x = x" - assumes "(b \ c) \ x = x" - shows "(a \ b) \ x = x" -proof (cases) - assume "a = b \ c = b" - with assms show "(a \ b) \ x = x" by auto -next - assume *: "\ (a = b \ c = b)" - have "((a \ c) + (b \ c) + (a \ c)) \ x = x" - using assms by simp - also have "(a \ c) + (b \ c) + (a \ c) = (a \ b)" - using assms * by (simp add: swap_triple) - finally show "(a \ b) \ x = x" . -qed - -lemma swap_fresh_fresh: - assumes a: "a \ x" - and b: "b \ x" - shows "(a \ b) \ x = x" -proof (cases) - assume asm: "sort_of a = sort_of b" - have "finite {c. (a \ c) \ x \ x}" "finite {c. (b \ c) \ x \ x}" - using a b unfolding fresh_def supp_def by simp_all - then have "finite ({c. (a \ c) \ x \ x} \ {c. (b \ c) \ x \ x})" by simp - then obtain c - where "(a \ c) \ x = x" "(b \ c) \ x = x" "sort_of c = sort_of b" - by (rule obtain_atom) (auto) - then show "(a \ b) \ x = x" using asm by (rule_tac swap_rel_trans) (simp_all) -next - assume "sort_of a \ sort_of b" - then show "(a \ b) \ x = x" by simp -qed - - -subsection {* supp and fresh are equivariant *} - -lemma finite_Collect_bij: - assumes a: "bij f" - shows "finite {x. P (f x)} = finite {x. P x}" -by (metis a finite_vimage_iff vimage_Collect_eq) - -lemma fresh_permute_iff: - shows "(p \ a) \ (p \ x) \ a \ x" -proof - - have "(p \ a) \ (p \ x) \ finite {b. (p \ a \ b) \ p \ x \ p \ x}" - unfolding fresh_def supp_def by simp - also have "\ \ finite {b. (p \ a \ p \ b) \ p \ x \ p \ x}" - using bij_permute by (rule finite_Collect_bij [symmetric]) - also have "\ \ finite {b. p \ (a \ b) \ x \ p \ x}" - by (simp only: permute_eqvt [of p] swap_eqvt) - also have "\ \ finite {b. (a \ b) \ x \ x}" - by (simp only: permute_eq_iff) - also have "\ \ a \ x" - unfolding fresh_def supp_def by simp - finally show ?thesis . -qed - -lemma fresh_eqvt: - shows "p \ (a \ x) = (p \ a) \ (p \ x)" - by (simp add: permute_bool_def fresh_permute_iff) - -lemma supp_eqvt: - fixes p :: "perm" - and x :: "'a::pt" - shows "p \ (supp x) = supp (p \ x)" - unfolding supp_conv_fresh - unfolding permute_fun_def Collect_def - by (simp add: Not_eqvt fresh_eqvt) - -subsection {* supports *} - -definition - supports :: "atom set \ 'a::pt \ bool" (infixl "supports" 80) -where - "S supports x \ \a b. (a \ S \ b \ S \ (a \ b) \ x = x)" - -lemma supp_is_subset: - fixes S :: "atom set" - and x :: "'a::pt" - assumes a1: "S supports x" - and a2: "finite S" - shows "(supp x) \ S" -proof (rule ccontr) - assume "\(supp x \ S)" - then obtain a where b1: "a \ supp x" and b2: "a \ S" by auto - from a1 b2 have "\b. b \ S \ (a \ b) \ x = x" by (unfold supports_def) (auto) - hence "{b. (a \ b) \ x \ x} \ S" by auto - with a2 have "finite {b. (a \ b)\x \ x}" by (simp add: finite_subset) - then have "a \ (supp x)" unfolding supp_def by simp - with b1 show False by simp -qed - -lemma supports_finite: - fixes S :: "atom set" - and x :: "'a::pt" - assumes a1: "S supports x" - and a2: "finite S" - shows "finite (supp x)" -proof - - have "(supp x) \ S" using a1 a2 by (rule supp_is_subset) - then show "finite (supp x)" using a2 by (simp add: finite_subset) -qed - -lemma supp_supports: - fixes x :: "'a::pt" - shows "(supp x) supports x" -proof (unfold supports_def, intro strip) - fix a b - assume "a \ (supp x) \ b \ (supp x)" - then have "a \ x" and "b \ x" by (simp_all add: fresh_def) - then show "(a \ b) \ x = x" by (rule swap_fresh_fresh) -qed - -lemma supp_is_least_supports: - fixes S :: "atom set" - and x :: "'a::pt" - assumes a1: "S supports x" - and a2: "finite S" - and a3: "\S'. finite S' \ (S' supports x) \ S \ S'" - shows "(supp x) = S" -proof (rule equalityI) - show "(supp x) \ S" using a1 a2 by (rule supp_is_subset) - with a2 have fin: "finite (supp x)" by (rule rev_finite_subset) - have "(supp x) supports x" by (rule supp_supports) - with fin a3 show "S \ supp x" by blast -qed - -lemma subsetCI: - shows "(\x. x \ A \ x \ B \ False) \ A \ B" - by auto - -lemma finite_supp_unique: - assumes a1: "S supports x" - assumes a2: "finite S" - assumes a3: "\a b. \a \ S; b \ S; sort_of a = sort_of b\ \ (a \ b) \ x \ x" - shows "(supp x) = S" - using a1 a2 -proof (rule supp_is_least_supports) - fix S' - assume "finite S'" and "S' supports x" - show "S \ S'" - proof (rule subsetCI) - fix a - assume "a \ S" and "a \ S'" - have "finite (S \ S')" - using `finite S` `finite S'` by simp - then obtain b where "b \ S \ S'" and "sort_of b = sort_of a" - by (rule obtain_atom) - then have "b \ S" and "b \ S'" and "sort_of a = sort_of b" - by simp_all - then have "(a \ b) \ x = x" - using `a \ S'` `S' supports x` by (simp add: supports_def) - moreover have "(a \ b) \ x \ x" - using `a \ S` `b \ S` `sort_of a = sort_of b` - by (rule a3) - ultimately show "False" by simp - qed -qed - -section {* Finitely-supported types *} - -class fs = pt + - assumes finite_supp: "finite (supp x)" - -lemma pure_supp: - shows "supp (x::'a::pure) = {}" - unfolding supp_def by (simp add: permute_pure) - -lemma pure_fresh: - fixes x::"'a::pure" - shows "a \ x" - unfolding fresh_def by (simp add: pure_supp) - -instance pure < fs -by default (simp add: pure_supp) - - -subsection {* Type @{typ atom} is finitely-supported. *} - -lemma supp_atom: - shows "supp a = {a}" -apply (rule finite_supp_unique) -apply (clarsimp simp add: supports_def) -apply simp -apply simp -done - -lemma fresh_atom: - shows "a \ b \ a \ b" - unfolding fresh_def supp_atom by simp - -instance atom :: fs -by default (simp add: supp_atom) - - -section {* Type @{typ perm} is finitely-supported. *} - -lemma perm_swap_eq: - shows "(a \ b) \ p = p \ (p \ (a \ b)) = (a \ b)" -unfolding permute_perm_def -by (metis add_diff_cancel minus_perm_def) - -lemma supports_perm: - shows "{a. p \ a \ a} supports p" - unfolding supports_def - by (simp add: perm_swap_eq swap_eqvt) - -lemma finite_perm_lemma: - shows "finite {a::atom. p \ a \ a}" - using finite_Rep_perm [of p] - unfolding permute_atom_def . - -lemma supp_perm: - shows "supp p = {a. p \ a \ a}" -apply (rule finite_supp_unique) -apply (rule supports_perm) -apply (rule finite_perm_lemma) -apply (simp add: perm_swap_eq swap_eqvt) -apply (auto simp add: expand_perm_eq swap_atom) -done - -lemma fresh_perm: - shows "a \ p \ p \ a = a" -unfolding fresh_def by (simp add: supp_perm) - -lemma supp_swap: - shows "supp (a \ b) = (if a = b \ sort_of a \ sort_of b then {} else {a, b})" - by (auto simp add: supp_perm swap_atom) - -lemma fresh_zero_perm: - shows "a \ (0::perm)" - unfolding fresh_perm by simp - -lemma supp_zero_perm: - shows "supp (0::perm) = {}" - unfolding supp_perm by simp - -lemma fresh_plus_perm: - fixes p q::perm - assumes "a \ p" "a \ q" - shows "a \ (p + q)" - using assms - unfolding fresh_def - by (auto simp add: supp_perm) - -lemma supp_plus_perm: - fixes p q::perm - shows "supp (p + q) \ supp p \ supp q" - by (auto simp add: supp_perm) - -lemma fresh_minus_perm: - fixes p::perm - shows "a \ (- p) \ a \ p" - unfolding fresh_def - apply(auto simp add: supp_perm) - apply(metis permute_minus_cancel)+ - done - -lemma supp_minus_perm: - fixes p::perm - shows "supp (- p) = supp p" - unfolding supp_conv_fresh - by (simp add: fresh_minus_perm) - -instance perm :: fs -by default (simp add: supp_perm finite_perm_lemma) - -lemma plus_perm_eq: - fixes p q::"perm" - assumes asm: "supp p \ supp q = {}" - shows "p + q = q + p" -unfolding expand_perm_eq -proof - fix a::"atom" - show "(p + q) \ a = (q + p) \ a" - proof - - { assume "a \ supp p" "a \ supp q" - then have "(p + q) \ a = (q + p) \ a" - by (simp add: supp_perm) - } - moreover - { assume a: "a \ supp p" "a \ supp q" - then have "p \ a \ supp p" by (simp add: supp_perm) - then have "p \ a \ supp q" using asm by auto - with a have "(p + q) \ a = (q + p) \ a" - by (simp add: supp_perm) - } - moreover - { assume a: "a \ supp p" "a \ supp q" - then have "q \ a \ supp q" by (simp add: supp_perm) - then have "q \ a \ supp p" using asm by auto - with a have "(p + q) \ a = (q + p) \ a" - by (simp add: supp_perm) - } - ultimately show "(p + q) \ a = (q + p) \ a" - using asm by blast - qed -qed - -section {* Finite Support instances for other types *} - -subsection {* Type @{typ "'a \ 'b"} is finitely-supported. *} - -lemma supp_Pair: - shows "supp (x, y) = supp x \ supp y" - by (simp add: supp_def Collect_imp_eq Collect_neg_eq) - -lemma fresh_Pair: - shows "a \ (x, y) \ a \ x \ a \ y" - by (simp add: fresh_def supp_Pair) - -instance "*" :: (fs, fs) fs -apply default -apply (induct_tac x) -apply (simp add: supp_Pair finite_supp) -done - -subsection {* Type @{typ "'a + 'b"} is finitely supported *} - -lemma supp_Inl: - shows "supp (Inl x) = supp x" - by (simp add: supp_def) - -lemma supp_Inr: - shows "supp (Inr x) = supp x" - by (simp add: supp_def) - -lemma fresh_Inl: - shows "a \ Inl x \ a \ x" - by (simp add: fresh_def supp_Inl) - -lemma fresh_Inr: - shows "a \ Inr y \ a \ y" - by (simp add: fresh_def supp_Inr) - -instance "+" :: (fs, fs) fs -apply default -apply (induct_tac x) -apply (simp_all add: supp_Inl supp_Inr finite_supp) -done - -subsection {* Type @{typ "'a option"} is finitely supported *} - -lemma supp_None: - shows "supp None = {}" -by (simp add: supp_def) - -lemma supp_Some: - shows "supp (Some x) = supp x" - by (simp add: supp_def) - -lemma fresh_None: - shows "a \ None" - by (simp add: fresh_def supp_None) - -lemma fresh_Some: - shows "a \ Some x \ a \ x" - by (simp add: fresh_def supp_Some) - -instance option :: (fs) fs -apply default -apply (induct_tac x) -apply (simp_all add: supp_None supp_Some finite_supp) -done - -subsubsection {* Type @{typ "'a list"} is finitely supported *} - -lemma supp_Nil: - shows "supp [] = {}" - by (simp add: supp_def) - -lemma supp_Cons: - shows "supp (x # xs) = supp x \ supp xs" -by (simp add: supp_def Collect_imp_eq Collect_neg_eq) - -lemma fresh_Nil: - shows "a \ []" - by (simp add: fresh_def supp_Nil) - -lemma fresh_Cons: - shows "a \ (x # xs) \ a \ x \ a \ xs" - by (simp add: fresh_def supp_Cons) - -instance list :: (fs) fs -apply default -apply (induct_tac x) -apply (simp_all add: supp_Nil supp_Cons finite_supp) -done - -section {* Support and freshness for applications *} - -lemma supp_fun_app: - shows "supp (f x) \ (supp f) \ (supp x)" -proof (rule subsetCI) - fix a::"atom" - assume a: "a \ supp (f x)" - assume b: "a \ supp f \ supp x" - then have "finite {b. (a \ b) \ f \ f}" "finite {b. (a \ b) \ x \ x}" - unfolding supp_def by auto - then have "finite ({b. (a \ b) \ f \ f} \ {b. (a \ b) \ x \ x})" by simp - moreover - have "{b. ((a \ b) \ f) ((a \ b) \ x) \ f x} \ ({b. (a \ b) \ f \ f} \ {b. (a \ b) \ x \ x})" - by auto - ultimately have "finite {b. ((a \ b) \ f) ((a \ b) \ x) \ f x}" - using finite_subset by auto - then have "a \ supp (f x)" unfolding supp_def - by (simp add: permute_fun_app_eq) - with a show "False" by simp -qed - -lemma fresh_fun_app: - shows "a \ (f, x) \ a \ f x" -unfolding fresh_def -using supp_fun_app -by (auto simp add: supp_Pair) - -lemma fresh_fun_eqvt_app: - assumes a: "\p. p \ f = f" - shows "a \ x \ a \ f x" -proof - - from a have b: "supp f = {}" - unfolding supp_def by simp - show "a \ x \ a \ f x" - unfolding fresh_def - using supp_fun_app b - by auto -qed - -end