text‹ Refined types › nominal_datatype"τ" =
T_refined_type x::x b c::c binds x in c (‹{ _ : _ | _ }› [50, 50] 1000)
text‹ Statements ›
nominal_datatype
s =
AS_val v ( ‹[_]s›)
| AS_let x::x e s::s binds x in s ( ‹(LET _ = _ IN _)›)
| AS_let2 x::x τ s s::s binds x in s ( ‹(LET _ : _ = _ IN _)›)
| AS_if v s s ( ‹(IF _ THEN _ ELSE _)› [0, 61, 0] 61)
| AS_var u::u τ v s::s binds u in s ( ‹(VAR _ : _ = _ IN _)›)
| AS_assign u v ( ‹(_ ::= _)›)
| AS_match v branch_list ( ‹(MATCH _ WITH { _ })›)
| AS_while s s ( ‹(WHILE _ DO { _ } )› [0, 0] 61)
| AS_seq s s ( ‹( _ ;; _ )› [1000, 61] 61)
| AS_assert c s ( ‹(ASSERT _ IN _ )› ) and branch_s =
AS_branch dc x::x s::s binds x in s ( ‹( _ _ ==> _ )›) and branch_list =
AS_final branch_s ( ‹{ _ }› )
| AS_cons branch_s branch_list ( ‹( _ | _ )›)
text‹ Function and union type definitions ›
nominal_datatype"fun_typ" =
AF_fun_typ x::x "b" c::c τ::τ s::s binds x in c τ s
nominal_datatype"fun_typ_q" =
AF_fun_typ_some bv::bv ft::fun_typ binds bv in ft
| AF_fun_typ_none fun_typ
text‹These lemmas deal primarily with freshness and alpha-equivalence›
subsubsection‹Atoms›
lemma x_not_in_u_atoms[simp]: fixes u::u and x::x and us::"u set" shows"atom x ∉ atom`us" by (simp add: image_iff)
lemma x_fresh_u[simp]: fixes u::u and x::x shows"atom x ♯ u" by auto
lemma x_not_in_b_set[simp]: fixes x::x and bs::"bv fset" shows"atom x ∉ supp bs" by(induct bs,auto, simp add: supp_finsert supp_at_base)
lemma x_fresh_b[simp]: fixes x::x and b::b shows"atom x ♯ b" apply (induct b rule: b.induct, auto simp: pure_supp) using pure_supp fresh_def by blast+
lemma x_fresh_bv[simp]: fixes x::x and bv::bv shows"atom x ♯ bv" using fresh_def supp_at_base by auto
lemma u_not_in_x_atoms[simp]: fixes u::u and x::x and xs::"x set" shows"atom u ∉ atom`xs" by (simp add: image_iff)
lemma bv_not_in_x_atoms[simp]: fixes bv::bv and x::x and xs::"x set" shows"atom bv ∉ atom`xs" by (simp add: image_iff)
lemma u_not_in_b_atoms[simp]: fixes b :: b and u::u shows"atom u ∉ supp b" by (induct b rule: b.induct,auto simp: pure_supp supp_at_base)
lemma u_not_in_b_set[simp]: fixes u::u and bs::"bv fset" shows"atom u ∉ supp bs" by(induct bs, auto simp add: supp_at_base supp_finsert)
lemma u_fresh_b[simp]: fixes x::u and b::b shows"atom x ♯ b" by(induct b rule: b.induct, auto simp: pure_fresh )
lemma supp_b_v_disjoint: fixes x::x and bv::bv shows"supp (V_var x) ∩ supp (B_var bv) = {}" by (simp add: supp_at_base)
lemma supp_b_u_disjoint[simp]: fixes b::b and u::u shows"supp u ∩ supp b = {}" by(nominal_induct b rule:b.strong_induct,(auto simp add: pure_supp b.supp supp_at_base)+)
lemma u_fresh_bv[simp]: fixes u::u and b::bv shows"atom u ♯ b" using fresh_at_base by simp
subsubsection‹Basic Types›
nominal_function b_of :: "τ ==> b"where "b_of { z : b | c } = b" apply(auto,simp add: eqvt_def b_of_graph_aux_def ) by (meson τ.exhaust)
nominal_termination (eqvt) by lexicographic_order
lemma supp_b_empty[simp]: fixes b :: b and x::x shows"atom x ∉ supp b" by (induct b rule: b.induct, auto simp: pure_supp supp_at_base x_not_in_b_set)
lemma flip_b_id[simp]: fixes x::x and b::b shows"(x ↔ x') ∙ b = b" by(rule flip_fresh_fresh, auto simp add: fresh_def)
lemma flip_x_b_cancel[simp]: fixes x::x and y::x and b::b and bv::bv shows"(x ↔ y) ∙ b = b"and"(x ↔ y) ∙ bv = bv" using flip_b_id apply simp by (metis b.eq_iff(7) b.perm_simps(7) flip_b_id)
lemma flip_bv_x_cancel[simp]: fixes bv::bv and z::bv and x::x shows"(bv ↔ z) ∙ x = x"using flip_fresh_fresh[of bv x z] fresh_at_base by auto
lemma flip_bv_u_cancel[simp]: fixes bv::bv and z::bv and x::u shows"(bv ↔ z) ∙ x = x"using flip_fresh_fresh[of bv x z] fresh_at_base by auto
subsubsection‹Literals›
lemma supp_bitvec_empty: fixes bv::"bit list" shows"supp bv = {}" proof(induct bv) case Nil thenshow ?caseusing supp_Nil by auto next case (Cons a bv) thenshow ?caseusing supp_Cons bit.supp by (metis (mono_tags, opaque_lifting) bit.strong_exhaust l.supp(5) sup_bot.right_neutral) qed
lemma bitvec_pure[simp]: fixes bv::"bit list"and x::x shows"atom x ♯ bv"using fresh_def supp_bitvec_empty by auto
lemma supp_l_empty[simp]: fixes l:: l shows"supp (V_lit l) = {}" by(nominal_induct l rule: l.strong_induct,
auto simp add: l.strong_exhaust pure_supp v.fv_defs supp_bitvec_empty)
lemma type_l_nosupp[simp]: fixes x::x and l::l shows"atom x ∉ supp ({ z : b | [[z]v]ce == [[l]v]ce})" using supp_at_base supp_l_empty ce.supp(1) c.supp τ.supp by force
lemma flip_bitvec0: fixes x::"bit list" assumes"atom c ♯ (z, x, z')" shows"(z ↔ c) ∙ x = (z' ↔ c) ∙ x" proof - have"atom z ♯ x"and"atom z' ♯ x" using flip_fresh_fresh assms supp_bitvec_empty fresh_def by blast+ moreoverhave"atom c ♯ x"using supp_bitvec_empty fresh_def by auto ultimatelyshow ?thesis using assms flip_fresh_fresh by metis qed
lemma flip_bitvec: assumes"atom c ♯ (z, L_bitvec x, z')" shows"(z ↔ c) ∙ x = (z' ↔ c) ∙ x" proof - have"atom z ♯ x"and"atom z' ♯ x" using flip_fresh_fresh assms supp_bitvec_empty fresh_def by blast+ moreoverhave"atom c ♯ x"using supp_bitvec_empty fresh_def by auto ultimatelyshow ?thesis using assms flip_fresh_fresh by metis qed
lemma type_l_eq: shows"{ z : b | [[z]v]ce == [V_lit l]ce} = ({ z' : b | [[z']v]ce == [V_lit l]ce})" by(auto,nominal_induct l rule: l.strong_induct,auto, metis permute_pure, auto simp add: flip_bitvec)
lemma flip_l_eq: fixes x::l shows"(z ↔ c) ∙ x = (z' ↔ c) ∙ x" proof - have"atom z ♯ x"and"atom c ♯ x"and"atom z' ♯ x" using flip_fresh_fresh fresh_def supp_l_empty by fastforce+ thus ?thesis using flip_fresh_fresh by metis qed
lemma flip_l_eq1: fixes x::l assumes"(z ↔ c) ∙ x = (z' ↔ c) ∙ x'" shows"x' = x" proof - have"atom z ♯ x"and"atom c ♯ x'"and"atom c ♯ x"and"atom z' ♯ x'" using flip_fresh_fresh fresh_def supp_l_empty by fastforce+ thus ?thesis using flip_fresh_fresh assms by metis qed
subsubsection‹Types›
lemma flip_base_eq: fixes b::b and x::x and y::x shows"(x ↔ y) ∙ b = b" using b.fresh by (simp add: flip_fresh_fresh fresh_def)
text‹ Obtain an alpha-equivalent type where the bound variable is fresh in some term t › lemma has_fresh_z0: fixes t::"'b::fs" shows"∃z. atom z ♯ (c',t) ∧ ({z' : b | c' }) = ({ z : b | (z ↔ z' ) ∙ c' })" proof - obtain z::x where fr: "atom z ♯ (c',t)"using obtain_fresh by blast moreoverhence"({ z' : b | c' }) = ({ z : b | (z ↔ z') ∙ c' })" using τ.eq_iff Abs1_eq_iff by (metis flip_commute flip_fresh_fresh fresh_PairD(1)) ultimatelyshow ?thesis by fastforce qed
lemma has_fresh_z: fixes t::"'b::fs" shows"∃z b c. atom z ♯ t ∧ τ = { z : b | c }" proof - obtain z' and b and c' where teq: "τ = ({ z' : b | c' })"using τ.exhaust by blast obtain z::x where fr: "atom z ♯ (t,c')"using obtain_fresh by blast hence"({ z' : b | c' }) = ({ z : b | (z ↔ z') ∙ c' })"using τ.eq_iff Abs1_eq_iff
flip_commute flip_fresh_fresh fresh_PairD(1) by (metis fresh_PairD(2)) hence"atom z ♯ t ∧ τ = ({ z : b | (z ↔ z') ∙ c' })"using fr teq by force thus ?thesis using teq fr by fast qed
lemma obtain_fresh_z: fixes t::"'b::fs" obtains z and b and c where"atom z ♯ t ∧ τ = { z : b | c }" using has_fresh_z by blast
lemma has_fresh_z2: fixes t::"'b::fs" shows"∃z c. atom z ♯ t ∧ τ = { z : b_of τ | c }" proof - obtain z and b and c where"atom z ♯ t ∧ τ = { z : b | c }"using obtain_fresh_z by metis moreoverthenhave"b_of τ = b"using τ.eq_iff by simp ultimatelyshow ?thesis using obtain_fresh_z τ.eq_iff by auto qed
lemma obtain_fresh_z2: fixes t::"'b::fs" obtains z and c where"atom z ♯ t ∧ τ = { z : b_of τ | c }" using has_fresh_z2 by blast
subsubsection‹Values›
lemma u_notin_supp_v[simp]: fixes u::u and v::v shows"atom u ∉ supp v" proof(nominal_induct v rule: v.strong_induct) case (V_lit l) thenshow ?caseusing supp_l_empty by auto next case (V_var x) thenshow ?case by (simp add: supp_at_base) next case (V_pair v1 v2) thenshow ?caseby auto next case (V_cons tyid list v) thenshow ?caseusing pure_supp by auto next case (V_consp tyid list b v) thenshow ?caseusing pure_supp by auto qed
lemma u_fresh_xv[simp]: fixes u::u and x::x and v::v shows"atom u ♯ (x,v)" proof - have"atom u ♯ x"using fresh_def by fastforce moreoverhave"atom u ♯ v"using fresh_def u_notin_supp_v by metis ultimatelyshow ?thesis using fresh_prod2 by auto qed
text‹ Part of an effort to make the proofs across inductive cases more uniform by distilling
non-uniform parts into lemmas like this› lemma v_flip_eq: fixes v::v and va::v and x::x and c::x assumes"atom c ♯ (v, va)"and"atom c ♯ (x, xa, v, va)"and"(x ↔ c) ∙ v = (xa ↔ c) ∙va" shows"((v = V_lit l ⟶ (∃l'. va = V_lit l' ∧ (x ↔ c) ∙ l = (xa ↔ c) ∙ l'))) ∧ ((v = V_var y ⟶ (∃y'. va = V_var y' ∧ (x ↔ c) ∙ y = (xa ↔ c) ∙ y'))) ∧ ((v = V_pair vone vtwo ⟶ (∃v1' v2'. va = V_pair v1' v2' ∧ (x ↔ c) ∙ vone = (xa ↔c) ∙ v1' ∧ (x ↔ c) ∙ vtwo = (xa ↔ c) ∙ v2'))) ∧ ((v = V_cons tyid dc vone ⟶ (∃v1'. va = V_cons tyid dc v1'∧ (x ↔ c) ∙ vone = (xa↔ c) ∙ v1'))) ∧ ((v = V_consp tyid dc b vone ⟶ (∃v1'. va = V_consp tyid dc b v1'∧ (x ↔ c) ∙ vone = (xa ↔ c) ∙ v1')))" using assms proof(nominal_induct v rule:v.strong_induct) case (V_lit l) thenshow ?caseusing assms v.perm_simps
empty_iff flip_def fresh_def fresh_permute_iff supp_l_empty swap_fresh_fresh v.fresh by (metis permute_swap_cancel2 v.distinct) next case (V_var x) thenshow ?caseusing assms v.perm_simps
empty_iff flip_def fresh_def fresh_permute_iff supp_l_empty swap_fresh_fresh v.fresh by (metis permute_swap_cancel2 v.distinct) next case (V_pair v1 v2) have" (V_pair v1 v2 = V_pair vone vtwo ⟶ (∃v1' v2'. va = V_pair v1' v2' ∧ (x ↔ c)∙ vone = (xa ↔ c) ∙ v1' ∧ (x ↔ c) ∙ vtwo = (xa ↔ c) ∙ v2'))"proof assume"V_pair v1 v2= V_pair vone vtwo" thus"(∃v1' v2'. va = V_pair v1' v2' ∧ (x ↔ c) ∙ vone = (xa ↔ c) ∙ v1' ∧ (x ↔ c) ∙ vtwo = (xa ↔ c) ∙ v2')" using V_pair assms by (metis (no_types, opaque_lifting) flip_def permute_swap_cancel v.perm_simps(3)) qed thus ?caseusing V_pair by auto next case (V_cons tyid dc v1) have" (V_cons tyid dc v1 = V_cons tyid dc vone ⟶ (∃ v1'. va = V_cons tyid dc v1' ∧ (x ↔ c) ∙ vone = (xa ↔ c) ∙ v1'))"proof assume as: "V_cons tyid dc v1 = V_cons tyid dc vone" hence"(x ↔ c) ∙ (V_cons tyid dc vone) = V_cons tyid dc ((x ↔ c) ∙ vone)"proof - have"(x ↔ c) ∙ dc = dc"using pure_permute_id by metis moreoverhave"(x ↔ c) ∙ tyid = tyid"using pure_permute_id by metis ultimatelyshow ?thesis using v.perm_simps(4) by simp qed thenobtain v1' where"(xa ↔ c) ∙ va = V_cons tyid dc v1' ∧ (x ↔ c) ∙ vone = v1'"usingassms V_cons using as by fastforce hence" va = V_cons tyid dc ((xa ↔ c) ∙ v1') ∧ (x ↔ c) ∙ vone = v1'"using permute_flip_cancel empty_iff flip_def fresh_def supp_b_empty swap_fresh_fresh by (metis pure_fresh v.perm_simps(4))
thus"(∃v1'. va = V_cons tyid dc v1' ∧ (x ↔ c) ∙ vone = (xa ↔ c) ∙ v1')" using V_cons assms by simp qed thus ?caseusing V_cons by auto next case (V_consp tyid dc b v1) have" (V_consp tyid dc b v1 = V_consp tyid dc b vone ⟶ (∃ v1'. va = V_consp tyid dc b v1' ∧ (x ↔ c) ∙ vone = (xa ↔ c) ∙ v1'))"proof assume as: "V_consp tyid dc b v1 = V_consp tyid dc b vone" hence"(x ↔ c) ∙ (V_consp tyid dc b vone) = V_consp tyid dc b ((x ↔ c) ∙ vone)"proof - have"(x ↔ c) ∙ dc = dc"using pure_permute_id by metis moreoverhave"(x ↔ c) ∙ tyid = tyid"using pure_permute_id by metis ultimatelyshow ?thesis using v.perm_simps(4) by simp qed thenobtain v1' where"(xa ↔ c) ∙ va = V_consp tyid dc b v1' ∧ (x ↔ c) ∙ vone = v1'"using assms V_consp using as by fastforce hence" va = V_consp tyid dc b ((xa ↔ c) ∙ v1') ∧ (x ↔ c) ∙ vone = v1'"using permute_flip_cancel empty_iff flip_def fresh_def supp_b_empty swap_fresh_fresh
pure_fresh v.perm_simps by (metis (mono_tags, opaque_lifting)) thus"(∃v1'. va = V_consp tyid dc b v1' ∧ (x ↔ c) ∙ vone = (xa ↔ c) ∙ v1')" using V_consp assms by simp qed thus ?caseusing V_consp by auto qed
lemma flip_eq: fixes x::x and xa::x and s::"'a::fs"and sa::"'a::fs" assumes"(∀c. atom c ♯ (s, sa) ⟶ atom c ♯ (x, xa, s, sa) ⟶ (x ↔ c) ∙ s = (xa ↔ c) ∙ sa)"and"x ≠ xa" shows"(x ↔ xa) ∙ s = sa" proof - have" ([[atom x]]lst. s = [[atom xa]]lst. sa)"using assms Abs1_eq_iff_all by simp hence"(xa = x ∧ sa = s ∨ xa ≠ x ∧ sa = (xa ↔ x) ∙ s ∧ atom xa ♯ s)"using assms Abs1_eq_iff[of xa sa x s] by simp thus ?thesis using assms by (metis flip_commute) qed
lemma swap_v_supp: fixes v::v and d::x and z::x assumes"atom d ♯ v" shows"supp ((z ↔ d ) ∙ v) ⊆ supp v - { atom z } ∪ { atom d}" using assms proof(nominal_induct v rule:v.strong_induct) case (V_lit l) thenshow ?caseusing l.supp by (metis supp_l_empty empty_subsetI l.strong_exhaust pure_supp supp_eqvt v.supp) next case (V_var x) hence"d ≠ x"using fresh_def by fastforce thus ?caseapply(cases "z = x") using supp_at_base V_var ‹d≠x›by fastforce+ next case (V_cons tyid dc v) show ?caseusing v.supp(4) pure_supp using V_cons.hyps V_cons.prems fresh_def by auto next case (V_consp tyid dc b v) show ?caseusing v.supp(4) pure_supp using V_consp.hyps V_consp.prems fresh_def by auto qed(force+)
subsubsection‹Expressions›
lemma swap_e_supp: fixes e::e and d::x and z::x assumes"atom d ♯ e" shows"supp ((z ↔ d ) ∙ e) ⊆ supp e - { atom z } ∪ { atom d}" using assms proof(nominal_induct e rule:e.strong_induct) case (AE_val v) thenshow ?caseusing swap_v_supp by simp next case (AE_app f v) thenshow ?caseusing swap_v_supp by (simp add: pure_supp) next case (AE_appP b f v) hence df: "atom d ♯ v"using fresh_def e.supp by force have"supp ((z ↔ d ) ∙ (AE_appP b f v)) = supp (AE_appP b f ((z ↔ d ) ∙ v))"using e.supp by (metis b.eq_iff(3) b.perm_simps(3) e.perm_simps(3) flip_b_id) alsohave"... = supp b ∪ supp f ∪ supp ((z ↔ d ) ∙ v)"using e.supp by auto alsohave"... ⊆ supp b ∪ supp f ∪ supp v - { atom z } ∪ { atom d}"using swap_v_supp[OF df] pure_supp by auto finallyshow ?caseusing e.supp by auto next case (AE_op opp v1 v2) hence df: "atom d ♯ v1 ∧ atom d ♯ v2"using fresh_def e.supp by force have"((z ↔ d ) ∙ (AE_op opp v1 v2)) = AE_op opp ((z ↔ d ) ∙ v1) ((z ↔ d ) ∙ v2)"using
e.perm_simps flip_commute opp.perm_simps AE_op opp.strong_exhaust pure_supp by (metis (full_types))
hence"supp ((z ↔ d) ∙ AE_op opp v1 v2) = supp (AE_op opp ((z ↔ d) ∙v1) ((z ↔ d) ∙v2))"by simp alsohave"... = supp ((z ↔ d) ∙v1) ∪ supp ((z ↔ d) ∙v2)"using e.supp by (metis (mono_tags, opaque_lifting) opp.strong_exhaust opp.supp sup_bot.left_neutral) alsohave"... ⊆ (supp v1 - { atom z } ∪ { atom d}) ∪ (supp v2 - { atom z } ∪ { atom d})"using swap_v_supp AE_op df by blast finallyshow ?caseusing e.supp opp.supp by blast next case (AE_fst v) thenshow ?caseusing swap_v_supp by auto next case (AE_snd v) thenshow ?caseusing swap_v_supp by auto next case (AE_mvar u) thenshow ?caseusing
Diff_empty Diff_insert0 Un_upper1 atom_x_sort flip_def flip_fresh_fresh fresh_def set_eq_subset supp_eqvt swap_set_in_eq by (metis sort_of_atom_eq) next case (AE_len v) thenshow ?caseusing swap_v_supp by auto next case (AE_concat v1 v2) thenshow ?caseusing swap_v_supp by auto next case (AE_split v1 v2) thenshow ?caseusing swap_v_supp by auto qed
lemma swap_ce_supp: fixes e::ce and d::x and z::x assumes"atom d ♯ e" shows"supp ((z ↔ d ) ∙ e) ⊆ supp e - { atom z } ∪ { atom d}" using assms proof(nominal_induct e rule:ce.strong_induct) case (CE_val v) thenshow ?caseusing swap_v_supp ce.fresh ce.supp by simp next case (CE_op opp v1 v2) hence df: "atom d ♯ v1 ∧ atom d ♯ v2"using fresh_def e.supp by force have"((z ↔ d ) ∙ (CE_op opp v1 v2)) = CE_op opp ((z ↔ d ) ∙ v1) ((z ↔ d ) ∙ v2)"using
ce.perm_simps flip_commute opp.perm_simps CE_op opp.strong_exhaust x_fresh_b pure_supp by (metis (full_types))
hence"supp ((z ↔ d) ∙ CE_op opp v1 v2) = supp (CE_op opp ((z ↔ d) ∙v1) ((z ↔ d) ∙v2))"by simp alsohave"... = supp ((z ↔ d) ∙v1) ∪ supp ((z ↔ d) ∙v2)"using ce.supp by (metis (mono_tags, opaque_lifting) opp.strong_exhaust opp.supp sup_bot.left_neutral) alsohave"... ⊆ (supp v1 - { atom z } ∪ { atom d}) ∪ (supp v2 - { atom z } ∪ { atom d})"using swap_v_supp CE_op df by blast finallyshow ?caseusing ce.supp opp.supp by blast next case (CE_fst v) thenshow ?caseusing ce.supp ce.fresh swap_v_supp by auto next case (CE_snd v) thenshow ?caseusing ce.supp ce.fresh swap_v_supp by auto next case (CE_len v) thenshow ?caseusing ce.supp ce.fresh swap_v_supp by auto next case (CE_concat v1 v2) thenshow ?caseusing ce.supp ce.fresh swap_v_supp ce.perm_simps proof - have"∀x v xa. ¬ atom (x::x) ♯ (v::v) ∨ supp ((xa ↔ x) ∙ v) ⊆ supp v - {atom xa} ∪ {atom x}" by (meson swap_v_supp) (* 0.0 ms *) thenshow ?thesis using CE_concat ce.supp by auto qed qed
lemma swap_c_supp: fixes c::c and d::x and z::x assumes"atom d ♯ c" shows"supp ((z ↔ d ) ∙ c) ⊆ supp c - { atom z } ∪ { atom d}" using assms proof(nominal_induct c rule:c.strong_induct) case (C_eq e1 e2) thenshow ?caseusing swap_ce_supp by auto qed(auto+)
lemma type_e_eq: assumes"atom z ♯ e"and"atom z' ♯ e" shows"{ z : b | [[z]v]ce == e } = ({ z' : b | [[z']v]ce == e })" by (auto,metis (full_types) assms(1) assms(2) flip_fresh_fresh fresh_PairD(1) fresh_PairD(2))
lemma type_e_eq2: assumes"atom z ♯ e"and"atom z' ♯ e"and"b=b'" shows"{ z : b | [[z]v]ce == e } = ({ z' : b' | [[z']v]ce == e })" using assms type_e_eq by fast
lemma e_flip_eq: fixes e::e and ea::e assumes"atom c ♯ (e, ea)"and"atom c ♯ (x, xa, e, ea)"and"(x ↔ c) ∙ e = (xa ↔ c) ∙ea" shows"(e = AE_val w ⟶ (∃w'. ea = AE_val w' ∧ (x ↔ c) ∙ w = (xa ↔ c) ∙ w')) ∨ (e = AE_op opp v1 v2 ⟶ (∃v1' v2'. ea = AS_op opp v1' v2' ∧ (x ↔ c) ∙ v1 = (xa ↔ c)∙ v1') ∧ (x ↔ c) ∙ v2 = (xa ↔ c) ∙ v2') ∨ (e = AE_fst v ⟶ (∃v'. ea = AE_fst v' ∧ (x ↔ c) ∙ v = (xa ↔ c) ∙ v')) ∨ (e = AE_snd v ⟶ (∃v'. ea = AE_snd v' ∧ (x ↔ c) ∙ v = (xa ↔ c) ∙ v')) ∨ (e = AE_len v ⟶ (∃v'. ea = AE_len v' ∧ (x ↔ c) ∙ v = (xa ↔ c) ∙ v')) ∨ (e = AE_concat v1 v2 ⟶ (∃v1' v2'. ea = AS_concat v1' v2' ∧ (x ↔ c) ∙ v1 = (xa ↔ c)∙ v1') ∧ (x ↔ c) ∙ v2 = (xa ↔ c) ∙ v2') ∨ (e = AE_app f v ⟶ (∃v'. ea = AE_app f v' ∧ (x ↔ c) ∙ v = (xa ↔ c) ∙ v'))" by (metis assms e.perm_simps permute_flip_cancel2)
lemma fresh_opp_all: fixes opp::opp shows"z ♯ opp" using e.fresh opp.exhaust opp.fresh by metis
lemma fresh_e_opp_all: shows"(z ♯ v1 ∧ z ♯ v2) = z ♯ AE_op opp v1 v2" using e.fresh opp.exhaust opp.fresh fresh_opp_all by simp
lemma fresh_e_opp: fixes z::x assumes"atom z ♯ v1 ∧ atom z ♯ v2" shows"atom z ♯ AE_op opp v1 v2" using e.fresh opp.exhaust opp.fresh opp.supp by (metis assms)
subsubsection‹Statements›
lemma branch_s_flip_eq: fixes v::v and va::v assumes"atom c ♯ (v, va)"and"atom c ♯ (x, xa, v, va)"and"(x ↔ c) ∙ s = (xa ↔ c) ∙sa" shows"(s = AS_val w ⟶ (∃w'. sa = AS_val w' ∧ (x ↔ c) ∙ w = (xa ↔ c) ∙ w')) ∨ (s = AS_seq s1 s2 ⟶ (∃s1' s2'. sa = AS_seq s1' s2' ∧ (x ↔ c) ∙ s1 = (xa ↔ c) ∙ s1') ∧ (x ↔ c) ∙ s2 = (xa ↔ c) ∙ s2') ∨ (s = AS_if v s1 s2 ⟶ (∃v' s1' s2'. sa = AS_if seq s1' s2' ∧ (x ↔ c) ∙ s1 = (xa ↔ c) ∙ s1') ∧ (x ↔ c) ∙ s2 = (xa ↔ c) ∙ s2' ∧ (x ↔ c) ∙ c = (xa ↔ c) ∙ v')" by (metis assms s_branch_s_branch_list.perm_simps permute_flip_cancel2)
lemma Γ_induct [case_names GNil GCons] : "P GNil ==> (∧x b c Γ'. P Γ' ==> P ((x,b,c) #\<Gamma> Γ')) ==> P Γ" proof(induct Γ rule:Γ.induct) case GNil thenshow ?caseby auto next case (GCons x1 x2) thenobtain x and b and c where"x1=(x,b,c)"using prod_cases3 by blast thenshow ?caseusing GCons by presburger qed
instantiation Δ :: pt begin
primrec permute_Δ where
DNil_eqvt: "p ∙ DNil = DNil"
| DCons_eqvt: "p ∙ (x #\<Delta> xs) = p ∙ x #\<Delta> p ∙ (xs::Δ)"
instanceby standard (induct_tac [!] x, simp_all) end
lemmas [eqvt] = permute_Δ.simps
lemma Δ_induct [case_names DNil DCons] : "P DNil ==> (∧u t Δ'. P Δ' ==> P ((u,t) #\<Delta> Δ')) ==> P Δ" proof(induct Δ rule: Δ.induct) case DNil thenshow ?caseby auto next case (DCons x1 x2) thenobtain u and t where"x1=(u,t)"by fastforce thenshow ?caseusing DCons by presburger qed
lemma Φ_induct [case_names PNil PConsNone PConsSome] : "P [] ==> (∧f x b c τ s' Φ'. P Φ' ==> P ((AF_fundef f (AF_fun_typ_none (AF_fun_typ x b c τ s'))) # Φ')) ==> (∧f bv x b c τ s' Φ'. P Φ' ==> P ((AF_fundef f (AF_fun_typ_some bv (AF_fun_typ x b c τ s'))) # Φ')) ==> P Φ" proof(induct Φ rule: list.induct) case Nil thenshow ?caseby auto next case (Cons x1 x2) thenobtain f and t where ft: "x1 = (AF_fundef f t)" by (meson fun_def.exhaust) thenshow ?caseproof(nominal_induct t rule:fun_typ_q.strong_induct) case (AF_fun_typ_some bv ft) thenshow ?caseusing Cons ft by (metis fun_typ.exhaust) next case (AF_fun_typ_none ft) thenshow ?caseusing Cons ft by (metis fun_typ.exhaust) qed qed
lemma Θ_induct [case_names TNil AF_typedef AF_typedef_poly] : "P [] ==> (∧tid dclist Θ'. P Θ' ==> P ((AF_typedef tid dclist) # Θ')) ==> (∧tid bv dclist Θ'. P Θ' ==> P ((AF_typedef_poly tid bv dclist ) # Θ')) ==> P Θ" proof(induct Θ rule: list.induct) case Nil thenshow ?caseby auto next case (Cons td T) show ?caseby(cases td rule: type_def.exhaust, (simp add: Cons)+) qed
instantiation Γ :: pt begin
primrec permute_Γ where
GNil_eqvt: "p ∙ GNil = GNil"
| GCons_eqvt: "p ∙ (x #\<Gamma> xs) = p ∙ x #\<Gamma> p ∙ (xs::Γ)"
instanceby standard (induct_tac [!] x, simp_all) end
lemmas [eqvt] = permute_Γ.simps
lemma G_cons_eqvt[simp]: fixes Γ::Γ shows"p ∙ ((x,b,c) #\<Gamma> Γ) = ((p ∙ x, p ∙ b , p ∙ c) #\<Gamma> (p ∙ Γ ))" (is"?A = ?B" ) using Cons_eqvt triple_eqvt supp_b_empty by simp
lemma G_cons_flip[simp]: fixes x::x and Γ::Γ shows"(x↔x') ∙ ((x'',b,c) #\<Gamma> Γ) = (((x↔x') ∙ x'', b , (x↔x') ∙ c) #\<Gamma> ((x↔x') ∙ Γ ))" using Cons_eqvt triple_eqvt supp_b_empty by auto
lemma G_cons_flip_fresh[simp]: fixes x::x and Γ::Γ assumes"atom x ♯ (c,Γ)"and"atom x' ♯ (c,Γ)" shows"(x↔x') ∙ ((x',b,c) #\<Gamma> Γ) = ((x, b , c) #\<Gamma> Γ )" using G_cons_flip flip_fresh_fresh assms by force
lemma G_cons_flip_fresh2[simp]: fixes x::x and Γ::Γ assumes"atom x ♯ (c,Γ)"and"atom x' ♯ (c,Γ)" shows"(x↔x') ∙ ((x,b,c) #\<Gamma> Γ) = ((x', b , c) #\<Gamma> Γ )" using G_cons_flip flip_fresh_fresh assms by force
lemma G_cons_flip_fresh3[simp]: fixes x::x and Γ::Γ assumes"atom x ♯ Γ"and"atom x' ♯ Γ" shows"(x↔x') ∙ ((x',b,c) #\<Gamma> Γ) = ((x, b , (x↔x') ∙ c) #\<Gamma> Γ )" using G_cons_flip flip_fresh_fresh assms by force
lemma neq_GNil_conv: "(xs ≠ GNil) = (∃y ys. xs = y #\<Gamma> ys)" by (induct xs) auto
nominal_function append_g :: "Γ ==> Γ ==> Γ" (infixr‹@›65) where "append_g GNil g = g"
| "append_g (xbc #\<Gamma> g1) g2 = (xbc #\<Gamma> (g1@g2))" apply (auto,simp add: eqvt_def append_g_graph_aux_def ) using neq_GNil_conv surj_pair by metis
nominal_termination (eqvt) by lexicographic_order
nominal_function dom :: "Γ ==> x set"where "dom Γ = (fst` (toSet Γ))" apply auto unfolding eqvt_def dom_graph_aux_def lfp_eqvt toSet.eqvt by simp
nominal_termination (eqvt) by lexicographic_order
text‹ Use of this is sometimes mixed in with use of freshness and support for the context however it makes it clear
for immutable variables, the context is `self-supporting'›
nominal_function atom_dom :: "Γ ==> atom set"where "atom_dom Γ = atom`(dom Γ)" apply auto unfolding eqvt_def atom_dom_graph_aux_def lfp_eqvt toSet.eqvt by simp
nominal_termination (eqvt) by lexicographic_order
lemma supp_Γ: "supp Γ = supp (toSet Γ)" proof(induct Γ rule: Γ_induct) case GNil thenshow ?caseusing supp_GNil toSet.simps by (simp add: supp_set_empty) next case (GCons x b c Γ') thenshow ?caseusing supp_GCons toSet.simps finite_Γ supp_of_finite_union using supp_of_finite_insert by fastforce qed
lemma supp_of_subset: fixes G::"('a::fs set)" assumes"finite G"and"finite G'"and"G ⊆ G'" shows"supp G ⊆ supp G'" using supp_of_finite_sets assms by (metis subset_Un_eq supp_of_finite_union)
lemma supp_weakening: assumes"toSet G ⊆ toSet G'" shows"supp G ⊆ supp G'" using supp_Γ finite_Γ by (simp add: supp_of_subset assms)
lemma fresh_weakening[ms_fresh]: assumes"toSet G ⊆ toSet G'"and"x ♯ G'" shows"x ♯ G" proof(rule ccontr) assume"¬ x ♯ G" hence"x ∈ supp G"using fresh_def by auto hence"x ∈ supp G'"using supp_weakening assms by auto thus False using fresh_def assms by auto qed
lemma fresh_gamma_append: fixes xs::Γ shows"a ♯ (xs @ ys) ⟷ a ♯ xs ∧ a ♯ ys" by (induct xs, simp_all add: fresh_GNil fresh_GCons)
lemma supp_triple[simp]: shows"supp (x, y, z) = supp x ∪ supp y ∪ supp z" proof - have"supp (x,y,z) = supp (x,(y,z))"by auto hence"supp (x,y,z) = supp x ∪ (supp y ∪ supp z)"using supp_Pair by metis thus ?thesis by auto qed
lemma fresh_in_g[simp]: fixes Γ::Γ and x'::x shows"atom x' ♯ Γ' @ (x, b0, c0) #\<Gamma> Γ = (atom x' ∉ supp Γ' ∪ supp x ∪ supp b0∪ supp c0 ∪ supp Γ)" proof - have"atom x' ♯ Γ' @ (x, b0, c0) #\<Gamma> Γ = (atom x' ∉ supp (Γ' @((x,b0,c0) #\<Gamma> Γ)))" using fresh_def by auto alsohave"... = (atom x' ∉ supp Γ' ∪ supp ((x,b0,c0) #\<Gamma> Γ))"using supp_append_g by fast alsohave"... = (atom x' ∉ supp Γ' ∪ supp x ∪ supp b0 ∪ supp c0 ∪ supp Γ)"using supp_GCons supp_append_g supp_triple by auto finallyshow ?thesis by fast qed
lemma fresh_suffix[ms_fresh]: fixes Γ::Γ assumes"atom x ♯ Γ'@Γ" shows"atom x ♯ Γ" using assms by(induct Γ' rule: Γ_induct, auto simp add: append_g.simps fresh_GCons)
lemma not_GCons_self [simp]: fixes xs::Γ shows"xs ≠ x #\<Gamma> xs" by (induct xs) auto
lemma fresh_restrict: fixes y::x and Γ::Γ assumes"atom y ♯ (Γ' @ (x, b, c) #\<Gamma> Γ)" shows"atom y ♯ (Γ'@Γ)" using assms by(induct Γ' rule: Γ_induct, auto simp add:fresh_GCons fresh_GNil )
lemma fresh_dom_free: assumes"atom x ♯ Γ" shows"(x,b,c) ∉ toSet Γ" using assms proof(induct Γ rule: Γ_induct) case GNil thenshow ?caseby auto next case (GCons x' b' c' Γ') hence"x≠x'"using fresh_def fresh_GCons fresh_Pair supp_at_base by blast moreoverhave"atom x ♯ Γ'"using fresh_GCons GCons by auto ultimatelyshow ?caseusing toSet.simps GCons by auto qed
lemma Γ_set_intros: "x ∈ toSet ( x #\<Gamma> xs)"and"y ∈ toSet xs ==> y ∈ toSet (x #\<Gamma> xs)" by simp+
lemma fresh_dom_free2: assumes"atom x ∉ atom_dom Γ" shows"(x,b,c) ∉ toSet Γ" using assms proof(induct Γ rule: Γ_induct) case GNil thenshow ?caseby auto next case (GCons x' b' c' Γ') hence"x≠x'"using fresh_def fresh_GCons fresh_Pair supp_at_base by auto moreoverhave"atom x ∉ atom_dom Γ'"using fresh_GCons GCons by auto ultimatelyshow ?caseusing toSet.simps GCons by auto qed
subsection‹Mutable Variable Context Lemmas›
lemma supp_DNil: shows"supp DNil = {}" by (simp add: supp_def)
lemma supp_DCons: fixes xs::Δ shows"supp (x #\<Delta> xs) = supp x ∪ supp xs" by (simp add: supp_def Collect_imp_eq Collect_neg_eq)
lemma fresh_DNil[ms_fresh]: shows"a ♯ DNil" by (simp add: fresh_def supp_DNil)
lemma fresh_DCons[ms_fresh]: fixes xs::Δ shows"a ♯ (x #\<Delta> xs) ⟷ a ♯ x ∧ a ♯ xs" by (simp add: fresh_def supp_DCons)
nominal_function lookup :: "Γ ==> x ==> (b*c) option"where "lookup GNil x = None"
| "lookup ((x,b,c)#\<Gamma>G) y = (if x=y then Some (b,c) else lookup G y)" by (auto,simp add: eqvt_def lookup_graph_aux_def, metis neq_GNil_conv surj_pair)
nominal_termination (eqvt) by lexicographic_order
nominal_function replace_in_g :: "Γ ==> x ==> c ==> Γ" (‹_[_⟼_]› [1000,0,0] 200) where "replace_in_g GNil _ _ = GNil"
| "replace_in_g ((x,b,c)#\<Gamma>G) x' c' = (if x=x' then ((x,b,c')#\<Gamma>G) else (x,b,c)#\<Gamma>(replace_in_g G x' c'))" apply(auto,simp add: eqvt_def replace_in_g_graph_aux_def) using surj_pair Γ.exhaust by metis
nominal_termination (eqvt) by lexicographic_order
text‹ Functions for looking up data-constructors in the Pi context ›
nominal_function lookup_fun :: "Φ ==> f ==> fun_def option"where "lookup_fun [] g = None"
| "lookup_fun ((AF_fundef f ft)#Π) g = (if (f=g) then Some (AF_fundef f ft) else lookup_fun Π g)" apply(auto,simp add: eqvt_def lookup_fun_graph_aux_def ) by (metis fun_def.exhaust neq_Nil_conv)
nominal_termination (eqvt) by lexicographic_order
nominal_function lookup_td :: "Θ ==> string ==> type_def option"where "lookup_td [] g = None"
| "lookup_td ((AF_typedef s lst ) # (Θ::Θ)) g = (if (s = g) then Some (AF_typedef s lst ) else lookup_td Θ g)"
| "lookup_td ((AF_typedef_poly s bv lst ) # (Θ::Θ)) g = (if (s = g) then Some (AF_typedef_poly s bv lst ) else lookup_td Θ g)" apply(auto,simp add: eqvt_def lookup_td_graph_aux_def ) by (metis type_def.exhaust neq_Nil_conv)
nominal_termination (eqvt) by lexicographic_order
nominal_function name_of_type ::"type_def ==> f "where "name_of_type (AF_typedef f _ ) = f"
| "name_of_type (AF_typedef_poly f _ _) = f" apply(auto,simp add: eqvt_def name_of_type_graph_aux_def ) using type_def.exhaust by blast
nominal_termination (eqvt) by lexicographic_order
nominal_function name_of_fun ::"fun_def ==> f "where "name_of_fun (AF_fundef f ft) = f" apply(auto,simp add: eqvt_def name_of_fun_graph_aux_def ) using fun_def.exhaust by blast
nominal_termination (eqvt) by lexicographic_order
nominal_function remove2 :: "'a::pt ==> 'a list ==> 'a list"where "remove2 x [] = []" | "remove2 x (y # xs) = (if x = y then xs else y # remove2 x xs)" by (simp add: eqvt_def remove2_graph_aux_def,auto+,meson list.exhaust)
nominal_termination (eqvt) by lexicographic_order
lemma eqvt_triple: fixes y::"'a::at"and ya::"'a::at"and xa::"'c::at"and va::"'d::fs"and s::s and sa::s and f::"s*'c*'d ==> s" assumes"atom y ♯ (xa, va)"and"atom ya ♯ (xa, va)"and "∀c. atom c ♯ (s, sa) ⟶ atom c ♯ (y, ya, s, sa) ⟶ (y ↔ c) ∙ s = (ya ↔ c) ∙ sa" and"eqvt_at f (s,xa,va)"and"eqvt_at f (sa,xa,va)"and "atom c ♯ (s, va, xa, sa)"and"atom c ♯ (y, ya, f (s, xa, va), f (sa, xa, va))" shows"(y ↔ c) ∙ f (s, xa, va) = (ya ↔ c) ∙ f (sa, xa, va)" proof - have" (y ↔ c) ∙ f (s, xa, va) = f ( (y ↔ c) ∙ (s,xa,va))"using assms eqvt_at_def by metis alsohave"... = f ( (y ↔ c) ∙ s, (y ↔ c) ∙ xa ,(y ↔ c) ∙ va)"by auto alsohave"... = f ( (ya ↔ c) ∙ sa, (ya ↔ c) ∙ xa ,(ya ↔ c) ∙ va)"proof - have" (y ↔ c) ∙ s = (ya ↔ c) ∙ sa"using assms Abs1_eq_iff_all by auto moreoverhave"((y ↔ c) ∙ xa) = ((ya ↔ c) ∙ xa)"using assms flip_fresh_fresh fresh_prodN by metis moreoverhave"((y ↔ c) ∙ va) = ((ya ↔ c) ∙ va)"using assms flip_fresh_fresh fresh_prodN by metis ultimatelyshow ?thesis by auto qed alsohave"... = f ( (ya ↔ c) ∙ (sa,xa,va))"by auto finallyshow ?thesis using assms eqvt_at_def by metis qed
section‹Functions for bit list/vectors›
inductive split :: "int ==> bit list ==> bit list * bit list ==> bool"where "split 0 xs ([], xs)"
| "split m xs (ys,zs) ==> split (m+1) (x#xs) ((x # ys), zs)" equivariance split nominal_inductive split .
lemma split_concat: assumes"split n v (v1,v2)" shows"v = append v1 v2" using assms proof(induct "(v1,v2)" arbitrary: v1 v2 rule: split.inducts) case1 thenshow ?caseby auto next case (2 m xs ys zs x) thenshow ?caseby auto qed
lemma split_n: assumes"split n v (v1,v2)" shows"0 ≤ n ∧ n ≤ int (length v)" using assms proof(induct rule: split.inducts) case (1 xs) thenshow ?caseby auto next case (2 m xs ys zs x) thenshow ?caseby auto qed
lemma split_length: assumes"split n v (v1,v2)" shows"n = int (length v1)" using assms proof(induct "(v1,v2)" arbitrary: v1 v2 rule: split.inducts) case (1 xs) thenshow ?caseby auto next case (2 m xs ys zs x) thenshow ?caseby auto qed
lemma obtain_split: assumes"0 ≤ n"and"n ≤ int (length bv)" shows"∃ bv1 bv2. split n bv (bv1 , bv2)" using assms proof(induct bv arbitrary: n) case Nil thenshow ?caseusing split.introsby auto next case (Cons b bv) show ?caseproof(cases "n = 0") case True thenshow ?thesis using split.introsby auto next case False thenobtain m where m:"n=m+1"using Cons by (metis add.commute add_minus_cancel) moreoverhave"0 ≤ m"using False m Cons by linarith thenobtain bv1 and bv2 where"split m bv (bv1 , bv2)"using Cons m by force hence"split n (b # bv) ((b#bv1), bv2)"using m split.introsby auto thenshow ?thesis by auto qed qed
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.