nominal_datatype ty =
Atom nat
| Arrow ty ty (infixr‹→› 200)
| TupleT ty ty (infixr‹⊗› 210)
lemma fresh_type [simp]: "(a::name) \ (T::ty)" by (induct T rule: ty.induct) (simp_all add: fresh_nat)
lemma supp_type [simp]: "supp (T::ty) = ({} :: name set)" by (induct T rule: ty.induct) (simp_all add: ty.supp supp_nat)
lemma perm_type: "(pi::name prm) \ (T::ty) = T" by (induct T rule: ty.induct) (simp_all add: perm_nat_def)
nominal_datatype trm =
Var name
| Tuple trm trm (‹(1'\_,/ _'⟩)›)
| Abs ty "\name\trm"
| App trm trm (infixl‹⋅› 200)
| Let ty trm btrm and btrm =
Base trm
| Bind ty "\name\btrm"
abbreviation
Abs_syn :: "name \ ty \ trm \ trm" (‹(3λ_:_./ _)› [0, 0, 10] 10) where "\x:T. t \ Abs T x t"
datatype pat =
PVar name ty
| PTuple pat pat (‹(1'\\_,/ _'⟩⟩)›)
(* FIXME: The following should be done automatically by the nominal package *) overloading pat_perm ≡"perm :: name prm \ pat \ pat" (unchecked) begin
primrec pat_perm where "pat_perm pi (PVar x ty) = PVar (pi \ x) (pi \ ty)"
| "pat_perm pi \\p, q\\ = \\pat_perm pi p, pat_perm pi q\\"
end
declare pat_perm.simps [eqvt]
lemma supp_PVar [simp]: "((supp (PVar x T))::name set) = supp x" by (simp add: supp_def perm_fresh_fresh)
lemma supp_PTuple [simp]: "((supp \\p, q\\)::name set) = supp p \ supp q" by (simp add: supp_def Collect_disj_eq del: disj_not1)
instance pat :: pt_name proof fix x :: pat show"([]::(name \ _) list) \ x = x" by (induct x) simp_all fix pi1 pi2 :: "(name \ name) list" show"(pi1 @ pi2) \ x = pi1 \ pi2 \ x" by (induct x) (simp_all add: pt_name2) assume"pi1 \ pi2" thenshow"pi1 \ x = pi2 \ x" by (induct x) (simp_all add: pt_name3) qed
instance pat :: fs_name proof fix x :: pat show"finite (supp x::name set)" by (induct x) (simp_all add: fin_supp) qed
(* the following function cannot be defined using nominal_primrec, *) (* since variable parameters are currently not allowed. *) primrec abs_pat :: "pat \ btrm \ btrm" (‹(3λ[_]./ _)› [0, 10] 10) where "(\[PVar x T]. t) = Bind T x t"
| "(\[\\p, q\\]. t) = (\[p]. \[q]. t)"
lemma abs_pat_eqvt [eqvt]: "(pi :: name prm) \ (\[p]. t) = (\[pi \ p]. (pi \ t))" by (induct p arbitrary: t) simp_all
lemma abs_pat_fresh [simp]: "(x::name) \ (\[p]. t) = (x \ supp p \ x \ t)" by (induct p arbitrary: t) (simp_all add: abs_fresh supp_atm)
lemma abs_pat_alpha: assumes fresh: "((pi::name prm) \ supp p::name set) \* t" and pi: "set pi \ supp p \ pi \ supp p" shows"(\[p]. t) = (\[pi \ p]. pi \ t)" proof - note pt_name_inst at_name_inst pi moreoverhave"(supp p::name set) \* (\[p]. t)" by (simp add: fresh_star_def) moreoverfrom fresh have"(pi \ supp p::name set) \* (\[p]. t)" by (simp add: fresh_star_def) ultimatelyhave"pi \ (\[p]. t) = (\[p]. t)" by (rule pt_freshs_freshs) thenshow ?thesis by (simp add: eqvts) qed
primrec pat_vars :: "pat \ name list" where "pat_vars (PVar x T) = [x]"
| "pat_vars \\p, q\\ = pat_vars q @ pat_vars p"
lemma pat_vars_eqvt [eqvt]: "(pi :: name prm) \ (pat_vars p) = pat_vars (pi \ p)" by (induct p rule: pat.induct) (simp_all add: eqvts)
abbreviation "sub_ctx" :: "ctx \ ctx \ bool" (‹_ ⊑ _›) where "\\<^sub>1 \ \\<^sub>2 \ \x. x \ set \\<^sub>1 \ x \ set \\<^sub>2"
abbreviation
Let_syn :: "pat \ trm \ trm \ trm" (‹(LET (_ =/ _)/ IN (_))› 10) where "LET p = t IN u \ Let (pat_type p) t (\[p]. Base u)"
inductive typing :: "ctx \ trm \ ty \ bool" (‹_ ⊨ _ : _› [60, 60, 60] 60) where
Var [intro]: "valid \ \ (x, T) \ set \ \ \ \ Var x : T"
| Tuple [intro]: "\ \ t : T \ \ \ u : U \ \ \ \t, u\ : T \ U"
| Abs [intro]: "(x, T) # \ \ t : U \ \ \ (\x:T. t) : T \ U"
| App [intro]: "\ \ t : T \ U \ \ \ u : T \ \ \ t \ u : U"
| Let: "((supp p)::name set) \* t \
Γ ⊨ t : T ==>⊨ p : T ==> Δ ==> Δ @ Γ ⊨ u : U ==>
Γ ⊨ (LET p = t IN u) : U"
equivariance ptyping
equivariance valid
equivariance typing
lemma valid_typing: assumes"\ \ t : T" shows"valid \"using assms by induct auto
lemma pat_var: assumes"\ p : T \ \" shows"(supp p::name set) = supp \"using assms by induct (auto simp add: supp_list_nil supp_list_cons supp_prod supp_list_append)
lemma better_T_Let [intro]: assumes t: "\ \ t : T"and p: "\ p : T \ \"and u: "\ @ \ \ u : U" shows"\ \ (LET p = t IN u) : U" proof - obtain pi::"name prm"where pi: "(pi \ (supp p::name set)) \* (t, Base u, \)" and pi': "set pi \ supp p \ (pi \ supp p)" by (rule at_set_avoiding [OF at_name_inst fin_supp fin_supp]) from p u have p_fresh: "(supp p::name set) \* \" by (auto simp add: fresh_star_def pat_var dest!: valid_typing valid_app_fresh) from pi have p_fresh': "(pi \ (supp p::name set)) \* \" by (simp add: fresh_star_prod_elim) from pi have p_fresh'': "(pi \ (supp p::name set)) \* Base u" by (simp add: fresh_star_prod_elim) from pi have"(supp (pi \ p)::name set) \* t" by (simp add: fresh_star_prod_elim eqvts) moreovernote t moreoverfrom p have"pi \ (\ p : T \ \)"by (rule perm_boolI) thenhave"\ (pi \ p) : T \ (pi \ \)"by (simp add: eqvts perm_type) moreoverfrom u have"pi \ (\ @ \ \ u : U)"by (rule perm_boolI) with pt_freshs_freshs [OF pt_name_inst at_name_inst pi' p_fresh p_fresh'] have"(pi \ \) @ \ \ (pi \ u) : U"by (simp add: eqvts perm_type) ultimatelyhave"\ \ (LET (pi \ p) = t IN (pi \ u)) : U" by (rule Let) thenshow ?thesis by (simp add: abs_pat_alpha [OF p_fresh'' pi'] pat_type_perm_eq) qed
lemma weakening: assumes"\\<^sub>1 \ t : T"and"valid \\<^sub>2"and"\\<^sub>1 \ \\<^sub>2" shows"\\<^sub>2 \ t : T"using assms proof (nominal_induct Γ🚫1 t T avoiding: Γ🚫2 rule: typing.strong_induct) case (Abs x T Γ t U) thenshow ?case by (simp add: typing.Abs valid.Cons) next case (Let p t Γ T Δ u U) thenshow ?case by (smt (verit, ccfv_threshold) Un_iff pat_freshs set_append typing.simps valid_app_mono valid_typing) qed auto
inductive
match :: "pat \ trm \ (name \ trm) list \ bool" (‹⊨ _ ⊳ _ ==> _› [50, 50, 50] 50) where
PVar: "\ PVar x T \ t \ [(x, t)]"
| PProd: "\ p \ t \ \ \ \ q \ u \ \' \ \ \\p, q\\ \ \t, u\ \ \ @ \'"
fun
lookup :: "(name \ trm) list \ name \ trm" where "lookup [] x = Var x"
| "lookup ((y, e) # \) x = (if x = y then e else lookup \ x)"
lemma lookup_eqvt[eqvt]: fixes pi :: "name prm" and θ :: "(name \ trm) list" and X :: "name" shows"pi \ (lookup \ X) = lookup (pi \ \) (pi \ X)" by (induct θ) (auto simp add: eqvts)
nominal_primrec
psubst :: "(name \ trm) list \ trm \ trm" (‹_(_)› [95,0] 210) and psubstb :: "(name \ trm) list \ btrm \ btrm" (‹_(_)🚫b› [95,0] 210) where "\\Var x\ = (lookup \ x)"
| "\\t \ u\ = \\t\ \ \\u\"
| "\\\t, u\\ = \\\t\, \\u\\"
| "\\Let T t u\ = Let T (\\t\) (\\u\\<^sub>b)"
| "x \ \ \ \\\x:T. t\ = (\x:T. \\t\)"
| "\\Base t\\<^sub>b = Base (\\t\)"
| "x \ \ \ \\Bind T x t\\<^sub>b = Bind T x (\\t\\<^sub>b)" by (finite_guess | simp add: abs_fresh | fresh_guess)+
lemma lookup_fresh: "x = y \ x \ set (map fst \) \ \(y, t)\set \. x \ t \ x \ lookup \ y" by (induct θ) (use fresh_atm in force)+
lemma psubst_fresh: assumes"x \ set (map fst \)"and"\(y, t)\set \. x \ t" shows"x \ \\t\"and"x \ \\t'\\<^sub>b"using assms proof (nominal_induct t and t' avoiding: \ rule: trm_btrm.strong_inducts) case (Var name) thenshow ?case by (metis lookup_fresh simps(1)) qed (auto simp: abs_fresh)
lemma psubst_eqvt[eqvt]: fixes pi :: "name prm" shows"pi \ (\\t\) = (pi \ \)\pi \ t\" and"pi \ (\\t'\\<^sub>b) = (pi \ \)\pi \ t'\\<^sub>b" by (nominal_induct t and t' avoiding: \ rule: trm_btrm.strong_inducts)
(simp_all add: eqvts fresh_bij)
abbreviation
subst :: "trm \ name \ trm \ trm" (‹_[_↝_]› [100,0,0] 100) where "t[x\t'] \ [(x,t')]\t\"
abbreviation
substb :: "btrm \ name \ trm \ btrm" (‹_[_↝_]🚫b› [100,0,0] 100) where "t[x\t']\<^sub>b \ [(x,t')]\t\\<^sub>b"
lemma lookup_forget: "(supp (map fst \)::name set) \* x \ lookup \ x = Var x" by (induct θ) (auto simp add: split_paired_all fresh_star_def fresh_atm supp_list_cons supp_atm)
lemma psubst_forget: "(supp (map fst \)::name set) \* t \ \\t\ = t" "(supp (map fst \)::name set) \* t' \ \\t'\\<^sub>b = t'" proof (nominal_induct t and t' avoiding: \ rule: trm_btrm.strong_inducts) case (Var name) thenshow ?case by (simp add: fresh_star_set lookup_forget) next case (Abs ty name trm) thenshow ?case apply (simp add: fresh_def) by (metis abs_fresh(1) fresh_star_set supp_fst trm.fresh(3)) next case (Bind ty name btrm) thenshow ?case apply (simp add: fresh_def) by (metis abs_fresh(1) btrm.fresh(2) fresh_star_set supp_fst) qed (auto simp: fresh_star_set)
lemma psubst_nil[simp]: "[]\t\ = t""[]\t'\\<^sub>b = t'" by (induct t and t' rule: trm_btrm.inducts) (simp_all add: fresh_list_nil)
lemma psubst_cons: assumes"(supp (map fst \)::name set) \* u" shows"((x, u) # \)\t\ = \\t[x\u]\"and"((x, u) # \)\t'\\<^sub>b = \\t'[x\u]\<^sub>b\\<^sub>b" using assms by (nominal_induct t and t' avoiding: x u \ rule: trm_btrm.strong_inducts)
(simp_all add: fresh_list_nil fresh_list_cons psubst_forget)
lemma psubst_append: "(supp (map fst (\\<^sub>1 @ \\<^sub>2))::name set) \* map snd (\\<^sub>1 @ \\<^sub>2) \ (\\<^sub>1 @ \\<^sub>2)\t\= \\<^sub>2\\\<^sub>1\t\\" proof (induct θ🚫1 arbitrary: t) case Nil thenshow ?case by (auto simp: psubst_nil) next case (Cons a θ🚫1) thenshow ?case proof (cases a) case (Pair a b) with Cons show ?thesis apply (simp add: supp_list_cons fresh_star_set fresh_list_cons) by (metis Un_iff fresh_star_set map_append psubst_cons(1) supp_list_append) qed qed
inductive eval :: "trm \ trm \ bool" (‹_ ⟼ _› [60,60] 60) where
TupleL: "t \ t' \ \t, u\ \ \t', u\"
| TupleR: "u \ u' \ \t, u\ \ \t, u'\"
| Abs: "t \ t' \ (\x:T. t) \ (\x:T. t')"
| AppL: "t \ t' \ t \ u \ t' \ u"
| AppR: "u \ u' \ t \ u \ t \ u'"
| Beta: "x \ u \ (\x:T. t) \ u \ t[x\u]"
| Let: "((supp p)::name set) \* t \ distinct (pat_vars p) \ ⊨ p ⊳ t ==> θ ==> (LET p = t IN u) ⟼ θ(u)"
equivariance match
equivariance eval
lemma match_vars: assumes"\ p \ t \ \"and"x \ supp p" shows"x \ set (map fst \)"using assms by induct (auto simp add: supp_atm)
lemma match_fresh_mono: assumes"\ p \ t \ \"and"(x::name) \ t" shows"\(y, t)\set \. x \ t"using assms by induct auto
nominal_inductive2 eval avoids
Abs: "{x}"
| Beta: "{x}"
| Let: "(supp p)::name set" proof (simp_all add: fresh_star_def abs_fresh fin_supp) show"x \ t[x\u]"if"x \ u"for x t u by (simp add: ‹x ♯ u› psubst_fresh(1)) next show"\x\supp p. (x::name) \ \\u\" if"\x\supp p. (x::name) \ t"and"\ p \ t \ \" for p t θ u by (meson that match_fresh_mono match_vars psubst_fresh(1)) qed
lemma typing_case_Abs: assumes ty: "\ \ (\x:T. t) : S" and fresh: "x \ \" and R: "\U. S = T \ U \ (x, T) # \ \ t : U \ P" shows P using ty proof cases case (Abs x' T' t' U) obtain y::name where y: "y \ (x, \, \x':T'. t')" by (rule exists_fresh) (auto intro: fin_supp) from‹(λx:T. t) = (λx':T'. t')\ [symmetric] have x: "x \ (\x':T'. t')"by (simp add: abs_fresh) have x': "x'♯ (λx':T'. t')" by (simp add: abs_fresh) from‹(x', T') # Γ ⊨ t' : U\ have x'': "x'♯ Γ" by (auto dest: valid_typing) have"(\x:T. t) = (\x':T'. t')"by fact alsofrom x x' y have "\ = [(x, y)] \ [(x', y)] ∙ (λx':T'. t')" by (simp only: perm_fresh_fresh fresh_prod) alsohave"\ = (\x:T'. [(x, y)] \ [(x', y)] \ t')" by (simp add: swap_simps perm_fresh_fresh) finallyhave"(\x:T. t) = (\x:T'. [(x, y)] \ [(x', y)] \ t')" . thenhave T: "T = T'"and t: "[(x, y)] \ [(x', y)] \ t' = t" by (simp_all add: trm.inject alpha) from Abs T have"S = T \ U"by simp moreoverfrom‹(x', T') # Γ ⊨ t' : U\ have"[(x, y)] \ [(x', y)] \ ((x', T') # \ \ t' : U)" by (simp add: perm_bool) with T t y x'' fresh have"(x, T) # \ \ t : U" by (simp add: eqvts swap_simps perm_fresh_fresh fresh_prod) ultimatelyshow ?thesis by (rule R) qed simp_all
nominal_primrec ty_size :: "ty \ nat" where "ty_size (Atom n) = 0"
| "ty_size (T \ U) = ty_size T + ty_size U + 1"
| "ty_size (T \ U) = ty_size T + ty_size U + 1" by (rule TrueI)+
lemma bind_tuple_ineq: "ty_size (pat_type p) < ty_size U \ Bind U x t \ (\[p]. u)" by (induct p arbitrary: U x t u) (auto simp add: btrm.inject)
lemma perm_mem_left: "(x::name) \ ((pi::name prm) \ A) \ (rev pi \ x) \ A" by (drule perm_boolI [of _ "rev pi"]) (simp add: eqvts perm_pi_simp)
lemma perm_mem_right: "(rev (pi::name prm) \ (x::name)) \ A \ x \ (pi \ A)" by (drule perm_boolI [of _ pi]) (simp add: eqvts perm_pi_simp)
lemma perm_cases: assumes pi: "set pi \ A \ A" shows"((pi::name prm) \ B) \ A \ B" proof fix x assume"x \ pi \ B" thenshow"x \ A \ B"using pi proof (induct pi arbitrary: x B rule: rev_induct) case Nil thenshow ?case by simp next case (snoc y xs) thenshow ?case apply simp by (metis SigmaE perm_mem_left perm_pi_simp(2) pt_name2 swap_simps(3)) qed qed
lemma abs_pat_alpha': assumes eq: "(\[p]. t) = (\[q]. u)" and ty: "pat_type p = pat_type q" and pv: "distinct (pat_vars p)" and qv: "distinct (pat_vars q)" shows"\pi::name prm. p = pi \ q \ t = pi \ u \
set pi ⊆ (supp p ∪ supp q) × (supp p ∪ supp q)" using assms proof (induct p arbitrary: q t u) case (PVar x T) note PVar' = this show ?case proof (cases q) case (PVar x' T') with‹(λ[PVar x T]. t) = (λ[q]. u)› have"x = x' \ t = u \ x \ x' \ t = [(x, x')] \ u \ x \ u" by (simp add: btrm.inject alpha) thenshow ?thesis proof assume"x = x' \ t = u" with PVar PVar' have "PVar x T = ([]::name prm) \ q \
t = ([]::name prm) ∙ u ∧
set ([]::name prm) ⊆ (supp (PVar x T) ∪ supp q) ×
(supp (PVar x T) ∪ supp q)" by simp thenshow ?thesis .. next assume"x \ x' \ t = [(x, x')] \ u \ x \ u" with PVar PVar' have "PVar x T = [(x, x')] ∙ q ∧
t = [(x, x')] \ u \
set [(x, x')] \ (supp (PVar x T) \ supp q) \
(supp (PVar x T) ∪ supp q)" by (simp add: perm_swap swap_simps supp_atm perm_type) thenshow ?thesis .. qed next case (PTuple p🚫1 p🚫2) with PVar have"ty_size (pat_type p\<^sub>1) < ty_size T"by simp thenhave"Bind T x t \ (\[p\<^sub>1]. \[p\<^sub>2]. u)" by (rule bind_tuple_ineq) moreoverfrom PTuple PVar have"Bind T x t = (\[p\<^sub>1]. \[p\<^sub>2]. u)"by simp ultimatelyshow ?thesis .. qed next case (PTuple p🚫1 p🚫2) note PTuple' = this show ?case proof (cases q) case (PVar x T) with PTuple have"ty_size (pat_type p\<^sub>1) < ty_size T"by auto thenhave"Bind T x u \ (\[p\<^sub>1]. \[p\<^sub>2]. t)" by (rule bind_tuple_ineq) moreoverfrom PTuple PVar have"Bind T x u = (\[p\<^sub>1]. \[p\<^sub>2]. t)"by simp ultimatelyshow ?thesis .. next case (PTuple p🚫1' p\<^sub>2') with PTuple' have "(\[p\<^sub>1]. \[p\<^sub>2]. t) = (\[p\<^sub>1']. λ[p🚫2']. u)" by simp moreoverfrom PTuple PTuple' have "pat_type p\<^sub>1 = pat_type p\<^sub>1'" by (simp add: ty.inject) moreoverfrom PTuple' have "distinct (pat_vars p\<^sub>1)" by simp moreoverfrom PTuple PTuple' have "distinct (pat_vars p\<^sub>1')" by simp ultimatelyhave"\pi::name prm. p\<^sub>1 = pi \ p\<^sub>1' \
(λ[p🚫2]. t) = pi ∙ (λ[p🚫2']. u) \
set pi ⊆ (supp p🚫1 ∪ supp p🚫1') \ (supp p\<^sub>1 \ supp p\<^sub>1')" by (rule PTuple') thenobtain pi::"name prm"where "p\<^sub>1 = pi \ p\<^sub>1'""(\[p\<^sub>2]. t) = pi \ (\[p\<^sub>2']. u)"and
pi: "set pi \ (supp p\<^sub>1 \ supp p\<^sub>1') \ (supp p\<^sub>1 \ supp p\<^sub>1')"by auto from‹(λ[p🚫2]. t) = pi ∙ (λ[p🚫2']. u)\ have"(\[p\<^sub>2]. t) = (\[pi \ p\<^sub>2']. pi \ u)" by (simp add: eqvts) moreoverfrom PTuple PTuple' have "pat_type p\<^sub>2 = pat_type (pi \ p\<^sub>2')" by (simp add: ty.inject pat_type_perm_eq) moreoverfrom PTuple' have "distinct (pat_vars p\<^sub>2)" by simp moreoverfrom PTuple PTuple' have "distinct (pat_vars (pi \ p\<^sub>2'))" by (simp add: pat_vars_eqvt [symmetric] distinct_eqvt [symmetric]) ultimatelyhave"\pi'::name prm. p\<^sub>2 = pi' \ pi \ p\<^sub>2' \
t = pi' \ pi \ u \
set pi' \ (supp p\<^sub>2 \ supp (pi \ p\<^sub>2')) × (supp p🚫2 ∪ supp (pi ∙ p🚫2'))" by (rule PTuple') thenobtain pi'::"name prm" where "p\<^sub>2 = pi' \ pi \ p\<^sub>2'""t = pi' \ pi \ u"and
pi': "set pi'⊆ (supp p🚫2 ∪ supp (pi ∙ p🚫2')) \
(supp p🚫2 ∪ supp (pi ∙ p🚫2'))" by auto from PTuple PTuple' have "pi \ distinct (pat_vars \\p\<^sub>1', p🚫2'\\)" by simp thenhave"distinct (pat_vars \\pi \ p\<^sub>1', pi \ p\<^sub>2'\\)"by (simp only: eqvts) with‹p🚫1 = pi ∙ p🚫1'\ PTuple' have fresh: "(supp p\<^sub>2 \ supp (pi \ p\<^sub>2') :: name set) \* p\<^sub>1" by (auto simp add: set_pat_vars_supp fresh_star_def fresh_def eqvts) from‹p🚫1 = pi ∙ p🚫1'\ have "pi'∙ (p🚫1 = pi ∙ p🚫1')" by (rule perm_boolI) with pt_freshs_freshs [OF pt_name_inst at_name_inst pi' fresh fresh] have"p\<^sub>1 = pi' \ pi \ p\<^sub>1'"by (simp add: eqvts) with‹p🚫2 = pi' \ pi \ p\<^sub>2'›have"\\p\<^sub>1, p\<^sub>2\\ = (pi' @ pi) \ \\p\<^sub>1', p\<^sub>2'\\" by (simp add: pt_name2) moreover have"((supp p\<^sub>2 \ (pi \ supp p\<^sub>2')) \ (supp p\<^sub>2 \ (pi \ supp p\<^sub>2'))::(name \ name) set) \
(supp p🚫2 ∪ (supp p🚫1 ∪ supp p🚫1' \ supp p\<^sub>2')) × (supp p🚫2 ∪ (supp p🚫1 ∪ supp p🚫1' \ supp p\<^sub>2'))" by (rule subset_refl Sigma_mono Un_mono perm_cases [OF pi])+ with pi' have "set pi'⊆…" by (simp add: supp_eqvt [symmetric]) with pi have"set (pi' @ pi) \ (supp \\p\<^sub>1, p\<^sub>2\\ \ supp \\p\<^sub>1', p\<^sub>2'\\) \
(supp ⟨⟨p🚫1, p🚫2⟩⟩∪ supp ⟨⟨p🚫1', p\<^sub>2'⟩⟩)" by (simp add: Sigma_Un_distrib1 Sigma_Un_distrib2 Un_ac) blast moreovernote‹t = pi' \ pi \ u\ ultimatelyhave"\\p\<^sub>1, p\<^sub>2\\ = (pi' @ pi) \ q \ t = (pi' @ pi) \ u \
set (pi' @ pi) \ (supp \\p\<^sub>1, p\<^sub>2\\ \ supp q) \
(supp ⟨⟨p🚫1, p🚫2⟩⟩∪ supp q)" using PTuple by (simp add: pt_name2) thenshow ?thesis .. qed qed
lemma typing_case_Let: assumes ty: "\ \ (LET p = t IN u) : U" and fresh: "(supp p::name set) \* \" and distinct: "distinct (pat_vars p)" and R: "\T \. \ \ t : T \ \ p : T \ \ \ \ @ \ \ u : U \ P" shows P using ty proof cases case (Let p' t' T Δ u') thenhave"(supp \::name set) \* \" by (auto intro: valid_typing valid_app_freshs) withLethave"(supp p'::name set) \* \" by (simp add: pat_var) with fresh have fresh': "(supp p \ supp p' :: name set) ♯* Γ" by (auto simp add: fresh_star_def) fromLethave"(\[p]. Base u) = (\[p']. Base u')" by (simp add: trm.inject) moreoverfromLethave"pat_type p = pat_type p'" by (simp add: trm.inject) moreovernote distinct moreoverfrom‹Δ @ Γ ⊨ u' : U\ have "valid (\ @ \)" by (rule valid_typing) thenhave"valid \"by (rule valid_appD) with‹⊨ p' : T \ \\ have "distinct (pat_vars p')" by (simp add: valid_distinct pat_vars_ptyping) ultimatelyhave"\pi::name prm. p = pi \ p' \ Base u = pi \ Base u' \
set pi ⊆ (supp p ∪ supp p') \ (supp p \ supp p')" by (rule abs_pat_alpha') thenobtain pi::"name prm"where pi: "p = pi \ p'""u = pi \ u'" and pi': "set pi \ (supp p \ supp p') × (supp p ∪ supp p')" by (auto simp add: btrm.inject) fromLethave"\ \ t : T"by (simp add: trm.inject) moreoverfrom‹⊨ p' : T \ \\ have "\ (pi \ p') : (pi ∙ T) ==> (pi ∙ Δ)" by (simp add: ptyping.eqvt) with pi have"\ p : T \ (pi \ \)"by (simp add: perm_type) moreoverfromLet have"(pi \ \) @ (pi \ \) \ (pi \ u') : (pi \ U)" by (simp add: append_eqvt [symmetric] typing.eqvt) with pi have"(pi \ \) @ \ \ u : U" by (simp add: perm_type pt_freshs_freshs
[OF pt_name_inst at_name_inst pi' fresh' fresh']) ultimatelyshow ?thesis by (rule R) qed simp_all
lemma preservation: assumes"t \ t'"and"\ \ t : T" shows"\ \ t' : T"using assms proof (nominal_induct avoiding: Γ T rule: eval.strong_induct) case (TupleL t t' u) from‹Γ ⊨⟨t, u⟩ : T›obtain T🚫1 T🚫2 where"T = T\<^sub>1 \ T\<^sub>2""\ \ t : T\<^sub>1""\ \ u : T\<^sub>2" by cases (simp_all add: trm.inject) from‹Γ ⊨ t : T🚫1›have"\ \ t' : T\<^sub>1"by (rule TupleL) thenhave"\ \ \t', u\ : T\<^sub>1 \ T\<^sub>2"using‹Γ ⊨ u : T🚫2› by (rule Tuple) with‹T = T🚫1 ⊗ T🚫2›show ?caseby simp next case (TupleR u u' t) from‹Γ ⊨⟨t, u⟩ : T›obtain T🚫1 T🚫2 where"T = T\<^sub>1 \ T\<^sub>2""\ \ t : T\<^sub>1""\ \ u : T\<^sub>2" by cases (simp_all add: trm.inject) from‹Γ ⊨ u : T🚫2›have"\ \ u' : T\<^sub>2"by (rule TupleR) with‹Γ ⊨ t : T🚫1›have"\ \ \t, u'\ : T\<^sub>1 \ T\<^sub>2" by (rule Tuple) with‹T = T🚫1 ⊗ T🚫2›show ?caseby simp next case (Abs t t' x S) from‹Γ ⊨ (λx:S. t) : T›‹x ♯ Γ›obtain U where
T: "T = S \ U"and U: "(x, S) # \ \ t : U" by (rule typing_case_Abs) from U have"(x, S) # \ \ t' : U"by (rule Abs) thenhave"\ \ (\x:S. t') : S \ U" by (rule typing.Abs) with T show ?caseby simp next case (Beta x u S t) from‹Γ ⊨ (λx:S. t) ⋅ u : T›‹x ♯ Γ› obtain"(x, S) # \ \ t : T"and"\ \ u : S" by cases (auto simp add: trm.inject ty.inject elim: typing_case_Abs) thenshow ?caseby (rule subst_type) next case (Let p t θ u) from‹Γ ⊨ (LET p = t IN u) : T›‹supp p ♯* Γ›‹distinct (pat_vars p)› obtain U Δ where"\ p : U \ \""\ \ t : U""\ @ \ \ u : T" by (rule typing_case_Let) thenshow ?caseusing‹⊨ p ⊳ t ==> θ›‹supp p ♯* t› by (rule match_type) next case (AppL t t' u) from‹Γ ⊨ t ⋅ u : T›obtain U where
t: "\ \ t : U \ T"and u: "\ \ u : U" by cases (auto simp add: trm.inject) from t have"\ \ t' : U \ T"by (rule AppL) thenshow ?caseusing u by (rule typing.App) next case (AppR u u' t) from‹Γ ⊨ t ⋅ u : T›obtain U where
t: "\ \ t : U \ T"and u: "\ \ u : U" by cases (auto simp add: trm.inject) from u have"\ \ u' : U"by (rule AppR) with t show ?caseby (rule typing.App) qed
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.