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
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-10)
¤
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.