theory Nominal imports"HOL-Library.Infinite_Set""HOL-Library.Old_Datatype"
keywords "atom_decl" :: thy_decl and "nominal_datatype" :: thy_defn and "equivariance" :: thy_decl and "nominal_primrec""nominal_inductive""nominal_inductive2" :: thy_goal_defn and "avoids" begin
declare [[typedef_overloaded]]
section‹Permutations› (*======================*)
type_synonym
'x prm = "('x × 'x) list"
(* polymorphic constants for permutation and swapping *) consts
perm :: "'x prm ==> 'a ==> 'a" (infixr‹∙› 80)
swap :: "('x × 'x) ==> 'x ==> 'x"
(* a "private" copy of the option type used in the abstraction function *) datatype 'a noption = nSome 'a | nNone
datatype_compat noption
(* a "private" copy of the product type used in the nominal induct method *) datatype ('a, 'b) nprod = nPair 'a 'b
datatype_compat nprod
(* an auxiliary constant for the decision procedure involving *) (* permutations (to avoid loops when using perm-compositions) *) definition "perm_aux pi x = pi∙x"
(* permutation on lists *) lemma append_eqvt: fixes pi :: "'x prm" and l1 :: "'a list" and l2 :: "'a list" shows"pi∙(l1@l2) = (pi∙l1)@(pi∙l2)" by (induct l1) auto
lemma rev_eqvt: fixes pi :: "'x prm" and l :: "'a list" shows"pi∙(rev l) = rev (pi∙l)" by (induct l) (simp_all add: append_eqvt)
lemma set_eqvt: fixes pi :: "'x prm" and xs :: "'a list" shows"pi∙(set xs) = set (pi∙xs)" by (induct xs) (auto simp add: empty_eqvt insert_eqvt)
(* permutation on characters and strings *) lemma perm_string: fixes s::"string" shows"pi∙s = s" by (induct s)(auto simp add: perm_char_def)
lemma supp_prod: fixes x :: "'a" and y :: "'b" shows"(supp (x,y)) = (supp x)∪(supp y)" by (force simp add: supp_def Collect_imp_eq Collect_neg_eq)
lemma supp_nprod: fixes x :: "'a" and y :: "'b" shows"(supp (nPair x y)) = (supp x)∪(supp y)" by (force simp add: supp_def Collect_imp_eq Collect_neg_eq)
lemma supp_list_nil[simp]: shows"supp [] = {}" by (simp add: supp_def)
lemma supp_list_cons: fixes x :: "'a" and xs :: "'a list" shows"supp (x#xs) = (supp x)∪(supp xs)" by (auto simp add: supp_def Collect_imp_eq Collect_neg_eq)
(* lemmas about freshness *) lemma fresh_set_empty[simp]: shows"a♯{}" by (simp add: fresh_def supp_set_empty)
lemma fresh_unit[simp]: shows"a♯()" by (simp add: fresh_def supp_unit)
lemma fresh_prod: fixes a :: "'x" and x :: "'a" and y :: "'b" shows"a♯(x,y) = (a♯x ∧ a♯y)" by (simp add: fresh_def supp_prod)
lemma fresh_list_nil[simp]: fixes a :: "'x" shows"a♯[]" by (simp add: fresh_def supp_list_nil)
lemma fresh_list_cons: fixes a :: "'x" and x :: "'a" and xs :: "'a list" shows"a♯(x#xs) = (a♯x ∧ a♯xs)" by (simp add: fresh_def supp_list_cons)
lemma fresh_list_append: fixes a :: "'x" and xs :: "'a list" and ys :: "'a list" shows"a♯(xs@ys) = (a♯xs ∧ a♯ys)" by (simp add: fresh_def supp_list_append)
lemma fresh_list_rev[simp]: fixes a :: "'x" and xs :: "'a list" shows"a♯(rev xs) = a♯xs" by (simp add: fresh_def supp_list_rev)
lemma fresh_none[simp]: fixes a :: "'x" shows"a♯None" by (simp add: fresh_def supp_none)
lemma fresh_some[simp]: fixes a :: "'x" and x :: "'a" shows"a♯(Some x) = a♯x" by (simp add: fresh_def supp_some)
lemma fresh_int[simp]: fixes a :: "'x" and i :: "int" shows"a♯i" by (simp add: fresh_def supp_int)
lemma fresh_nat[simp]: fixes a :: "'x" and n :: "nat" shows"a♯n" by (simp add: fresh_def supp_nat)
lemma fresh_char[simp]: fixes a :: "'x" and c :: "char" shows"a♯c" by (simp add: fresh_def supp_char)
lemma fresh_string[simp]: fixes a :: "'x" and s :: "string" shows"a♯s" by (simp add: fresh_def supp_string)
lemma fresh_bool[simp]: fixes a :: "'x" and b :: "bool" shows"a♯b" by (simp add: fresh_def supp_bool)
text‹Normalization of freshness results; cf.\ ‹nominal_induct›\lemma fresh_unit_elim: shows"(a♯() ==> PROP C) ≡ PROP C" by (simp add: fresh_def supp_unit)
lemma fresh_prod_elim: shows"(a♯(x,y) ==> PROP C) ≡ (a♯x ==> a♯y ==> PROP C)" by rule (simp_all add: fresh_prod)
(* this rule needs to be added before the fresh_prodD is *) (* added to the simplifier with mksimps *) lemma [simp]: shows"a♯x1 ==> a♯x2 ==> a♯(x1,x2)" by (simp add: fresh_prod)
ML ‹ val mksimps_pairs = (🍋‹Nominal.fresh›, › declaration‹fn _ => Simplifier.map_ss (Simplifier.set_mksimps (mksimps mksimps_pairs)) ›
section‹Abstract Properties for Permutations and Atoms› (*=========================================================*)
(* properties for being a permutation type *) definition "pt TYPE('a) TYPE('x) ≡ (∀(x::'a). ([]::'x prm)∙x = x) ∧ (∀(pi1::'x prm) (pi2::'x prm) (x::'a). (pi1@pi2)∙x = pi1∙(pi2∙x)) ∧ (∀(pi1::'x prm) (pi2::'x prm) (x::'a). pi1 ≜ pi2 ⟶ pi1∙x = pi2∙x)"
(* properties for being an atom type *) definition "at TYPE('x) ≡ (∀(x::'x). ([]::'x prm)∙x = x) ∧ (∀(a::'x) (b::'x) (pi::'x prm) (x::'x). ((a,b)#(pi::'x prm))∙x = swap (a,b) (pi∙x)) ∧ (∀(a::'x) (b::'x) (c::'x). swap (a,b) c = (if a=c then b else (if b=c then a else c))) ∧ (infinite (UNIV::'x set))"
(* property of two atom-types being disjoint *) definition "disjoint TYPE('x) TYPE('y) ≡ (∀(pi::'x prm)(x::'y). pi∙x = x) ∧ (∀(pi::'y prm)(x::'x). pi∙x = x)"
(* composition property of two permutation on a type 'a *) definition "cp TYPE ('a) TYPE('x) TYPE('y) ≡ (∀(pi2::'y prm) (pi1::'x prm) (x::'a) . pi1∙(pi2∙x) = (pi1∙pi2)∙(pi1∙x))"
(* property of having finite support *) definition "fs TYPE('a) TYPE('x) ≡∀(x::'a). finite ((supp x)::'x set)"
section‹Lemmas about the atom-type properties› (*==============================================*)
lemma at1: fixes x::"'x" assumes a: "at TYPE('x)" shows"([]::'x prm)∙x = x" using a by (simp add: at_def)
lemma at2: fixes a ::"'x" and b ::"'x" and x ::"'x" and pi::"'x prm" assumes a: "at TYPE('x)" shows"((a,b)#pi)∙x = swap (a,b) (pi∙x)" using a by (simp only: at_def)
lemma at3: fixes a ::"'x" and b ::"'x" and c ::"'x" assumes a: "at TYPE('x)" shows"swap (a,b) c = (if a=c then b else (if b=c then a else c))" using a by (simp only: at_def)
lemma at_swap_simps: fixes a ::"'x" and b ::"'x" assumes a: "at TYPE('x)" shows"[(a,b)]∙a = b" and"[(a,b)]∙b = a" and"[a≠c; b≠c]==> [(a,b)]∙c = c" using a by (simp_all add: at_calc)
lemma at4: assumes a: "at TYPE('x)" shows"infinite (UNIV::'x set)" using a by (simp add: at_def)
lemma at_append: fixes pi1 :: "'x prm" and pi2 :: "'x prm" and c :: "'x" assumes at: "at TYPE('x)" shows"(pi1@pi2)∙c = pi1∙(pi2∙c)" proof (induct pi1) case Nil show ?caseby (simp add: at1[OF at]) next case (Cons x xs) have"(xs@pi2)∙c = xs∙(pi2∙c)"by fact alsohave"(x#xs)@pi2 = x#(xs@pi2)"by simp ultimatelyshow ?caseby (cases "x", simp add: at2[OF at]) qed
lemma at_swap: fixes a :: "'x" and b :: "'x" and c :: "'x" assumes at: "at TYPE('x)" shows"swap (a,b) (swap (a,b) c) = c" by (auto simp add: at3[OF at])
lemma at_rev_pi: fixes pi :: "'x prm" and c :: "'x" assumes at: "at TYPE('x)" shows"(rev pi)∙(pi∙c) = c" proof(induct pi) case Nil show ?caseby (simp add: at1[OF at]) next case (Cons x xs) thus ?case by (cases "x", simp add: at2[OF at] at_append[OF at] at1[OF at] at_swap[OF at]) qed
lemma at_pi_rev: fixes pi :: "'x prm" and x :: "'x" assumes at: "at TYPE('x)" shows"pi∙((rev pi)∙x) = x" by (rule at_rev_pi[OF at, of "rev pi" _,simplified])
lemma at_bij1: fixes pi :: "'x prm" and x :: "'x" and y :: "'x" assumes at: "at TYPE('x)" and a: "(pi∙x) = y" shows"x=(rev pi)∙y" proof - from a have"y=(pi∙x)"by (rule sym) thus ?thesis by (simp only: at_rev_pi[OF at]) qed
lemma at_bij2: fixes pi :: "'x prm" and x :: "'x" and y :: "'x" assumes at: "at TYPE('x)" and a: "((rev pi)∙x) = y" shows"x=pi∙y" proof - from a have"y=((rev pi)∙x)"by (rule sym) thus ?thesis by (simp only: at_pi_rev[OF at]) qed
lemma at_bij: fixes pi :: "'x prm" and x :: "'x" and y :: "'x" assumes at: "at TYPE('x)" shows"(pi∙x = pi∙y) = (x=y)" proof assume"pi∙x = pi∙y" hence"x=(rev pi)∙(pi∙y)"by (rule at_bij1[OF at]) thus"x=y"by (simp only: at_rev_pi[OF at]) next assume"x=y" thus"pi∙x = pi∙y"by simp qed
lemma at_ds1: fixes a :: "'x" assumes at: "at TYPE('x)" shows"[(a,a)] ≜ []" by (force simp add: prm_eq_def at_calc[OF at])
lemma at_ds2: fixes pi :: "'x prm" and a :: "'x" and b :: "'x" assumes at: "at TYPE('x)" shows"([(a,b)]@pi) ≜ (pi@[((rev pi)∙a,(rev pi)∙b)])" by (force simp add: prm_eq_def at_append[OF at] at_bij[OF at] at_pi_rev[OF at]
at_rev_pi[OF at] at_calc[OF at])
lemma at_ds3: fixes a :: "'x" and b :: "'x" and c :: "'x" assumes at: "at TYPE('x)" and a: "distinct [a,b,c]" shows"[(a,c),(b,c),(a,c)] ≜ [(a,b)]" using a by (force simp add: prm_eq_def at_calc[OF at])
lemma at_ds4: fixes a :: "'x" and b :: "'x" and pi :: "'x prm" assumes at: "at TYPE('x)" shows"(pi@[(a,(rev pi)∙b)]) ≜ ([(pi∙a,b)]@pi)" by (force simp add: prm_eq_def at_append[OF at] at_calc[OF at] at_bij[OF at]
at_pi_rev[OF at] at_rev_pi[OF at])
lemma at_ds5: fixes a :: "'x" and b :: "'x" assumes at: "at TYPE('x)" shows"[(a,b)] ≜ [(b,a)]" by (force simp add: prm_eq_def at_calc[OF at])
lemma at_ds5': fixes a :: "'x" and b :: "'x" assumes at: "at TYPE('x)" shows"[(a,b),(b,a)] ≜ []" by (force simp add: prm_eq_def at_calc[OF at])
lemma at_ds6: fixes a :: "'x" and b :: "'x" and c :: "'x" assumes at: "at TYPE('x)" and a: "distinct [a,b,c]" shows"[(a,c),(a,b)] ≜ [(b,c),(a,c)]" using a by (force simp add: prm_eq_def at_calc[OF at])
lemma at_ds8_aux: fixes pi :: "'x prm" and a :: "'x" and b :: "'x" and c :: "'x" assumes at: "at TYPE('x)" shows"pi∙(swap (a,b) c) = swap (pi∙a,pi∙b) (pi∙c)" by (force simp add: at_calc[OF at] at_bij[OF at])
lemma at_ds8: fixes pi1 :: "'x prm" and pi2 :: "'x prm" and a :: "'x" and b :: "'x" assumes at: "at TYPE('x)" shows"(pi1@pi2) ≜ ((pi1∙pi2)@pi1)" proof(induct pi2) show"(pi1 @ []) ≜ (pi1 ∙ [] @ pi1)" by(simp add: prm_eq_def) show"∧a l. (pi1 @ l) ≜ (pi1 ∙ l @ pi1) ==> (pi1 @ a # l) ≜ (pi1 ∙ (a # l) @ pi1) " by(auto simp add: prm_eq_def at at2 at_append at_ds8_aux) qed
lemma at_ds9: fixes pi1 :: "'x prm" and pi2 :: "'x prm" and a :: "'x" and b :: "'x" assumes at: "at TYPE('x)" shows" ((rev pi2)@(rev pi1)) ≜ ((rev pi1)@(rev (pi1∙pi2)))" using at at_ds8 at_prm_rev_eq1 rev_append by fastforce
lemma at_ds10: fixes pi :: "'x prm" and a :: "'x" and b :: "'x" assumes"at TYPE('x)" and"b♯(rev pi)" shows"([(pi∙a,b)]@pi) ≜ (pi@[(a,b)])" by (metis assms at_bij1 at_ds2 at_prm_fresh)
🍋‹there always exists an atom that is not being in a finite set› lemma ex_in_inf: fixes A::"'x set" assumes at: "at TYPE('x)" and fs: "finite A" obtains c::"'x"where"c∉A" using at at4 ex_new_if_finite fs by blast
text‹there always exists a fresh name for an object with finite support› lemma at_exists_fresh': fixes x :: "'a" assumes at: "at TYPE('x)" and fs: "finite ((supp x)::'x set)" shows"∃c::'x. c♯x" by (auto simp add: fresh_def intro: ex_in_inf[OF at, OF fs])
lemma at_exists_fresh: fixes x :: "'a" assumes at: "at TYPE('x)" and fs: "finite ((supp x)::'x set)" obtains c::"'x"where"c♯x" by (auto intro: ex_in_inf[OF at, OF fs] simp add: fresh_def)
lemma at_finite_select: fixes S::"'a set" assumes a: "at TYPE('a)" and b: "finite S" shows"∃x. x ∉ S" by (meson a b ex_in_inf)
section‹Lemmas about the permutation properties› (*=================================================*)
lemma pt1: fixes x::"'a" assumes a: "pt TYPE('a) TYPE('x)" shows"([]::'x prm)∙x = x" using a by (simp add: pt_def)
lemma pt2: fixes pi1::"'x prm" and pi2::"'x prm" and x ::"'a" assumes a: "pt TYPE('a) TYPE('x)" shows"(pi1@pi2)∙x = pi1∙(pi2∙x)" using a by (simp add: pt_def)
lemma pt3: fixes pi1::"'x prm" and pi2::"'x prm" and x ::"'a" assumes a: "pt TYPE('a) TYPE('x)" shows"pi1 ≜ pi2 ==> pi1∙x = pi2∙x" using a by (simp add: pt_def)
lemma pt3_rev: fixes pi1::"'x prm" and pi2::"'x prm" and x ::"'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi1 ≜ pi2 ==> (rev pi1)∙x = (rev pi2)∙x" by (rule pt3[OF pt], simp add: at_prm_rev_eq[OF at])
section‹composition properties› (* ============================== *) lemma cp1: fixes pi1::"'x prm" and pi2::"'y prm" and x ::"'a" assumes cp: "cp TYPE ('a) TYPE('x) TYPE('y)" shows"pi1∙(pi2∙x) = (pi1∙pi2)∙(pi1∙x)" using cp by (simp add: cp_def)
lemma cp_pt_inst: assumes"pt TYPE('a) TYPE('x)" and"at TYPE('x)" shows"cp TYPE('a) TYPE('x) TYPE('x)" using assms at_ds8 cp_def pt2 pt3 by fastforce
section‹disjointness properties› (*=================================*) lemma dj_perm_forget: fixes pi::"'y prm" and x ::"'x" assumes dj: "disjoint TYPE('x) TYPE('y)" shows"pi∙x=x" using dj by (simp_all add: disjoint_def)
lemma dj_perm_set_forget: fixes pi::"'y prm" and x ::"'x set" assumes dj: "disjoint TYPE('x) TYPE('y)" shows"pi∙x=x" using dj by (simp_all add: perm_set_def disjoint_def)
lemma dj_perm_perm_forget: fixes pi1::"'x prm" and pi2::"'y prm" assumes dj: "disjoint TYPE('x) TYPE('y)" shows"pi2∙pi1=pi1" using dj by (induct pi1, auto simp add: disjoint_def)
lemma dj_cp: fixes pi1::"'x prm" and pi2::"'y prm" and x ::"'a" assumes cp: "cp TYPE ('a) TYPE('x) TYPE('y)" and dj: "disjoint TYPE('y) TYPE('x)" shows"pi1∙(pi2∙x) = (pi2)∙(pi1∙x)" by (simp add: cp1[OF cp] dj_perm_perm_forget[OF dj])
lemma dj_supp: fixes a::"'x" assumes dj: "disjoint TYPE('x) TYPE('y)" shows"(supp a) = ({}::'y set)" by (simp add: supp_def dj_perm_forget[OF dj])
lemma at_fresh_ineq: fixes a :: "'x" and b :: "'y" assumes dj: "disjoint TYPE('y) TYPE('x)" shows"a♯b" by (simp add: fresh_def dj_supp[OF dj])
section‹permutation type instances› (* ===================================*)
lemma pt_fun_inst: assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('b) TYPE('x)" and at: "at TYPE('x)" shows"pt TYPE('a==>'b) TYPE('x)" unfolding pt_def using assms by (auto simp add: perm_fun_def pt1 pt2 ptb pt3 pt3_rev)
lemma pt_bool_inst[simp]: shows"pt TYPE(bool) TYPE('x)" by (simp add: pt_def perm_bool_def)
lemma pt_option_inst: assumes pta: "pt TYPE('a) TYPE('x)" shows"pt TYPE('a option) TYPE('x)" proof - have"([]::('x × _) list) ∙ x = x"for x :: "'a option" by (metis assms none_eqvt not_None_eq pt1 some_eqvt) moreoverhave"(pi1 @ pi2) ∙ x = pi1 ∙ pi2 ∙ x" for pi1 pi2 :: "('x × 'x) list"and x :: "'a option" by (metis assms none_eqvt option.collapse pt2 some_eqvt) moreoverhave"pi1 ∙ x = pi2 ∙ x" if"pi1 ≜ pi2"for pi1 pi2 :: "('x × 'x) list"and x :: "'a option" using that pt3[OF pta] by (metis none_eqvt not_Some_eq some_eqvt) ultimatelyshow ?thesis by (auto simp add: pt_def) qed
lemma pt_noption_inst: assumes pta: "pt TYPE('a) TYPE('x)" shows"pt TYPE('a noption) TYPE('x)" proof - have"([]::('x × _) list) ∙ x = x"for x :: "'a noption" by (metis assms nnone_eqvt noption.exhaust nsome_eqvt pt1) moreoverhave"(pi1 @ pi2) ∙ x = pi1 ∙ pi2 ∙ x" for pi1 pi2 :: "('x × 'x) list"and x :: "'a noption" using pt2[OF pta] by (metis nnone_eqvt noption.exhaust nsome_eqvt) moreoverhave"pi1 ∙ x = pi2 ∙ x" if"pi1 ≜ pi2" for pi1 pi2 :: "('x × 'x) list" and x :: "'a noption" using that pt3[OF pta] by (metis nnone_eqvt noption.exhaust nsome_eqvt) ultimatelyshow ?thesis by (auto simp add: pt_def) qed
lemma pt_nprod_inst: assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('b) TYPE('x)" shows"pt TYPE(('a,'b) nprod) TYPE('x)" proof - have"([]::('x × _) list) ∙ x = x" for x :: "('a, 'b) nprod" by (metis assms(1) nprod.exhaust perm_nprod.simps pt1 ptb) moreoverhave"(pi1 @ pi2) ∙ x = pi1 ∙ pi2 ∙ x" for pi1 pi2 :: "('x × 'x) list"and x :: "('a, 'b) nprod" using pt2[OF pta] pt2[OF ptb] by (metis nprod.exhaust perm_nprod.simps) moreoverhave"pi1 ∙ x = pi2 ∙ x" if"pi1 ≜ pi2"for pi1 pi2 :: "('x × 'x) list"and x :: "('a, 'b) nprod" using that pt3[OF pta] pt3[OF ptb] by (smt (verit) nprod.exhaust perm_nprod.simps) ultimatelyshow ?thesis by (auto simp add: pt_def) qed
section‹further lemmas for permutation types› (*==============================================*)
lemma pt_rev_pi: fixes pi :: "'x prm" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"(rev pi)∙(pi∙x) = x" proof - have"((rev pi)@pi) ≜ ([]::'x prm)"by (simp add: at_ds7[OF at]) hence"((rev pi)@pi)∙(x::'a) = ([]::'x prm)∙x"by (simp add: pt3[OF pt]) thus ?thesis by (simp add: pt1[OF pt] pt2[OF pt]) qed
lemma pt_pi_rev: fixes pi :: "'x prm" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙((rev pi)∙x) = x" by (simp add: pt_rev_pi[OF pt, OF at,of "rev pi""x",simplified])
lemma pt_bij1: fixes pi :: "'x prm" and x :: "'a" and y :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and a: "(pi∙x) = y" shows"x=(rev pi)∙y" proof - from a have"y=(pi∙x)"by (rule sym) thus ?thesis by (simp only: pt_rev_pi[OF pt, OF at]) qed
lemma pt_bij2: fixes pi :: "'x prm" and x :: "'a" and y :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and a: "x = (rev pi)∙y" shows"(pi∙x)=y" using a by (simp add: pt_pi_rev[OF pt, OF at])
lemma pt_bij: fixes pi :: "'x prm" and x :: "'a" and y :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"(pi∙x = pi∙y) = (x=y)" proof assume"pi∙x = pi∙y" hence"x=(rev pi)∙(pi∙y)"by (rule pt_bij1[OF pt, OF at]) thus"x=y"by (simp only: pt_rev_pi[OF pt, OF at]) next assume"x=y" thus"pi∙x = pi∙y"by simp qed
lemma pt_eq_eqvt: fixes pi :: "'x prm" and x :: "'a" and y :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙(x=y) = (pi∙x = pi∙y)" using pt at by (auto simp add: pt_bij perm_bool)
lemma pt_bij3: fixes pi :: "'x prm" and x :: "'a" and y :: "'a" assumes a: "x=y" shows"(pi∙x = pi∙y)" using a by simp
lemma pt_bij4: fixes pi :: "'x prm" and x :: "'a" and y :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and a: "pi∙x = pi∙y" shows"x = y" using a by (simp add: pt_bij[OF pt, OF at])
lemma pt_swap_bij: fixes a :: "'x" and b :: "'x" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"[(a,b)]∙([(a,b)]∙x) = x" by (rule pt_bij2[OF pt, OF at], simp)
lemma pt_swap_bij': fixes a :: "'x" and b :: "'x" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"[(a,b)]∙([(b,a)]∙x) = x" by (metis assms at_ds5 pt_def pt_swap_bij)
lemma pt_swap_bij'': fixes a :: "'x" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"[(a,a)]∙x = x" by (metis assms at_ds1 pt_def)
lemma fresh_singleton: shows"a♯{x} = a♯x" by (simp add: fresh_def supp_singleton)
lemma pt_set_bij1: fixes pi :: "'x prm" and x :: "'a" and X :: "'a set" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"((pi∙x)∈X) = (x∈((rev pi)∙X))" by (force simp add: perm_set_def pt_rev_pi[OF pt, OF at] pt_pi_rev[OF pt, OF at])
lemma pt_set_bij1a: fixes pi :: "'x prm" and x :: "'a" and X :: "'a set" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"(x∈(pi∙X)) = (((rev pi)∙x)∈X)" by (force simp add: perm_set_def pt_rev_pi[OF pt, OF at] pt_pi_rev[OF pt, OF at])
lemma pt_set_bij: fixes pi :: "'x prm" and x :: "'a" and X :: "'a set" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"((pi∙x)∈(pi∙X)) = (x∈X)" by (simp add: perm_set_def pt_bij[OF pt, OF at])
lemma pt_in_eqvt: fixes pi :: "'x prm" and x :: "'a" and X :: "'a set" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙(x∈X)=((pi∙x)∈(pi∙X))" using assms by (auto simp add: pt_set_bij perm_bool)
lemma pt_set_bij2: fixes pi :: "'x prm" and x :: "'a" and X :: "'a set" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and a: "x∈X" shows"(pi∙x)∈(pi∙X)" using a by (simp add: pt_set_bij[OF pt, OF at])
lemma pt_set_bij2a: fixes pi :: "'x prm" and x :: "'a" and X :: "'a set" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and a: "x∈((rev pi)∙X)" shows"(pi∙x)∈X" using a by (simp add: pt_set_bij1[OF pt, OF at])
lemma pt_subseteq_eqvt: fixes pi :: "'x prm" and Y :: "'a set" and X :: "'a set" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"(pi∙(X⊆Y)) = ((pi∙X)⊆(pi∙Y))" by (auto simp add: perm_set_def perm_bool pt_bij[OF pt, OF at])
lemma pt_set_diff_eqvt: fixes X::"'a set" and Y::"'a set" and pi::"'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙(X - Y) = (pi∙X) - (pi∙Y)" by (auto simp add: perm_set_def pt_bij[OF pt, OF at])
lemma pt_Collect_eqvt: fixes pi::"'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙{x::'a. P x} = {x. P ((rev pi)∙x)}" proof - have"∃y. x = pi ∙ y ∧ P y" if"P (rev pi ∙ x)"for x using that by (metis at pt pt_pi_rev) thenshow ?thesis by (auto simp add: perm_set_def pt_rev_pi [OF assms]) qed
🍋‹some helper lemmas for the pt_perm_supp_ineq lemma› lemma Collect_permI: fixes pi :: "'x prm" and x :: "'a" assumes a: "∀x. (P1 x = P2 x)" shows"{pi∙x| x. P1 x} = {pi∙x| x. P2 x}" using a by force
lemma Infinite_cong: assumes a: "X = Y" shows"infinite X = infinite Y" using a by (simp)
lemma pt_set_eq_ineq: fixes pi :: "'y prm" assumes pt: "pt TYPE('x) TYPE('y)" and at: "at TYPE('y)" shows"{pi∙x| x::'x. P x} = {x::'x. P ((rev pi)∙x)}" by (force simp only: pt_rev_pi[OF pt, OF at] pt_pi_rev[OF pt, OF at])
lemma pt_inject_on_ineq: fixes X :: "'y set" and pi :: "'x prm" assumes pt: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" shows"inj_on (perm pi) X" proof (unfold inj_on_def, intro strip) fix x::"'y"and y::"'y" assume"pi∙x = pi∙y" thus"x=y"by (simp add: pt_bij[OF pt, OF at]) qed
lemma pt_set_finite_ineq: fixes X :: "'x set" and pi :: "'y prm" assumes pt: "pt TYPE('x) TYPE('y)" and at: "at TYPE('y)" shows"finite (pi∙X) = finite X" proof - have image: "(pi∙X) = (perm pi ` X)"by (force simp only: perm_set_def) show ?thesis proof (rule iffI) assume"finite (pi∙X)" hence"finite (perm pi ` X)"using image by (simp) thus"finite X"using pt_inject_on_ineq[OF pt, OF at] by (rule finite_imageD) next assume"finite X" hence"finite (perm pi ` X)"by (rule finite_imageI) thus"finite (pi∙X)"using image by (simp) qed qed
lemma pt_set_infinite_ineq: fixes X :: "'x set" and pi :: "'y prm" assumes pt: "pt TYPE('x) TYPE('y)" and at: "at TYPE('y)" shows"infinite (pi∙X) = infinite X" using pt at by (simp add: pt_set_finite_ineq)
lemma pt_perm_supp_ineq: fixes pi :: "'x prm" and x :: "'a" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" and cp: "cp TYPE('a) TYPE('x) TYPE('y)" shows"(pi∙((supp x)::'y set)) = supp (pi∙x)" (is"?LHS = ?RHS") proof - have"?LHS = {pi∙a | a. infinite {b. [(a,b)]∙x ≠ x}}"by (simp add: supp_def perm_set_def) alsohave"… = {pi∙a | a. infinite {pi∙b | b. [(a,b)]∙x ≠ x}}" proof (rule Collect_permI, rule allI, rule iffI) fix a assume"infinite {b::'y. [(a,b)]∙x ≠ x}" hence"infinite (pi∙{b::'y. [(a,b)]∙x ≠ x})"by (simp add: pt_set_infinite_ineq[OF ptb, OF at]) thus"infinite {pi∙b |b::'y. [(a,b)]∙x ≠ x}"by (simp add: perm_set_def) next fix a assume"infinite {pi∙b |b::'y. [(a,b)]∙x ≠ x}" hence"infinite (pi∙{b::'y. [(a,b)]∙x ≠ x})"by (simp add: perm_set_def) thus"infinite {b::'y. [(a,b)]∙x ≠ x}" by (simp add: pt_set_infinite_ineq[OF ptb, OF at]) qed alsohave"… = {a. infinite {b::'y. [((rev pi)∙a,(rev pi)∙b)]∙x ≠ x}}" by (simp add: pt_set_eq_ineq[OF ptb, OF at]) alsohave"… = {a. infinite {b. pi∙([((rev pi)∙a,(rev pi)∙b)]∙x) ≠ (pi∙x)}}" by (simp add: pt_bij[OF pta, OF at]) alsohave"… = {a. infinite {b. [(a,b)]∙(pi∙x) ≠ (pi∙x)}}" proof (rule Collect_cong, rule Infinite_cong, rule Collect_cong) fix a::"'y"and b::"'y" have"pi∙(([((rev pi)∙a,(rev pi)∙b)])∙x) = [(a,b)]∙(pi∙x)" by (simp add: cp1[OF cp] pt_pi_rev[OF ptb, OF at]) thus"(pi∙([((rev pi)∙a,(rev pi)∙b)]∙x) ≠ pi∙x) = ([(a,b)]∙(pi∙x) ≠ pi∙x)"by simp qed finallyshow"?LHS = ?RHS"by (simp add: supp_def) qed
lemma pt_perm_supp: fixes pi :: "'x prm" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"(pi∙((supp x)::'x set)) = supp (pi∙x)" by (rule pt_perm_supp_ineq) (auto simp: assms at_pt_inst cp_pt_inst)
lemma pt_supp_finite_pi: fixes pi :: "'x prm" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and f: "finite ((supp x)::'x set)" shows"finite ((supp (pi∙x))::'x set)" by (metis at at_pt_inst f pt pt_perm_supp pt_set_finite_ineq)
lemma pt_fresh_left_ineq: fixes pi :: "'x prm" and x :: "'a" and a :: "'y" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" and cp: "cp TYPE('a) TYPE('x) TYPE('y)" shows"a♯(pi∙x) = ((rev pi)∙a)♯x" using pt_perm_supp_ineq[OF pta, OF ptb, OF at, OF cp] pt_set_bij1[OF ptb, OF at] by (simp add: fresh_def)
lemma pt_fresh_right_ineq: fixes pi :: "'x prm" and x :: "'a" and a :: "'y" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" and cp: "cp TYPE('a) TYPE('x) TYPE('y)" shows"(pi∙a)♯x = a♯((rev pi)∙x)" by (simp add: assms pt_fresh_left_ineq)
lemma pt_fresh_bij_ineq: fixes pi :: "'x prm" and x :: "'a" and a :: "'y" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" and cp: "cp TYPE('a) TYPE('x) TYPE('y)" shows"(pi∙a)♯(pi∙x) = a♯x" using assms pt_bij1 pt_fresh_right_ineq by fastforce
lemma pt_fresh_left: fixes pi :: "'x prm" and x :: "'a" and a :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"a♯(pi∙x) = ((rev pi)∙a)♯x" by (simp add: assms at_pt_inst cp_pt_inst pt_fresh_left_ineq)
lemma pt_fresh_right: fixes pi :: "'x prm" and x :: "'a" and a :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"(pi∙a)♯x = a♯((rev pi)∙x)" by (simp add: assms at_pt_inst cp_pt_inst pt_fresh_right_ineq)
lemma pt_fresh_bij: fixes pi :: "'x prm" and x :: "'a" and a :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"(pi∙a)♯(pi∙x) = a♯x" by (metis assms pt_bij1 pt_fresh_right)
lemma pt_fresh_bij1: fixes pi :: "'x prm" and x :: "'a" and a :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and a: "a♯x" shows"(pi∙a)♯(pi∙x)" using a by (simp add: pt_fresh_bij[OF pt, OF at])
lemma pt_fresh_bij2: fixes pi :: "'x prm" and x :: "'a" and a :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and a: "(pi∙a)♯(pi∙x)" shows"a♯x" using a by (simp add: pt_fresh_bij[OF pt, OF at])
lemma pt_fresh_eqvt: fixes pi :: "'x prm" and x :: "'a" and a :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙(a♯x) = (pi∙a)♯(pi∙x)" by (simp add: perm_bool pt_fresh_bij[OF pt, OF at])
lemma pt_perm_fresh1: fixes a :: "'x" and b :: "'x" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE ('x)" and a1: "¬(a♯x)" and a2: "b♯x" shows"[(a,b)]∙x ≠ x" proof assume neg: "[(a,b)]∙x = x" from a1 have a1':"a∈(supp x)"by (simp add: fresh_def) from a2 have a2':"b∉(supp x)"by (simp add: fresh_def) from a1' a2' have a3: "a≠b"by force from a1' have"([(a,b)]∙a)∈([(a,b)]∙(supp x))" by (simp only: pt_set_bij[OF at_pt_inst[OF at], OF at]) hence"b∈([(a,b)]∙(supp x))"by (simp add: at_calc[OF at]) hence"b∈(supp ([(a,b)]∙x))"by (simp add: pt_perm_supp[OF pt,OF at]) with a2' neg show False by simp qed
(* the next two lemmas are needed in the proof *) (* of the structural induction principle *) lemma pt_fresh_aux: fixes a::"'x" and b::"'x" and c::"'x" and x::"'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE ('x)" assumes a1: "c≠a"and a2: "a♯x"and a3: "c♯x" shows"c♯([(a,b)]∙x)" using a1 a2 a3 by (simp_all add: pt_fresh_left[OF pt, OF at] at_calc[OF at])
lemma pt_fresh_perm_app: fixes pi :: "'x prm" and a :: "'x" and x :: "'y" assumes pt: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" and h1: "a♯pi" and h2: "a♯x" shows"a♯(pi∙x)" using assms proof - have"a♯(rev pi)"using h1 by (simp add: fresh_list_rev) thenhave"(rev pi)∙a = a"by (simp add: at_prm_fresh[OF at]) thenhave"((rev pi)∙a)♯x"using h2 by simp thus"a♯(pi∙x)"by (simp add: pt_fresh_right[OF pt, OF at]) qed
lemma pt_fresh_perm_app_ineq: fixes pi::"'x prm" and c::"'y" and x::"'a" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" and cp: "cp TYPE('a) TYPE('x) TYPE('y)" and dj: "disjoint TYPE('y) TYPE('x)" assumes a: "c♯x" shows"c♯(pi∙x)" using a by (simp add: pt_fresh_left_ineq[OF pta, OF ptb, OF at, OF cp] dj_perm_forget[OF dj])
lemma pt_fresh_eqvt_ineq: fixes pi::"'x prm" and c::"'y" and x::"'a" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" and cp: "cp TYPE('a) TYPE('x) TYPE('y)" and dj: "disjoint TYPE('y) TYPE('x)" shows"pi∙(c♯x) = (pi∙c)♯(pi∙x)" by (simp add: pt_fresh_left_ineq[OF pta, OF ptb, OF at, OF cp] dj_perm_forget[OF dj] perm_bool)
🍋‹the co-set of a finite set is infinte› lemma finite_infinite: assumes a: "finite {b::'x. P b}" and b: "infinite (UNIV::'x set)" shows"infinite {b. ¬P b}" proof - from a b have"infinite (UNIV - {b::'x. P b})"by (simp add: Diff_infinite_finite) moreover have"{b::'x. ¬P b} = UNIV - {b::'x. P b}"by auto ultimatelyshow"infinite {b::'x. ¬P b}"by simp qed
lemma pt_fresh_fresh: fixes x :: "'a" and a :: "'x" and b :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE ('x)" and a1: "a♯x"and a2: "b♯x" shows"[(a,b)]∙x=x" proof (cases "a=b") assume"a=b" hence"[(a,b)] ≜ []"by (simp add: at_ds1[OF at]) hence"[(a,b)]∙x=([]::'x prm)∙x"by (rule pt3[OF pt]) thus ?thesis by (simp only: pt1[OF pt]) next assume c2: "a≠b" from a1 have f1: "finite {c. [(a,c)]∙x ≠ x}"by (simp add: fresh_def supp_def) from a2 have f2: "finite {c. [(b,c)]∙x ≠ x}"by (simp add: fresh_def supp_def) from f1 and f2 have f3: "finite {c. perm [(a,c)] x ≠ x ∨ perm [(b,c)] x ≠ x}" by (force simp only: Collect_disj_eq) have"infinite {c. [(a,c)]∙x = x ∧ [(b,c)]∙x = x}" by (simp add: finite_infinite[OF f3,OF at4[OF at], simplified]) hence"infinite ({c. [(a,c)]∙x = x ∧ [(b,c)]∙x = x}-{a,b})" by (force dest: Diff_infinite_finite) hence"({c. [(a,c)]∙x = x ∧ [(b,c)]∙x = x}-{a,b}) ≠ {}" by (metis finite_set set_empty2) hence"∃c. c∈({c. [(a,c)]∙x = x ∧ [(b,c)]∙x = x}-{a,b})"by (force) thenobtain c where eq1: "[(a,c)]∙x = x" and eq2: "[(b,c)]∙x = x" and ineq: "a≠c ∧ b≠c" by (force) hence"[(a,c)]∙([(b,c)]∙([(a,c)]∙x)) = x"by simp hence eq3: "[(a,c),(b,c),(a,c)]∙x = x"by (simp add: pt2[OF pt,symmetric]) from c2 ineq have"[(a,c),(b,c),(a,c)] ≜ [(a,b)]"by (simp add: at_ds3[OF at]) hence"[(a,c),(b,c),(a,c)]∙x = [(a,b)]∙x"by (rule pt3[OF pt]) thus ?thesis using eq3 by simp qed
lemma pt_pi_fresh_fresh: fixes x :: "'a" and pi :: "'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE ('x)" and a: "∀(a,b)∈set pi. a♯x ∧ b♯x" shows"pi∙x=x" using a proof (induct pi) case Nil show"([]::'x prm)∙x = x"by (rule pt1[OF pt]) next case (Cons ab pi) have a: "∀(a,b)∈set (ab#pi). a♯x ∧ b♯x"by fact have ih: "(∀(a,b)∈set pi. a♯x ∧ b♯x) ==> pi∙x=x"by fact obtain a b where e: "ab=(a,b)"by (cases ab) (auto) from a have a': "a♯x""b♯x"using e by auto have"(ab#pi)∙x = ([(a,b)]@pi)∙x"using e by simp alsohave"… = [(a,b)]∙(pi∙x)"by (simp only: pt2[OF pt]) alsohave"… = [(a,b)]∙x"using ih a by simp alsohave"… = x"using a' by (simp add: pt_fresh_fresh[OF pt, OF at]) finallyshow"(ab#pi)∙x = x"by simp qed
lemma pt_perm_compose: fixes pi1 :: "'x prm" and pi2 :: "'x prm" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi2∙(pi1∙x) = (pi2∙pi1)∙(pi2∙x)" proof - have"(pi2@pi1) ≜ ((pi2∙pi1)@pi2)"by (rule at_ds8 [OF at]) hence"(pi2@pi1)∙x = ((pi2∙pi1)@pi2)∙x"by (rule pt3[OF pt]) thus ?thesis by (simp add: pt2[OF pt]) qed
lemma pt_perm_compose': fixes pi1 :: "'x prm" and pi2 :: "'x prm" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"(pi2∙pi1)∙x = pi2∙(pi1∙((rev pi2)∙x))" proof - have"pi2∙(pi1∙((rev pi2)∙x)) = (pi2∙pi1)∙(pi2∙((rev pi2)∙x))" by (rule pt_perm_compose[OF pt, OF at]) alsohave"… = (pi2∙pi1)∙x"by (simp add: pt_pi_rev[OF pt, OF at]) finallyhave"pi2∙(pi1∙((rev pi2)∙x)) = (pi2∙pi1)∙x"by simp thus ?thesis by simp qed
section‹equivariance for some connectives› lemma pt_all_eqvt: fixes pi :: "'x prm" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙(∀(x::'a). P x) = (∀(x::'a). pi∙(P ((rev pi)∙x)))" by (smt (verit, ccfv_threshold) assms pt_bij1 true_eqvt)
lemma pt_ex_eqvt: fixes pi :: "'x prm" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙(∃(x::'a). P x) = (∃(x::'a). pi∙(P ((rev pi)∙x)))" proof - have"∧x. P x ==> P (rev pi ∙ pi ∙ x)" by (simp add: assms(1) at pt_rev_pi) thenshow ?thesis by(auto simp add: perm_bool perm_fun_def) qed
lemma pt_ex1_eqvt: fixes pi :: "'x prm" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"(pi∙(∃!x. P (x::'a))) = (∃!x. pi∙(P (rev pi∙x)))" unfolding Ex1_def by (simp add: pt_ex_eqvt[OF pt at] conj_eqvt pt_all_eqvt[OF pt at]
imp_eqvt pt_eq_eqvt[OF pt at] pt_pi_rev[OF pt at])
lemma pt_the_eqvt: fixes pi :: "'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and unique: "∃!x. P x" shows"pi∙(THE(x::'a). P x) = (THE(x::'a). pi∙(P ((rev pi)∙x)))" by (smt (verit, best) assms perm_bool_def pt_rev_pi theI_unique unique)
section‹facts about supports› (*==============================*)
lemma supports_subset: fixes x :: "'a" and S1 :: "'x set" and S2 :: "'x set" assumes a: "S1 supports x" and b: "S1 ⊆ S2" shows"S2 supports x" using a b by (force simp add: supports_def)
lemma supp_is_subset: fixes S :: "'x set" and x :: "'a" assumes a1: "S supports x" and a2: "finite S" shows"(supp x)⊆S" proof (rule ccontr) assume"¬(supp x ⊆ S)" hence"∃a. a∈(supp x) ∧ a∉S"by force thenobtain a where b1: "a∈supp x"and b2: "a∉S"by force from a1 b2 have"∀b. (b∉S ⟶ ([(a,b)]∙x = x))"by (unfold supports_def, force) hence"{b. [(a,b)]∙x ≠ x}⊆S"by force with a2 have"finite {b. [(a,b)]∙x ≠ x}"by (simp add: finite_subset) hence"a∉(supp x)"by (unfold supp_def, auto) with b1 show False by simp qed
lemma supp_supports: fixes x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE ('x)" shows"((supp x)::'x set) supports x" proof (unfold supports_def, intro strip) fix a b assume"(a::'x)∉(supp x) ∧ (b::'x)∉(supp x)" hence"a♯x"and"b♯x"by (auto simp add: fresh_def) thus"[(a,b)]∙x = x"by (rule pt_fresh_fresh[OF pt, OF at]) qed
lemma supports_finite: fixes S :: "'x set" and x :: "'a" assumes a1: "S supports x" and a2: "finite S" shows"finite ((supp x)::'x set)" proof - have"(supp x)⊆S"using a1 a2 by (rule supp_is_subset) thus ?thesis using a2 by (simp add: finite_subset) qed
lemma supp_is_inter: fixes x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE ('x)" and fs: "fs TYPE('a) TYPE('x)" shows"((supp x)::'x set) = (∩{S. finite S ∧ S supports x})" proof (rule equalityI) show"((supp x)::'x set) ⊆ (∩{S. finite S ∧ S supports x})" proof (clarify) fix S c assume b: "c∈((supp x)::'x set)"and"finite (S::'x set)"and"S supports x" hence"((supp x)::'x set)⊆S"by (simp add: supp_is_subset) with b show"c∈S"by force qed next show"(∩{S. finite S ∧ S supports x}) ⊆ ((supp x)::'x set)" proof (clarify, simp) fix c assume d: "∀(S::'x set). finite S ∧ S supports x ⟶ c∈S" have"((supp x)::'x set) supports x"by (rule supp_supports[OF pt, OF at]) with d fs1[OF fs] show"c∈supp x"by force qed qed
lemma supp_is_least_supports: fixes S :: "'x set" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE ('x)" and a1: "S supports x" and a2: "finite S" and a3: "∀S'. (S' supports x) ⟶ S⊆S'" shows"S = (supp x)" proof (rule equalityI) show"((supp x)::'x set)⊆S"using a1 a2 by (rule supp_is_subset) next have"((supp x)::'x set) supports x"by (rule supp_supports[OF pt, OF at]) with a3 show"S⊆supp x"by force qed
lemma supports_set: fixes S :: "'x set" and X :: "'a set" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE ('x)" and a: "∀x∈X. (∀(a::'x) (b::'x). a∉S∧b∉S ⟶ ([(a,b)]∙x)∈X)" shows"S supports X" proof - have"x ∈ X" if"a ∉ S""b ∉ S"and"x ∈ [(a, b)] ∙ X"for a b x using that by (metis a assms(1) at pt_pi_rev pt_set_bij1a) moreoverhave"x ∈ [(a, b)] ∙ X" if"a ∉ S""b ∉ S"and"x ∈ X"for a b x using that by (simp add: a assms(1) at pt_set_bij1a) ultimatelyshow ?thesis by (meson subsetI subset_antisym supports_def) qed
lemma supports_fresh: fixes S :: "'x set" and a :: "'x" and x :: "'a" assumes a1: "S supports x" and a2: "finite S" and a3: "a∉S" shows"a♯x" by (meson assms fresh_def in_mono supp_is_subset)
lemma at_fin_set_supports: fixes X::"'x set" assumes at: "at TYPE('x)" shows"X supports X" proof - have"∀a b. a∉X ∧ b∉X ⟶ [(a,b)]∙X = X" by (auto simp add: perm_set_def at_calc[OF at]) thenshow ?thesis by (simp add: supports_def) qed
lemma infinite_Collection: assumes a1:"infinite X" and a2:"∀b∈X. P(b)" shows"infinite {b∈X. P(b)}" using assms rev_finite_subset by fastforce
lemma at_fin_set_supp: fixes X::"'x set" assumes at: "at TYPE('x)" and fs: "finite X" shows"(supp X) = X" proof (rule subset_antisym) show"(supp X) ⊆ X"using at_fin_set_supports[OF at] using fs by (simp add: supp_is_subset) next have inf: "infinite (UNIV-X)"using at4[OF at] fs by (auto simp add: Diff_infinite_finite)
{ fix a::"'x" assume asm: "a∈X" hence"∀b∈(UNIV-X). [(a,b)]∙X≠X" by (auto simp add: perm_set_def at_calc[OF at]) with inf have"infinite {b∈(UNIV-X). [(a,b)]∙X≠X}"by (rule infinite_Collection) hence"infinite {b. [(a,b)]∙X≠X}"by (rule_tac infinite_super, auto) hence"a∈(supp X)"by (simp add: supp_def)
} thenshow"X⊆(supp X)"by blast qed
lemma at_fin_set_fresh: fixes X::"'x set" assumes at: "at TYPE('x)" and fs: "finite X" shows"(x ♯ X) = (x ∉ X)" by (simp add: at_fin_set_supp fresh_def at fs)
section‹Permutations acting on Functions› (*==========================================*)
lemma pt_fun_app_eq: fixes f :: "'a==>'b" and x :: "'a" and pi :: "'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙(f x) = (pi∙f)(pi∙x)" by (simp add: perm_fun_def pt_rev_pi[OF pt, OF at])
🍋‹sometimes pt_fun_app_eq does too much; this lemma 'corrects it'› lemma pt_perm: fixes x :: "'a" and pi1 :: "'x prm" and pi2 :: "'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE ('x)" shows"(pi1∙perm pi2)(pi1∙x) = pi1∙(pi2∙x)" by (simp add: pt_fun_app_eq[OF pt, OF at])
lemma pt_fun_eq: fixes f :: "'a==>'b" and pi :: "'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"(pi∙f = f) = (∀ x. pi∙(f x) = f (pi∙x))" (is"?LHS = ?RHS") proof assume a: "?LHS" show"?RHS" proof fix x have"pi∙(f x) = (pi∙f)(pi∙x)"by (simp add: pt_fun_app_eq[OF pt, OF at]) alsohave"… = f (pi∙x)"using a by simp finallyshow"pi∙(f x) = f (pi∙x)"by simp qed next assume b: "?RHS" show"?LHS" proof (rule ccontr) assume"(pi∙f) ≠ f" hence"∃x. (pi∙f) x ≠ f x"by (simp add: fun_eq_iff) thenobtain x where b1: "(pi∙f) x ≠ f x"by force from b have"pi∙(f ((rev pi)∙x)) = f (pi∙((rev pi)∙x))"by force hence"(pi∙f)(pi∙((rev pi)∙x)) = f (pi∙((rev pi)∙x))" by (simp add: pt_fun_app_eq[OF pt, OF at]) hence"(pi∙f) x = f x"by (simp add: pt_pi_rev[OF pt, OF at]) with b1 show"False"by simp qed qed
🍋‹two helper lemmas for the equivariance of functions› lemma pt_swap_eq_aux: fixes y :: "'a" and pi :: "'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and a: "∀(a::'x) (b::'x). [(a,b)]∙y = y" shows"pi∙y = y" proof(induct pi) case Nil show ?caseby (simp add: pt1[OF pt]) next case (Cons x xs) have ih: "xs∙y = y"by fact obtain a b where p: "x=(a,b)"by force have"((a,b)#xs)∙y = ([(a,b)]@xs)∙y"by simp alsohave"… = [(a,b)]∙(xs∙y)"by (simp only: pt2[OF pt]) finallyshow ?caseusing a ih p by simp qed
lemma pt_eqvt_fun1a: fixes f :: "'a==>'b" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('b) TYPE('x)" and at: "at TYPE('x)" and a: "((supp f)::'x set)={}" shows"∀(pi::'x prm). pi∙f = f" proof (intro strip) fix pi have"∀a b. a∉((supp f)::'x set) ∧ b∉((supp f)::'x set) ⟶ (([(a,b)]∙f) = f)" by (intro strip, fold fresh_def,
simp add: pt_fresh_fresh[OF pt_fun_inst[OF pta, OF ptb, OF at],OF at]) with a have"∀(a::'x) (b::'x). ([(a,b)]∙f) = f"by force hence"∀(pi::'x prm). pi∙f = f" by (simp add: pt_swap_eq[OF pt_fun_inst[OF pta, OF ptb, OF at]]) thus"(pi::'x prm)∙f = f"by simp qed
lemma pt_eqvt_fun1b: fixes f :: "'a==>'b" assumes a: "∀(pi::'x prm). pi∙f = f" shows"((supp f)::'x set)={}" using a by (simp add: supp_def)
lemma pt_eqvt_fun1: fixes f :: "'a==>'b" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('b) TYPE('x)" and at: "at TYPE('x)" shows"(((supp f)::'x set)={}) = (∀(pi::'x prm). pi∙f = f)" (is"?LHS = ?RHS") by (rule iffI, simp add: pt_eqvt_fun1a[OF pta, OF ptb, OF at], simp add: pt_eqvt_fun1b)
lemma pt_eqvt_fun2a: fixes f :: "'a==>'b" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('b) TYPE('x)" and at: "at TYPE('x)" assumes a: "((supp f)::'x set)={}" shows"∀(pi::'x prm) (x::'a). pi∙(f x) = f(pi∙x)" proof (intro strip) fix pi x from a have b: "∀(pi::'x prm). pi∙f = f"by (simp add: pt_eqvt_fun1[OF pta, OF ptb, OF at]) have"(pi::'x prm)∙(f x) = (pi∙f)(pi∙x)"by (simp add: pt_fun_app_eq[OF pta, OF at]) with b show"(pi::'x prm)∙(f x) = f (pi∙x)"by force qed
lemma pt_eqvt_fun2b: fixes f :: "'a==>'b" assumes pt1: "pt TYPE('a) TYPE('x)" and pt2: "pt TYPE('b) TYPE('x)" and at: "at TYPE('x)" assumes a: "∀(pi::'x prm) (x::'a). pi∙(f x) = f(pi∙x)" shows"((supp f)::'x set)={}" proof - from a have"∀(pi::'x prm). pi∙f = f"by (simp add: pt_fun_eq[OF pt1, OF at, symmetric]) thus ?thesis by (simp add: supp_def) qed
lemma pt_eqvt_fun2: fixes f :: "'a==>'b" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('b) TYPE('x)" and at: "at TYPE('x)" shows"(((supp f)::'x set)={}) = (∀(pi::'x prm) (x::'a). pi∙(f x) = f(pi∙x))" by (rule iffI,
simp add: pt_eqvt_fun2a[OF pta, OF ptb, OF at],
simp add: pt_eqvt_fun2b[OF pta, OF ptb, OF at])
lemma pt_supp_fun_subset: fixes f :: "'a==>'b" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('b) TYPE('x)" and at: "at TYPE('x)" and f1: "finite ((supp f)::'x set)" and f2: "finite ((supp x)::'x set)" shows"supp (f x) ⊆ (((supp f)∪(supp x))::'x set)" proof - have s1: "((supp f)∪((supp x)::'x set)) supports (f x)" proof (simp add: supports_def, fold fresh_def, auto) fix a::"'x"and b::"'x" assume"a♯f"and"b♯f" hence a1: "[(a,b)]∙f = f" by (rule pt_fresh_fresh[OF pt_fun_inst[OF pta, OF ptb, OF at], OF at]) assume"a♯x"and"b♯x" hence a2: "[(a,b)]∙x = x"by (rule pt_fresh_fresh[OF pta, OF at]) from a1 a2 show"[(a,b)]∙(f x) = (f x)"by (simp add: pt_fun_app_eq[OF pta, OF at]) qed from f1 f2 have"finite ((supp f)∪((supp x)::'x set))"by force with s1 show ?thesis by (rule supp_is_subset) qed
lemma pt_empty_supp_fun_subset: fixes f :: "'a==>'b" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('b) TYPE('x)" and at: "at TYPE('x)" and e: "(supp f)=({}::'x set)" shows"supp (f x) ⊆ ((supp x)::'x set)" proof (unfold supp_def, auto) fix a::"'x" assume a1: "finite {b. [(a, b)]∙x ≠ x}" assume"infinite {b. [(a, b)]∙(f x) ≠ f x}" hence a2: "infinite {b. f ([(a, b)]∙x) ≠ f x}"using e by (simp add: pt_eqvt_fun2[OF pta, OF ptb, OF at]) have a3: "{b. f ([(a,b)]∙x) ≠ f x}⊆{b. [(a,b)]∙x ≠ x}"by force from a1 a2 a3 show False by (force dest: finite_subset) qed
section‹Facts about the support of finite sets of finitely supported things› (*=============================================================================*)
lemma UNION_f_eqvt: fixes X::"('a set)" and f::"'a ==> 'x set" and pi::"'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙(∪x∈X. f x) = (∪x∈(pi∙X). (pi∙f) x)" proof - have pt_x: "pt TYPE('x) TYPE('x)"by (force intro: at_pt_inst at) show ?thesis proof - have"∃x. (∃u. x = pi ∙ u ∧ u ∈ X) ∧ pi ∙ z ∈ (pi ∙ f) x" if"y ∈ X"and"z ∈ f y"for y z using that by (metis assms at_pt_inst pt_fun_app_eq pt_set_bij) moreoverhave"∃u. x = pi ∙ u ∧ (∃x∈X. u ∈ f x)" if"x ∈ (pi ∙ f) (pi ∙ y)"and"y ∈ X"for x y using that by (metis at at_pi_rev pt pt_fun_app_eq pt_set_bij1a pt_x) ultimatelyshow ?thesis by (auto simp: perm_set_def) qed qed
lemma X_to_Un_supp_eqvt: fixes X::"('a set)" and pi::"'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙(X_to_Un_supp X) = ((X_to_Un_supp (pi∙X))::'x set)" by (metis UNION_f_eqvt X_to_Un_supp_def assms pt_fun_eq pt_perm_supp)
lemma Union_of_fin_supp_sets: fixes X::"('a set)" assumes fs: "fs TYPE('a) TYPE('x)" and fi: "finite X" shows"finite (∪x∈X. ((supp x)::'x set))" using fi by (induct, auto simp add: fs1[OF fs])
lemma Union_included_in_supp: fixes X::"('a set)" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and fs: "fs TYPE('a) TYPE('x)" and fi: "finite X" shows"(∪x∈X. ((supp x)::'x set)) ⊆ supp X" proof - have"supp ((X_to_Un_supp X)::'x set) ⊆ ((supp X)::'x set)" proof (rule pt_empty_supp_fun_subset) show"supp (λa. X_to_Un_supp (a::'a set)::'x set) = ({}::'x set)" by (simp add: X_to_Un_supp_eqvt at at_pt_inst pt pt_eqvt_fun2b pt_set_inst) qed (use assms at_pt_inst pt_set_inst in auto) hence"supp (∪x∈X. ((supp x)::'x set)) ⊆ ((supp X)::'x set)"by (simp add: X_to_Un_supp_def) moreover have"supp (∪x∈X. ((supp x)::'x set)) = (∪x∈X. ((supp x)::'x set))" using Union_of_fin_supp_sets at at_fin_set_supp fi fs by auto ultimatelyshow ?thesis by force qed
lemma supp_of_fin_sets: fixes X::"('a set)" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and fs: "fs TYPE('a) TYPE('x)" and fi: "finite X" shows"(supp X) = (∪x∈X. ((supp x)::'x set))" proof (rule equalityI) have"finite (∪ (supp ` X)::'x set)" using Union_of_fin_supp_sets fi fs by blast thenshow"(supp X::'x set) ⊆∪ (supp ` X)" by (metis Union_supports_set at pt supp_is_subset) next show"(∪x∈X. (supp x::'x set)) ⊆ supp X" by (simp add: Union_included_in_supp at fi fs pt) qed
lemma supp_fin_union: fixes X::"('a set)" and Y::"('a set)" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and fs: "fs TYPE('a) TYPE('x)" and f1: "finite X" and f2: "finite Y" shows"(supp (X∪Y)) = (supp X)∪((supp Y)::'x set)" using f1 f2 by (force simp add: supp_of_fin_sets[OF pt, OF at, OF fs])
lemma supp_fin_insert: fixes X::"('a set)" and x::"'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and fs: "fs TYPE('a) TYPE('x)" and f: "finite X" shows"(supp (insert x X)) = (supp x)∪((supp X)::'x set)" proof - have"(supp (insert x X)) = ((supp ({x}∪(X::'a set)))::'x set)"by simp alsohave"… = (supp {x})∪(supp X)" by (rule supp_fin_union[OF pt, OF at, OF fs], simp_all add: f) finallyshow"(supp (insert x X)) = (supp x)∪((supp X)::'x set)" by (simp add: supp_singleton) qed
lemma fresh_fin_union: fixes X::"('a set)" and Y::"('a set)" and a::"'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and fs: "fs TYPE('a) TYPE('x)" and f1: "finite X" and f2: "finite Y" shows"a♯(X∪Y) = (a♯X ∧ a♯Y)" by (simp add: assms fresh_def supp_fin_union)
lemma fresh_fin_insert: fixes X::"('a set)" and x::"'a" and a::"'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and fs: "fs TYPE('a) TYPE('x)" and f: "finite X" shows"a♯(insert x X) = (a♯x ∧ a♯X)" by (simp add: assms fresh_def supp_fin_insert)
lemma fresh_fin_insert1: fixes X::"('a set)" and x::"'a" and a::"'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and fs: "fs TYPE('a) TYPE('x)" and f: "finite X" and a1: "a♯x" and a2: "a♯X" shows"a♯(insert x X)" using a1 a2 by (simp add: fresh_fin_insert[OF pt, OF at, OF fs, OF f])
lemma pt_list_set_supp: fixes xs :: "'a list" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and fs: "fs TYPE('a) TYPE('x)" shows"supp (set xs) = ((supp xs)::'x set)" proof - have"supp (set xs) = (∪x∈(set xs). ((supp x)::'x set))" by (rule supp_of_fin_sets[OF pt, OF at, OF fs], rule finite_set) alsohave"(∪x∈(set xs). ((supp x)::'x set)) = (supp xs)" proof(induct xs) case Nil show ?caseby (simp add: supp_list_nil) next case (Cons h t) thus ?caseby (simp add: supp_list_cons) qed finallyshow ?thesis by simp qed
lemma pt_list_set_fresh: fixes a :: "'x" and xs :: "'a list" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and fs: "fs TYPE('a) TYPE('x)" shows"a♯(set xs) = a♯xs" by (simp add: fresh_def pt_list_set_supp[OF pt, OF at, OF fs])
section‹generalisation of freshness to lists and sets of atoms› (*================================================================*)
lemma fresh_star_set_eq: "set xs ♯* c = xs ♯* c" by (simp add: fresh_star_def)
lemma fresh_star_Un_elim: "((S ∪ T) ♯* c ==> PROP C) ≡ (S ♯* c ==> T ♯* c ==> PROP C)" proof assume🍋: "(S ∪ T) ♯* c ==> PROP C"and c: "S ♯* c""T ♯* c" show"PROP C" using c by (intro 🍋) (metis Un_iff fresh_star_set) qed (auto simp: fresh_star_def)
lemma fresh_star_insert_elim: "(insert x S ♯* c ==> PROP C) ≡ (x ♯ c ==> S ♯* c ==> PROP C)" by rule (simp_all add: fresh_star_def)
lemma fresh_star_empty_elim: "({} ♯* c ==> PROP C) ≡ PROP C" by (simp add: fresh_star_def)
text‹Normalization of freshness results; see \ ‹nominal_induct›\ lemma fresh_star_unit_elim: shows"((a::'a set)♯*() ==> PROP C) ≡ PROP C" and"((b::'a list)♯*() ==> PROP C) ≡ PROP C" by (simp_all add: fresh_star_def fresh_def supp_unit)
lemma pt_fresh_star_bij_ineq: fixes pi :: "'x prm" and x :: "'a" and a :: "'y set" and b :: "'y list" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" and cp: "cp TYPE('a) TYPE('x) TYPE('y)" shows"(pi∙a)♯*(pi∙x) = a♯*x" and"(pi∙b)♯*(pi∙x) = b♯*x" unfolding fresh_star_def proof - have"y ♯ x"if"∀z∈pi ∙ a. z ♯ pi ∙ x"and"y ∈ a"for y using that by (meson assms at pt_fresh_bij_ineq pt_set_bij2) moreoverhave"y ♯ pi ∙ x"if"∀z∈a. z ♯ x"and"y ∈ pi ∙ a"for y using that by (simp add: assms pt_fresh_left_ineq pt_set_bij1a) moreoverhave"y ♯ x" if"∀z∈set (pi ∙ b). z ♯ pi ∙ x"and"y ∈ set b"for y using that by (metis at cp pt_fresh_bij_ineq pt_set_bij pta ptb set_eqvt) moreoverhave"y ♯ pi ∙ x" if"∀z∈set b. z ♯ x"and"y ∈ set (pi ∙ b)"for y using that by (metis at cp pt_fresh_left_ineq pt_set_bij1a pta ptb set_eqvt) ultimatelyshow"(∀xa∈pi ∙ a. xa ♯ pi ∙ x) = (∀xa∈a. xa ♯ x)""(∀xa∈set (pi ∙ b). xa ♯ pi ∙ x) = (∀xa∈set b. xa ♯ x)" by blast+ qed
lemma pt_fresh_star_bij: fixes pi :: "'x prm" and x :: "'a" and a :: "'x set" and b :: "'x list" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"(pi∙a)♯*(pi∙x) = a♯*x" and"(pi∙b)♯*(pi∙x) = b♯*x" proof (rule pt_fresh_star_bij_ineq) show"(pi ∙ b) ♯* (pi ∙ x) = b ♯* x" by (simp add: at at_pt_inst cp_pt_inst pt pt_fresh_star_bij_ineq) qed (auto simp: at pt at_pt_inst cp_pt_inst)
lemma pt_fresh_star_eqvt: fixes pi :: "'x prm" and x :: "'a" and a :: "'x set" and b :: "'x list" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙(a♯*x) = (pi∙a)♯*(pi∙x)" and"pi∙(b♯*x) = (pi∙b)♯*(pi∙x)" by (simp_all add: perm_bool pt_fresh_star_bij[OF pt, OF at])
lemma pt_fresh_star_eqvt_ineq: fixes pi::"'x prm" and a::"'y set" and b::"'y list" and x::"'a" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" and cp: "cp TYPE('a) TYPE('x) TYPE('y)" and dj: "disjoint TYPE('y) TYPE('x)" shows"pi∙(a♯*x) = (pi∙a)♯*(pi∙x)" and"pi∙(b♯*x) = (pi∙b)♯*(pi∙x)" by (simp_all add: pt_fresh_star_bij_ineq[OF pta, OF ptb, OF at, OF cp] dj_perm_forget[OF dj] perm_bool)
lemma pt_freshs_freshs: assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE ('x)" and pi: "set (pi::'x prm) ⊆ Xs × Ys" and Xs: "Xs ♯* (x::'a)" and Ys: "Ys ♯* x" shows"pi∙x = x" using pi proof (induct pi) case Nil show ?caseby (simp add: pt1 [OF pt]) next case (Cons p pi) obtain a b where p: "p = (a, b)"by (cases p) with Cons Xs Ys have"a ♯ x""b ♯ x" by (simp_all add: fresh_star_def) with Cons p show ?case by (simp add: pt_fresh_fresh [OF pt at]
pt2 [OF pt, of "[(a, b)]" pi, simplified]) qed
lemma pt_fresh_star_pi: fixes x::"'a" and pi::"'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and a: "((supp x)::'x set)♯* pi" shows"pi∙x = x" using a apply(induct pi) apply (simp add: assms(1) pt1) apply(auto simp add: fresh_star_def fresh_list_cons fresh_prod pt1[OF pt]) by (metis Cons_eq_append_conv append_self_conv2 assms(1) at at_fresh fresh_def pt2 pt_fresh_fresh)
section‹Infrastructure lemmas for strong rule inductions› (*==========================================================*)
text‹ For every set of atoms, there is another set of atoms avoiding a finitely supported c and there is a permutation which 'translates' between both sets. ›
lemma at_set_avoiding_aux: fixes Xs::"'a set" and As::"'a set" assumes at: "at TYPE('a)" and b: "Xs ⊆ As" and c: "finite As" and d: "finite ((supp c)::'a set)" shows"∃(pi::'a prm). (pi∙Xs)♯*c ∧ (pi∙Xs) ∩ As = {} ∧ set pi ⊆ Xs × (pi∙Xs)" proof - from b c have"finite Xs"by (simp add: finite_subset) thenshow ?thesis using b proof (induct) case empty have"({}::'a set)♯*c"by (simp add: fresh_star_def) moreover have"({}::'a set) ∩ As = {}"by simp moreover have"set ([]::'a prm) ⊆ {} × {}"by simp ultimatelyshow ?caseby (simp add: empty_eqvt) next case (insert x Xs) thenhave ih: "∃pi. (pi∙Xs)♯*c ∧ (pi∙Xs) ∩ As = {} ∧ set pi ⊆ Xs × (pi∙Xs)"by simp thenobtain pi where a1: "(pi∙Xs)♯*c"and a2: "(pi∙Xs) ∩ As = {}"and
a4: "set pi ⊆ Xs × (pi∙Xs)"by blast have b: "x∉Xs"by fact have d1: "finite As"by fact have d2: "finite Xs"by fact have d3: "({x} ∪ Xs) ⊆ As"using insert(4) by simp from d d1 d2 obtain y::"'a"where fr: "y♯(c,pi∙Xs,As)" apply(rule_tac at_exists_fresh[OF at, where x="(c,pi∙Xs,As)"]) apply(auto simp add: supp_prod at_supp[OF at] at_fin_set_supp[OF at]
pt_supp_finite_pi[OF pt_set_inst[OF at_pt_inst[OF at]] at]) done have"({y}∪(pi∙Xs))♯*c"using a1 fr by (simp add: fresh_star_def) moreover have"({y}∪(pi∙Xs))∩As = {}"using a2 d1 fr by (simp add: fresh_prod at_fin_set_fresh[OF at]) moreover have"pi∙x=x"using a4 b a2 d3 by (rule_tac at_prm_fresh2[OF at]) (auto) thenhave"set ((pi∙x,y)#pi) ⊆ ({x} ∪ Xs) × ({y}∪(pi∙Xs))"using a4 by auto moreover have"(((pi∙x,y)#pi)∙({x} ∪ Xs)) = {y}∪(pi∙Xs)" proof - have eq: "[(pi∙x,y)]∙(pi∙Xs) = (pi∙Xs)" proof - have"(pi∙x)♯(pi∙Xs)"using b d2 by (simp add: pt_fresh_bij [OF pt_set_inst [OF at_pt_inst [OF at]], OF at]
at_fin_set_fresh [OF at]) moreover have"y♯(pi∙Xs)"using fr by simp ultimatelyshow"[(pi∙x,y)]∙(pi∙Xs) = (pi∙Xs)" by (simp add: pt_fresh_fresh[OF pt_set_inst
[OF at_pt_inst[OF at]], OF at]) qed have"(((pi∙x,y)#pi)∙({x}∪Xs)) = ([(pi∙x,y)]∙(pi∙({x}∪Xs)))" by (simp add: pt2[symmetric, OF pt_set_inst [OF at_pt_inst[OF at]]]) alsohave"… = {y}∪([(pi∙x,y)]∙(pi∙Xs))" by (simp only: union_eqvt perm_set_def at_calc[OF at])(auto) finallyshow"(((pi∙x,y)#pi)∙({x} ∪ Xs)) = {y}∪(pi∙Xs)"using eq by simp qed ultimately show ?caseby (rule_tac x="(pi∙x,y)#pi"in exI) (auto) qed qed
lemma at_set_avoiding: fixes Xs::"'a set" assumes at: "at TYPE('a)" and a: "finite Xs" and b: "finite ((supp c)::'a set)" obtains pi::"'a prm"where"(pi∙Xs)♯*c"and"set pi ⊆ Xs × (pi∙Xs)" using a b at_set_avoiding_aux[OF at, where Xs="Xs"and As="Xs"and c="c"] by (blast)
lemma cp_list_inst: assumes c1: "cp TYPE ('a) TYPE('x) TYPE('y)" shows"cp TYPE ('a list) TYPE('x) TYPE('y)" using c1 apply(clarsimp simp add: cp_def) by (induct_tac x) auto
lemma cp_set_inst: assumes c1: "cp TYPE ('a) TYPE('x) TYPE('y)" shows"cp TYPE ('a set) TYPE('x) TYPE('y)" using c1 unfolding cp_def perm_set_def by (smt (verit) Collect_cong mem_Collect_eq)
lemma cp_option_inst: assumes c1: "cp TYPE ('a) TYPE('x) TYPE('y)" shows"cp TYPE ('a option) TYPE('x) TYPE('y)" using c1 unfolding cp_def by (metis none_eqvt not_None_eq some_eqvt)
lemma cp_noption_inst: assumes c1: "cp TYPE ('a) TYPE('x) TYPE('y)" shows"cp TYPE ('a noption) TYPE('x) TYPE('y)" using c1 unfolding cp_def by (metis nnone_eqvt noption.exhaust nsome_eqvt)
lemma cp_unit_inst: shows"cp TYPE (unit) TYPE('x) TYPE('y)" by (simp add: cp_def)
lemma cp_bool_inst: shows"cp TYPE (bool) TYPE('x) TYPE('y)" apply(clarsimp simp add: cp_def) by (induct_tac x) auto
lemma cp_prod_inst: assumes c1: "cp TYPE ('a) TYPE('x) TYPE('y)" and c2: "cp TYPE ('b) TYPE('x) TYPE('y)" shows"cp TYPE ('a×'b) TYPE('x) TYPE('y)" using c1 c2 by (simp add: cp_def)
lemma cp_fun_inst: assumes c1: "cp TYPE ('a) TYPE('x) TYPE('y)" and c2: "cp TYPE ('b) TYPE('x) TYPE('y)" and pt: "pt TYPE ('y) TYPE('x)" and at: "at TYPE ('x)" shows"cp TYPE ('a==>'b) TYPE('x) TYPE('y)" using c1 c2 by(auto simp add: cp_def perm_fun_def fun_eq_iff at pt pt_list_inst pt_prod_inst pt_rev_pi rev_eqvt)
lemma freshness_lemma: fixes h :: "'x==>'a" assumes pta: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and f1: "finite ((supp h)::'x set)" and a: "∃a::'x. a♯(h,h a)" shows"∃fr::'a. ∀a::'x. a♯h ⟶ (h a) = fr" proof - have ptb: "pt TYPE('x) TYPE('x)"by (simp add: at_pt_inst[OF at]) have ptc: "pt TYPE('x==>'a) TYPE('x)"by (simp add: pt_fun_inst[OF ptb, OF pta, OF at]) from a obtain a0 where a1: "a0♯h"and a2: "a0♯(h a0)"by (force simp add: fresh_prod) show ?thesis proof let ?fr = "h (a0::'x)" show"∀(a::'x). (a♯h ⟶ ((h a) = ?fr))" proof (intro strip) fix a assume a3: "(a::'x)♯h" show"h (a::'x) = h a0" proof (cases "a=a0") case True thus"h (a::'x) = h a0"by simp next case False assume"a≠a0" hence c1: "a∉((supp a0)::'x set)"by (simp add: fresh_def[symmetric] at_fresh[OF at]) have c2: "a∉((supp h)::'x set)"using a3 by (simp add: fresh_def) from c1 c2 have c3: "a∉((supp h)∪((supp a0)::'x set))"by force have f2: "finite ((supp a0)::'x set)"by (simp add: at_supp[OF at]) from f1 f2 have"((supp (h a0))::'x set)⊆((supp h)∪(supp a0))" by (simp add: pt_supp_fun_subset[OF ptb, OF pta, OF at]) hence"a∉((supp (h a0))::'x set)"using c3 by force hence"a♯(h a0)"by (simp add: fresh_def) with a2 have d1: "[(a0,a)]∙(h a0) = (h a0)"by (rule pt_fresh_fresh[OF pta, OF at]) from a1 a3 have d2: "[(a0,a)]∙h = h"by (rule pt_fresh_fresh[OF ptc, OF at]) from d1 have"h a0 = [(a0,a)]∙(h a0)"by simp alsohave"…= ([(a0,a)]∙h)([(a0,a)]∙a0)"by (simp add: pt_fun_app_eq[OF ptb, OF at]) alsohave"… = h ([(a0,a)]∙a0)"using d2 by simp alsohave"… = h a"by (simp add: at_calc[OF at]) finallyshow"h a = h a0"by simp qed qed qed qed
lemma freshness_lemma_unique: fixes h :: "'x==>'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and f1: "finite ((supp h)::'x set)" and a: "∃(a::'x). a♯(h,h a)" shows"∃!(fr::'a). ∀(a::'x). a♯h ⟶ (h a) = fr" proof (rule ex_ex1I) from pt at f1 a show"∃fr::'a. ∀a::'x. a♯h ⟶ h a = fr"by (simp add: freshness_lemma) next fix fr1 fr2 assume b1: "∀a::'x. a♯h ⟶ h a = fr1" assume b2: "∀a::'x. a♯h ⟶ h a = fr2" from a obtain a where"(a::'x)♯h"by (force simp add: fresh_prod) with b1 b2 have"h a = fr1 ∧ h a = fr2"by force thus"fr1 = fr2"by force qed
🍋‹packaging the freshness lemma into a function› definition fresh_fun :: "('x==>'a)==>'a"where "fresh_fun (h) ≡ THE fr. (∀(a::'x). a♯h ⟶ (h a) = fr)"
lemma fresh_fun_app: fixes h :: "'x==>'a" and a :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and f1: "finite ((supp h)::'x set)" and a: "∃(a::'x). a♯(h,h a)" and b: "a♯h" shows"(fresh_fun h) = (h a)" proof (unfold fresh_fun_def, rule the_equality) show"∀(a'::'x). a'♯h ⟶ h a' = h a" proof (intro strip) fix a'::"'x" assume c: "a'♯h" from pt at f1 a have"∃(fr::'a). ∀(a::'x). a♯h ⟶ (h a) = fr"by (rule freshness_lemma) with b c show"h a' = h a"by force qed next fix fr::"'a" assume"∀a. a♯h ⟶ h a = fr" with b show"fr = h a"by force qed
lemma fresh_fun_app': fixes h :: "'x==>'a" and a :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and f1: "finite ((supp h)::'x set)" and a: "a♯h""a♯h a" shows"(fresh_fun h) = (h a)" by (meson assms fresh_fun_app fresh_prod pt)
lemma fresh_fun_equiv_ineq: fixes h :: "'y==>'a" and pi:: "'x prm" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('y) TYPE('x)" and ptb':"pt TYPE('a) TYPE('y)" and at: "at TYPE('x)" and at': "at TYPE('y)" and cpa: "cp TYPE('a) TYPE('x) TYPE('y)" and cpb: "cp TYPE('y) TYPE('x) TYPE('y)" and f1: "finite ((supp h)::'y set)" and a1: "∃(a::'y). a♯(h,h a)" shows"pi∙(fresh_fun h) = fresh_fun(pi∙h)" (is"?LHS = ?RHS") proof - have ptd: "pt TYPE('y) TYPE('y)"by (simp add: at_pt_inst[OF at']) have ptc: "pt TYPE('y==>'a) TYPE('x)"by (simp add: pt_fun_inst[OF ptb, OF pta, OF at]) have cpc: "cp TYPE('y==>'a) TYPE ('x) TYPE ('y)"by (rule cp_fun_inst[OF cpb cpa ptb at]) have f2: "finite ((supp (pi∙h))::'y set)" proof - from f1 have"finite (pi∙((supp h)::'y set))" by (simp add: pt_set_finite_ineq[OF ptb, OF at]) thus ?thesis by (simp add: pt_perm_supp_ineq[OF ptc, OF ptb, OF at, OF cpc]) qed from a1 obtain a' where c0: "a'♯(h,h a')"by force hence c1: "a'♯h"and c2: "a'♯(h a')"by (simp_all add: fresh_prod) have c3: "(pi∙a')♯(pi∙h)"using c1 by (simp add: pt_fresh_bij_ineq[OF ptc, OF ptb, OF at, OF cpc]) have c4: "(pi∙a')♯(pi∙h) (pi∙a')" proof - from c2 have"(pi∙a')♯(pi∙(h a'))" by (simp add: pt_fresh_bij_ineq[OF pta, OF ptb, OF at,OF cpa]) thus ?thesis by (simp add: pt_fun_app_eq[OF ptb, OF at]) qed have a2: "∃(a::'y). a♯(pi∙h,(pi∙h) a)"using c3 c4 by (force simp add: fresh_prod) have d1: "?LHS = pi∙(h a')"using c1 a1 by (simp add: fresh_fun_app[OF ptb', OF at', OF f1]) have d2: "?RHS = (pi∙h) (pi∙a')"using c3 a2 by (simp add: fresh_fun_app[OF ptb', OF at', OF f2]) show ?thesis using d1 d2 by (simp add: pt_fun_app_eq[OF ptb, OF at]) qed
lemma fresh_fun_equiv: fixes h :: "'x==>'a" and pi:: "'x prm" assumes pta: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and f1: "finite ((supp h)::'x set)" and a1: "∃(a::'x). a♯(h,h a)" shows"pi∙(fresh_fun h) = fresh_fun(pi∙h)" (is"?LHS = ?RHS") proof - have ptb: "pt TYPE('x) TYPE('x)"by (simp add: at_pt_inst[OF at]) have ptc: "pt TYPE('x==>'a) TYPE('x)"by (simp add: pt_fun_inst[OF ptb, OF pta, OF at]) have f2: "finite ((supp (pi∙h))::'x set)" proof - from f1 have"finite (pi∙((supp h)::'x set))"by (simp add: pt_set_finite_ineq[OF ptb, OF at]) thus ?thesis by (simp add: pt_perm_supp[OF ptc, OF at]) qed from a1 obtain a' where c0: "a'♯(h,h a')"by force hence c1: "a'♯h"and c2: "a'♯(h a')"by (simp_all add: fresh_prod) have c3: "(pi∙a')♯(pi∙h)"using c1 by (simp add: pt_fresh_bij[OF ptc, OF at]) have c4: "(pi∙a')♯(pi∙h) (pi∙a')" proof - from c2 have"(pi∙a')♯(pi∙(h a'))"by (simp add: pt_fresh_bij[OF pta, OF at]) thus ?thesis by (simp add: pt_fun_app_eq[OF ptb, OF at]) qed have a2: "∃(a::'x). a♯(pi∙h,(pi∙h) a)"using c3 c4 by (force simp add: fresh_prod) have d1: "?LHS = pi∙(h a')"using c1 a1 by (simp add: fresh_fun_app[OF pta, OF at, OF f1]) have d2: "?RHS = (pi∙h) (pi∙a')"using c3 a2 by (simp add: fresh_fun_app[OF pta, OF at, OF f2]) show ?thesis using d1 d2 by (simp add: pt_fun_app_eq[OF ptb, OF at]) qed
lemma pt_abs_fun_inst: assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pt TYPE('x==>('a noption)) TYPE('x)" by (simp add: at at_pt_inst pt pt_fun_inst pt_noption_inst)
definition abs_fun :: "'x==>'a==>('x==>('a noption))" (‹[_]._› [100,100] 100) where "[a].x ≡ (λb. (if b=a then nSome(x) else (if b♯x then nSome([(a,b)]∙x) else nNone)))"
(* FIXME: should be called perm_if and placed close to the definition of permutations on bools *) lemma abs_fun_if: fixes pi :: "'x prm" and x :: "'a" and y :: "'a" and c :: "bool" shows"pi∙(if c then x else y) = (if c then (pi∙x) else (pi∙y))" by force
lemma abs_fun_pi_ineq: fixes a :: "'y" and x :: "'a" and pi :: "'x prm" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" and cp: "cp TYPE('a) TYPE('x) TYPE('y)" shows"pi∙([a].x) = [(pi∙a)].(pi∙x)" unfolding fun_eq_iff proof fix y have"(((rev pi)∙y) = a) = (y = pi∙a)" by (metis at pt_rev_pi ptb) moreover have"(((rev pi)∙y)♯x) = (y♯(pi∙x))" by (simp add: assms pt_fresh_left_ineq) moreover have"pi∙([(a,(rev pi)∙y)]∙x) = [(pi∙a,y)]∙(pi∙x)" using assms cp1[OF cp] by (simp add: pt_pi_rev) ultimately show"(pi ∙ [a].x) y = ([(pi ∙ a)].(pi ∙ x)) y" by (simp add: abs_fun_def perm_fun_def) qed
lemma abs_fun_pi: fixes a :: "'x" and x :: "'a" and pi :: "'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi∙([a].x) = [(pi∙a)].(pi∙x)" by (simp add: abs_fun_pi_ineq at at_pt_inst cp_pt_inst pt)
lemma abs_fun_eq1: fixes x :: "'a" and y :: "'a" and a :: "'x" shows"([a].x = [a].y) = (x = y)" by (metis abs_fun_def noption.inject)
lemma abs_fun_eq2: fixes x :: "'a" and y :: "'a" and a :: "'x" and b :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and a1: "a≠b" and a2: "[a].x = [b].y" shows"x=[(a,b)]∙y ∧ a♯y" proof - from a2 have"∀c::'x. ([a].x) c = ([b].y) c"by (force simp add: fun_eq_iff) hence"([a].x) a = ([b].y) a"by simp hence a3: "nSome(x) = ([b].y) a"by (simp add: abs_fun_def) show"x=[(a,b)]∙y ∧ a♯y" proof (cases "a♯y") assume a4: "a♯y" hence"x=[(b,a)]∙y"using a3 a1 by (simp add: abs_fun_def) moreover have"[(a,b)]∙y = [(b,a)]∙y"by (rule pt3[OF pt], rule at_ds5[OF at]) ultimatelyshow ?thesis using a4 by simp next assume"¬a♯y" hence"nSome(x) = nNone"using a1 a3 by (simp add: abs_fun_def) hence False by simp thus ?thesis by simp qed qed
lemma abs_fun_eq3: fixes x :: "'a" and y :: "'a" and a :: "'x" and b :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and a1: "a≠b" and a2: "x=[(a,b)]∙y" and a3: "a♯y" shows"[a].x =[b].y" proof - show ?thesis proof (simp only: abs_fun_def fun_eq_iff, intro strip) fix c::"'x" let ?LHS = "if c=a then nSome(x) else if c♯x then nSome([(a,c)]∙x) else nNone" and ?RHS = "if c=b then nSome(y) else if c♯y then nSome([(b,c)]∙y) else nNone" show"?LHS=?RHS" proof - have"(c=a) ∨ (c=b) ∨ (c≠a ∧ c≠b)"by blast moreover🍋‹case c=a›
{ have"nSome(x) = nSome([(a,b)]∙y)"using a2 by simp alsohave"… = nSome([(b,a)]∙y)"by (simp, rule pt3[OF pt], rule at_ds5[OF at]) finallyhave"nSome(x) = nSome([(b,a)]∙y)"by simp moreover assume"c=a" ultimatelyhave"?LHS=?RHS"using a1 a3 by simp
} moreover🍋‹case c=b›
{ have a4: "y=[(a,b)]∙x"using a2 by (simp only: pt_swap_bij[OF pt, OF at]) hence"a♯([(a,b)]∙x)"using a3 by simp hence"b♯x"by (simp add: at_calc[OF at] pt_fresh_left[OF pt, OF at]) moreover assume"c=b" ultimatelyhave"?LHS=?RHS"using a1 a4 by simp
} moreover🍋‹case c≠a ∧ c≠b›
{ assume a5: "c≠a ∧ c≠b" moreover have"c♯x = c♯y"using a2 a5 by (force simp add: at_calc[OF at] pt_fresh_left[OF pt, OF at]) moreover have"c♯y ⟶ [(a,c)]∙x = [(b,c)]∙y" proof (intro strip) assume a6: "c♯y" have"[(a,c),(b,c),(a,c)] ≜ [(a,b)]"using a1 a5 by (force intro: at_ds3[OF at]) hence"[(a,c)]∙([(b,c)]∙([(a,c)]∙y)) = [(a,b)]∙y" by (simp add: pt2[OF pt, symmetric] pt3[OF pt]) hence"[(a,c)]∙([(b,c)]∙y) = [(a,b)]∙y"using a3 a6 by (simp add: pt_fresh_fresh[OF pt, OF at]) hence"[(a,c)]∙([(b,c)]∙y) = x"using a2 by simp hence"[(b,c)]∙y = [(a,c)]∙x"by (drule_tac pt_bij1[OF pt, OF at], simp) thus"[(a,c)]∙x = [(b,c)]∙y"by simp qed ultimatelyhave"?LHS=?RHS"by simp
} ultimatelyshow"?LHS = ?RHS"by blast qed qed qed
(* alpha equivalence *) lemma abs_fun_eq: fixes x :: "'a" and y :: "'a" and a :: "'x" and b :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"([a].x = [b].y) = ((a=b ∧ x=y)∨(a≠b ∧ x=[(a,b)]∙y ∧ a♯y))" proof (rule iffI) assume b: "[a].x = [b].y" show"(a=b ∧ x=y)∨(a≠b ∧ x=[(a,b)]∙y ∧ a♯y)" proof (cases "a=b") case True with b show ?thesis by (simp add: abs_fun_eq1) next case False with b show ?thesis by (simp add: abs_fun_eq2[OF pt, OF at]) qed next assume"(a=b ∧ x=y)∨(a≠b ∧ x=[(a,b)]∙y ∧ a♯y)" thus"[a].x = [b].y" proof assume"a=b ∧ x=y"thus ?thesis by simp next assume"a≠b ∧ x=[(a,b)]∙y ∧ a♯y" thus ?thesis by (simp add: abs_fun_eq3[OF pt, OF at]) qed qed
(* symmetric version of alpha-equivalence *) lemma abs_fun_eq': fixes x :: "'a" and y :: "'a" and a :: "'x" and b :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"([a].x = [b].y) = ((a=b ∧ x=y)∨(a≠b ∧ [(b,a)]∙x=y ∧ b♯x))" by (auto simp add: abs_fun_eq[OF pt, OF at] pt_swap_bij'[OF pt, OF at]
pt_fresh_left[OF pt, OF at]
at_calc[OF at])
(* alpha_equivalence with a fresh name *) lemma abs_fun_fresh: fixes x :: "'a" and y :: "'a" and c :: "'x" and a :: "'x" and b :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and fr: "c≠a""c≠b""c♯x""c♯y" shows"([a].x = [b].y) = ([(a,c)]∙x = [(b,c)]∙y)" proof (rule iffI) assume eq0: "[a].x = [b].y" show"[(a,c)]∙x = [(b,c)]∙y" proof (cases "a=b") case True thenshow ?thesis using eq0 by (simp add: pt_bij[OF pt, OF at] abs_fun_eq[OF pt, OF at]) next case False have ineq: "a≠b"by fact with eq0 have eq: "x=[(a,b)]∙y"and fr': "a♯y"by (simp_all add: abs_fun_eq[OF pt, OF at]) from eq have"[(a,c)]∙x = [(a,c)]∙[(a,b)]∙y"by (simp add: pt_bij[OF pt, OF at]) alsohave"… = ([(a,c)]∙[(a,b)])∙([(a,c)]∙y)"by (rule pt_perm_compose[OF pt, OF at]) alsohave"… = [(c,b)]∙y"using ineq fr fr' by (simp add: pt_fresh_fresh[OF pt, OF at] at_calc[OF at]) alsohave"… = [(b,c)]∙y"by (rule pt3[OF pt], rule at_ds5[OF at]) finallyshow ?thesis by simp qed next assume eq: "[(a,c)]∙x = [(b,c)]∙y" thus"[a].x = [b].y" proof (cases "a=b") case True thenshow ?thesis using eq by (simp add: pt_bij[OF pt, OF at] abs_fun_eq[OF pt, OF at]) next case False have ineq: "a≠b"by fact from fr have"([(a,c)]∙c)♯([(a,c)]∙x)"by (simp add: pt_fresh_bij[OF pt, OF at]) hence"a♯([(b,c)]∙y)"using eq fr by (simp add: at_calc[OF at]) hence fr0: "a♯y"using ineq fr by (simp add: pt_fresh_left[OF pt, OF at] at_calc[OF at]) from eq have"x = (rev [(a,c)])∙([(b,c)]∙y)"by (rule pt_bij1[OF pt, OF at]) alsohave"… = [(a,c)]∙([(b,c)]∙y)"by simp alsohave"… = ([(a,c)]∙[(b,c)])∙([(a,c)]∙y)"by (rule pt_perm_compose[OF pt, OF at]) alsohave"… = [(b,a)]∙y"using ineq fr fr0 by (simp add: pt_fresh_fresh[OF pt, OF at] at_calc[OF at]) alsohave"… = [(a,b)]∙y"by (rule pt3[OF pt], rule at_ds5[OF at]) finallyshow ?thesis using ineq fr0 by (simp add: abs_fun_eq[OF pt, OF at]) qed qed
lemma abs_fun_fresh': fixes x :: "'a" and y :: "'a" and c :: "'x" and a :: "'x" and b :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and as: "[a].x = [b].y" and fr: "c≠a""c≠b""c♯x""c♯y" shows"x = [(a,c)]∙[(b,c)]∙y" using assms by (metis abs_fun_fresh pt_swap_bij)
lemma abs_fun_supp_approx: fixes x :: "'a" and a :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"((supp ([a].x))::'x set) ⊆ (supp (x,a))" proof fix c assume"c∈((supp ([a].x))::'x set)" hence"infinite {b. [(c,b)]∙([a].x) ≠ [a].x}"by (simp add: supp_def) hence"infinite {b. [([(c,b)]∙a)].([(c,b)]∙x) ≠ [a].x}"by (simp add: abs_fun_pi[OF pt, OF at]) moreover have"{b. [([(c,b)]∙a)].([(c,b)]∙x) ≠ [a].x} ⊆ {b. ([(c,b)]∙x,[(c,b)]∙a) ≠ (x, a)}"by force ultimatelyhave"infinite {b. ([(c,b)]∙x,[(c,b)]∙a) ≠ (x, a)}"by (simp add: infinite_super) thus"c∈(supp (x,a))"by (simp add: supp_def) qed
lemma abs_fun_finite_supp: fixes x :: "'a" and a :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and f: "finite ((supp x)::'x set)" shows"finite ((supp ([a].x))::'x set)" proof - from f have"finite ((supp (x,a))::'x set)"by (simp add: supp_prod at_supp[OF at]) moreover have"((supp ([a].x))::'x set) ⊆ (supp (x,a))"by (rule abs_fun_supp_approx[OF pt, OF at]) ultimatelyshow ?thesis by (simp add: finite_subset) qed
lemma fresh_abs_funI1: fixes x :: "'a" and a :: "'x" and b :: "'x" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and f: "finite ((supp x)::'x set)" and a1: "b♯x" and a2: "a≠b" shows"b♯([a].x)" proof - have"∃c::'x. c♯(b,a,x,[a].x)" proof (rule at_exists_fresh'[OF at], auto simp add: supp_prod at_supp[OF at] f) show"finite ((supp ([a].x))::'x set)"using f by (simp add: abs_fun_finite_supp[OF pt, OF at]) qed thenobtain c where fr1: "c≠b" and fr2: "c≠a" and fr3: "c♯x" and fr4: "c♯([a].x)" by (force simp add: fresh_prod at_fresh[OF at]) have e: "[(c,b)]∙([a].x) = [a].([(c,b)]∙x)"using a2 fr1 fr2 by (force simp add: abs_fun_pi[OF pt, OF at] at_calc[OF at]) from fr4 have"([(c,b)]∙c)♯ ([(c,b)]∙([a].x))" by (simp add: pt_fresh_bij[OF pt_abs_fun_inst[OF pt, OF at], OF at]) hence"b♯([a].([(c,b)]∙x))"using fr1 fr2 e by (simp add: at_calc[OF at]) thus ?thesis using a1 fr3 by (simp add: pt_fresh_fresh[OF pt, OF at]) qed
lemma fresh_abs_funE: fixes a :: "'x" and b :: "'x" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and f: "finite ((supp x)::'x set)" and a1: "b♯([a].x)" and a2: "b≠a" shows"b♯x" proof - have"∃c::'x. c♯(b,a,x,[a].x)" proof (rule at_exists_fresh'[OF at], auto simp add: supp_prod at_supp[OF at] f) show"finite ((supp ([a].x))::'x set)"using f by (simp add: abs_fun_finite_supp[OF pt, OF at]) qed thenobtain c where fr1: "b≠c" and fr2: "c≠a" and fr3: "c♯x" and fr4: "c♯([a].x)"by (force simp add: fresh_prod at_fresh[OF at]) have"[a].x = [(b,c)]∙([a].x)"using a1 fr4 by (simp add: pt_fresh_fresh[OF pt_abs_fun_inst[OF pt, OF at], OF at]) hence"[a].x = [a].([(b,c)]∙x)"using fr2 a2 by (force simp add: abs_fun_pi[OF pt, OF at] at_calc[OF at]) hence b: "([(b,c)]∙x) = x"by (simp add: abs_fun_eq1) from fr3 have"([(b,c)]∙c)♯([(b,c)]∙x)" by (simp add: pt_fresh_bij[OF pt, OF at]) thus ?thesis using b fr1 by (simp add: at_calc[OF at]) qed
lemma fresh_abs_funI2: fixes a :: "'x" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and f: "finite ((supp x)::'x set)" shows"a♯([a].x)" proof - have"∃c::'x. c♯(a,x)" by (rule at_exists_fresh'[OF at], auto simp add: supp_prod at_supp[OF at] f) thenobtain c where fr1: "a≠c"and fr1_sym: "c≠a" and fr2: "c♯x"by (force simp add: fresh_prod at_fresh[OF at]) have"c♯([a].x)"using f fr1 fr2 by (simp add: fresh_abs_funI1[OF pt, OF at]) hence"([(c,a)]∙c)♯([(c,a)]∙([a].x))"using fr1 by (simp only: pt_fresh_bij[OF pt_abs_fun_inst[OF pt, OF at], OF at]) hence a: "a♯([c].([(c,a)]∙x))"using fr1_sym by (simp add: abs_fun_pi[OF pt, OF at] at_calc[OF at]) have"[c].([(c,a)]∙x) = ([a].x)"using fr1_sym fr2 by (simp add: abs_fun_eq[OF pt, OF at]) thus ?thesis using a by simp qed
lemma fresh_abs_fun_iff: fixes a :: "'x" and b :: "'x" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and f: "finite ((supp x)::'x set)" shows"(b♯([a].x)) = (b=a ∨ b♯x)" by (auto dest: fresh_abs_funE[OF pt, OF at,OF f]
intro: fresh_abs_funI1[OF pt, OF at,OF f]
fresh_abs_funI2[OF pt, OF at,OF f])
lemma abs_fun_supp: fixes a :: "'x" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" and f: "finite ((supp x)::'x set)" shows"supp ([a].x) = (supp x)-{a}" by (force simp add: supp_fresh_iff fresh_abs_fun_iff[OF pt, OF at, OF f])
(* maybe needs to be better stated as supp intersection supp *) lemma abs_fun_supp_ineq: fixes a :: "'y" and x :: "'a" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" and cp: "cp TYPE('a) TYPE('x) TYPE('y)" and dj: "disjoint TYPE('y) TYPE('x)" shows"((supp ([a].x))::'x set) = (supp x)" unfolding supp_def using abs_fun_pi_ineq[OF pta, OF ptb, OF at, OF cp] dj_perm_forget[OF dj] by (smt (verit, ccfv_threshold) Collect_cong abs_fun_eq1)
lemma fresh_abs_fun_iff_ineq: fixes a :: "'y" and b :: "'x" and x :: "'a" assumes pta: "pt TYPE('a) TYPE('x)" and ptb: "pt TYPE('y) TYPE('x)" and at: "at TYPE('x)" and cp: "cp TYPE('a) TYPE('x) TYPE('y)" and dj: "disjoint TYPE('y) TYPE('x)" shows"b♯([a].x) = b♯x" by (simp add: fresh_def abs_fun_supp_ineq[OF pta, OF ptb, OF at, OF cp, OF dj])
section‹abstraction type for the parsing in nominal datatype› (*==============================================================*)
inductive_set ABS_set :: "('x==>('a noption)) set" where
ABS_in: "(abs_fun a x)∈ABS_set"
section‹lemmas for deciding permutation equations› (*===================================================*)
lemma perm_aux_fold: shows"perm_aux pi x = pi∙x"by (simp only: perm_aux_def)
lemma pt_perm_compose_aux: fixes pi1 :: "'x prm" and pi2 :: "'x prm" and x :: "'a" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"pi2∙(pi1∙x) = perm_aux (pi2∙pi1) (pi2∙x)" proof - have"(pi2@pi1) ≜ ((pi2∙pi1)@pi2)"by (rule at_ds8[OF at]) hence"(pi2@pi1)∙x = ((pi2∙pi1)@pi2)∙x"by (rule pt3[OF pt]) thus ?thesis by (simp add: pt2[OF pt] perm_aux_def) qed
lemma cp1_aux: fixes pi1::"'x prm" and pi2::"'y prm" and x ::"'a" assumes cp: "cp TYPE ('a) TYPE('x) TYPE('y)" shows"pi1∙(pi2∙x) = perm_aux (pi1∙pi2) (pi1∙x)" using cp by (simp add: cp_def perm_aux_def)
lemma perm_eq_app: fixes f :: "'a==>'b" and x :: "'a" and pi :: "'x prm" assumes pt: "pt TYPE('a) TYPE('x)" and at: "at TYPE('x)" shows"(pi∙(f x)=y) = ((pi∙f)(pi∙x)=y)" by (simp add: pt_fun_app_eq[OF pt, OF at])
lemma perm_eq_lam: fixes f :: "'a==>'b" and x :: "'a" and pi :: "'x prm" shows"((pi∙(λx. f x))=y) = ((λx. (pi∙(f ((rev pi)∙x))))=y)" by (simp add: perm_fun_def)
section‹test› lemma at_prm_eq_compose: fixes pi1 :: "'x prm" and pi2 :: "'x prm" and pi3 :: "'x prm" assumes at: "at TYPE('x)" and a: "pi1 ≜ pi2" shows"(pi3∙pi1) ≜ (pi3∙pi2)" proof - have pt: "pt TYPE('x) TYPE('x)"by (rule at_pt_inst[OF at]) have pt_prm: "pt TYPE('x prm) TYPE('x)" by (rule pt_list_inst[OF pt_prod_inst[OF pt, OF pt]]) from a show ?thesis by (auto simp add: prm_eq_def at pt pt_perm_compose') qed
(************************) (* Various eqvt-lemmas *)
lemma Zero_nat_eqvt[simp]: shows"pi∙(0::nat) = 0" by (auto simp add: perm_nat_def)
lemma One_nat_eqvt[simp]: shows"pi∙(1::nat) = 1" by (simp add: perm_nat_def)
lemma div_int_eqvt: fixes x::"int" shows"pi∙(x div y) = (pi∙x) div (pi∙y)" by (simp add:perm_int_def)
(*******************************************************) (* Setup of the theorem attributes eqvt and eqvt_force *)
ML_file ‹nominal_thmdecls.ML› setup"NominalThmDecls.setup"
(* the lemmas numeral_nat_eqvt numeral_int_eqvt do not conform with the *) (* usual form of an eqvt-lemma, but they are needed for analysing *) (* permutations on nats and ints *) lemmas [eqvt_force] = numeral_nat_eqvt numeral_int_eqvt neg_numeral_int_eqvt
(***************************************) (* setup for the individial atom-kinds *) (* and nominal datatypes *)
ML_file ‹nominal_atoms.ML›
(************************************************************) (* various tactics for analysing permutations, supports etc *)
ML_file ‹nominal_permeq.ML›
method_setup perm_simp = ‹NominalPermeq.perm_simp_meth› ‹simp rules and simprocs for analysing permutations›
method_setup perm_simp_debug = ‹NominalPermeq.perm_simp_meth_debug› ‹simp rules and simprocs for analysing permutations including debugging facilities›
method_setup perm_extend_simp = ‹NominalPermeq.perm_extend_simp_meth› ‹tactic for deciding equalities involving permutations›
method_setup perm_extend_simp_debug = ‹NominalPermeq.perm_extend_simp_meth_debug› ‹tactic for deciding equalities involving permutations including debugging facilities›
method_setup supports_simp_debug = ‹NominalPermeq.supports_meth_debug› ‹tactic for deciding whether something supports something else including debugging facilities›
method_setup finite_guess = ‹NominalPermeq.finite_guess_meth› ‹tactic for deciding whether something has finite support›
method_setup finite_guess_debug = ‹NominalPermeq.finite_guess_meth_debug› ‹tactic for deciding whether something has finite support including debugging facilities›
method_setup fresh_guess = ‹NominalPermeq.fresh_guess_meth› ‹tactic for deciding whether an atom is fresh for something›
method_setup fresh_guess_debug = ‹NominalPermeq.fresh_guess_meth_debug› ‹tactic for deciding whether an atom is fresh for something including debugging facilities›
(*****************************************************************) (* tactics for generating fresh names and simplifying fresh_funs *)
ML_file ‹nominal_fresh_fun.ML›
(************************************************) (* main file for constructing nominal datatypes *) lemma allE_Nil: assumes"∀x. P x"obtains"P []" using assms ..
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.