lemma fresh_var_existence: assumes"finite (vs :: var set)" obtains x where"(x, α) ∉ vs" using ex_new_if_finite[OF infinite_UNIV_nat] proof - from assms obtain x where"x ∉ var_name ` vs" using ex_new_if_finite[OF infinite_UNIV_nat] by fastforce with that show ?thesis by force qed
lemma fresh_var_name_list_existence: assumes"finite (ns :: nat set)" obtains ns' where"length ns' = n"and"distinct ns'"and"lset ns' ∩ ns = {}" using assms proof (induction n arbitrary: thesis) case0 thenshow ?case by simp next case (Suc n) from assms obtain ns' where"length ns' = n"and"distinct ns'"and"lset ns' ∩ ns = {}" using Suc.IH by blast moreoverfrom assms obtain n' where"n' ∉ lset ns' ∪ ns" using ex_new_if_finite[OF infinite_UNIV_nat] by blast ultimately have"length (n' # ns') = Suc n"and"distinct (n' # ns')"and"lset (n' # ns') ∩ ns = {}" by simp_all with Suc.prems(1) show ?case by blast qed
text‹Generalized application. We define ‹⏹\Q\⋆ A [B1, B2, …, Bn]› as ‹A ⏹ B1⏹ B2⏹⋯⏹ Bn›:›
definition generalized_app :: "form → form list → form" (‹⏹\Q\⋆ _ _› [241, 241] 241) where
[simp]: "⏹\<Q>\<star> A Bs = foldl (⏹) A Bs"
text‹Generalized abstraction. We define ‹λ\Q\⋆ [x1, …, xn] A› as ‹λx1. ⋯ λxn. A›:›
definition generalized_abs :: "var list → form → form" (‹λ\Q\⋆ _ _› [141, 141] 141) where
[simp]: "λ\<Q>\<star> vs A = foldr (λ(x, α) B. λx<alpha>. B) vs A"
fun form_size :: "form → nat"where "form_size (x<alpha>) = 1"
| "form_size ({c}<alpha>) = 1"
| "form_size (A ⏹ B) = Suc (form_size A + form_size B)"
| "form_size (λx<alpha>. A) = Suc (form_size A)"
fun form_depth :: "form → nat"where "form_depth (x<alpha>) = 0"
| "form_depth ({c}<alpha>) = 0"
| "form_depth (A ⏹ B) = Suc (max (form_depth A) (form_depth B))"
| "form_depth (λx<alpha>. A) = Suc (form_depth A)"
subsection‹Subformulas›
fun subforms :: "form → form set"where "subforms (x<alpha>) = {}"
| "subforms ({c}<alpha>) = {}"
| "subforms (A ⏹ B) = {A, B}"
| "subforms (λx<alpha>. A) = {A}"
datatype direction = Left (‹«›) | Right (‹¬›) type_synonym position = "direction list"
fun positions :: "form → position set"where "positions (x<alpha>) = {[]}"
| "positions ({c}<alpha>) = {[]}"
| "positions (A ⏹ B) = {[]} ∪ {« # p | p. p ∈ positions A} ∪ {¬ # p | p. p ∈ positions B}"
| "positions (λx<alpha>. A) = {[]} ∪ {« # p | p. p ∈ positions A}"
lemma empty_is_position [simp]: shows"[] ∈ positions A" by (cases A rule: positions.cases) simp_all
fun subform_at :: "form → position ⇀ form"where "subform_at A [] = Some A"
| "subform_at (A ⏹ B) (« # p) = subform_at A p"
| "subform_at (A ⏹ B) (¬ # p) = subform_at B p"
| "subform_at (λx<alpha>. A) (« # p) = subform_at A p"
| "subform_at _ _ = None"
fun is_subform_at :: "form → position → form → bool" (‹(_ ⪯/ _)› [51,0,51] 50) where "is_subform_at A [] A' = (A = A')"
| "is_subform_at C (« # p) (A ⏹ B) = is_subform_at C p A"
| "is_subform_at C (¬ # p) (A ⏹ B) = is_subform_at C p B"
| "is_subform_at C (« # p) (λx<alpha>. A) = is_subform_at C p A"
| "is_subform_at _ _ _ = False"
lemma is_subform_at_alt_def: shows"A' ⪯ A = (case subform_at A p of Some B → B = A' | None → False)" by (induction A' p A rule: is_subform_at.induct) auto
lemma superform_existence: assumes"B ⪯ @ [d] C" obtains A where"B ⪯d] A"and"A ⪯ C" using assms by (induction B p C rule: is_subform_at.induct) auto
lemma subform_at_subforms_con: assumes"{c}<alpha>⪯ C" shows"∄A. A ⪯ @ [d] C" using assms by (induction"{c}<alpha>" p C rule: is_subform_at.induct) auto
lemma subform_at_subforms_var: assumes"x<alpha>⪯ C" shows"∄A. A ⪯ @ [d] C" using assms by (induction"x<alpha>" p C rule: is_subform_at.induct) auto
lemma subform_at_subforms_app: assumes"A ⏹ B ⪯ C" shows"A ⪯ @ [«] C"and"B ⪯ @ [¬] C" using assms by (induction"A ⏹ B" p C rule: is_subform_at.induct) auto
lemma subform_at_subforms_abs: assumes"λx<alpha>. A ⪯ C" shows"A ⪯ @ [«] C" using assms by (induction"λx<alpha>. A" p C rule: is_subform_at.induct) auto
lemma is_subform_implies_in_positions: assumes"B ⪯ A" shows"p ∈ positions A" using assms by (induction rule: is_subform_at.induct) simp_all
lemma subform_size_decrease: assumes"A ⪯ B"and"p ≠ []" shows"form_size A < form_size B" using assms by (induction A p B rule: is_subform_at.induct) force+
lemma strict_subform_is_not_form: assumes"p ≠ []"and"A' ⪯ A" shows"A' ≠ A" using assms and subform_size_decrease by blast
lemma no_right_subform_of_abs: shows"∄B. B ⪯<guillemotright> # p λx<alpha>. A" by simp
lemma subforms_from_var: assumes"A ⪯ x<alpha>" shows"A = x<alpha>"and"p = []" using assms by (auto elim: is_subform_at.elims)
lemma subforms_from_con: assumes"A ⪯{c}<alpha>" shows"A = {c}<alpha>"and"p = []" using assms by (auto elim: is_subform_at.elims)
lemma subforms_from_app: assumes"A ⪯ B ⏹ C" shows" (A = B ⏹ C ∧ p = []) ∨ (A ≠ B ⏹ C ∧ (∃p' ∈ positions B. p = « # p' ∧ A ⪯' B) ∨ (∃p' ∈ positions C. p = ¬ # p' ∧ A ⪯' C))" using assms and strict_subform_is_not_form by (auto simp add: is_subform_implies_in_positions elim: is_subform_at.elims)
lemma subforms_from_abs: assumes"A ⪯ λx<alpha>. B" shows"(A = λx<alpha>. B ∧ p = []) ∨ (A ≠ λx<alpha>. B ∧ (∃p' ∈ positions B. p = « # p' ∧ A ⪯' B))" using assms and strict_subform_is_not_form by (auto simp add: is_subform_implies_in_positions elim: is_subform_at.elims)
lemma leftmost_subform_in_generalized_app: shows"B ⪯ (length As) «⏹\<Q>\<star> B As" by (induction As arbitrary: B) (simp_all, metis replicate_append_same subform_at_subforms_app(1))
lemma self_subform_is_at_top: assumes"A ⪯ A" shows"p = []" using assms and strict_subform_is_not_form by blast
lemma at_top_is_self_subform: assumes"A ⪯] B" shows"A = B" using assms by (auto elim: is_subform_at.elims)
lemma is_subform_at_uniqueness: assumes"B ⪯ A"and"C ⪯ A" shows"B = C" using assms by (induction A arbitrary: p B C) (auto elim: is_subform_at.elims)
lemma is_subform_at_existence: assumes"p ∈ positions A" obtains B where"B ⪯ A" using assms by (induction A arbitrary: p) (auto elim: is_subform_at.elims, blast+)
lemma is_subform_at_transitivity: assumes"A ⪯1 B"and"B ⪯2 C" shows"A ⪯2 @ p1 C" using assms by (induction B p2 C arbitrary: A p1 rule: is_subform_at.induct) simp_all
lemma subform_nesting: assumes"strict_prefix p' p" and"B ⪯' A" and"C ⪯ A" shows"C ⪯ (length p') p B" proof - from assms(1) have"p ≠ []" using strict_prefix_simps(1) by blast with assms(1,3) show ?thesis proof (induction p arbitrary: C rule: rev_induct) case Nil thenshow ?case by blast next case (snoc d p'') thenshow ?case proof (cases "p'' = p'") case True obtain A' where"C ⪯d] A'"and"A' ⪯' A" by (fact superform_existence[OF snoc.prems(2)[unfolded True]]) from‹A' ⪯' A›and assms(2) have"A' = B" by (rule is_subform_at_uniqueness) with‹C ⪯d] A'›have"C ⪯d] B" by (simp only:) with True show ?thesis by auto next case False with snoc.prems(1) have"strict_prefix p' p''" using prefix_order.dual_order.strict_implies_order by fastforce thenhave"p'' ≠ []" by force moreoverfrom snoc.prems(2) obtain A' where"C ⪯d] A'"and"A' ⪯'' A" using superform_existence by blast ultimatelyhave"A' ⪯ (length p') p'' B" using snoc.IH and‹strict_prefix p' p''›by blast with‹C ⪯d] A'›and snoc.prems(1) show ?thesis using is_subform_at_transitivity and prefix_length_less by fastforce qed qed qed
lemma loop_subform_impossibility: assumes"B ⪯ A" and"strict_prefix p' p" shows"¬ B ⪯' A" using assms and prefix_length_less and self_subform_is_at_top and subform_nesting by fastforce
lemma nested_subform_size_decreases: assumes"strict_prefix p' p" and"B ⪯' A" and"C ⪯ A" shows"form_size C < form_size B" proof - from assms(1) have"p ≠ []" by force have"C ⪯ (length p') p B" by (fact subform_nesting[OF assms]) moreoverhave"drop (length p') p ≠ []" using prefix_length_less[OF assms(1)] by force ultimatelyshow ?thesis using subform_size_decrease by simp qed
definition is_subform :: "form → form → bool" (infix‹⪯›50) where
[simp]: "A ⪯ B = (∃p. A ⪯ B)"
instantiation form :: ord begin
definition "A ≤ B ⟷ A ⪯ B"
definition "A < B ⟷ A ⪯ B ∧ A ≠ B"
instance ..
end
instance form :: preorder proof (standard, unfold less_eq_form_def less_form_def) fix A show"A ⪯ A" unfolding is_subform_def using is_subform_at.simps(1) by blast next fix A and B and C assume"A ⪯ B"and"B ⪯ C" thenshow"A ⪯ C" unfolding is_subform_def using is_subform_at_transitivity by blast next fix A and B show"A ⪯ B ∧ A ≠ B ⟷ A ⪯ B ∧¬ B ⪯ A" unfolding is_subform_def by (metis is_subform_at.simps(1) not_less_iff_gr_or_eq subform_size_decrease) qed
lemma position_subform_existence_equivalence: shows"p ∈ positions A ⟷ (∃A'. A' ⪯ A)" by (meson is_subform_at_existence is_subform_implies_in_positions)
lemma position_prefix_is_position: assumes"p ∈ positions A"and"prefix p' p" shows"p' ∈ positions A" using assms proof (induction p rule: rev_induct) case Nil thenshow ?case by simp next case (snoc d p'') from snoc.prems(1) have"p'' ∈ positions A" by (meson position_subform_existence_equivalence superform_existence) with snoc.prems(1,2) show ?case using snoc.IH by fastforce qed
subsection‹Free and bound variables›
consts vars :: "'a → var set"
overloading "vars_form"≡"vars :: form → var set" "vars_form_set"≡"vars :: form set → var set"(* abuse of notation *) begin
fun vars_form :: "form → var set"where "vars_form (x<alpha>) = {(x, α)}"
| "vars_form ({c}<alpha>) = {}"
| "vars_form (A ⏹ B) = vars_form A ∪ vars_form B"
| "vars_form (λx<alpha>. A) = vars_form A ∪ {(x, α)}"
fun vars_form_set :: "form set → var set"where "vars_form_set S = (∪A ∈ S. vars A)"
lemma vars_form_finiteness: fixes A :: form shows"finite (vars A)" by (induction rule: vars_form.induct) simp_all
lemma vars_form_set_finiteness: fixes S :: "form set" assumes"finite S" shows"finite (vars S)" using assms unfolding vars_form_set.simps using vars_form_finiteness by blast
lemma form_var_names_finiteness: fixes A :: form shows"finite (var_names A)" using vars_form_finiteness by blast
lemma form_set_var_names_finiteness: fixes S :: "form set" assumes"finite S" shows"finite (var_names S)" using assms and vars_form_set_finiteness by blast
consts free_vars :: "'a → var set"
overloading "free_vars_form"≡"free_vars :: form → var set" "free_vars_form_set"≡"free_vars :: form set → var set"(* abuse of notation *) begin
fun free_vars_form :: "form → var set"where "free_vars_form (x<alpha>) = {(x, α)}"
| "free_vars_form ({c}<alpha>) = {}"
| "free_vars_form (A ⏹ B) = free_vars_form A ∪ free_vars_form B"
| "free_vars_form (λx<alpha>. A) = free_vars_form A - {(x, α)}"
fun free_vars_form_set :: "form set → var set"where "free_vars_form_set S = (∪A ∈ S. free_vars A)"
lemma free_vars_form_finiteness: fixes A :: form shows"finite (free_vars A)" by (induction rule: free_vars_form.induct) simp_all
lemma free_vars_of_generalized_app: shows"free_vars (⏹\<Q>\<star> A Bs) = free_vars A ∪ free_vars (lset Bs)" by (induction Bs arbitrary: A) auto
lemma free_vars_of_generalized_abs: shows"free_vars (λ\<Q>\<star> vs A) = free_vars A - lset vs" by (induction vs arbitrary: A) auto
lemma free_vars_in_all_vars: fixes A :: form shows"free_vars A ⊆ vars A" proof (induction A) case (FVar v) thenshow ?case using surj_pair[of v] by force next case (FCon k) thenshow ?case using surj_pair[of k] by force next case (FApp A B) have"free_vars (A ⏹ B) = free_vars A ∪ free_vars B" using free_vars_form.simps(3) . alsofrom FApp.IH have"…⊆ vars A ∪ vars B" by blast alsohave"… = vars (A ⏹ B)" using vars_form.simps(3)[symmetric] . finallyshow ?case by (simp only:) next case (FAbs v A) thenshow ?case using surj_pair[of v] by force qed
lemma free_vars_in_all_vars_set: fixes S :: "form set" shows"free_vars S ⊆ vars S" using free_vars_in_all_vars by fastforce
lemma singleton_form_set_vars: shows"vars {FVar y} = {y}" using surj_pair[of y] by force
fun bound_vars where "bound_vars (x<alpha>) = {}"
| "bound_vars ({c}<alpha>) = {}"
| "bound_vars (B ⏹ C) = bound_vars B ∪ bound_vars C"
| "bound_vars (λx<alpha>. B) = {(x, α)} ∪ bound_vars B"
lemma vars_is_free_and_bound_vars: shows"vars A = free_vars A ∪ bound_vars A" by (induction A) auto
fun binders_at :: "form → position → var set"where "binders_at (A ⏹ B) (« # p) = binders_at A p"
| "binders_at (A ⏹ B) (¬ # p) = binders_at B p"
| "binders_at (λx<alpha>. A) (« # p) = {(x, α)} ∪ binders_at A p"
| "binders_at A [] = {}"
| "binders_at A p = {}"
lemma binders_at_concat: assumes"A' ⪯ A" shows"binders_at A (p @ p') = binders_at A p ∪ binders_at A' p'" using assms by (induction p A rule: is_subform_at.induct) auto
subsection‹Free and bound occurrences›
definition occurs_at :: "var → position → form → bool"where
[iff]: "occurs_at v p B ⟷ (FVar v ⪯ B)"
lemma occurs_at_alt_def: shows"occurs_at v [] (FVar v') ⟷ (v = v')" and"occurs_at v p ({c}<alpha>) ⟷ False" and"occurs_at v (« # p) (A ⏹ B) ⟷ occurs_at v p A" and"occurs_at v (¬ # p) (A ⏹ B) ⟷ occurs_at v p B" and"occurs_at v (« # p) (λx<alpha>. A) ⟷ occurs_at v p A" and"occurs_at v (d # p) (FVar v') ⟷ False" and"occurs_at v (¬ # p) (λx<alpha>. A) ⟷ False" and"occurs_at v [] (A ⏹ B) ⟷ False" and"occurs_at v [] (λx<alpha>. A) ⟷ False" by (fastforce elim: is_subform_at.elims)+
definition occurs :: "var → form → bool"where
[iff]: "occurs v B ⟷ (∃p ∈ positions B. occurs_at v p B)"
lemma occurs_in_vars: assumes"occurs v A" shows"v ∈ vars A" using assms by (induction A) force+
definition in_scope_of_abs :: "var → position → form → bool"where
[iff]: "in_scope_of_abs v p B ⟷ ( p ≠ [] ∧ ( ∃p' ∈ lset (strict_prefixes p). case (subform_at B p') of Some (FAbs v' _) → v = v' | _ → False ) )"
lemma in_scope_of_abs_alt_def: shows" in_scope_of_abs v p B ⟷ p ≠ [] ∧ (∃p' ∈ positions B. ∃C. strict_prefix p' p ∧ FAbs v C ⪯' B)" proof assume"in_scope_of_abs v p B" thenshow"p ≠ [] ∧ (∃p' ∈ positions B. ∃C. strict_prefix p' p ∧ FAbs v C ⪯' B)" by (induction rule: subform_at.induct) force+ next assume"p ≠ [] ∧ (∃p' ∈ positions B. ∃C. strict_prefix p' p ∧ FAbs v C ⪯' B)" thenshow"in_scope_of_abs v p B" by (induction rule: subform_at.induct) fastforce+ qed
lemma in_scope_of_abs_in_left_app: shows"in_scope_of_abs v (« # p) (A ⏹ B) ⟷ in_scope_of_abs v p A" by force
lemma in_scope_of_abs_in_right_app: shows"in_scope_of_abs v (¬ # p) (A ⏹ B) ⟷ in_scope_of_abs v p B" by force
lemma in_scope_of_abs_in_app: assumes"in_scope_of_abs v p (A ⏹ B)" obtains p' where"(p = « # p' ∧ in_scope_of_abs v p' A) ∨ (p = ¬ # p' ∧ in_scope_of_abs v p' B)" proof - from assms obtain d and p' where"p = d # p'" unfolding in_scope_of_abs_def by (meson list.exhaust) thenshow ?thesis proof (cases d) case Left with assms and‹p = d # p'›show ?thesis using that and in_scope_of_abs_in_left_app by simp next case Right with assms and‹p = d # p'›show ?thesis using that and in_scope_of_abs_in_right_app by simp qed qed
lemma not_in_scope_of_abs_in_app: assumes" ∀p'. (p = « # p' ⟶¬ in_scope_of_abs v' p' A) ∧ (p = ¬ # p' ⟶¬ in_scope_of_abs v' p' B)" shows"¬ in_scope_of_abs v' p (A ⏹ B)" using assms and in_scope_of_abs_in_app by metis
lemma in_scope_of_abs_in_abs: shows"in_scope_of_abs v (« # p) (FAbs v' B) ⟷ v = v' ∨ in_scope_of_abs v p B" proof assume"in_scope_of_abs v (« # p) (FAbs v' B)" thenobtain p' and C where"p' ∈ positions (FAbs v' B)" and"strict_prefix p' (« # p)" and"FAbs v C ⪯' FAbs v' B" unfolding in_scope_of_abs_alt_def by blast thenshow"v = v' ∨ in_scope_of_abs v p B" proof (cases p') case Nil with‹FAbs v C ⪯' FAbs v' B›have"v = v'" by auto thenshow ?thesis by simp next case (Cons d p'') with‹strict_prefix p' (« # p)›have"d = «" by simp from‹FAbs v C ⪯' FAbs v' B›and Cons have"p'' ∈ positions B" by
(cases "(FAbs v C, p', FAbs v' B)" rule: is_subform_at.cases)
(simp_all add: is_subform_implies_in_positions) moreoverfrom‹FAbs v C ⪯' FAbs v' B›and Cons and‹d = «›have"FAbs v C ⪯'' B" by (metis is_subform_at.simps(4) old.prod.exhaust) moreoverfrom‹strict_prefix p' (« # p)›and Cons have"strict_prefix p'' p" by auto ultimatelyhave"in_scope_of_abs v p B" using in_scope_of_abs_alt_def by auto thenshow ?thesis by simp qed next assume"v = v' ∨ in_scope_of_abs v p B" thenshow"in_scope_of_abs v (« # p) (FAbs v' B)" unfolding in_scope_of_abs_alt_def using position_subform_existence_equivalence and surj_pair[of v'] by force qed
lemma not_in_scope_of_abs_in_var: shows"¬ in_scope_of_abs v p (FVar v')" unfolding in_scope_of_abs_def by (cases p) simp_all
lemma in_scope_of_abs_in_vars: assumes"in_scope_of_abs v p A" shows"v ∈ vars A" using assms proof (induction A arbitrary: p) case (FVar v') thenshow ?case using not_in_scope_of_abs_in_var by blast next case (FCon k) thenshow ?case using in_scope_of_abs_alt_def by (blast elim: is_subform_at.elims(2)) next case (FApp B C) from FApp.prems obtain d and p' where"p = d # p'" unfolding in_scope_of_abs_def by (meson neq_Nil_conv) thenshow ?case proof (cases d) case Left with FApp.prems and‹p = d # p'›have"in_scope_of_abs v p' B" using in_scope_of_abs_in_left_app by blast thenhave"v ∈ vars B" by (fact FApp.IH(1)) thenshow ?thesis by simp next case Right with FApp.prems and‹p = d # p'›have"in_scope_of_abs v p' C" using in_scope_of_abs_in_right_app by blast thenhave"v ∈ vars C" by (fact FApp.IH(2)) thenshow ?thesis by simp qed next case (FAbs v' B) thenshow ?case proof (cases "v = v'") case True thenshow ?thesis using surj_pair[of v] by force next case False with FAbs.prems obtain p' and d where"p = d # p'" unfolding in_scope_of_abs_def by (meson neq_Nil_conv) thenshow ?thesis proof (cases d) case Left with FAbs.prems and False and‹p = d # p'›have"in_scope_of_abs v p' B" using in_scope_of_abs_in_abs by blast thenhave"v ∈ vars B" by (fact FAbs.IH) thenshow ?thesis using surj_pair[of v'] by force next case Right with FAbs.prems and‹p = d # p'›and False show ?thesis by (cases rule: is_subform_at.cases) auto qed qed qed
lemma binders_at_alt_def: assumes"p ∈ positions A" shows"binders_at A p = {v | v. in_scope_of_abs v p A}" using assms and in_set_prefixes by (induction rule: binders_at.induct) auto
definition is_bound_at :: "var → position → form → bool"where
[iff]: "is_bound_at v p B ⟷ occurs_at v p B ∧ in_scope_of_abs v p B"
lemma not_is_bound_at_in_var: shows"¬ is_bound_at v p (FVar v')" by (fastforce elim: is_subform_at.elims(2))
lemma not_is_bound_at_in_con: shows"¬ is_bound_at v p (FCon k)" by (fastforce elim: is_subform_at.elims(2))
lemma is_bound_at_in_left_app: shows"is_bound_at v (« # p) (B ⏹ C) ⟷ is_bound_at v p B" by auto
lemma is_bound_at_in_right_app: shows"is_bound_at v (¬ # p) (B ⏹ C) ⟷ is_bound_at v p C" by auto
lemma is_bound_at_from_app: assumes"is_bound_at v p (B ⏹ C)" obtains p' where"(p = « # p' ∧ is_bound_at v p' B) ∨ (p = ¬ # p' ∧ is_bound_at v p' C)" proof - from assms obtain d and p' where"p = d # p'" using subforms_from_app by blast thenshow ?thesis proof (cases d) case Left with assms and that and‹p = d # p'›show ?thesis using is_bound_at_in_left_app by simp next case Right with assms and that and‹p = d # p'›show ?thesis using is_bound_at_in_right_app by simp qed qed
lemma is_bound_at_from_abs: assumes"is_bound_at v (« # p) (FAbs v' B)" shows"v = v' ∨ is_bound_at v p B" using assms by (fastforce elim: is_subform_at.elims)
lemma is_bound_at_from_absE: assumes"is_bound_at v p (FAbs v' B)" obtains p' where"p = « # p'"and"v = v' ∨ is_bound_at v p' B" proof - obtain x and α where"v' = (x, α)" by fastforce with assms obtain p' where"p = « # p'" using subforms_from_abs by blast with assms and that show ?thesis using is_bound_at_from_abs by simp qed
lemma is_bound_at_to_abs: assumes"(v = v' ∧ occurs_at v p B) ∨ is_bound_at v p B" shows"is_bound_at v (« # p) (FAbs v' B)" unfolding is_bound_at_def proof from assms(1) show"occurs_at v (« # p) (FAbs v' B)" using surj_pair[of v'] by force from assms show"in_scope_of_abs v (« # p) (FAbs v' B)" using in_scope_of_abs_in_abs by auto qed
lemma is_bound_at_in_bound_vars: assumes"p ∈ positions A" and"is_bound_at v p A ∨ v ∈ binders_at A p" shows"v ∈ bound_vars A" using assms proof (induction A arbitrary: p) case (FApp B C) from FApp.prems(2) consider (a) "is_bound_at v p (B ⏹ C)" | (b) "v ∈ binders_at (B ⏹ C) p" by blast thenshow ?case proof cases case a thenhave"p ≠ []" using occurs_at_alt_def(8) by blast thenobtain d and p' where"p = d # p'" by (meson list.exhaust) with‹p ∈ positions (B ⏹ C)›
consider (a1) "p = « # p'"and"p' ∈ positions B" | (a2) "p = ¬ # p'"and"p' ∈ positions C" by force thenshow ?thesis proof cases case a1 from a1(1) and‹is_bound_at v p (B ⏹ C)›have"is_bound_at v p' B" using is_bound_at_in_left_app by blast with a1(2) have"v ∈ bound_vars B" using FApp.IH(1) by blast thenshow ?thesis by simp next case a2 from a2(1) and‹is_bound_at v p (B ⏹ C)›have"is_bound_at v p' C" using is_bound_at_in_right_app by blast with a2(2) have"v ∈ bound_vars C" using FApp.IH(2) by blast thenshow ?thesis by simp qed next case b thenhave"p ≠ []" by force thenobtain d and p' where"p = d # p'" by (meson list.exhaust) with‹p ∈ positions (B ⏹ C)›
consider (b1) "p = « # p'"and"p' ∈ positions B" | (b2) "p = ¬ # p'"and"p' ∈ positions C" by force thenshow ?thesis proof cases case b1 from b1(1) and‹v ∈ binders_at (B ⏹ C) p›have"v ∈ binders_at B p'" by force with b1(2) have"v ∈ bound_vars B" using FApp.IH(1) by blast thenshow ?thesis by simp next case b2 from b2(1) and‹v ∈ binders_at (B ⏹ C) p›have"v ∈ binders_at C p'" by force with b2(2) have"v ∈ bound_vars C" using FApp.IH(2) by blast thenshow ?thesis by simp qed qed next case (FAbs v' B) from FAbs.prems(2) consider (a) "is_bound_at v p (FAbs v' B)" | (b) "v ∈ binders_at (FAbs v' B) p" by blast thenshow ?case proof cases case a thenhave"p ≠ []" using occurs_at_alt_def(9) by force with‹p ∈ positions (FAbs v' B)›obtain p' where"p = « # p'"and"p' ∈ positions B" by (cases "FAbs v' B" rule: positions.cases) fastforce+ from‹p = « # p'›and‹is_bound_at v p (FAbs v' B)›have"v = v' ∨ is_bound_at v p' B" using is_bound_at_from_abs by blast then consider (a1) "v = v'" | (a2) "is_bound_at v p' B" by blast thenshow ?thesis proof cases case a1 thenshow ?thesis using surj_pair[of v'] by fastforce next case a2 thenhave"v ∈ bound_vars B" using‹p' ∈ positions B›and FAbs.IH by blast thenshow ?thesis using surj_pair[of v'] by fastforce qed next case b thenhave"p ≠ []" by force with FAbs.prems(1) obtain p' where"p = « # p'"and"p' ∈ positions B" by (cases "FAbs v' B" rule: positions.cases) fastforce+ with b consider (b1) "v = v'" | (b2) "v ∈ binders_at B p'" by (cases "FAbs v' B" rule: positions.cases) fastforce+ thenshow ?thesis proof cases case b1 thenshow ?thesis using surj_pair[of v'] by fastforce next case b2 thenhave"v ∈ bound_vars B" using‹p' ∈ positions B›and FAbs.IH by blast thenshow ?thesis using surj_pair[of v'] by fastforce qed qed qed fastforce+
lemma bound_vars_in_is_bound_at: assumes"v ∈ bound_vars A" obtains p where"p ∈ positions A"and"is_bound_at v p A ∨ v ∈ binders_at A p" using assms proof (induction A arbitrary: thesis rule: bound_vars.induct) case (3 B C) from‹v ∈ bound_vars (B ⏹ C)› consider (a) "v ∈ bound_vars B" | (b) "v ∈ bound_vars C" by fastforce thenshow ?case proof cases case a with"3.IH"(1) obtain p where"p ∈ positions B"and"is_bound_at v p B ∨ v ∈ binders_at B p" by blast from‹p ∈ positions B›have"« # p ∈ positions (B ⏹ C)" by simp from‹is_bound_at v p B ∨ v ∈ binders_at B p›
consider (a1) "is_bound_at v p B" | (a2) "v ∈ binders_at B p" by blast thenshow ?thesis proof cases case a1 thenhave"is_bound_at v (« # p) (B ⏹ C)" using is_bound_at_in_left_app by blast thenshow ?thesis using"3.prems"(1) and is_subform_implies_in_positions by blast next case a2 thenhave"v ∈ binders_at (B ⏹ C) (« # p)" by simp thenshow ?thesis using"3.prems"(1) and‹« # p ∈ positions (B ⏹ C)›by blast qed next case b with"3.IH"(2) obtain p where"p ∈ positions C"and"is_bound_at v p C ∨ v ∈ binders_at C p" by blast from‹p ∈ positions C›have"¬ # p ∈ positions (B ⏹ C)" by simp from‹is_bound_at v p C ∨ v ∈ binders_at C p›
consider (b1) "is_bound_at v p C" | (b2) "v ∈ binders_at C p" by blast thenshow ?thesis proof cases case b1 thenhave"is_bound_at v (¬ # p) (B ⏹ C)" using is_bound_at_in_right_app by blast thenshow ?thesis using"3.prems"(1) and is_subform_implies_in_positions by blast next case b2 thenhave"v ∈ binders_at (B ⏹ C) (¬ # p)" by simp thenshow ?thesis using"3.prems"(1) and‹¬ # p ∈ positions (B ⏹ C)›by blast qed qed next case (4 x α B) from‹v ∈ bound_vars (λxα. B)› consider (a) "v = (x, α)" | (b) "v ∈ bound_vars B" by force thenshow ?case proof cases case a thenhave"v ∈ binders_at (λx<alpha>. B) [«]" by simp thenshow ?thesis using"4.prems"(1) and is_subform_implies_in_positions by fastforce next case b with"4.IH"(1) obtain p where"p ∈ positions B"and"is_bound_at v p B ∨ v ∈ binders_at B p" by blast from‹p ∈ positions B›have"« # p ∈ positions (λx<alpha>. B)" by simp from‹is_bound_at v p B ∨ v ∈ binders_at B p›
consider (b1) "is_bound_at v p B" | (b2) "v ∈ binders_at B p" by blast thenshow ?thesis proof cases case b1 thenhave"is_bound_at v (« # p) (λx<alpha>. B)" using is_bound_at_to_abs by blast thenshow ?thesis using"4.prems"(1) and‹« # p ∈ positions (λxα. B)›by blast next case b2 thenhave"v ∈ binders_at (λx<alpha>. B) (« # p)" by simp thenshow ?thesis using"4.prems"(1) and‹« # p ∈ positions (λxα. B)›by blast qed qed qed simp_all
lemma bound_vars_alt_def: shows"bound_vars A = {v | v p. p ∈ positions A ∧ (is_bound_at v p A ∨ v ∈ binders_at A p)}" using bound_vars_in_is_bound_at and is_bound_at_in_bound_vars by (intro subset_antisym subsetI CollectI, metis) blast
definition is_free_at :: "var → position → form → bool"where
[iff]: "is_free_at v p B ⟷ occurs_at v p B ∧¬ in_scope_of_abs v p B"
lemma is_free_at_in_var: shows"is_free_at v [] (FVar v') ⟷ v = v'" by simp
lemma not_is_free_at_in_con: shows"¬ is_free_at v [] ({c}<alpha>)" by simp
lemma is_free_at_in_left_app: shows"is_free_at v (« # p) (B ⏹ C) ⟷ is_free_at v p B" by auto
lemma is_free_at_in_right_app: shows"is_free_at v (¬ # p) (B ⏹ C) ⟷ is_free_at v p C" by auto
lemma is_free_at_from_app: assumes"is_free_at v p (B ⏹ C)" obtains p' where"(p = « # p' ∧ is_free_at v p' B) ∨ (p = ¬ # p' ∧ is_free_at v p' C)" proof - from assms obtain d and p' where"p = d # p'" using subforms_from_app by blast thenshow ?thesis proof (cases d) case Left with assms and that and‹p = d # p'›show ?thesis using is_free_at_in_left_app by blast next case Right with assms and that and‹p = d # p'›show ?thesis using is_free_at_in_right_app by blast qed qed
lemma is_free_at_from_abs: assumes"is_free_at v (« # p) (FAbs v' B)" shows"is_free_at v p B" using assms by (fastforce elim: is_subform_at.elims)
lemma is_free_at_from_absE: assumes"is_free_at v p (FAbs v' B)" obtains p' where"p = « # p'"and"is_free_at v p' B" proof - obtain x and α where"v' = (x, α)" by fastforce with assms obtain p' where"p = « # p'" using subforms_from_abs by blast with assms and that show ?thesis using is_free_at_from_abs by blast qed
lemma is_free_at_to_abs: assumes"is_free_at v p B"and"v ≠ v'" shows"is_free_at v (« # p) (FAbs v' B)" unfolding is_free_at_def proof from assms(1) show"occurs_at v (« # p) (FAbs v' B)" using surj_pair[of v'] by fastforce from assms show"¬ in_scope_of_abs v (« # p) (FAbs v' B)" unfolding is_free_at_def using in_scope_of_abs_in_abs by presburger qed
lemma is_free_at_in_free_vars: assumes"p ∈ positions A"and"is_free_at v p A" shows"v ∈ free_vars A" using assms proof (induction A arbitrary: p) case (FApp B C) from‹is_free_at v p (B ⏹ C)›have"p ≠ []" using occurs_at_alt_def(8) by blast thenobtain d and p' where"p = d # p'" by (meson list.exhaust) with‹p ∈ positions (B ⏹ C)›
consider (a) "p = « # p'"and"p' ∈ positions B" | (b) "p = ¬ # p'"and"p' ∈ positions C" by force thenshow ?case proof cases case a from a(1) and‹is_free_at v p (B ⏹ C)›have"is_free_at v p' B" using is_free_at_in_left_app by blast with a(2) have"v ∈ free_vars B" using FApp.IH(1) by blast thenshow ?thesis by simp next case b from b(1) and‹is_free_at v p (B ⏹ C)›have"is_free_at v p' C" using is_free_at_in_right_app by blast with b(2) have"v ∈ free_vars C" using FApp.IH(2) by blast thenshow ?thesis by simp qed next case (FAbs v' B) from‹is_free_at v p (FAbs v' B)›have"p ≠ []" using occurs_at_alt_def(9) by force with‹p ∈ positions (FAbs v' B)›obtain p' where"p = « # p'"and"p' ∈ positions B" by (cases "FAbs v' B" rule: positions.cases) fastforce+ moreoverfrom‹p = « # p'›and‹is_free_at v p (FAbs v' B)›have"is_free_at v p' B" using is_free_at_from_abs by blast ultimatelyhave"v ∈ free_vars B" using FAbs.IH by simp moreoverfrom‹p = « # p'›and‹is_free_at v p (FAbs v' B)›have"v ≠ v'" using in_scope_of_abs_in_abs by blast ultimatelyshow ?case using surj_pair[of v'] by force qed fastforce+
lemma free_vars_in_is_free_at: assumes"v ∈ free_vars A" obtains p where"p ∈ positions A"and"is_free_at v p A" using assms proof (induction A arbitrary: thesis rule: free_vars_form.induct) case (3 A B) from‹v ∈ free_vars (A ⏹ B)› consider (a) "v ∈ free_vars A" | (b) "v ∈ free_vars B" by fastforce thenshow ?case proof cases case a with"3.IH"(1) obtain p where"p ∈ positions A"and"is_free_at v p A" by blast from‹p ∈ positions A›have"« # p ∈ positions (A ⏹ B)" by simp moreoverfrom‹is_free_at v p A›have"is_free_at v (« # p) (A ⏹ B)" using is_free_at_in_left_app by blast ultimatelyshow ?thesis using"3.prems"(1) by presburger next case b with"3.IH"(2) obtain p where"p ∈ positions B"and"is_free_at v p B" by blast from‹p ∈ positions B›have"¬ # p ∈ positions (A ⏹ B)" by simp moreoverfrom‹is_free_at v p B›have"is_free_at v (¬ # p) (A ⏹ B)" using is_free_at_in_right_app by blast ultimatelyshow ?thesis using"3.prems"(1) by presburger qed next case (4 x α A) from‹v ∈ free_vars (λxα. A)›have"v ∈ free_vars A - {(x, α)}"and"v ≠ (x, α)" by simp_all thenhave"v ∈ free_vars A" by blast with"4.IH"obtain p where"p ∈ positions A"and"is_free_at v p A" by blast from‹p ∈ positions A›have"« # p ∈ positions (λx<alpha>. A)" by simp moreoverfrom‹is_free_at v p A›and‹v ≠ (x, α)›have"is_free_at v (« # p) (λx<alpha>. A)" using is_free_at_to_abs by blast ultimatelyshow ?case using"4.prems"(1) by presburger qed simp_all
lemma free_vars_alt_def: shows"free_vars A = {v | v p. p ∈ positions A ∧ is_free_at v p A}" using free_vars_in_is_free_at and is_free_at_in_free_vars by (intro subset_antisym subsetI CollectI, metis) blast
text‹
In the following definition, note that the variable immeditately preceded by ‹λ›counts as a bound
variable: ›
definition is_bound :: "var → form → bool"where
[iff]: "is_bound v B ⟷ (∃p ∈ positions B. is_bound_at v p B ∨ v ∈ binders_at B p)"
lemma is_bound_in_app_homomorphism: shows"is_bound v (A ⏹ B) ⟷ is_bound v A ∨ is_bound v B" proof assume"is_bound v (A ⏹ B)" thenobtain p where"p ∈ positions (A ⏹ B)"and"is_bound_at v p (A ⏹ B) ∨ v ∈ binders_at (A ⏹ B) p" by auto thenhave"p ≠ []" by fastforce with‹p ∈ positions (A ⏹ B)›obtain p' and d where"p = d # p'" by auto from‹is_bound_at v p (A ⏹ B) ∨ v ∈ binders_at (A ⏹ B) p›
consider (a) "is_bound_at v p (A ⏹ B)" | (b) "v ∈ binders_at (A ⏹ B) p" by blast thenshow"is_bound v A ∨ is_bound v B" proof cases case a thenshow ?thesis proof (cases d) case Left thenhave"p' ∈ positions A" using‹p = d # p'›and‹p ∈ positions (A ⏹ B)›by fastforce moreoverfrom‹is_bound_at v p (A ⏹ B)›have"occurs_at v p' A" using Left and‹p = d # p'›and is_subform_at.simps(2) by force moreoverfrom‹is_bound_at v p (A ⏹ B)›have"in_scope_of_abs v p' A" using Left and‹p = d # p'›by fastforce ultimatelyshow ?thesis by auto next case Right thenhave"p' ∈ positions B" using‹p = d # p'›and‹p ∈ positions (A ⏹ B)›by fastforce moreoverfrom‹is_bound_at v p (A ⏹ B)›have"occurs_at v p' B" using Right and‹p = d # p'›and is_subform_at.simps(3) by force moreoverfrom‹is_bound_at v p (A ⏹ B)›have"in_scope_of_abs v p' B" using Right and‹p = d # p'›by fastforce ultimatelyshow ?thesis by auto qed next case b thenshow ?thesis proof (cases d) case Left thenhave"p' ∈ positions A" using‹p = d # p'›and‹p ∈ positions (A ⏹ B)›by fastforce moreoverfrom‹v ∈ binders_at (A ⏹ B) p›have"v ∈ binders_at A p'" using Left and‹p = d # p'›by force ultimatelyshow ?thesis by auto next case Right thenhave"p' ∈ positions B" using‹p = d # p'›and‹p ∈ positions (A ⏹ B)›by fastforce moreoverfrom‹v ∈ binders_at (A ⏹ B) p›have"v ∈ binders_at B p'" using Right and‹p = d # p'›by force ultimatelyshow ?thesis by auto qed qed next assume"is_bound v A ∨ is_bound v B" thenshow"is_bound v (A ⏹ B)" proof (rule disjE) assume"is_bound v A" thenobtain p where"p ∈ positions A"and"is_bound_at v p A ∨ v ∈ binders_at A p" by auto from‹p ∈ positions A›have"« # p ∈ positions (A ⏹ B)" by auto from‹is_bound_at v p A ∨ v ∈ binders_at A p›
consider (a) "is_bound_at v p A" | (b) "v ∈ binders_at A p" by blast thenshow"is_bound v (A ⏹ B)" proof cases case a thenhave"occurs_at v (« # p) (A ⏹ B)" by auto moreoverfrom a have"is_bound_at v (« # p) (A ⏹ B)" by force ultimatelyshow"is_bound v (A ⏹ B)" using‹« # p ∈ positions (A ⏹ B)›by blast next case b thenhave"v ∈ binders_at (A ⏹ B) (« # p)" by auto thenshow"is_bound v (A ⏹ B)" using‹« # p ∈ positions (A ⏹ B)›by blast qed next assume"is_bound v B" thenobtain p where"p ∈ positions B"and"is_bound_at v p B ∨ v ∈ binders_at B p" by auto from‹p ∈ positions B›have"¬ # p ∈ positions (A ⏹ B)" by auto from‹is_bound_at v p B ∨ v ∈ binders_at B p›
consider (a) "is_bound_at v p B" | (b) "v ∈ binders_at B p" by blast thenshow"is_bound v (A ⏹ B)" proof cases case a thenhave"occurs_at v (¬ # p) (A ⏹ B)" by auto moreoverfrom a have"is_bound_at v (¬ # p) (A ⏹ B)" by force ultimatelyshow"is_bound v (A ⏹ B)" using‹¬ # p ∈ positions (A ⏹ B)›by blast next case b thenhave"v ∈ binders_at (A ⏹ B) (¬ # p)" by auto thenshow"is_bound v (A ⏹ B)" using‹¬ # p ∈ positions (A ⏹ B)›by blast qed qed qed
lemma is_bound_in_abs_body: assumes"is_bound v A" shows"is_bound v (λx<alpha>. A)" using assms unfolding is_bound_def proof fix p assume"p ∈ positions A"and"is_bound_at v p A ∨ v ∈ binders_at A p" moreoverfrom‹p ∈ positions A›have"« # p ∈ positions (λx<alpha>. A)" by simp ultimately consider (a) "is_bound_at v p A" | (b) "v ∈ binders_at A p" by blast thenshow"∃p ∈ positions (λx<alpha>. A). is_bound_at v p (λx<alpha>. A) ∨ v ∈ binders_at (λx<alpha>. A) p" proof cases case a thenhave"is_bound_at v (« # p) (λx<alpha>. A)" by force with‹« # p ∈ positions (λxα. A)›show ?thesis by blast next case b thenhave"v ∈ binders_at (λx<alpha>. A) (« # p)" by simp with‹« # p ∈ positions (λxα. A)›show ?thesis by blast qed qed
lemma absent_var_is_not_bound: assumes"v ∉ vars A" shows"¬ is_bound v A" using assms and binders_at_alt_def and in_scope_of_abs_in_vars by blast
lemma bound_vars_alt_def2: shows"bound_vars A = {v ∈ vars A. is_bound v A}" unfolding bound_vars_alt_def using absent_var_is_not_bound by fastforce
definition is_free :: "var → form → bool"where
[iff]: "is_free v B ⟷ (∃p ∈ positions B. is_free_at v p B)"
subsection‹Free variables for a formula in another formula›
definition is_free_for :: "form → var → form → bool"where
[iff]: "is_free_for A v B ⟷ ( ∀v' ∈ free_vars A. ∀p ∈ positions B. is_free_at v p B ⟶¬ in_scope_of_abs v' p B )"
lemma is_free_for_absent_var [intro]: assumes"v ∉ vars B" shows"is_free_for A v B" using assms and occurs_def and is_free_at_def and occurs_in_vars by blast
lemma is_free_for_in_var [intro]: shows"is_free_for A v (x<alpha>)" using subforms_from_var(2) by force
lemma is_free_for_in_con [intro]: shows"is_free_for A v ({c}<alpha>)" using subforms_from_con(2) by force
lemma is_free_for_from_app: assumes"is_free_for A v (B ⏹ C)" shows"is_free_for A v B"and"is_free_for A v C" proof -
{ fix v' assume"v' ∈ free_vars A" thenhave"∀p ∈ positions B. is_free_at v p B ⟶¬ in_scope_of_abs v' p B" proof (intro ballI impI) fix p assume"v' ∈ free_vars A"and"p ∈ positions B"and"is_free_at v p B" from‹p ∈ positions B›have"« # p ∈ positions (B ⏹ C)" by simp moreoverfrom‹is_free_at v p B›have"is_free_at v (« # p) (B ⏹ C)" using is_free_at_in_left_app by blast ultimatelyhave"¬ in_scope_of_abs v' (« # p) (B ⏹ C)" using assms and‹v' ∈ free_vars A›by blast thenshow"¬ in_scope_of_abs v' p B" by simp qed
} thenshow"is_free_for A v B" by force next
{ fix v' assume"v' ∈ free_vars A" thenhave"∀p ∈ positions C. is_free_at v p C ⟶¬ in_scope_of_abs v' p C" proof (intro ballI impI) fix p assume"v' ∈ free_vars A"and"p ∈ positions C"and"is_free_at v p C" from‹p ∈ positions C›have"¬ # p ∈ positions (B ⏹ C)" by simp moreoverfrom‹is_free_at v p C›have"is_free_at v (¬ # p) (B ⏹ C)" using is_free_at_in_right_app by blast ultimatelyhave"¬ in_scope_of_abs v' (¬ # p) (B ⏹ C)" using assms and‹v' ∈ free_vars A›by blast thenshow"¬ in_scope_of_abs v' p C" by simp qed
} thenshow"is_free_for A v C" by force qed
lemma is_free_for_to_app [intro]: assumes"is_free_for A v B"and"is_free_for A v C" shows"is_free_for A v (B ⏹ C)" unfolding is_free_for_def proof (intro ballI impI) fix v' and p assume"v' ∈ free_vars A"and"p ∈ positions (B ⏹ C)"and"is_free_at v p (B ⏹ C)" from‹is_free_at v p (B ⏹ C)›have"p ≠ []" using occurs_at_alt_def(8) by force thenobtain d and p' where"p = d # p'" by (meson list.exhaust) with‹p ∈ positions (B ⏹ C)›
consider (b) "p = « # p'"and"p' ∈ positions B" | (c) "p = ¬ # p'"and"p' ∈ positions C" by force thenshow"¬ in_scope_of_abs v' p (B ⏹ C)" proof cases case b from b(1) and‹is_free_at v p (B ⏹ C)›have"is_free_at v p' B" using is_free_at_in_left_app by blast with assms(1) and‹v' ∈ free_vars A›and‹p' ∈ positions B›have"¬ in_scope_of_abs v' p' B" by simp with b(1) show ?thesis using in_scope_of_abs_in_left_app by simp next case c from c(1) and‹is_free_at v p (B ⏹ C)›have"is_free_at v p' C" using is_free_at_in_right_app by blast with assms(2) and‹v' ∈ free_vars A›and‹p' ∈ positions C›have"¬ in_scope_of_abs v' p' C" by simp with c(1) show ?thesis using in_scope_of_abs_in_right_app by simp qed qed
lemma is_free_for_in_app: shows"is_free_for A v (B ⏹ C) ⟷ is_free_for A v B ∧ is_free_for A v C" using is_free_for_from_app and is_free_for_to_app by iprover
lemma is_free_for_to_abs [intro]: assumes"is_free_for A v B"and"(x, α) ∉ free_vars A" shows"is_free_for A v (λx<alpha>. B)" unfolding is_free_for_def proof (intro ballI impI) fix v' and p assume"v' ∈ free_vars A"and"p ∈ positions (λx<alpha>. B)"and"is_free_at v p (λx<alpha>. B)" from‹is_free_at v p (λxα. B)›have"p ≠ []" using occurs_at_alt_def(9) by force with‹p ∈ positions (λxα. B)›obtain p' where"p = « # p'"and"p' ∈ positions B" by force thenshow"¬ in_scope_of_abs v' p (λx<alpha>. B)" proof - from‹p = « # p'›and‹is_free_at v p (λxα. B)›have"is_free_at v p' B" using is_free_at_from_abs by blast with assms(1) and‹v' ∈ free_vars A›and‹p' ∈ positions B›have"¬ in_scope_of_abs v' p' B" by force moreoverfrom‹v' ∈ free_vars A›and assms(2) have"v' ≠ (x, α)" by blast ultimatelyshow ?thesis using‹p = « # p'›and in_scope_of_abs_in_abs by auto qed qed
lemma is_free_for_from_abs: assumes"is_free_for A v (λx<alpha>. B)"and"v ≠ (x, α)" shows"is_free_for A v B" unfolding is_free_for_def proof (intro ballI impI) fix v' and p assume"v' ∈ free_vars A"and"p ∈ positions B"and"is_free_at v p B" thenshow"¬ in_scope_of_abs v' p B" proof - from‹is_free_at v p B›and assms(2) have"is_free_at v (« # p) (λx<alpha>. B)" by (rule is_free_at_to_abs) moreoverfrom‹p ∈ positions B›have"« # p ∈ positions (λx<alpha>. B)" by simp ultimatelyhave"¬ in_scope_of_abs v' (« # p) (λx<alpha>. B)" using assms and‹v' ∈ free_vars A›by blast thenshow ?thesis using in_scope_of_abs_in_abs by blast qed qed
lemma closed_is_free_for [intro]: assumes"free_vars A = {}" shows"is_free_for A v B" using assms by force
lemma is_free_for_closed_form [intro]: assumes"free_vars B = {}" shows"is_free_for A v B" using assms and is_free_at_in_free_vars by blast
lemma is_free_for_alt_def: shows" is_free_for A v B ⟷ ( ∄p. ( p ∈ positions B ∧ is_free_at v p B ∧ p ≠ [] ∧ (∃v' ∈ free_vars A. ∃p' C. strict_prefix p' p ∧ FAbs v' C ⪯' B) ) )" unfolding is_free_for_def using in_scope_of_abs_alt_def and is_subform_implies_in_positions by meson
lemma binding_var_not_free_for_in_abs: assumes"is_free x B"and"x ≠ w" shows"¬ is_free_for (FVar w) x (FAbs w B)" proof (rule ccontr) assume"¬¬ is_free_for (FVar w) x (FAbs w B)" thenhave" ∀v' ∈ free_vars (FVar w). ∀p ∈ positions (FAbs w B). is_free_at x p (FAbs w B) ⟶¬ in_scope_of_abs v' p (FAbs w B)" by force moreoverhave"free_vars (FVar w) = {w}" using surj_pair[of w] by force ultimatelyhave" ∀p ∈ positions (FAbs w B). is_free_at x p (FAbs w B) ⟶¬ in_scope_of_abs w p (FAbs w B)" by blast moreoverfrom assms(1) obtain p where"is_free_at x p B" by fastforce from this and assms(2) have"is_free_at x (« # p) (FAbs w B)" by (rule is_free_at_to_abs) moreoverfrom this have"« # p ∈ positions (FAbs w B)" using is_subform_implies_in_positions by force ultimatelyhave"¬ in_scope_of_abs w (« # p) (FAbs w B)" by blast moreoverhave"in_scope_of_abs w (« # p) (FAbs w B)" using in_scope_of_abs_in_abs by blast ultimatelyshow False by contradiction qed
lemma absent_var_is_free_for [intro]: assumes"x ∉ vars A" shows"is_free_for (FVar x) y A" using in_scope_of_abs_in_vars and assms and surj_pair[of x] by fastforce
lemma form_is_free_for_absent_var [intro]: assumes"x ∉ vars A" shows"is_free_for B x A" using assms and occurs_in_vars by fastforce
lemma form_with_free_binder_not_free_for: assumes"v ≠ v'"and"v' ∈ free_vars A"and"v ∈ free_vars B" shows"¬ is_free_for A v (FAbs v' B)" proof - from assms(3) obtain p where"p ∈ positions B"and"is_free_at v p B" using free_vars_in_is_free_at by blast thenhave"« # p ∈ positions (FAbs v' B)"and"is_free_at v (« # p) (FAbs v' B)" using surj_pair[of v'] and is_free_at_to_abs[OF ‹is_free_at v p B› assms(1)] by force+ moreoverhave"in_scope_of_abs v' (« # p) (FAbs v' B)" using in_scope_of_abs_in_abs by blast ultimatelyshow ?thesis using assms(2) by blast qed
lemma is_replacement_at_implies_in_positions: assumes"C(•p ← A•)⊳ D" shows"p ∈ positions C" using assms by (induction rule: is_replacement_at.induct) auto
declare is_replacement_at.intros [intro!]
lemma is_replacement_at_existence: assumes"p ∈ positions C" obtains D where"C(•p ← A•)⊳ D" using assms proof (induction C arbitrary: p thesis) case (FApp C1 C2) from FApp.prems(2) consider
(a) "p = []"
| (b) "∃p'. p = « # p' ∧ p' ∈ positions C1"
| (c) "∃p'. p = ¬ # p' ∧ p' ∈ positions C2" by fastforce thenshow ?case proof cases case a with FApp.prems(1) show ?thesis by blast next case b with FApp.prems(1) show ?thesis using FApp.IH(1) and replace_left_app by meson next case c with FApp.prems(1) show ?thesis using FApp.IH(2) and replace_right_app by meson qed next case (FAbs v C') from FAbs.prems(2) consider (a) "p = []" | (b) "∃p'. p = « # p' ∧ p' ∈ positions C'" using surj_pair[of v] by fastforce thenshow ?case proof cases case a with FAbs.prems(1) show ?thesis by blast next case b with FAbs.prems(1,2) show ?thesis using FAbs.IH and surj_pair[of v] by blast qed qed force+
lemma is_replacement_at_minimal_change: assumes"C(•p ← A•)⊳ D" shows"A ⪯ D" and"∀p' ∈ positions D. ¬ prefix p' p ∧¬ prefix p p' ⟶ subform_at D p' = subform_at C p'" using assms by (induction rule: is_replacement_at.induct) auto
lemma is_replacement_at_binders: assumes"C(•p ← A•)⊳ D" shows"binders_at D p = binders_at C p" using assms by (induction rule: is_replacement_at.induct) simp_all
lemma is_replacement_at_occurs: assumes"C(•p ← A•)⊳ D" and"¬ prefix p' p"and"¬ prefix p p'" shows"occurs_at v p' C ⟷ occurs_at v p' D" using assms proof (induction arbitrary: p' rule: is_replacement_at.induct) case pos_found thenshow ?case by simp next case replace_left_app thenshow ?case proof (cases p') case (Cons d p'') with replace_left_app.prems(1,2) show ?thesis by (cases d) (use replace_left_app.IH in force)+ qed force next case replace_right_app thenshow ?case proof (cases p') case (Cons d p'') with replace_right_app.prems(1,2) show ?thesis by (cases d) (use replace_right_app.IH in force)+ qed force next case replace_abs thenshow ?case proof (cases p') case (Cons d p'') with replace_abs.prems(1,2) show ?thesis by (cases d) (use replace_abs.IH in force)+ qed force qed
lemma fresh_var_replacement_position_uniqueness: assumes"v ∉ vars C" and"C(•p ← FVar v•)⊳ G" and"occurs_at v p' G" shows"p' = p" proof (rule ccontr) assume"p' ≠ p" from assms(2) have"occurs_at v p G" by (simp add: is_replacement_at_minimal_change(1)) moreoverhave *: "occurs_at v p' C ⟷ occurs_at v p' G"if"¬ prefix p' p"and"¬ prefix p p'" using assms(2) and that and is_replacement_at_occurs by blast ultimatelyshow False proof (cases "¬ prefix p' p ∧¬ prefix p p'") case True with assms(3) and * have"occurs_at v p' C" by simp thenhave"v ∈ vars C" using is_subform_implies_in_positions and occurs_in_vars by fastforce with assms(1) show ?thesis by contradiction next case False have"FVar v ⪯ G" by (fact is_replacement_at_minimal_change(1)[OF assms(2)]) moreoverfrom assms(3) have"FVar v ⪯' G" by simp ultimatelyshow ?thesis using‹p' ≠ p›and False and loop_subform_impossibility by (blast dest: prefix_order.antisym_conv2) qed qed
lemma is_replacement_at_new_positions: assumes"C(•p ← A•)⊳ D"and"prefix p p'"and"p' ∈ positions D" obtains p'' where"p' = p @ p''"and"p'' ∈ positions A" using assms by (induction arbitrary: thesis p' rule: is_replacement_at.induct, auto) blast+
lemma replacement_override: assumes"C(•p ← B•)⊳ D"and"C(•p ← A•)⊳ F" shows"D(•p ← A•)⊳ F" using assms proof (induction arbitrary: F rule: is_replacement_at.induct) case pos_found from pos_found.hyps(1) and pos_found.prems have"A = F" using is_replacement_at.simps by blast with pos_found.hyps(1) show ?case by blast next case (replace_left_app p G C G' H) have"p ∈ positions G'" by (
fact is_subform_implies_in_positions
[OF is_replacement_at_minimal_change(1)[OF replace_left_app.hyps(2)]]
) from replace_left_app.prems obtain F' where"F = F' ⏹ H"and"G(•p ← A•)⊳ F'" by (fastforce elim: is_replacement_at.cases) from‹G(•p ← A•)⊳ F'›have"G'(•p ← A•)⊳ F'" by (fact replace_left_app.IH) with‹p ∈ positions G'›show ?case unfolding‹F = F' ⏹ H›by blast next case (replace_right_app p H C H' G) have"p ∈ positions H'" by
(
fact is_subform_implies_in_positions
[OF is_replacement_at_minimal_change(1)[OF replace_right_app.hyps(2)]]
) from replace_right_app.prems obtain F' where"F = G ⏹ F'"and"H(•p ← A•)⊳ F'" by (fastforce elim: is_replacement_at.cases) from‹H(•p ← A•)⊳ F'›have"H'(•p ← A•)⊳ F'" by (fact replace_right_app.IH) with‹p ∈ positions H'›show ?case unfolding‹F = G ⏹ F'›by blast next case (replace_abs p E C E' x γ) have"p ∈ positions E'" by
(
fact is_subform_implies_in_positions
[OF is_replacement_at_minimal_change(1)[OF replace_abs.hyps(2)]]
) from replace_abs.prems obtain F' where"F = λx<gamma>. F'"and"E(•p ← A•)⊳ F'" by (fastforce elim: is_replacement_at.cases) from‹E(•p ← A•)⊳ F'›have"E'(•p ← A•)⊳ F'" by (fact replace_abs.IH) with‹p ∈ positions E'›show ?case unfolding‹F = λxγ. F'›by blast qed
lemma leftmost_subform_in_generalized_app_replacement: shows"(⏹\<Q>\<star> C As)(•replicate (length As) «← D•)⊳ (⏹\<Q>\<star> D As)" using is_replacement_at_implies_in_positions and replace_left_app by (induction As arbitrary: D rule: rev_induct) auto
definition iota :: form (‹ι›) where
[simp]: "ι = FCon iota_constant"
definition is_Q_constant_of_type :: "con → type → bool"where
[iff]: "is_Q_constant_of_type p α ⟷ p = Q_constant_of_type α"
definition is_iota_constant :: "con → bool"where
[iff]: "is_iota_constant p ⟷ p = iota_constant"
definition is_logical_constant :: "con → bool"where
[iff]: "is_logical_constant p ⟷ (∃β. is_Q_constant_of_type p β) ∨ is_iota_constant p"
definition type_of_Q_constant :: "con → type"where
[simp]: "type_of_Q_constant p = (THE α. is_Q_constant_of_type p α)"
lemma constant_cases[case_names non_logical Q_constant ι_constant, cases type: con]: assumes"¬ is_logical_constant p ==> P" and"∧β. is_Q_constant_of_type p β ==> P" and"is_iota_constant p ==> P" shows"P" using assms by blast
subsection‹Definitions and abbreviations›
definition equality_of_type :: "form → type → form → form" (‹(_ =/ _)› [103, 0, 103] 102) where
[simp]: "A =<alpha> B = Q<alpha>⏹ A ⏹ B"
definition equivalence :: "form → form → form" (infixl‹≡\Q›102) where
[simp]: "A ≡\<Q> B = A = B"―‹more modular than the definition in cite‹"andrews:2002"››
definition true :: form (‹T›) where
[simp]: "T = Q =→o→o Q"
definition false :: form (‹F›) where
[simp]: "F = λx. T =→o λx. x"
definition PI :: "type → form" (‹∏›) where
[simp]: "∏<alpha> = Q<alpha>→o⏹ (λx<alpha>. T)"
definition forall :: "nat → type → form → form" (‹(4∀_./ _)› [0, 0, 141] 141) where
[simp]: "∀x<alpha>. A = ∏<alpha>⏹ (λx<alpha>. A)"
text‹Generalized universal quantification. We define ‹∀\Q\⋆ [x1, …, xn] A› as ‹∀x1. ⋯∀xn. A›:›
definition generalized_forall :: "var list → form → form" (‹∀\Q\⋆ _ _› [141, 141] 141) where
[simp]: "∀\<Q>\<star> vs A = foldr (λ(x, α) B. ∀x<alpha>. B) vs A"
lemma innermost_subform_in_generalized_forall: assumes"vs ≠ []" shows"A ⪯ (λ_ p. [¬,«] @ p) vs []∀\<Q>\<star> vs A" using assms by (induction vs) fastforce+
lemma innermost_replacement_in_generalized_forall: assumes"vs ≠ []" shows"(∀\<Q>\<star> vs C)(•foldr (λ_. (@) [¬,«]) vs [] ← B•)⊳ (∀\<Q>\<star> vs B)" using assms proof (induction vs) case Nil thenshow ?case by blast next case (Cons v vs) obtain x and α where"v = (x, α)" by fastforce thenshow ?case proof (cases "vs = []") case True with‹v = (x, α)›show ?thesis unfolding True by force next case False thenhave"foldr (λ_. (@) [¬,«]) vs [] ∈ positions (∀\<Q>\<star> vs C)" using innermost_subform_in_generalized_forall and is_subform_implies_in_positions byblast moreoverfrom False have"(∀\<Q>\<star> vs C)(•foldr (λ_. (@) [¬,«]) vs [] ← B•)⊳ (∀\<Q>\<star> vs B)" by (fact Cons.IH) ultimatelyhave"(λx<alpha>. ∀\<Q>\<star> vs C)(•« # foldr (λ_. (@) [¬,«]) vs [] ← B•)⊳ (λx<alpha>. ∀\<Q>\<star> vs B)" by (rule replace_abs) moreoverhave"« # foldr (λ_. (@) [¬,«]) vs [] ∈ positions (λx<alpha>. ∀\<Q>\<star> vs C)" using‹foldr (λ_. (@) [¬,«]) vs [] ∈ positions (∀\Q\⋆ vs C)›by simp ultimatelyhave" (∏<alpha>⏹ (λx<alpha>. ∀\<Q>\<star> vs C))(•¬ # « # foldr (λ_. (@) [¬,«]) vs [] ← B•)⊳ (∏<alpha>⏹ (λx<alpha>. ∀\<Q>\<star> vs B))" by blast thenhave"(∀x<alpha>. ∀\<Q>\<star> vs C)(•[¬,«] @ foldr (λ_. (@) [¬,«]) vs [] ← B•)⊳ (∀x<alpha>. ∀\<Q>\<star> vs B)" by simp thenshow ?thesis unfolding‹v = (x, α)›and generalized_forall_def and foldr.simps(2) and o_apply and case_prod_conv . qed qed
lemma false_is_forall: shows"F = ∀x. x" unfolding false_def and forall_def and PI_def and equality_of_type_def ..
definition conj_fun :: form (‹∧→o→o›) where
[simp]: "∧→o→o = λx. λy. ( (λg→o→o. g→o→o⏹ T⏹ T) =o→o→o)→o (λg→o→o. g→o→o⏹x⏹y) )"
definition conj_op :: "form → form → form" (infixl‹∧\Q›131) where
[simp]: "A ∧\<Q> B = ∧→o→o⏹ A ⏹ B"
text‹Generalized conjunction. We define ‹∧\Q\⋆ [A1, …, An]› as ‹A1∧\Q (⋯∧\Q (An-1∧\Q An) ⋯)›:›
definition generalized_conj_op :: "form list → form" (‹∧\Q\⋆ _› [0] 131) where
[simp]: "∧\<Q>\<star> As = foldr1 (∧\<Q>) As"
definition imp_fun :: form (‹⊃→o→o›) where―‹‹≡› used instead of ‹=›, see cite‹"andrews:2002"››
[simp]: "⊃→o→o = λx. λy. (x≡\<Q> x∧\<Q> y)"
definition imp_op :: "form → form → form" (infixl‹⊃\Q›111) where
[simp]: "A ⊃\<Q> B = ⊃→o→o⏹ A ⏹ B"
text‹Generalized implication. We define ‹[A1, …, An] ⊃\Q\⋆ B› as ‹A1⊃\Q (⋯⊃\Q(An⊃\Q B) ⋯)›:›
definition generalized_imp_op :: "form list → form → form" (infixl‹⊃\Q\⋆›111) where
[simp]: "As ⊃\<Q>\<star> B = foldr (⊃\<Q>) As B"
text‹
Given the definition below, it is interesting to note that ‹∼\Q A› and ‹F≡\Q A› are exactly the
same formula, namely ‹Q⏹ F⏹ A›: ›
definition neg :: "form → form" (‹∼\Q _› [141] 141) where
[simp]: "∼\<Q> A = Q⏹ F⏹ A"
definition disj_fun :: form (‹∨→o→o›) where
[simp]: "∨→o→o = λx. λy. ∼\<Q> (∼\<Q> x∧\<Q> ∼\<Q> y)"
definition disj_op :: "form → form → form" (infixl‹∨\Q›126) where
[simp]: "A ∨\<Q> B = ∨→o→o⏹ A ⏹ B"
definition exists :: "nat → type → form → form" (‹(4∃_./ _)› [0, 0, 141] 141) where
[simp]: "∃x<alpha>. A = ∼\<Q> (∀x<alpha>. ∼\<Q> A)"
lemma exists_fv: shows"free_vars (∃x<alpha>. A) = free_vars A - {(x, α)}" by simp
definition inequality_of_type :: "form → type → form → form" (‹(_ ≠/ _)› [103, 0, 103] 102) where
[simp]: "A ≠<alpha> B = ∼\<Q> (A =<alpha> B)"
lemma generalized_app_wff [intro]: assumes"length As = length ts" and"∀k < length As. As ! k ∈ wffs ! k" and"B ∈ wffs (→) ts β" shows"⏹\<Q>\<star> B As ∈ wffs<beta>" using assms proof (induction As ts arbitrary: B rule: list_induct2) case Nil thenshow ?case by simp next case (Cons A As t ts) from Cons.prems(1) have"A ∈ wffs" by fastforce moreoverfrom Cons.prems(2) have"B ∈ wffs→foldr (→) ts β" by auto ultimatelyhave"B ⏹ A ∈ wffs (→) ts β" by blast moreoverhave"∀k < length As. (A # As) ! (Suc k) = As ! k ∧ (t # ts) ! (Suc k) = ts ! k" by force with Cons.prems(1) have"∀k < length As. As ! k ∈ wffs ! k" by fastforce ultimatelyhave"⏹\<Q>\<star> (B ⏹ A) As ∈ wffs<beta>" using Cons.IH by (simp only:) moreoverhave"⏹\<Q>\<star> B (A # As) = ⏹\<Q>\<star> (B ⏹ A) As" by simp ultimatelyshow ?case by (simp only:) qed
lemma generalized_abs_wff [intro]: assumes"B ∈ wffs<beta>" shows"λ\<Q>\<star> vs B ∈ wffs (→) (map snd vs) β" using assms proof (induction vs) case Nil thenshow ?case by simp next case (Cons v vs) let ?δ = "foldr (→) (map snd vs) β" obtain x and α where"v = (x, α)" by fastforce thenhave"FVar v ∈ wffs<alpha>" by auto from Cons.prems have"λ\<Q>\<star> vs B ∈ wffsδ" by (fact Cons.IH) with‹v = (x, α)›have"FAbs v (λ\<Q>\<star> vs B) ∈ wffs<alpha>→?δ" by blast moreoverfrom‹v = (x, α)›have"foldr (→) (map snd (v # vs)) β = α→?δ" by simp moreoverhave"λ\<Q>\<star> (v # vs) B = FAbs v (λ\<Q>\<star> vs B)" by simp ultimatelyshow ?caseby (simp only:) qed
lemma Q_wff [intro]: shows"Q<alpha>∈ wffs<alpha>→α→o" by auto
lemma iota_wff [intro]: shows"ι ∈ wffsi→o)→i" by auto
lemma equality_wff [intro]: assumes"A ∈ wffs<alpha>"and"B ∈ wffs<alpha>" shows"A =<alpha> B ∈ wffs" using assms by auto
lemma equivalence_wff [intro]: assumes"A ∈ wffs"and"B ∈ wffs" shows"A ≡\<Q> B ∈ wffs" using assms unfolding equivalence_def by blast
lemma true_wff [intro]: shows"T∈ wffs" by force
lemma false_wff [intro]: shows"F∈ wffs" by auto
lemma pi_wff [intro]: shows"∏<alpha>∈ wffsα→o)→o" using PI_def by fastforce
lemma forall_wff [intro]: assumes"A ∈ wffs" shows"∀x<alpha>. A ∈ wffs" using assms and pi_wff unfolding forall_def by blast
lemma generalized_forall_wff [intro]: assumes"B ∈ wffs" shows"∀\<Q>\<star> vs B ∈ wffs" using assms proof (induction vs) case (Cons v vs) thenshow ?case using surj_pair[of v] by force qed simp
lemma conj_fun_wff [intro]: shows"∧→o→o∈ wffs→o→o" by auto
lemma conj_op_wff [intro]: assumes"A ∈ wffs"and"B ∈ wffs" shows"A ∧\<Q> B ∈ wffs" using assms unfolding conj_op_def by blast
lemma imp_fun_wff [intro]: shows"⊃→o→o∈ wffs→o→o" by auto
lemma imp_op_wff [intro]: assumes"A ∈ wffs"and"B ∈ wffs" shows"A ⊃\<Q> B ∈ wffs" using assms unfolding imp_op_def by blast
lemma neg_wff [intro]: assumes"A ∈ wffs" shows" ∼\<Q> A ∈ wffs" using assms by fastforce
lemma disj_fun_wff [intro]: shows"∨→o→o∈ wffs→o→o" by auto
lemma disj_op_wff [intro]: assumes"A ∈ wffs"and"B ∈ wffs" shows"A ∨\<Q> B ∈ wffs" using assms by auto
lemma exists_wff [intro]: assumes"A ∈ wffs" shows"∃x<alpha>. A ∈ wffs" using assms by fastforce
lemma inequality_wff [intro]: assumes"A ∈ wffs<alpha>"and"B ∈ wffs<alpha>" shows"A ≠<alpha> B ∈ wffs" using assms by fastforce
lemma wffs_from_app: assumes"A ⏹ B ∈ wffs<beta>" obtains α where"A ∈ wffs<alpha>→β"and"B ∈ wffs<alpha>" using assms by (blast elim: wffs_of_type_cases)
lemma wffs_from_generalized_app: assumes"⏹\<Q>\<star> B As ∈ wffs<beta>" obtains ts where"length ts = length As" and"∀k < length As. As ! k ∈ wffs ! k" and"B ∈ wffs (→) ts β" using assms proof (induction As arbitrary: B thesis) case Nil thenshow ?case by simp next case (Cons A As) from Cons.prems have"⏹\<Q>\<star> (B ⏹ A) As ∈ wffs<beta>" by auto thenobtain ts where"length ts = length As" and"∀k < length As. As ! k ∈ wffs ! k" and"B ⏹ A ∈ wffs (→) ts β" using Cons.IH by blast moreover from‹B ⏹ A ∈ wffs (→) ts β›obtain t where"B ∈ wffs→foldr (→) ts β"and"A ∈ wffs" by (elim wffs_from_app) moreoverfrom‹length ts = length As›have"length (t # ts) = length (A # As)" by simp moreoverfrom‹A ∈ wffs›and‹∀k < length As. As ! k ∈ wffs ! k› have"∀k < length (A # As). (A # As) ! k ∈ wffst # ts) ! k" by (simp add: nth_Cons') moreoverfrom‹B ∈ wffs→foldr (→) ts β›have"B ∈ wffs (→) (t # ts) β" by simp ultimatelyshow ?case using Cons.prems(1) by blast qed
lemma wffs_from_abs: assumes"λx<alpha>. A ∈ wffs<gamma>" obtains β where"γ = α→β"and"A ∈ wffs<beta>" using assms by (blast elim: wffs_of_type_cases)
lemma wffs_from_equality: assumes"A =<alpha> B ∈ wffs" shows"A ∈ wffs<alpha>"and"B ∈ wffs<alpha>" using assms by (fastforce elim: wffs_of_type_cases)+
lemma wffs_from_equivalence: assumes"A ≡\<Q> B ∈ wffs" shows"A ∈ wffs"and"B ∈ wffs" using assms unfolding equivalence_def by (fact wffs_from_equality)+
lemma wffs_from_forall: assumes"∀x<alpha>. A ∈ wffs" shows"A ∈ wffs" using assms unfolding forall_def and PI_def by (fold equality_of_type_def) (drule wffs_from_equality, blast elim: wffs_from_abs)
lemma wffs_from_conj_fun: assumes"∧→o→o⏹ A ⏹ B ∈ wffs" shows"A ∈ wffs"and"B ∈ wffs" using assms by (auto elim: wffs_from_app wffs_from_abs)
lemma wffs_from_conj_op: assumes"A ∧\<Q> B ∈ wffs" shows"A ∈ wffs"and"B ∈ wffs" using assms unfolding conj_op_def by (elim wffs_from_conj_fun)+
lemma wffs_from_imp_fun: assumes"⊃→o→o⏹ A ⏹ B ∈ wffs" shows"A ∈ wffs"and"B ∈ wffs" using assms by (auto elim: wffs_from_app wffs_from_abs)
lemma wffs_from_imp_op: assumes"A ⊃\<Q> B ∈ wffs" shows"A ∈ wffs"and"B ∈ wffs" using assms unfolding imp_op_def by (elim wffs_from_imp_fun)+
lemma wffs_from_neg: assumes"∼\<Q> A ∈ wffs" shows"A ∈ wffs" using assms unfolding neg_def by (fold equality_of_type_def) (drule wffs_from_equality, blast)
lemma wffs_from_disj_fun: assumes"∨→o→o⏹ A ⏹ B ∈ wffs" shows"A ∈ wffs"and"B ∈ wffs" using assms by (auto elim: wffs_from_app wffs_from_abs)
lemma wffs_from_disj_op: assumes"A ∨\<Q> B ∈ wffs" shows"A ∈ wffs"and"B ∈ wffs" using assms and wffs_from_disj_fun unfolding disj_op_def by blast+
lemma wffs_from_exists: assumes"∃x<alpha>. A ∈ wffs" shows"A ∈ wffs" using assms unfolding exists_def using wffs_from_neg and wffs_from_forall by blast
lemma wffs_from_inequality: assumes"A ≠<alpha> B ∈ wffs" shows"A ∈ wffs<alpha>"and"B ∈ wffs<alpha>" using assms unfolding inequality_of_type_def using wffs_from_equality and wffs_from_neg by meson+
lemma wff_has_unique_type: assumes"A ∈ wffs<alpha>"and"A ∈ wffs<beta>" shows"α = β" using assms proof (induction arbitrary: α β rule: form.induct) case (FVar v) obtain x and γ where"v = (x, γ)" by fastforce with FVar.prems have"α = γ"and"β = γ" by (blast elim: wffs_of_type_cases)+ thenshow ?case .. next case (FCon k) obtain x and γ where"k = (x, γ)" by fastforce with FCon.prems have"α = γ"and"β = γ" by (blast elim: wffs_of_type_cases)+ thenshow ?case .. next case (FApp A B) from FApp.prems obtain α' and β' where"A ∈ wffs<alpha>'→α"and"A ∈ wffs<beta>'→β" by (blast elim: wffs_from_app) with FApp.IH(1) show ?case by blast next case (FAbs v A) obtain x and γ where"v = (x, γ)" by fastforce with FAbs.prems obtain α' and β' where"α = γ→α'"and"β = γ→β'"and"A ∈ wffs<alpha>'"and"A ∈ wffs<beta>'" by (blast elim: wffs_from_abs) with FAbs.IH show ?case by simp qed
lemma wffs_of_type_o_induct [consumes 1, case_names Var Con App]: assumes"A ∈ wffs" and"∧x. P (x)" and"∧c. P ({c})" and"∧A B α. A ∈ wffs<alpha>→o==> B ∈ wffs<alpha>==>P (A ⏹ B)" shows"P A" using assms by (cases rule: wffs_of_type_cases) simp_all
lemma diff_types_implies_diff_wffs: assumes"A ∈ wffs<alpha>"and"B ∈ wffs<beta>" and"α ≠ β" shows"A ≠ B" using assms and wff_has_unique_type by blast
lemma is_free_for_in_generalized_app [intro]: assumes"is_free_for A v B"and"∀C ∈ lset Cs. is_free_for A v C" shows"is_free_for A v (⏹\<Q>\<star> B Cs)" using assms proof (induction Cs rule: rev_induct) case Nil thenshow ?case by simp next case (snoc C Cs) from snoc.prems(2) have"is_free_for A v C"and"∀C ∈ lset Cs. is_free_for A v C" by simp_all with snoc.prems(1) have"is_free_for A v (⏹\<Q>\<star> B Cs)" using snoc.IH by simp with‹is_free_for A v C›show ?case using is_free_for_to_app by simp qed
lemma is_free_for_in_equality [intro]: assumes"is_free_for A v B"and"is_free_for A v C" shows"is_free_for A v (B =<alpha> C)" using assms unfolding equality_of_type_def and Q_def and Q_constant_of_type_def by (intro is_free_for_to_app is_free_for_in_con)
lemma is_free_for_in_equivalence [intro]: assumes"is_free_for A v B"and"is_free_for A v C" shows"is_free_for A v (B ≡\<Q> C)" using assms unfolding equivalence_def by (rule is_free_for_in_equality)
lemma is_free_for_in_true [intro]: shows"is_free_for A v (T)" by force
lemma is_free_for_in_false [intro]: shows"is_free_for A v (F)" unfolding false_def by (intro is_free_for_in_equality is_free_for_closed_form) simp_all
lemma is_free_for_in_forall [intro]: assumes"is_free_for A v B"and"(x, α) ∉ free_vars A" shows"is_free_for A v (∀x<alpha>. B)" unfolding forall_def and PI_def proof (fold equality_of_type_def) have"is_free_for A v (λx<alpha>. T)" using is_free_for_to_abs[OF is_free_for_in_true assms(2)] by fastforce moreoverhave"is_free_for A v (λx<alpha>. B)" by (fact is_free_for_to_abs[OF assms]) ultimatelyshow"is_free_for A v (λx<alpha>. T =<alpha>→o λx<alpha>. B)" by (iprover intro: assms(1) is_free_for_in_equality is_free_for_in_true is_free_for_to_abs) qed
lemma is_free_for_in_generalized_forall [intro]: assumes"is_free_for A v B"and"lset vs ∩ free_vars A = {}" shows"is_free_for A v (∀\<Q>\<star> vs B)" using assms proof (induction vs) case Nil thenshow ?case by simp next case (Cons v' vs) obtain x and α where"v' = (x, α)" by fastforce from Cons.prems(2) have"v' ∉ free_vars A"and"lset vs ∩ free_vars A = {}" by simp_all from Cons.prems(1) and‹lset vs ∩ free_vars A = {}›have"is_free_for A v (∀\<Q>\<star> vs B)" by (fact Cons.IH) from this and‹v' ∉ free_vars A›[unfolded ‹v' = (x, α)›] have"is_free_for A v (∀x<alpha>. ∀\<Q>\<star> vs B)" by (intro is_free_for_in_forall) with‹v' = (x, α)›show ?case by simp qed
lemma is_free_for_in_conj [intro]: assumes"is_free_for A v B"and"is_free_for A v C" shows"is_free_for A v (B ∧\<Q> C)" proof - have"free_vars ∧→o→o = {}" by force thenhave"is_free_for A v (∧→o→o)" using is_free_for_closed_form by fast with assms have"is_free_for A v (∧→o→o⏹ B ⏹ C)" by (intro is_free_for_to_app) thenshow ?thesis by (fold conj_op_def) qed
lemma is_free_for_in_imp [intro]: assumes"is_free_for A v B"and"is_free_for A v C" shows"is_free_for A v (B ⊃\<Q> C)" proof - have"free_vars ⊃→o→o = {}" by force thenhave"is_free_for A v (⊃→o→o)" using is_free_for_closed_form by fast with assms have"is_free_for A v (⊃→o→o⏹ B ⏹ C)" by (intro is_free_for_to_app) thenshow ?thesis by (fold imp_op_def) qed
lemma is_free_for_in_neg [intro]: assumes"is_free_for A v B" shows"is_free_for A v (∼\<Q> B)" using assms unfolding neg_def and Q_def and Q_constant_of_type_def by (intro is_free_for_to_app is_free_for_in_false is_free_for_in_con)
lemma is_free_for_in_disj [intro]: assumes"is_free_for A v B"and"is_free_for A v C" shows"is_free_for A v (B ∨\<Q> C)" proof - have"free_vars ∨→o→o = {}" by force thenhave"is_free_for A v (∨→o→o)" using is_free_for_closed_form by fast with assms have"is_free_for A v (∨→o→o⏹ B ⏹ C)" by (intro is_free_for_to_app) thenshow ?thesis by (fold disj_op_def) qed
lemma replacement_preserves_typing: assumes"C(•p ← B•)⊳ D" and"A ⪯ C" and"A ∈ wffs<alpha>"and"B ∈ wffs<alpha>" shows"C ∈ wffs<beta>⟷ D ∈ wffs<beta>" using assms proof (induction arbitrary: β rule: is_replacement_at.induct) case (pos_found p C C' A) thenshow ?case using diff_types_implies_diff_wffs by auto qed (metis is_subform_at.simps(2,3,4) wffs_from_app wffs_from_abs wffs_of_type_simps)+
corollary replacement_preserves_typing': assumes"C(•p ← B•)⊳ D" and"A ⪯ C" and"A ∈ wffs<alpha>"and"B ∈ wffs<alpha>" and"C ∈ wffs<beta>"and"D ∈ wffs<gamma>" shows"β = γ" using assms and replacement_preserves_typing and wff_has_unique_type by simp
text‹Closed formulas and sentences:›
definition is_closed_wff_of_type :: "form → type → bool"where
[iff]: "is_closed_wff_of_type A α ⟷ A ∈ wffs<alpha>∧ free_vars A = {}"
definition is_sentence :: "form → bool"where
[iff]: "is_sentence A ⟷ is_closed_wff_of_type A o"
fun substitute :: "substitution → form → form" (‹S _ _› [51, 51]) where "S θ (x<alpha>) = (case θ $$ (x, α) of None → x<alpha> | Some A → A)"
| "S θ ({c}<alpha>) = {c}<alpha>"
| "S θ (A ⏹ B) = (S θ A) ⏹ (S θ B)"
| "S θ (λx<alpha>. A) = (if (x, α) ∉ fmdom' θ then λx<alpha>. S θ A else λx<alpha>. S (fmdrop (x, α) θ) A)"
lemma empty_substitution_neutrality: shows"S {$$} A = A" by (induction A) auto
lemma substitution_preserves_typing: assumes"is_substitution θ" and"A ∈ wffs<alpha>" shows"S θ A ∈ wffs<alpha>" using assms(2) and assms(1)[unfolded is_substitution_def] proof (induction arbitrary: θ) case (var_is_wff α x) thenshow ?case by (cases "(x, α) ∈ fmdom' θ") (use fmdom'_notI in‹force+›) next case (abs_is_wff β A α x) thenshow ?case proof (cases "(x, α) ∈ fmdom' θ") case True thenhave"S θ (λx<alpha>. A) = λx<alpha>. S (fmdrop (x, α) θ) A" by simp moreoverfrom abs_is_wff.prems have"is_substitution (fmdrop (x, α) θ)" by fastforce with abs_is_wff.IH have"S (fmdrop (x, α) θ) A ∈ wffs<beta>" by simp ultimatelyshow ?thesis by auto next case False thenhave"S θ (λx<alpha>. A) = λx<alpha>. S θ A" by simp moreoverfrom abs_is_wff.IH have"S θ A ∈ wffs<beta>" using abs_is_wff.prems by blast ultimatelyshow ?thesis by fastforce qed qed force+
lemma derived_substitution_simps: shows"S θ T = T" and"S θ F = F" and"S θ (∏<alpha>) = ∏<alpha>" and"S θ (∼\<Q> B) = ∼\<Q> (S θ B)" and"S θ (B =<alpha> C) = (S θ B) =<alpha> (S θ C)" and"S θ (B ∧\<Q> C) = (S θ B) ∧\<Q> (S θ C)" and"S θ (B ∨\<Q> C) = (S θ B) ∨\<Q> (S θ C)" and"S θ (B ⊃\<Q> C) = (S θ B) ⊃\<Q> (S θ C)" and"S θ (B ≡\<Q> C) = (S θ B) ≡\<Q> (S θ C)" and"S θ (B ≠<alpha> C) = (S θ B) ≠<alpha> (S θ C)" and"S θ (∀x<alpha>. B) = (if (x, α) ∉ fmdom' θ then ∀x<alpha>. S θ B else ∀x<alpha>. S(fmdrop (x, α) θ) B)" and"S θ (∃x<alpha>. B) = (if (x, α) ∉ fmdom' θ then ∃x<alpha>. S θ B else ∃x<alpha>. S(fmdrop (x, α) θ) B)" by auto
lemma generalized_app_substitution: shows"S θ (⏹\<Q>\<star> A Bs) = ⏹\<Q>\<star> (S θ A) (map (λB. S θ B) Bs)" by (induction Bs arbitrary: A) simp_all
lemma generalized_abs_substitution: shows"S θ (λ\<Q>\<star> vs A) = λ\<Q>\<star> vs (S (fmdrop_set (fmdom' θ ∩ lset vs) θ) A)" proof (induction vs arbitrary: θ) case Nil thenshow ?case by simp next case (Cons v vs) obtain x and α where"v = (x, α)" by fastforce thenshow ?case proof (cases "v ∉ fmdom' θ") case True thenhave *: "fmdom' θ ∩ lset (v # vs) = fmdom' θ ∩ lset vs" by simp from True have"S θ (λ\<Q>\<star> (v # vs) A) = λx<alpha>. S θ (λ\<Q>\<star> vs A)" using‹v = (x, α)›by auto alsohave"… = λx<alpha>. λ\<Q>\<star> vs (S (fmdrop_set (fmdom' θ ∩ lset vs) θ) A)" using Cons.IH by (simp only:) alsohave"… = λ\<Q>\<star> (v # vs) (S (fmdrop_set (fmdom' θ ∩ lset (v # vs)) θ) A)" using‹v = (x, α)›and * by auto finallyshow ?thesis . next case False let ?θ' = "fmdrop v θ" have *: "fmdrop_set (fmdom' θ ∩ lset (v # vs)) θ = fmdrop_set (fmdom' ?θ' ∩ lset vs) ?θ'" using False by clarsimp (metis Int_Diff Int_commute fmdrop_set_insert insert_Diff_single) from False have"S θ (λ\<Q>\<star> (v # vs) A) = λx<alpha>. S ?θ' (λ\<Q>\<star> vs A)" using‹v = (x, α)›by auto alsohave"… = λx<alpha>. λ\<Q>\<star> vs (S (fmdrop_set (fmdom' ?θ' ∩ lset vs) ?θ') A)" using Cons.IH by (simp only:) alsohave"… = λ\<Q>\<star> (v # vs) (S (fmdrop_set (fmdom' θ ∩ lset (v # vs)) θ) A)" using‹v = (x, α)›and * by auto finallyshow ?thesis . qed qed
lemma generalized_forall_substitution: shows"S θ (∀\<Q>\<star> vs A) = ∀\<Q>\<star> vs (S (fmdrop_set (fmdom' θ ∩ lset vs) θ) A)" proof (induction vs arbitrary: θ) case Nil thenshow ?case by simp next case (Cons v vs) obtain x and α where"v = (x, α)" by fastforce thenshow ?case proof (cases "v ∉ fmdom' θ") case True thenhave *: "fmdom' θ ∩ lset (v # vs) = fmdom' θ ∩ lset vs" by simp from True have"S θ (∀\<Q>\<star> (v # vs) A) = ∀x<alpha>. S θ (∀\<Q>\<star> vs A)" using‹v = (x, α)›by auto alsohave"… = ∀x<alpha>. ∀\<Q>\<star> vs (S (fmdrop_set (fmdom' θ ∩ lset vs) θ) A)" using Cons.IH by (simp only:) alsohave"… = ∀\<Q>\<star> (v # vs) (S (fmdrop_set (fmdom' θ ∩ lset (v # vs)) θ) A)" using‹v = (x, α)›and * by auto finallyshow ?thesis . next case False let ?θ' = "fmdrop v θ" have *: "fmdrop_set (fmdom' θ ∩ lset (v # vs)) θ = fmdrop_set (fmdom' ?θ' ∩ lset vs) ?θ'" using False by clarsimp (metis Int_Diff Int_commute fmdrop_set_insert insert_Diff_single) from False have"S θ (∀\<Q>\<star> (v # vs) A) = ∀x<alpha>. S ?θ' (∀\<Q>\<star> vs A)" using‹v = (x, α)›by auto alsohave"… = ∀x<alpha>. ∀\<Q>\<star> vs (S (fmdrop_set (fmdom' ?θ' ∩ lset vs) ?θ') A)" using Cons.IH by (simp only:) alsohave"… = ∀\<Q>\<star> (v # vs) (S (fmdrop_set (fmdom' θ ∩ lset (v # vs)) θ) A)" using‹v = (x, α)›and * by auto finallyshow ?thesis . qed qed
lemma singleton_substitution_simps: shows"S {(x, α) 🚫 A} (y<beta>) = (if (x, α) ≠ (y, β) then y<beta> else A)" and"S {(x, α) 🚫 A} ({c}<alpha>) = {c}<alpha>" and"S {(x, α) 🚫 A} (B ⏹ C) = (S {(x, α) 🚫 A} B) ⏹ (S {(x, α) 🚫 A} C)" and"S {(x, α) 🚫 A} (λy<beta>. B) = λy<beta>. (if (x, α) = (y, β) then B else S {(x, α) 🚫 A} B)" by (simp_all add: empty_substitution_neutrality fmdrop_fmupd_same)
lemma substitution_preserves_freeness: assumes"y ∉ free_vars A"and"y ≠ z" shows"y ∉ free_vars S {x 🚫 FVar z} A" using assms(1) proof (induction A rule: free_vars_form.induct) case (1 x' α) with assms(2) show ?case using surj_pair[of z] by (cases "x = (x', α)") force+ next case (4 x' α A) thenshow ?case using surj_pair[of z] by (cases "x = (x', α)") (use singleton_substitution_simps(4) in presburger, auto) qed auto
lemma renaming_substitution_minimal_change: assumes"y ∉ vars A"and"y ≠ z" shows"y ∉ vars (S {x 🚫 FVar z} A)" using assms(1) proof (induction A rule: vars_form.induct) case (1 x' α) with assms(2) show ?case using surj_pair[of z] by (cases "x = (x', α)") force+ next case (4 x' α A) thenshow ?case using surj_pair[of z] by (cases "x = (x', α)") (use singleton_substitution_simps(4) in presburger, auto) qed auto
lemma free_var_singleton_substitution_neutrality: assumes"v ∉ free_vars A" shows"S {v 🚫 B} A = A" using assms by
(induction A rule: free_vars_form.induct)
(simp_all, metis empty_substitution_neutrality fmdrop_empty fmdrop_fmupd_same)
lemma identity_singleton_substitution_neutrality: shows"S {v 🚫 FVar v} A = A" by
(induction A rule: free_vars_form.induct)
(simp_all add: empty_substitution_neutrality fmdrop_fmupd_same)
lemma free_var_in_renaming_substitution: assumes"x ≠ y" shows"(x, α) ∉ free_vars (S {(x, α) 🚫 y<alpha>} B)" using assms by (induction B rule: free_vars_form.induct) simp_all
lemma renaming_substitution_preserves_form_size: shows"form_size (S {v 🚫 FVar v'} A) = form_size A" proof (induction A rule: form_size.induct) case (1 x α) thenshow ?case using form_size.elims by auto next case (4 x α A) thenshow ?case by (cases "v = (x, α)") (use singleton_substitution_simps(4) in presburger, auto) qed simp_all
text‹The following lemma corresponds to X5100 in cite‹"andrews:2002"›:›
lemma substitution_composability: assumes"v' ∉ vars B" shows"S {v' 🚫 A} S {v 🚫 FVar v'} B = S {v 🚫 A} B" using assms proof (induction B arbitrary: v') case (FAbs w C) thenshow ?case proof (cases "v = w") case True from‹v' ∉ vars (FAbs w C)›have"v' ∉ free_vars (FAbs w C)" using free_vars_in_all_vars by blast thenhave"S {v' 🚫 A} (FAbs w C) = FAbs w C" by (rule free_var_singleton_substitution_neutrality) from‹v = w›have"v ∉ free_vars (FAbs w C)" using surj_pair[of w] by fastforce thenhave"S {v 🚫 A} (FAbs w C) = FAbs w C" by (fact free_var_singleton_substitution_neutrality) alsofrom‹S {v' 🚫 A} (FAbs w C) = FAbs w C›have"… = S {v' 🚫 A} (FAbs w C)" by (simp only:) alsofrom‹v = w›have"… = S {v' 🚫 A} S {v 🚫 FVar v'} (FAbs w C)" using free_var_singleton_substitution_neutrality[OF ‹v ∉ free_vars (FAbs w C)›] by (simp only:) finallyshow ?thesis .. next case False from FAbs.prems have"v' ∉ vars C" using surj_pair[of w] by fastforce thenshow ?thesis proof (cases "v' = w") case True with FAbs.prems show ?thesis using vars_form.elims by auto next case False from‹v ≠ w›have"S {v 🚫 A} (FAbs w C) = FAbs w (S {v 🚫 A} C)" using surj_pair[of w] by fastforce alsofrom FAbs.IH have"… = FAbs w (S {v' 🚫 A} S {v 🚫 FVar v'} C)" using‹v' ∉ vars C›by simp alsofrom‹v' ≠ w›have"… = S {v' 🚫 A} (FAbs w (S {v 🚫 FVar v'} C))" using surj_pair[of w] by fastforce alsofrom‹v ≠ w›have"… = S {v' 🚫 A} S {v 🚫 FVar v'} (FAbs w C)" using surj_pair[of w] by fastforce finallyshow ?thesis .. qed qed qed auto
text‹The following lemma corresponds to X5101 in cite‹"andrews:2002"›:›
lemma renaming_substitution_composability: assumes"z ∉ free_vars A"and"is_free_for (FVar z) x A" shows"S {z 🚫 FVar y} S {x 🚫 FVar z} A = S {x 🚫 FVar y} A" using assms proof (induction A arbitrary: z) case (FVar v) thenshow ?case using surj_pair[of v] and surj_pair[of z] by fastforce next case (FCon k) thenshow ?case using surj_pair[of k] by fastforce next case (FApp B C) let ?θzy = "{z 🚫 FVar y}"and ?θxz = "{x 🚫 FVar z}"and ?θxy = "{x 🚫 FVar y}" from‹is_free_for (FVar z) x (B ⏹ C)›have"is_free_for (FVar z) x B"and"is_free_for (FVar z) x C" using is_free_for_from_app by iprover+ moreoverfrom‹z ∉ free_vars (B ⏹ C)›have"z ∉ free_vars B"and"z ∉ free_vars C" by simp_all ultimatelyhave *: "S ?θzyS ?θxz B = S ?θxy B"and **: "S ?θzyS ?θxz C = S ?θxy C" using FApp.IH by simp_all have"S ?θzyS ?θxz (B ⏹ C) = (S ?θzyS ?θxz B) ⏹ (S ?θzyS ?θxz C)" by simp alsofrom * and ** have"… = (S ?θxy B) ⏹ (S ?θxy C)" by (simp only:) alsohave"… = S ?θxy (B ⏹ C)" by simp finallyshow ?case . next case (FAbs w B) let ?θzy = "{z 🚫 FVar y}"and ?θxz = "{x 🚫 FVar z}"and ?θxy = "{x 🚫 FVar y}" show ?case proof (cases "x = w") case True thenshow ?thesis proof (cases "z = w") case True with‹x = w›have"x ∉ free_vars (FAbs w B)"and"z ∉ free_vars (FAbs w B)" using surj_pair[of w] by fastforce+ from‹x ∉ free_vars (FAbs w B)›have"S ?θxy (FAbs w B) = FAbs w B" by (fact free_var_singleton_substitution_neutrality) alsofrom‹z ∉ free_vars (FAbs w B)›have"… = S ?θzy (FAbs w B)" by (fact free_var_singleton_substitution_neutrality[symmetric]) alsofrom‹x ∉ free_vars (FAbs w B)›have"… = S ?θzyS ?θxz (FAbs w B)" using free_var_singleton_substitution_neutrality by simp finallyshow ?thesis .. next case False with‹x = w›have"z ∉ free_vars B"and"x ∉ free_vars (FAbs w B)" using‹z ∉ free_vars (FAbs w B)›and surj_pair[of w] by fastforce+ from‹z ∉ free_vars B›have"S ?θzy B = B" by (fact free_var_singleton_substitution_neutrality) from‹x ∉ free_vars (FAbs w B)›have"S ?θxy (FAbs w B) = FAbs w B" by (fact free_var_singleton_substitution_neutrality) alsofrom‹S ?θzy B = B›have"… = FAbs w (S ?θzy B)" by (simp only:) alsofrom‹z ∉ free_vars (FAbs w B)›have"… = S ?θzy (FAbs w B)" by (simp add: ‹FAbs w B = FAbs w (S ?θzy B)› free_var_singleton_substitution_neutrality) alsofrom‹x ∉ free_vars (FAbs w B)›have"… = S ?θzyS ?θxz (FAbs w B)" using free_var_singleton_substitution_neutrality by simp finallyshow ?thesis .. qed next case False thenshow ?thesis proof (cases "z = w") case True have"x ∉ free_vars B" proof (rule ccontr) assume"¬ x ∉ free_vars B" with‹x ≠ w›have"x ∈ free_vars (FAbs w B)" using surj_pair[of w] by fastforce thenobtain p where"p ∈ positions (FAbs w B)"and"is_free_at x p (FAbs w B)" using free_vars_in_is_free_at by blast with‹is_free_for (FVar z) x (FAbs w B)›have"¬ in_scope_of_abs z p (FAbs w B)" by (meson empty_is_position is_free_at_in_free_vars is_free_at_in_var is_free_for_def) moreoverobtain p' where"p = « # p'" using is_free_at_from_absE[OF ‹is_free_at x p (FAbs w B)›] by blast ultimatelyhave"z ≠ w" using in_scope_of_abs_in_abs by blast with‹z = w›show False by contradiction qed thenhave *: "S ?θxy B = S ?θxz B" using free_var_singleton_substitution_neutrality by auto from‹x ≠ w›have"S ?θxy (FAbs w B) = FAbs w (S ?θxy B)" using surj_pair[of w] by fastforce alsofrom * have"… = FAbs w (S ?θxz B)" by (simp only:) alsofrom FAbs.prems(1) have"… = S ?θzy (FAbs w (S ?θxz B))" using‹x ∉ free_vars B›and free_var_singleton_substitution_neutrality by auto alsofrom‹x ≠ w›have"… = S ?θzyS ?θxz (FAbs w B)" using surj_pair[of w] by fastforce finallyshow ?thesis .. next case False obtain vwand α where"w = (vw, α)" by fastforce with‹is_free_for (FVar z) x (FAbs w B)›and‹x ≠ w›have"is_free_for (FVar z) x B" using is_free_for_from_abs by iprover moreoverfrom‹z ∉ free_vars (FAbs w B)›and‹z ≠ w›and‹w = (vw, α)›have"z ∉ free_vars B" by simp ultimatelyhave *: "S ?θzyS ?θxz B = S ?θxy B" using FAbs.IH by simp from‹x ≠ w›have"S ?θxy (FAbs w B) = FAbs w (S ?θxy B)" using‹w = (vw, α)›and free_var_singleton_substitution_neutrality by simp alsofrom * have"… = FAbs w (S ?θzyS ?θxz B)" by (simp only:) alsofrom‹z ≠ w›have"… = S ?θzy (FAbs w (S ?θxz B))" using‹w = (vw, α)›and free_var_singleton_substitution_neutrality by simp alsofrom‹x ≠ w›have"… = S ?θzyS ?θxz (FAbs w B)" using‹w = (vw, α)›and free_var_singleton_substitution_neutrality by simp finallyshow ?thesis .. qed qed qed
lemma absent_vars_substitution_preservation: assumes"v ∉ vars A" and"∀v' ∈ fmdom' θ. v ∉ vars (θ $$! v')" shows"v ∉ vars (S θ A)" using assms proof (induction A arbitrary: θ) case (FVar v') thenshow ?case using surj_pair[of v'] by (cases "v' ∈ fmdom' θ") (use fmlookup_dom'_iff in force)+ next case (FCon k) thenshow ?case using surj_pair[of k] by fastforce next case FApp thenshow ?case by simp next case (FAbs w B) from FAbs.prems(1) have"v ∉ vars B" using vars_form.elims by auto thenshow ?case proof (cases "w ∈ fmdom' θ") case True from FAbs.prems(2) have"∀v' ∈ fmdom' (fmdrop w θ). v ∉ vars ((fmdrop w θ) $$! v')" by auto with‹v ∉ vars B›have"v ∉ vars (S (fmdrop w θ) B)" by (fact FAbs.IH) with FAbs.prems(1) have"v ∉ vars (FAbs w (S (fmdrop w θ) B))" using surj_pair[of w] by fastforce moreoverfrom True have"S θ (FAbs w B) = FAbs w (S (fmdrop w θ) B)" using surj_pair[of w] by fastforce ultimatelyshow ?thesis by simp next case False thenshow ?thesis using FAbs.IH and FAbs.prems and surj_pair[of w] by fastforce qed qed
lemma substitution_free_absorption: assumes"θ $$ v = None"and"v ∉ free_vars B" shows"S ({v 🚫 A} ++f θ) B = S θ B" using assms proof (induction B arbitrary: θ) case (FAbs w B) show ?case proof (cases "v ≠ w") case True with FAbs.prems(2) have"v ∉ free_vars B" using surj_pair[of w] by fastforce thenshow ?thesis proof (cases "w ∈ fmdom' θ") case True thenhave"S ({v 🚫 A} ++f θ) (FAbs w B) = FAbs w (S (fmdrop w ({v 🚫 A} ++f θ)) B)" using surj_pair[of w] by fastforce alsofrom‹v ≠ w›and True have"… = FAbs w (S ({v 🚫 A} ++f fmdrop w θ) B)" by (simp add: fmdrop_fmupd) alsofrom FAbs.prems(1) and‹v ∉ free_vars B›have"… = FAbs w (S (fmdrop w θ) B)" using FAbs.IH by simp alsofrom True have"… = S θ (FAbs w B)" using surj_pair[of w] by fastforce finallyshow ?thesis . next case False with FAbs.prems(1) have"S ({v 🚫 A} ++f θ) (FAbs w B) = FAbs w (S ({v 🚫 A} ++f θ) B)" using‹v ≠ w›and surj_pair[of w] by fastforce alsofrom FAbs.prems(1) and‹v ∉ free_vars B›have"… = FAbs w (S θ B)" using FAbs.IH by simp alsofrom False have"… = S θ (FAbs w B)" using surj_pair[of w] by fastforce finallyshow ?thesis . qed next case False thenhave"fmdrop w ({v 🚫 A} ++f θ) = fmdrop w θ" by (simp add: fmdrop_fmupd_same) thenshow ?thesis using surj_pair[of w] by (metis (no_types, lifting) fmdrop_idle' substitute.simps(4)) qed qed fastforce+
lemma substitution_absorption: assumes"θ $$ v = None"and"v ∉ vars B" shows"S ({v 🚫 A} ++f θ) B = S θ B" using assms by (meson free_vars_in_all_vars in_mono substitution_free_absorption)
lemma is_free_for_with_renaming_substitution: assumes"is_free_for A x B" and"y ∉ vars B" and"x ∉ fmdom' θ" and"∀v ∈ fmdom' θ. y ∉ vars (θ $$! v)" and"∀v ∈ fmdom' θ. is_free_for (θ $$! v) v B" shows"is_free_for A y (S ({x 🚫 FVar y} ++f θ) B)" using assms proof (induction B arbitrary: θ) case (FVar w) thenshow ?case proof (cases "w = x") case True with FVar.prems(3) have"S ({x 🚫 FVar y} ++f θ) (FVar w) = FVar y" using surj_pair[of w] by fastforce thenshow ?thesis using self_subform_is_at_top by fastforce next case False thenshow ?thesis proof (cases "w ∈ fmdom' θ") case True from False have"S ({x 🚫 FVar y} ++f θ) (FVar w) = S θ (FVar w)" using substitution_absorption and surj_pair[of w] by force alsofrom True have"… = θ $$! w" using surj_pair[of w] by (metis fmdom'_notI option.case_eq_if substitute.simps(1)) finallyhave"S ({x 🚫 FVar y} ++f θ) (FVar w) = θ $$! w" . moreoverfrom True and FVar.prems(4) have"y ∉ vars (θ $$! w)" by blast ultimatelyshow ?thesis using form_is_free_for_absent_var by presburger next case False with FVar.prems(3) and‹w ≠ x›have"S ({x 🚫 FVar y} ++f θ) (FVar w) = FVar w" using surj_pair[of w] by fastforce with FVar.prems(2) show ?thesis using form_is_free_for_absent_var by presburger qed qed next case (FCon k) thenshow ?case using surj_pair[of k] by fastforce next case (FApp C D) from FApp.prems(2) have"y ∉ vars C"and"y ∉ vars D" by simp_all from FApp.prems(1) have"is_free_for A x C"and"is_free_for A x D" using is_free_for_from_app by iprover+ have"∀v ∈ fmdom' θ. is_free_for (θ $$! v) v C ∧ is_free_for (θ $$! v) v D" proof (rule ballI) fix v assume"v ∈ fmdom' θ" with FApp.prems(5) have"is_free_for (θ $$! v) v (C ⏹ D)" by blast thenshow"is_free_for (θ $$! v) v C ∧ is_free_for (θ $$! v) v D" using is_free_for_from_app by iprover+ qed thenhave
*: "∀v ∈ fmdom' θ. is_free_for (θ $$! v) v C"and **: "∀v ∈ fmdom' θ. is_free_for (θ $$! v) v D" by auto have"S ({x 🚫 FVar y} ++f θ) (C ⏹ D) = (S ({x 🚫 FVar y} ++f θ) C) ⏹ (S ({x 🚫 FVar y} ++f θ) D)" by simp moreoverhave"is_free_for A y (S ({x 🚫 FVar y} ++f θ) C)" by (rule FApp.IH(1)[OF ‹is_free_for A x C›‹y ∉ vars C› FApp.prems(3,4) *]) moreoverhave"is_free_for A y (S ({x 🚫 FVar y} ++f θ) D)" by (rule FApp.IH(2)[OF ‹is_free_for A x D›‹y ∉ vars D› FApp.prems(3,4) **]) ultimatelyshow ?case using is_free_for_in_app by simp next case (FAbs w B) obtain xwand αwwhere"w = (xw, αw)" by fastforce from FAbs.prems(2) have"y ∉ vars B" using vars_form.elims by auto thenshow ?case proof (cases "w = x") case True from True and‹x ∉ fmdom' θ›have"w ∉ fmdom' θ"and"x ∉ free_vars (FAbs w B)" using‹w = (xw, αw)›by fastforce+ with True have"S ({x 🚫 FVar y} ++f θ) (FAbs w B) = S θ (FAbs w B)" using substitution_free_absorption by blast alsohave"… = FAbs w (S θ B)" using‹w = (xw, αw)›‹w ∉ fmdom' θ› substitute.simps(4) by presburger finallyhave"S ({x 🚫 FVar y} ++f θ) (FAbs w B) = FAbs w (S θ B)" . moreoverfrom‹S θ (FAbs w B) = FAbs w (S θ B)›have"y ∉ vars (FAbs w (S θ B))" using absent_vars_substitution_preservation[OF FAbs.prems(2,4)] by simp ultimatelyshow ?thesis using is_free_for_absent_var by (simp only:) next case False obtain vwand αwwhere"w = (vw, αw)" by fastforce from FAbs.prems(1) and‹w ≠ x›and‹w = (vw, αw)›have"is_free_for A x B" using is_free_for_from_abs by iprover thenshow ?thesis proof (cases "w ∈ fmdom' θ") case True thenhave"S ({x 🚫 FVar y} ++f θ) (FAbs w B) = FAbs w (S (fmdrop w ({x 🚫 FVar y} ++f θ)) B)" using‹w = (vw, αw)›by (simp add: fmdrop_idle') alsofrom‹w ≠ x›and True have"… = FAbs w (S ({x 🚫 FVar y} ++f fmdrop w θ) B)" by (simp add: fmdrop_fmupd) finally have *: "S ({x 🚫 FVar y} ++f θ) (FAbs w B) = FAbs w (S ({x 🚫 FVar y} ++f fmdrop w θ) B)" . have"∀v ∈ fmdom' (fmdrop w θ). is_free_for (fmdrop w θ $$! v) v B" proof fix v assume"v ∈ fmdom' (fmdrop w θ)" with FAbs.prems(5) have"is_free_for (fmdrop w θ $$! v) v (FAbs w B)" by auto moreoverfrom‹v ∈ fmdom' (fmdrop w θ)›have"v ≠ w" by auto ultimatelyshow"is_free_for (fmdrop w θ $$! v) v B" unfolding‹w = (vw, αw)›using is_free_for_from_abs by iprover qed moreoverfrom FAbs.prems(3) have"x ∉ fmdom' (fmdrop w θ)" by simp moreoverfrom FAbs.prems(4) have"∀v ∈ fmdom' (fmdrop w θ). y ∉ vars (fmdrop w θ $$! v)" by simp ultimatelyhave"is_free_for A y (S ({x 🚫 FVar y} ++f fmdrop w θ) B)" using‹is_free_for A x B›and‹y ∉ vars B›and FAbs.IH by iprover thenshow ?thesis proof (cases "x ∉ free_vars B") case True have"y ∉ vars (S ({x 🚫 FVar y} ++f θ) (FAbs w B))" proof - have"S ({x 🚫 FVar y} ++f θ) (FAbs w B) = FAbs w (S ({x 🚫 FVar y} ++f fmdrop w θ) B)" using * . alsofrom‹x ∉ free_vars B›and FAbs.prems(3) have"… = FAbs w (S (fmdrop w θ) B)" using substitution_free_absorption by (simp add: fmdom'_notD) finallyhave"S ({x 🚫 FVar y} ++f θ) (FAbs w B) = FAbs w (S (fmdrop w θ) B)" . with FAbs.prems(2) and‹w = (vw, αw)›and FAbs.prems(4) show ?thesis using absent_vars_substitution_preservation by auto qed thenshow ?thesis using is_free_for_absent_var by simp next case False have"w ∉ free_vars A" proof (rule ccontr) assume"¬ w ∉ free_vars A" with False and‹w ≠ x›have"¬ is_free_for A x (FAbs w B)" using form_with_free_binder_not_free_for by simp with FAbs.prems(1) show False by contradiction qed with‹is_free_for A y (S ({x 🚫 FVar y} ++f fmdrop w θ) B)› have"is_free_for A y (FAbs w (S ({x 🚫 FVar y} ++f fmdrop w θ) B))" unfolding‹w = (vw, αw)›using is_free_for_to_abs by iprover with * show ?thesis by (simp only:) qed next case False have"∀v ∈ fmdom' θ. is_free_for (θ $$! v) v B" proof (rule ballI) fix v assume"v ∈ fmdom' θ" with FAbs.prems(5) have"is_free_for (θ $$! v) v (FAbs w B)" by blast moreoverfrom‹v ∈ fmdom' θ›and‹w ∉ fmdom' θ›have"v ≠ w" by blast ultimatelyshow"is_free_for (θ $$! v) v B" unfolding‹w = (vw, αw)›using is_free_for_from_abs by iprover qed with‹is_free_for A x B›and‹y ∉ vars B›and FAbs.prems(3,4) have"is_free_for A y (S ({x 🚫 FVar y} ++f θ) B)" using FAbs.IH by iprover thenshow ?thesis proof (cases "x ∉ free_vars B") case True have"y ∉ vars (S ({x 🚫 FVar y} ++f θ) (FAbs w B))" proof - from False and‹w = (vw, αw)›and‹w ≠ x› have"S ({x 🚫 FVar y} ++f θ) (FAbs w B) = FAbs w (S ({x 🚫 FVar y} ++f θ) B)" by auto alsofrom‹x ∉ free_vars B›and FAbs.prems(3) have"… = FAbs w (S θ B)" using substitution_free_absorption by (simp add: fmdom'_notD) finallyhave"S ({x 🚫 FVar y} ++f θ) (FAbs w B) = FAbs w (S θ B)" . with FAbs.prems(2,4) and‹w = (vw, αw)›show ?thesis using absent_vars_substitution_preservation by auto qed thenshow ?thesis using is_free_for_absent_var by simp next case False have"w ∉ free_vars A" proof (rule ccontr) assume"¬ w ∉ free_vars A" with False and‹w ≠ x›have"¬ is_free_for A x (FAbs w B)" using form_with_free_binder_not_free_for by simp with FAbs.prems(1) show False by contradiction qed with‹is_free_for A y (S ({x 🚫 FVar y} ++f θ) B)› have"is_free_for A y (FAbs w (S ({x 🚫 FVar y} ++f θ) B))" unfolding‹w = (vw, αw)›using is_free_for_to_abs by iprover moreoverfrom‹w ∉ fmdom' θ›and‹w ≠ x›and FAbs.prems(3) have"S ({x 🚫 FVar y} ++f θ) (FAbs w B) = FAbs w (S ({x 🚫 FVar y} ++f θ) B)" using surj_pair[of w] by fastforce ultimatelyshow ?thesis by (simp only:) qed qed qed qed
text‹
The following lemma allows us to fuse a singleton substitution and a simultaneous substitution,
as long as the variable of the former does not occur anywhere in the latter: ›
lemma substitution_fusion: assumes"is_substitution θ"and"is_substitution {v 🚫 A}" and"θ $$ v = None"and"∀v' ∈ fmdom' θ. v ∉ vars (θ $$! v')" shows"S {v 🚫 A} S θ B = S ({v 🚫 A} ++f θ) B" using assms(1,3,4) proof (induction B arbitrary: θ) case (FVar v') thenshow ?case proof (cases "v' ∉ fmdom' θ") case True thenshow ?thesis using surj_pair[of v'] by fastforce next case False thenobtain A' where"θ $$ v' = Some A'" by (meson fmlookup_dom'_iff) with False and FVar.prems(3) have"v ∉ vars A'" by fastforce thenhave"S {v 🚫 A} A' = A'" using free_var_singleton_substitution_neutrality and free_vars_in_all_vars by blast from‹θ $$ v' = Some A'›have"S {v 🚫 A} S θ (FVar v') = S {v 🚫 A} A'" using surj_pair[of v'] by fastforce alsofrom‹S {v 🚫 A} A' = A'›have"… = A'" by (simp only:) alsofrom‹θ $$ v' = Some A'›and‹θ $$ v = None›have"… = S ({v 🚫 A} ++f θ) (FVar v')" using surj_pair[of v'] by fastforce finallyshow ?thesis . qed next case (FCon k) thenshow ?case using surj_pair[of k] by fastforce next case (FApp C D) have"S {v 🚫 A} S θ (C ⏹ D) = S {v 🚫 A} ((S θ C) ⏹ (S θ D))" by auto alsohave"… = (S {v 🚫 A} S θ C) ⏹ (S {v 🚫 A} S θ D)" by simp alsofrom FApp.IH have"… = (S ({v 🚫 A} ++f θ) C) ⏹ (S ({v 🚫 A} ++f θ) D)" using FApp.prems(1,2,3) by presburger alsohave"… = S ({v 🚫 A} ++f θ) (C ⏹ D)" by simp finallyshow ?case . next case (FAbs w C) obtain vwand α where"w = (vw, α)" by fastforce thenshow ?case proof (cases "v ≠ w") case True show ?thesis proof (cases "w ∉ fmdom' θ") case True thenhave"S {v 🚫 A} S θ (FAbs w C) = S {v 🚫 A} (FAbs w (S θ C))" by (simp add: ‹w = (vw, α)›) alsofrom‹v ≠ w›have"… = FAbs w (S {v 🚫 A} S θ C)" by (simp add: ‹w = (vw, α)›) alsofrom FAbs.IH have"… = FAbs w (S ({v 🚫 A} ++f θ) C)" using FAbs.prems(1,2,3) by blast alsofrom‹v ≠ w›and True have"… = S ({v 🚫 A} ++f θ) (FAbs w C)" by (simp add: ‹w = (vw, α)›) finallyshow ?thesis . next case False thenhave"S {v 🚫 A} S θ (FAbs w C) = S {v 🚫 A} (FAbs w (S (fmdrop w θ) C))" by (simp add: ‹w = (vw, α)›) alsofrom‹v ≠ w›have"… = FAbs w (S {v 🚫 A} S (fmdrop w θ) C)" by (simp add: ‹w = (vw, α)›) alsohave"… = FAbs w (S ({v 🚫 A} ++f fmdrop w θ) C)" proof - from‹is_substitution θ›have"is_substitution (fmdrop w θ)" by fastforce moreoverfrom‹θ $$ v = None›have"(fmdrop w θ) $$ v = None" by force moreoverfrom FAbs.prems(3) have"∀v' ∈ fmdom' (fmdrop w θ). v ∉ vars ((fmdrop w θ) $$! v')" by force ultimatelyshow ?thesis using FAbs.IH by blast qed alsofrom‹v ≠ w›have"… = S ({v 🚫 A} ++f θ) (FAbs w C)" by (simp add: ‹w = (vw, α)› fmdrop_idle') finallyshow ?thesis . qed next case False thenshow ?thesis proof (cases "w ∉ fmdom' θ") case True thenhave"S {v 🚫 A} S θ (FAbs w C) = S {v 🚫 A} (FAbs w (S θ C))" by (simp add: ‹w = (vw, α)›) alsofrom‹¬ v ≠ w›have"… = FAbs w (S θ C)" using‹w = (vw, α)›and singleton_substitution_simps(4) by presburger alsofrom‹¬ v ≠ w›and True have"… = FAbs w (S (fmdrop w ({v 🚫 A} ++f θ)) C)" by (simp add: fmdrop_fmupd_same fmdrop_idle') alsofrom‹¬ v ≠ w›have"… = S ({v 🚫 A} ++f θ) (FAbs w C)" by (simp add: ‹w = (vw, α)›) finallyshow ?thesis . next case False thenhave"S {v 🚫 A} S θ (FAbs w C) = S {v 🚫 A} (FAbs w (S (fmdrop w θ) C))" by (simp add: ‹w = (vw, α)›) alsofrom‹¬ v ≠ w›have"… = FAbs w (S (fmdrop w θ) C)" using‹θ $$ v = None›and False by (simp add: fmdom'_notI) alsofrom‹¬ v ≠ w›have"… = FAbs w (S (fmdrop w ({v 🚫 A} ++f θ)) C)" by (simp add: fmdrop_fmupd_same) alsofrom‹¬ v ≠ w›and False and‹θ $$ v = None›have"… = S ({v 🚫 A} ++f θ) (FAbs w C)" by (simp add: fmdom'_notI) finallyshow ?thesis . qed qed qed
lemma updated_substitution_is_substitution: assumes"v ∉ fmdom' θ"and"is_substitution (θ(v 🚫 A))" shows"is_substitution θ" unfolding is_substitution_def proof (intro ballI) fix v' :: var obtain x and α where"v' = (x, α)" by fastforce assume"v' ∈ fmdom' θ" with assms(2)[unfolded is_substitution_def] have"v' ∈ fmdom' (θ(v 🚫 A))" by simp with assms(2)[unfolded is_substitution_def] have"θ(v 🚫 A) $$! (x, α) ∈ wffs<alpha>" using‹v' = (x, α)›by fastforce with assms(1) and‹v' ∈ fmdom' θ›and‹v' = (x, α)›have"θ $$! (x, α) ∈ wffs<alpha>" by (metis fmupd_lookup) thenshow"case v' of (x, α) → θ $$! (x, α) ∈ wffs<alpha>" by (simp add: ‹v' = (x, α)›) qed
definition is_renaming_substitution where
[iff]: "is_renaming_substitution θ ⟷ is_substitution θ ∧ fmpred (λ_ A. ∃v. A = FVar v) θ"
text‹
The following lemma proves that $ \d{\textsf{S}}\;^{x^1_{\alpha_1}\;\dots\;x^n_{\alpha_n}}_{y^1_{\alpha_1}\;\dots\;y^n_{\alpha_n}} B
= \d{\textsf{S}}\;^{x^1_{\alpha_1}}_{y^1_{\alpha_1}}\;\cdots\; \d{\textsf{S}}\;^{x^n_{\alpha_n}}_{y^n_{\alpha_n}} B$ provided that
▪ $x^1_{\alpha_1}\;\dots\;x^n_{\alpha_n}$ are distinct variables
▪ $y^1_{\alpha_1}\;\dots\;y^n_{\alpha_n}$ are distinct variables, distinct from
$x^1_{\alpha_1}\;\dots\;x^n_{\alpha_n}$ and from all variables in ‹B› (i.e., they are fresh
variables)
In other words, simultaneously renaming distinct variables with fresh ones is equivalent to
renaming each variable one at a time. ›
lemma fresh_vars_substitution_unfolding: fixes ps :: "(var × form) list" assumes"θ = fmap_of_list ps"and"is_renaming_substitution θ" and"distinct (map fst ps)"and"distinct (map snd ps)" and"vars (fmran' θ) ∩ (fmdom' θ ∪ vars B) = {}" shows"S θ B = foldr (λ(x, y) C. S {x 🚫 y} C) ps B" using assms proof (induction ps arbitrary: θ) case Nil thenhave"θ = {$$}" by simp thenhave"S θ B = B" using empty_substitution_neutrality by (simp only:) with Nil show ?case by simp next case (Cons p ps) from Cons.prems(1,2) obtain x and y where"θ $$ (fst p) = Some (FVar y)"and"p = (x, FVar y)" using surj_pair[of p] by fastforce let ?θ' = "fmap_of_list ps" from Cons.prems(1) and‹p = (x, FVar y)›have"θ = fmupd x (FVar y) ?θ'" by simp moreoverfrom Cons.prems(3) and‹p = (x, FVar y)›have"x ∉ fmdom' ?θ'" by simp ultimatelyhave"θ = {x 🚫 FVar y} ++f ?θ'" using fmap_singleton_comm by fastforce with Cons.prems(2) and‹x ∉ fmdom' ?θ'›have"is_renaming_substitution ?θ'" unfolding is_renaming_substitution_def and‹θ = fmupd x (FVar y) ?θ'› using updated_substitution_is_substitution by (metis fmdiff_fmupd fmdom'_notD fmpred_filter) from Cons.prems(2) and‹θ = fmupd x (FVar y) ?θ'›have"is_renaming_substitution {x 🚫 FVar y}" by auto have" foldr (λ(x, y) C. S {x 🚫 y} C) (p # ps) B = S {x 🚫 FVar y} (foldr (λ(x, y) C. S {x 🚫 y} C) ps B)" by (simp add: ‹p = (x, FVar y)›) alsohave"… = S {x 🚫 FVar y} S ?θ' B" proof - from Cons.prems(3,4) have"distinct (map fst ps)"and"distinct (map snd ps)" by fastforce+ moreoverhave"vars (fmran' ?θ') ∩ (fmdom' ?θ' ∪ vars B) = {}" proof - have"vars (fmran' θ) = vars ({FVar y} ∪ fmran' ?θ')" using‹θ = fmupd x (FVar y) ?θ'›and‹x ∉ fmdom' ?θ'›by (metis fmdom'_notD fmran'_fmupd) thenhave"vars (fmran' θ) = {y} ∪ vars (fmran' ?θ')" using singleton_form_set_vars by auto moreoverhave"fmdom' θ = {x} ∪ fmdom' ?θ'" by (simp add: ‹θ = {x 🚫 FVar y} ++f ?θ'›) ultimatelyshow ?thesis using Cons.prems(5) by auto qed ultimatelyshow ?thesis using Cons.IH and‹is_renaming_substitution ?θ'›by simp qed alsohave"… = S ({x 🚫 FVar y} ++f ?θ') B" proof (rule substitution_fusion) show"is_substitution ?θ'" using‹is_renaming_substitution ?θ'›by simp show"is_substitution {x 🚫 FVar y}" using‹is_renaming_substitution {x 🚫 FVar y}›by simp show"?θ' $$ x = None" using‹x ∉ fmdom' ?θ'›by blast show"∀v' ∈ fmdom' ?θ'. x ∉ vars (?θ' $$! v')" proof - have"x ∈ fmdom' θ" using‹θ = {x 🚫 FVar y} ++f ?θ'›by simp thenhave"x ∉ vars (fmran' θ)" using Cons.prems(5) by blast moreoverhave"{?θ' $$! v' | v'. v' ∈ fmdom' ?θ'} ⊆ fmran' θ" unfolding‹θ = ?θ'(x 🚫 FVar y)›using‹?θ' $$ x = None› by (auto simp add: fmlookup_of_list fmlookup_dom'_iff fmran'I weak_map_of_SomeI) ultimatelyshow ?thesis by force qed qed alsofrom‹θ = {x 🚫 FVar y} ++f ?θ'›have"… = S θ B" by (simp only:) finallyshow ?case .. qed
lemma free_vars_agreement_substitution_equality: assumes"fmdom' θ = fmdom' θ'" and"∀v ∈ free_vars A ∩ fmdom' θ. θ $$! v = θ' $$! v" shows"S θ A = S θ' A" using assms proof (induction A arbitrary: θ θ') case (FVar v) have"free_vars (FVar v) = {v}" using surj_pair[of v] by fastforce with FVar have"θ $$! v = θ' $$! v" by force with FVar.prems(1) show ?case using surj_pair[of v] by (metis fmdom'_notD fmdom'_notI option.collapse substitute.simps(1)) next case FCon thenshow ?case by (metis prod.exhaust_sel substitute.simps(2)) next case (FApp B C) have"S θ (B ⏹ C) = (S θ B) ⏹ (S θ C)" by simp alsohave"… = (S θ' B) ⏹ (S θ' C)" proof - have"∀v ∈ free_vars B ∩ fmdom' θ. θ $$! v = θ' $$! v" and"∀v ∈ free_vars C ∩ fmdom' θ. θ $$! v = θ' $$! v" using FApp.prems(2) by auto with FApp.IH(1,2) and FApp.prems(1) show ?thesis by blast qed finallyshow ?case by simp next case (FAbs w B) from FAbs.prems(1,2) have *: "∀v ∈ free_vars B - {w} ∩ fmdom' θ. θ $$! v = θ' $$! v" using surj_pair[of w] by fastforce show ?case proof (cases "w ∈ fmdom' θ") case True thenhave"S θ (FAbs w B) = FAbs w (S (fmdrop w θ) B)" using surj_pair[of w] by fastforce alsohave"… = FAbs w (S (fmdrop w θ') B)" proof - from * have"∀v ∈ free_vars B ∩ fmdom' (fmdrop w θ). (fmdrop w θ) $$! v = (fmdrop w θ') $$! v" by simp moreoverhave"fmdom' (fmdrop w θ) = fmdom' (fmdrop w θ')" by (simp add: FAbs.prems(1)) ultimatelyshow ?thesis using FAbs.IH by blast qed finallyshow ?thesis using FAbs.prems(1) and True and surj_pair[of w] by fastforce next case False thenhave"S θ (FAbs w B) = FAbs w (S θ B)" using surj_pair[of w] by fastforce alsohave"… = FAbs w (S θ' B)" proof - from * have"∀v ∈ free_vars B ∩ fmdom' θ. θ $$! v = θ' $$! v" using False by blast with FAbs.prems(1) show ?thesis using FAbs.IH by blast qed finallyshow ?thesis using FAbs.prems(1) and False and surj_pair[of w] by fastforce qed qed
text‹
The following lemma proves that $ \d{\textsf{S}}\;^{x_\alpha}_{A_\alpha}\; \d{\textsf{S}}\;^{x^1_{\alpha_1}\;\dots\;x^n_{\alpha_n}}_{A^1_{\alpha_1}\;\dots\;A^n_{\alpha_n}} B
= \d{\textsf{S}}\;{ \begingroup\setlength\arraycolsep{2pt} \begin{matrix} \scriptstyle{x_\alpha} & \scriptstyle{x^1_{\alpha_1}} & \scriptstyle{\dots} & \scriptstyle{x^n_{\alpha_n}} \\ \scriptstyle{A_\alpha} & \scriptstyle{\d{\small{\textsf{S}}}\;^{x_\alpha}_{A_\alpha} A^1_{\alpha_1}}
& \scriptstyle{\dots} & \scriptstyle{\d{\small{\textsf{S}}}\;^{x_\alpha}_{A_\alpha} A^n_{\alpha_n}} \end{matrix} \endgroup} B$ provided that $x_\alpha$ is distinct from $x^1_{\alpha_1}, \dots, x^n_{\alpha_n}$
and $A^i_{\alpha_i}$ is free for $x^i_{\alpha_i}$ in $B$: ›
lemma substitution_consolidation: assumes"v ∉ fmdom' θ" and"∀v' ∈ fmdom' θ. is_free_for (θ $$! v') v' B" shows"S {v 🚫 A} S θ B = S ({v 🚫 A} ++f fmmap (λA'. S {v 🚫 A} A') θ) B" using assms proof (induction B arbitrary: θ) case (FApp B C) have"∀v' ∈ fmdom' θ. is_free_for (θ $$! v') v' B ∧ is_free_for (θ $$! v') v' C" proof fix v' assume"v' ∈ fmdom' θ" with FApp.prems(2) have"is_free_for (θ $$! v') v' (B ⏹ C)" by blast thenshow"is_free_for (θ $$! v') v' B ∧ is_free_for (θ $$! v') v' C" using is_free_for_from_app by iprover qed with FApp.IH and FApp.prems(1) show ?case by simp next case (FAbs w B) let ?θ' = "fmmap (λA'. S {v 🚫 A} A') θ" show ?case proof (cases "w ∈ fmdom' θ") case True thenhave"w ∈ fmdom' ?θ'" by simp with True and FAbs.prems have"v ≠ w" by blast from True have"S {v 🚫 A} S θ (FAbs w B) = S {v 🚫 A} (FAbs w (S (fmdrop w θ) B))" using surj_pair[of w] by fastforce alsofrom‹v ≠ w›have"… = FAbs w (S {v 🚫 A} S (fmdrop w θ) B)" using surj_pair[of w] by fastforce alsohave"… = FAbs w (S (fmdrop w ({v 🚫 A} ++f ?θ')) B)" proof - obtain xwand αwwhere"w = (xw, αw)" by fastforce have"∀v' ∈ fmdom' (fmdrop w θ). is_free_for ((fmdrop w θ) $$! v') v' B" proof fix v' assume"v' ∈ fmdom' (fmdrop w θ)" with FAbs.prems(2) have"is_free_for (θ $$! v') v' (FAbs w B)" by auto with‹w = (xw, αw)›and‹v' ∈ fmdom' (fmdrop w θ)› have"is_free_for (θ $$! v') v' (λxw<alpha>w. B)"and"v' ≠ (xw, αw)" by auto thenhave"is_free_for (θ $$! v') v' B" using is_free_for_from_abs by presburger with‹v' ≠ (xw, αw)›and‹w = (xw, αw)›show"is_free_for (fmdrop w θ $$! v') v' B" by simp qed moreoverhave"v ∉ fmdom' (fmdrop w θ)" by (simp add: FAbs.prems(1)) ultimatelyshow ?thesis using FAbs.IH and‹v ≠ w›by (simp add: fmdrop_fmupd) qed finallyshow ?thesis using‹w ∈ fmdom' ?θ'›and surj_pair[of w] by fastforce next case False thenhave"w ∉ fmdom' ?θ'" by simp from FAbs.prems have"v ∉ fmdom' ?θ'" by simp from False have *: "S {v 🚫 A} S θ (FAbs w B) = S {v 🚫 A} (FAbs w (S θ B))" using surj_pair[of w] by fastforce thenshow ?thesis proof (cases "v ≠ w") case True thenhave"S {v 🚫 A} (FAbs w (S θ B)) = FAbs w (S {v 🚫 A} (S θ B))" using surj_pair[of w] by fastforce alsohave"… = FAbs w (S ({v 🚫 A} ++f ?θ') B)" proof - obtain xwand αwwhere"w = (xw, αw)" by fastforce have"∀v' ∈ fmdom' θ. is_free_for (θ $$! v') v' B" proof fix v' assume"v' ∈ fmdom' θ" with FAbs.prems(2) have"is_free_for (θ $$! v') v' (FAbs w B)" by auto with‹w = (xw, αw)›and‹v' ∈ fmdom' θ›and False have"is_free_for (θ $$! v') v' (λxw<alpha>w. B)"and"v' ≠ (xw, αw)" by fastforce+ thenhave"is_free_for (θ $$! v') v' B" using is_free_for_from_abs by presburger with‹v' ≠ (xw, αw)›and‹w = (xw, αw)›show"is_free_for (θ $$! v') v' B" by simp qed with FAbs.IH show ?thesis using FAbs.prems(1) by blast qed finallyshow ?thesis proof - assume" S {v 🚫 A} (FAbs w (S θ B)) = FAbs w (S ({v 🚫 A} ++f fmmap (substitute {v 🚫 A}) θ) B)" moreoverhave"w ∉ fmdom' ({v 🚫 A} ++f fmmap (substitute {v 🚫 A}) θ)" using False and True by auto ultimatelyshow ?thesis using * and surj_pair[of w] by fastforce qed next case False thenhave"v ∉ free_vars (FAbs w (S θ B))" using surj_pair[of w] by fastforce thenhave **: "S {v 🚫 A} (FAbs w (S θ B)) = FAbs w (S θ B)" using free_var_singleton_substitution_neutrality by blast alsohave"… = FAbs w (S ?θ' B)" proof -
{ fix v' assume"v' ∈ fmdom' θ" with FAbs.prems(1) have"v' ≠ v" by blast assume"v ∈ free_vars (θ $$! v')"and"v' ∈ free_vars B" with‹v' ≠ v›have"¬ is_free_for (θ $$! v') v' (FAbs v B)" using form_with_free_binder_not_free_for by blast with FAbs.prems(2) and‹v' ∈ fmdom' θ›and False have False by blast
} thenhave"∀v' ∈ fmdom' θ. v ∉ free_vars (θ $$! v') ∨ v' ∉ free_vars B" by blast thenhave"∀v' ∈ fmdom' θ. v' ∈ free_vars B ⟶S {v 🚫 A} (θ $$! v') = θ $$! v'" using free_var_singleton_substitution_neutrality by blast thenhave"∀v' ∈ free_vars B. θ $$! v' = ?θ' $$! v'" by (metis fmdom'_map fmdom'_notD fmdom'_notI fmlookup_map option.map_sel) thenhave"S θ B = S ?θ' B" using free_vars_agreement_substitution_equality by (metis IntD1 fmdom'_map) thenshow ?thesis by simp qed alsofrom False and FAbs.prems(1) have"… = FAbs w (S (fmdrop w ({v 🚫 A} ++f ?θ')) B)" by (simp add: fmdrop_fmupd_same fmdrop_idle') alsofrom False have"… = S ({v 🚫 A} ++f ?θ') (FAbs w B)" using surj_pair[of w] by fastforce finallyshow ?thesis using * and ** by (simp only:) qed qed qed force+
lemma vars_range_substitution: assumes"is_substitution θ" and"v ∉ vars (fmran' θ)" shows"v ∉ vars (fmran' (fmdrop w θ))" using assms proof (induction θ) case fmempty thenshow ?case by simp next case (fmupd v' A θ) from fmdom'_notI[OF fmupd.hyps] and fmupd.prems(1) have"is_substitution θ" by (rule updated_substitution_is_substitution) moreoverfrom fmupd.prems(2) and fmupd.hyps have"v ∉ vars (fmran' θ)" by simp ultimatelyhave"v ∉ vars (fmran' (fmdrop w θ))" by (rule fmupd.IH) with fmupd.hyps and fmupd.prems(2) show ?case by (simp add: fmdrop_fmupd) qed
lemma excluded_var_from_substitution: assumes"is_substitution θ" and"v ∉ fmdom' θ" and"v ∉ vars (fmran' θ)" and"v ∉ vars A" shows"v ∉ vars (S θ A)" using assms proof (induction A arbitrary: θ) case (FVar v') thenshow ?case proof (cases "v' ∈ fmdom' θ") case True thenhave"θ $$! v' ∈ fmran' θ" by (simp add: fmlookup_dom'_iff fmran'I) with FVar(3) have"v ∉ vars (θ $$! v')" by simp with True show ?thesis using surj_pair[of v'] and fmdom'_notI by force next case False with FVar.prems(4) show ?thesis using surj_pair[of v'] by force qed next case (FCon k) thenshow ?case using surj_pair[of k] by force next case (FApp B C) thenshow ?case by auto next case (FAbs w B) have"v ∉ vars B"and"v ≠ w" using surj_pair[of w] and FAbs.prems(4) by fastforce+ thenshow ?case proof (cases "w ∉ fmdom' θ") case True thenhave"S θ (FAbs w B) = FAbs w (S θ B)" using surj_pair[of w] by fastforce moreoverfrom FAbs.IH have"v ∉ vars (S θ B)" using FAbs.prems(1-3) and‹v ∉ vars B›by blast ultimatelyshow ?thesis using‹v ≠ w›and surj_pair[of w] by fastforce next case False thenhave"S θ (FAbs w B) = FAbs w (S (fmdrop w θ) B)" using surj_pair[of w] by fastforce moreoverhave"v ∉ vars (S (fmdrop w θ) B)" proof - from FAbs.prems(1) have"is_substitution (fmdrop w θ)" by fastforce moreoverfrom FAbs.prems(2) have"v ∉ fmdom' (fmdrop w θ)" by simp moreoverfrom FAbs.prems(1,3) have"v ∉ vars (fmran' (fmdrop w θ))" by (fact vars_range_substitution) ultimatelyshow ?thesis using FAbs.IH and‹v ∉ vars B›by simp qed ultimatelyshow ?thesis using‹v ≠ w›and surj_pair[of w] by fastforce qed qed
subsection‹Renaming of bound variables›
fun rename_bound_var :: "var → nat → form → form"where "rename_bound_var v y (x<alpha>) = x<alpha>"
| "rename_bound_var v y ({c}<alpha>) = {c}<alpha>"
| "rename_bound_var v y (B ⏹ C) = rename_bound_var v y B ⏹ rename_bound_var v y C"
| "rename_bound_var v y (λx<alpha>. B) = ( if (x, α) = v then λy<alpha>. S {(x, α) 🚫 y<alpha>} (rename_bound_var v y B) else λx<alpha>. (rename_bound_var v y B) )"
lemma rename_bound_var_preserves_typing: assumes"A ∈ wffs<alpha>" shows"rename_bound_var (y, γ) z A ∈ wffs<alpha>" using assms proof (induction A) case (abs_is_wff β A δ x) thenshow ?case proof (cases "(x, δ) = (y, γ)") case True from abs_is_wff.IH have"S {(y, γ) 🚫 z<gamma>} (rename_bound_var (y, γ) z A) ∈ wffs<beta>" using substitution_preserves_typing by (simp add: wffs_of_type_intros(1)) thenhave"λz<gamma>. S {(y, γ) 🚫 z<gamma>} (rename_bound_var (y, γ) z A) ∈ wffs<gamma>→β" by blast with True show ?thesis by simp next case False from abs_is_wff.IH have"λx<delta>. rename_bound_var (y, γ) z A ∈ wffs<delta>→β" by blast with False show ?thesis by auto qed qed auto
lemma old_bound_var_not_free_in_abs_after_renaming: assumes"A ∈ wffs<alpha>" and"z<gamma>≠ y<gamma>" and"(z, γ) ∉ vars A" shows"(y, γ) ∉ free_vars (rename_bound_var (y, γ) z (λy<gamma>. A))" using assms and free_var_in_renaming_substitution by (induction A) auto
lemma rename_bound_var_free_vars: assumes"A ∈ wffs<alpha>" and"z<gamma>≠ y<gamma>" and"(z, γ) ∉ vars A" shows"(z, γ) ∉ free_vars (rename_bound_var (y, γ) z A)" using assms by (induction A) auto
lemma old_bound_var_not_free_after_renaming: assumes"A ∈ wffs<alpha>" and"z<gamma>≠ y<gamma>" and"(z, γ) ∉ vars A" and"(y, γ) ∉ free_vars A" shows"(y, γ) ∉ free_vars (rename_bound_var (y, γ) z A)" using assms proofinduction case (abs_is_wff β A α x) thenshow ?case proof (cases "(x, α) = (y, γ)") case True with abs_is_wff.hyps and abs_is_wff.prems(2) show ?thesis using old_bound_var_not_free_in_abs_after_renaming by auto next case False with abs_is_wff.prems(2,3) and assms(2) show ?thesis using abs_is_wff.IH by force qed qed fastforce+
lemma old_bound_var_not_ocurring_after_renaming: assumes"A ∈ wffs<alpha>" and"z<gamma>≠ y<gamma>" shows"¬ occurs_at (y, γ) p (S {(y, γ) 🚫 z<gamma>} (rename_bound_var (y, γ) z A))" using assms(1) proof (induction A arbitrary: p) case (var_is_wff α x) from assms(2) show ?case using subform_size_decrease by (cases "(x, α) = (y, γ)") fastforce+ next case (con_is_wff α c) thenshow ?case using occurs_at_alt_def(2) by auto next case (app_is_wff α β A B) thenshow ?case proof (cases p) case (Cons d p') thenshow ?thesis by (cases d) (use app_is_wff.IH in auto) qed simp next case (abs_is_wff β A α x) thenshow ?case proof (cases p) case (Cons d p') thenshow ?thesis proof (cases d) case Left have *: "¬ occurs_at (y, γ) p (λx<alpha>. S {(y, γ) 🚫 z<gamma>} (rename_bound_var (y, γ) z A))" for x and α using Left and Cons and abs_is_wff.IH by simp thenshow ?thesis proof (cases "(x, α) = (y, γ)") case True with assms(2) have" S {(y, γ) 🚫 z<gamma>} (rename_bound_var (y, γ) z (λx<alpha>. A)) = λz<gamma>. S {(y, γ) 🚫 z<gamma>} (rename_bound_var (y, γ) z A)" using free_var_in_renaming_substitution and free_var_singleton_substitution_neutrality by simp moreoverhave"¬ occurs_at (y, γ) p (λz<gamma>. S {(y, γ) 🚫 z<gamma>} (rename_bound_var (y, γ) z A))" using Left and Cons and * by simp ultimatelyshow ?thesis by simp next case False with assms(2) have" S {(y, γ) 🚫 z<gamma>} (rename_bound_var (y, γ) z (λx<alpha>. A)) = λx<alpha>. S {(y, γ) 🚫 z<gamma>} (rename_bound_var (y, γ) z A)" by simp moreoverhave"¬ occurs_at (y, γ) p (λx<alpha>. S {(y, γ) 🚫 z<gamma>} (rename_bound_var (y, γ) z A))" using Left and Cons and * by simp ultimatelyshow ?thesis by simp qed qed (simp add: Cons) qed simp qed
text‹
The following lemma states that the result of term‹rename_bound_var› does not contain bound
occurrences of the renamed variable: ›
lemma rename_bound_var_not_bound_occurrences: assumes"A ∈ wffs<alpha>" and"z<gamma>≠ y<gamma>" and"(z, γ) ∉ vars A" and"occurs_at (y, γ) p (rename_bound_var (y, γ) z A)" shows"¬ in_scope_of_abs (z, γ) p (rename_bound_var (y, γ) z A)" using assms(1,3,4) proof (induction arbitrary: p) case (var_is_wff α x) thenshow ?case by (simp add: subforms_from_var(2)) next case (con_is_wff α c) thenshow ?case using occurs_at_alt_def(2) by auto next case (app_is_wff α β B C) from app_is_wff.prems(1) have"(z, γ) ∉ vars B"and"(z, γ) ∉ vars C" by simp_all from app_is_wff.prems(2) have"occurs_at (y, γ) p (rename_bound_var (y, γ) z B ⏹ rename_bound_var (y, γ) z C)" by simp then consider
(a) "∃p'. p = « # p' ∧ occurs_at (y, γ) p' (rename_bound_var (y, γ) z B)"
| (b) "∃p'. p = ¬ # p' ∧ occurs_at (y, γ) p' (rename_bound_var (y, γ) z C)" using subforms_from_app by force thenshow ?case proof cases case a thenobtain p' where"p = « # p'"and"occurs_at (y, γ) p' (rename_bound_var (y, γ) z B)" by blast thenhave"¬ in_scope_of_abs (z, γ) p' (rename_bound_var (y, γ) z B)" using app_is_wff.IH(1)[OF ‹(z, γ) ∉ vars B›] by blast thenhave"¬ in_scope_of_abs (z, γ) p (rename_bound_var (y, γ) z (B ⏹ C))"for C using‹p = « # p'›and in_scope_of_abs_in_left_app by simp thenshow ?thesis by blast next case b thenobtain p' where"p = ¬ # p'"and"occurs_at (y, γ) p' (rename_bound_var (y, γ) z C)" by blast thenhave"¬ in_scope_of_abs (z, γ) p' (rename_bound_var (y, γ) z C)" using app_is_wff.IH(2)[OF ‹(z, γ) ∉ vars C›] by blast thenhave"¬ in_scope_of_abs (z, γ) p (rename_bound_var (y, γ) z (B ⏹ C))"for B using‹p = ¬ # p'›and in_scope_of_abs_in_right_app by simp thenshow ?thesis by blast qed next case (abs_is_wff β A α x) from abs_is_wff.prems(1) have"(z, γ) ∉ vars A"and"(z, γ) ≠ (x, α)" by fastforce+ thenshow ?case proof (cases "(y, γ) = (x, α)") case True thenhave"occurs_at (y, γ) p (λz<gamma>. S {(y, γ) 🚫 z<gamma>} (rename_bound_var (y, γ) z A))" using abs_is_wff.prems(2) by simp moreoverhave"¬ occurs_at (y, γ) p (λz<gamma>. S {(y, γ) 🚫 z<gamma>} (rename_bound_var (y, γ) z A))" using old_bound_var_not_ocurring_after_renaming[OF abs_is_wff.hyps assms(2)] and subforms_from_abs by fastforce ultimatelyshow ?thesis by contradiction next case False thenhave *: "rename_bound_var (y, γ) z (λx<alpha>. A) = λx<alpha>. rename_bound_var (y, γ) z A" by auto with abs_is_wff.prems(2) have"occurs_at (y, γ) p (λx<alpha>. rename_bound_var (y, γ) z A)" by auto thenobtain p' where"p = « # p'"and"occurs_at (y, γ) p' (rename_bound_var (y, γ) z A)" using subforms_from_abs by fastforce thenhave"¬ in_scope_of_abs (z, γ) p' (rename_bound_var (y, γ) z A)" using abs_is_wff.IH[OF ‹(z, γ) ∉ vars A›] by blast thenhave"¬ in_scope_of_abs (z, γ) (« # p') (λx<alpha>. rename_bound_var (y, γ) z A)" using‹p = « # p'›and in_scope_of_abs_in_abs and‹(z, γ) ≠ (x, α)›by auto thenshow ?thesis using * and‹p = « # p'›by simp qed qed
lemma is_free_for_in_rename_bound_var: assumes"A ∈ wffs<alpha>" and"z<gamma>≠ y<gamma>" and"(z, γ) ∉ vars A" shows"is_free_for (z<gamma>) (y, γ) (rename_bound_var (y, γ) z A)" proof (rule ccontr) assume"¬ is_free_for (z<gamma>) (y, γ) (rename_bound_var (y, γ) z A)" thenobtain p where"is_free_at (y, γ) p (rename_bound_var (y, γ) z A)" and"in_scope_of_abs (z, γ) p (rename_bound_var (y, γ) z A)" by force thenshow False using rename_bound_var_not_bound_occurrences[OF assms] by fastforce qed
lemma renaming_substitution_preserves_bound_vars: shows"bound_vars (S {(y, γ) 🚫 z<gamma>} A) = bound_vars A" proof (induction A) case (FAbs v A) thenshow ?case using singleton_substitution_simps(4) and surj_pair[of v] by (cases "v = (y, γ)") (presburger, force) qed force+
lemma rename_bound_var_bound_vars: assumes"A ∈ wffs<alpha>" and"z<gamma>≠ y<gamma>" shows"(y, γ) ∉ bound_vars (rename_bound_var (y, γ) z A)" using assms and renaming_substitution_preserves_bound_vars by (induction A) auto
lemma old_var_not_free_not_occurring_after_rename: assumes"A ∈ wffs<alpha>" and"z<gamma>≠ y<gamma>" and"(y, γ) ∉ free_vars A" and"(z, γ) ∉ vars A" shows"(y, γ) ∉ vars (rename_bound_var (y, γ) z A)" using assms and rename_bound_var_bound_vars[OF assms(1,2)] and old_bound_var_not_free_after_renaming and vars_is_free_and_bound_vars by blast
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.194 Sekunden
(vorverarbeitet am 2026-07-02)
¤
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.