(* FIXME only for codegen*) type_synonym cname = int
text‹ML terms:›
datatype ml =
― ‹ML›
C_ML cname (‹CML›) (* ref to compiled code *)
| V_ML ml_vname (‹VML›)
| A_ML ml "(ml list)" (‹AML›)
| Lam_ML ml (‹LamML›)
― ‹the universal datatype›
| CU cname "(ml list)"
| VU vname "(ml list)"
| Clo ml "(ml list)" nat
― ‹ML function \emph{apply}›
| "apply" ml ml
text‹Lambda-terms:›
datatype tm = C cname | V vname | Λ tm | At tm tm (infix‹∙›100)
| "term" ml ― ‹ML function \texttt{term}›
text‹The following locale captures type conventions for variables.
It is not actually used, merely a formal comment.›
locale Vars = fixes r s t:: tm and rs ss ts :: "tm list" and u v w :: ml and us vs ws :: "ml list" and nm :: cname and x :: vname and X :: ml_vname
text‹The subset of pure terms:›
inductive pure :: "tm ==> bool"where "pure(C nm)" | "pure(V x)" |
Lam: "pure t ==> pure(Λ t)" | "pure s ==> pure t ==> pure(s∙t)"
declare pure.intros[simp] declare Lam[simp del]
lemma pure_Lam[simp]: "pure(Λ t) = pure t" proof assume"pure(Λ t)"thus"pure t" proof cases qed auto next assume"pure t"thus"pure(Λ t)"by(rule Lam) qed
text‹Closed terms w.r.t.\ ML variables:›
fun closed_ML :: "nat ==> ml ==> bool" (‹closedML›) where "closedML i (CML nm) = True" | "closedML i (VML X) = (X<i)" | "closedML i (AML v vs) = (closedML i v ∧ (∀v ∈ set vs. closedML i v))" | "closedML i (LamML v) = closedML (i+1) v" | "closedML i (CU nm vs) = (∀v ∈ set vs. closedML i v)" | "closedML i (VU nm vs) = (∀v ∈ set vs. closedML i v)" | "closedML i (Clo f vs n) = (closedML i f ∧ (∀v ∈ set vs. closedML i v))" | "closedML i (apply v w) = (closedML i v ∧ closedML i w)"
fun closed_tm_ML :: "nat ==> tm ==> bool" (‹closedML›) where "closed_tm_ML i (r∙s) = (closed_tm_ML i r ∧ closed_tm_ML i s)" | "closed_tm_ML i (Λ t) = (closed_tm_ML i t)" | "closed_tm_ML i (term v) = closed_ML i v" | "closed_tm_ML i v = True"
text‹Free variables:›
fun fv_ML :: "ml ==> ml_vname set" (‹fvML›) where "fvML (CML nm) = {}" | "fvML (VML X) = {X}" | "fvML (AML v vs) = fvML v ∪ (∪v ∈ set vs. fvML v)" | "fvML (LamML v) = {X. Suc X : fvML v}" | "fvML (CU nm vs) = (∪v ∈ set vs. fvML v)" | "fvML (VU nm vs) = (∪v ∈ set vs. fvML v)" | "fvML (Clo f vs n) = fvML f ∪ (∪v ∈ set vs. fvML v)" | "fvML (apply v w) = fvML v ∪ fvML w"
primrec fv :: "tm ==> vname set"where "fv (C nm) = {}" | "fv (V X) = {X}" | "fv (s ∙ t) = fv s ∪ fv t" | "fv (Λ t) = {X. Suc X : fv t}"
subsection"Iterated Term Application"
abbreviation foldl_At (infix‹∙∙›90) where "t ∙∙ ts ≡ foldl (∙) t ts"
lemma args_tm_foldl_At[simp]: "args_tm(s ∙∙ ts) = args_tm s @ ts" by(induct ts arbitrary: s) auto
lemma tm_eq_iff: "atomic_tm(head_tm s) ==> atomic_tm(head_tm t) ==> s = t ⟷ head_tm s = head_tm t ∧ args_tm s = args_tm t" apply(induct s arbitrary: t) apply(case_tac t, simp+)+ done
declare
tm_eq_iff[of "h ∙∙ ts", simp]
tm_eq_iff[of _ "h ∙∙ ts", simp] for h ts
lemma atomic_tm_head_tm: "atomic_tm(head_tm t)" by(induct t) auto
lemma head_tm_idem: "head_tm(head_tm t) = head_tm t" by(induct t) auto
lemma args_tm_head_tm: "args_tm(head_tm t) = []" by(induct t) auto
lemma eta_head_args: "t = head_tm t ∙∙ args_tm t" by (subst tm_eq_iff) (auto simp: atomic_tm_head_tm head_tm_idem args_tm_head_tm)
lemma tm_vector_cases: "(∃n ts. t = V n ∙∙ ts) ∨ (∃nm ts. t = C nm ∙∙ ts) ∨ (∃t' ts. t = Λ t' ∙∙ ts) ∨ (∃v ts. t = term v ∙∙ ts)" apply(induct t) apply simp_all by (metis snoc_eq_iff_butlast)
lemma fv_head_C[simp]: "fv (t ∙∙ ts) = fv t ∪ (∪t∈set ts. fv t)" by(induct ts arbitrary:t) auto
subsection"Lifting and Substitution"
fun lift_ml :: "nat ==> ml ==> ml" (‹lift›) where "lift i (CML nm) = CML nm" | "lift i (VML X) = VML X" | "lift i (AML v vs) = AML (lift i v) (map (lift i) vs)" | "lift i (LamML v) = LamML (lift i v)" | "lift i (CU nm vs) = CU nm (map (lift i) vs)" | "lift i (VU x vs) = VU (if x < i then x else x+1) (map (lift i) vs)" | "lift i (Clo v vs n) = Clo (lift i v) (map (lift i) vs) n" | "lift i (apply u v) = apply (lift i u) (lift i v)"
lemmas ml_induct = lift_ml.induct[of "λi v. P v"] for P
fun lift_tm :: "nat ==> tm ==> tm" (‹lift›) where "lift i (C nm) = C nm" | "lift i (V x) = V(if x < i then x else x+1)" | "lift i (s∙t) = (lift i s)∙(lift i t)" | "lift i (Λ t) = Λ(lift (i+1) t)" | "lift i (term v) = term (lift i v)"
fun lift_ML :: "nat ==> ml ==> ml" (‹liftML›) where "liftML i (CML nm) = CML nm" | "liftML i (VML X) = VML (if X < i then X else X+1)" | "liftML i (AML v vs) = AML (liftML i v) (map (liftML i) vs)" | "liftML i (LamML v) = LamML (liftML (i+1) v)" | "liftML i (CU nm vs) = CU nm (map (liftML i) vs)" | "liftML i (VU x vs) = VU x (map (liftML i) vs)" | "liftML i (Clo v vs n) = Clo (liftML i v) (map (liftML i) vs) n" | "liftML i (apply u v) = apply (liftML i u) (liftML i v)"
definition
cons :: "tm ==> (nat ==> tm) ==> (nat ==> tm)" (infix‹##›65) where "t##σ ≡ λi. case i of 0 ==> t | Suc j ==> lift 0 (σ j)"
definition
cons_ML :: "ml ==> (nat ==> ml) ==> (nat ==> ml)" (infix‹##›65) where "v##σ ≡ λi. case i of 0 ==> v::ml | Suc j ==> liftML 0 (σ j)"
text‹Only for pure terms!› primrec subst :: "(nat ==> tm) ==> tm ==> tm" where "subst σ (C nm) = C nm"
| "subst σ (V x) = σ x"
| "subst σ (Λ t) = Λ(subst (V 0 ## σ) t)"
| "subst σ (s∙t) = (subst σ s) ∙ (subst σ t)"
fun subst_ML :: "(nat ==> ml) ==> ml ==> ml" (‹substML›) where "substML σ (CML nm) = CML nm" | "substML σ (VML X) = σ X" | "substML σ (AML v vs) = AML (substML σ v) (map (substML σ) vs)" | "substML σ (LamML v) = LamML (substML (VML 0 ## σ) v)" | "substML σ (CU nm vs) = CU nm (map (substML σ) vs)" | "substML σ (VU x vs) = VU x (map (substML σ) vs)" | "substML σ (Clo v vs n) = Clo (substML σ v) (map (substML σ) vs) n" | "substML σ (apply u v) = apply (substML σ u) (substML σ v)" (* FIXME currrently needed for code generator lemmas[code]=lift_tm.simpslift_ml.simps
lemmas [code] = subst_ML.simps *)
abbreviation
subst_decr :: "nat ==> tm ==> nat ==> tm"where "subst_decr k t ≡ λn. if n<k then V n else if n=k then t else V(n - 1)" abbreviation
subst_decr_ML :: "nat ==> ml ==> nat ==> ml"where "subst_decr_ML k v ≡ λn. if n<k then VML n else if n=k then v else VML(n - 1)" abbreviation
subst1 :: "tm ==> tm ==> nat ==> tm" (‹(_/[_'/_])› [300, 0, 0] 300) where "s[t/k] ≡ subst (subst_decr k t) s" abbreviation
subst1_ML :: "ml ==> ml ==> nat ==> ml" (‹(_/[_'/_])› [300, 0, 0] 300) where "u[v/k] ≡ substML (subst_decr_ML k v) u"
lemma apply_cons[simp]: "(t##σ) i = (if i=0 then t::tm else lift 0 (σ(i - 1)))" by(simp add: cons_def split:nat.split)
lemma apply_cons_ML[simp]: "(v##σ) i = (if i=0 then v::ml else liftML 0 (σ(i - 1)))" by(simp add: cons_ML_def split:nat.split)
lemma lift_foldl_At[simp]: "lift k (s ∙∙ ts) = (lift k s) ∙∙ (map (lift k) ts)" by(induct ts arbitrary:s) simp_all
lemma lift_lift_ml: fixes v :: ml shows "i < k+1 ==> lift (Suc k) (lift i v) = lift i (lift k v)" by(induct i v rule:lift_ml.induct)
simp_all lemma lift_lift_tm: fixes t :: tm shows "i < k+1 ==> lift (Suc k) (lift i t) = lift i (lift k t)" by(induct t arbitrary: i rule:lift_tm.induct)(simp_all add:lift_lift_ml)
lemma lift_lift_ML: "i < k+1 ==> liftML (Suc k) (liftML i v) = liftML i (liftML k v)" by(induct v arbitrary: i rule:lift_ML.induct)
simp_all
lemma lift_lift_ML_comm: "lift j (liftML i v) = liftML i (lift j v)" by(induct v arbitrary: i j rule:lift_ML.induct)
simp_all
lemma V_ML_cons_ML_subst_decr[simp]: "VML 0 ## subst_decr_ML k v = subst_decr_ML (Suc k) (liftML 0 v)" by(rule ext)(simp add:cons_ML_def split:nat.split)
lemma shift_subst_decr[simp]: "V 0 ## subst_decr k t = subst_decr (Suc k) (lift 0 t)" by(rule ext)(simp add:cons_def split:nat.split)
lemma lift_comp_subst_decr[simp]: "lift 0 o subst_decr_ML k v = subst_decr_ML k (lift 0 v)" by(rule ext) simp
lemma subst_ML_ext: "∀i. σ i = σ' i ==> substML σ v = substML σ' v" by(metis ext)
lemma subst_ext: "∀i. σ i = σ' i ==> subst σ v = subst σ' v" by(metis ext)
lemma lift_Pure_tms[simp]: "pure t ==> pure(lift k t)" by(induct arbitrary:k pred:pure) simp_all
corollary subst_ML_id2[simp]: "closedML 0 v ==> substML σ v = v" using subst_ML_id[where k=0] by simp
lemma subst_ML_coincidence: "closedML k v ==>∀i<k. σ i = σ' i ==> substML σ v = substML σ' v" by (induct σ v arbitrary: k σ' rule: subst_ML.induct) auto
lemma closed_tm_ML_foldl_At: "closedML k (t ∙∙ ts) ⟷ closedML k t ∧ (∀t ∈ set ts. closedML k t)" by(induct ts arbitrary: t) simp_all
lemma closed_ML_lift[simp]: fixes v :: ml shows"closedML k v ==> closedML k (lift m v)" by(induct k v arbitrary: m rule: lift_ML.induct)
(simp_all add:list_eq_iff_nth_eq)
lemma closed_ML_Suc: "closedML n v ==> closedML (Suc n) (liftML k v)" by (induct k v arbitrary: n rule: lift_ML.induct) simp_all
lemma closed_ML_subst_ML: "∀i. closedML k (σ i) ==> closedML k (substML σ v)" by(induct σ v arbitrary: k rule: subst_ML.induct) (auto simp: closed_ML_Suc)
lemma closed_ML_subst_ML2: "closedML k v ==>∀i<k. closedML l (σ i) ==> closedML l (substML σ v)" by(induct σ v arbitrary: k l rule: subst_ML.induct)(auto simp: closed_ML_Suc)
lemma subst_foldl[simp]: "subst σ (s ∙∙ ts) = (subst σ s) ∙∙ (map (subst σ) ts)" by (induct ts arbitrary: s) auto
lemma subst_V: "pure t ==> subst V t = t" by(induct pred:pure) simp_all
lemma lift_subst_aux: "pure t ==>∀i<k. σ' i = lift k (σ i) ==> ∀i≥k. σ'(Suc i) = lift k (σ i) ==> σ' k = V k ==> lift k (subst σ t) = subst σ' (lift k t)" apply(induct arbitrary:σ σ' k pred:pure) apply (simp_all add: split:nat.split) apply(erule meta_allE)+ apply(erule meta_impE) defer apply(erule meta_impE) defer apply(erule meta_mp) apply (simp_all add: cons_def lift_lift_ml lift_lift_tm split:nat.split) done
corollary lift_subst: "pure t ==> lift 0 (subst σ t) = subst (V 0 ## σ) (lift 0 t)" by (simp add: lift_subst_aux lift_lift_ml)
lemma pattern_At'D12: "pattern r ==> r = (s ∙ t) ==> pattern s ∧ pattern t" proof(induct arbitrary: s t pred:pattern) case pat_V thus ?caseby simp next case pat_C thus ?case by (simp add: atomic_tm_head_tm split:if_split_asm)
(metis eta_head_args in_set_butlastD pattern.pat_C) qed
lemma pattern_At_decomp: "pattern(s ∙ t) ==>∃nm ss. s = C nm ∙∙ ss" proof(induct s arbitrary: t) case (At s1 s2) show ?case using At by (metis foldl_Cons foldl_Nil foldl_append pattern_AtD12) qed (auto elim!: pattern.cases split:if_split_asm)
subsection"Reduction of ‹λ›-terms"
text‹The source program:›
axiomatization R :: "(cname * tm list * tm)set"where
pure_R: "(nm,ts,t) : R ==> (∀t ∈ set ts. pure t) ∧ pure t"and
fv_R: "(nm,ts,t) : R ==> X : fv t ==>∃t' ∈ set ts. X : fv t'"and
pattern_R: "(nm,ts,t') : R ==> patterns ts"
inductive_set
Red_tm :: "(tm * tm)set" and red_tm :: "[tm, tm] => bool" (infixl‹→›50) where "s → t ≡ (s, t) ∈ Red_tm"
― ‹$\beta$-reduction›
| "(Λ t) ∙ s → t[s/0]"
― ‹$\eta$-expansion›
| "t → Λ ((lift 0 t) ∙ (V 0))"
― ‹Rewriting›
| "(nm,ts,t) : R ==> (C nm) ∙∙ (map (subst σ) ts) → subst σ t"
| "t → t' ==> Λ t → Λ t'"
| "s → s' ==> s ∙ t → s' ∙ t"
| "t → t' ==> s ∙ t → s ∙ t'"
abbreviation
reds_tm :: "[tm, tm] => bool" (infixl‹→*›50) where "s →* t ≡ (s, t) ∈ Red_tm^*"
lemma red_At2[simp]: "t →* t' ==> s ∙ t →* s ∙ t'" apply(induct rule:rtrancl_induct) apply(simp_all) apply(blast intro:rtrancl_into_rtrancl Red_tm.intros) done
lemma Reds_tm_list_foldl_At: "ts →* ts' ==> s →* s' ==> s ∙∙ ts →* s' ∙∙ ts'" apply(induct arbitrary:s s' rule:Reds_tm_list.induct) apply simp apply simp apply(blast dest: red_At1 red_At2 intro:rtrancl_trans) done
subsection"Reduction of ML-terms"
text‹The compiled rule set:›
consts compR :: "(cname * ml list * ml)set"
text‹\noindent
actual definition is given in \S\ref{sec:Compiler} below.›
text‹Now we characterize ML values that cannot possibly be rewritten by a
in @{const compR}.›
lemma termination_no_match_ML: "i < length ps ==> rev ps ! i = CU nm vs ==> sum_list (map size vs) < sum_list (map size ps)" apply(subgoal_tac "CU nm vs : set ps") apply(drule sum_list_map_remove1[of _ _ size]) apply (simp add:size_list_conv_sum_list) apply (metis in_set_conv_nth length_rev set_rev) done
declare conj_cong[fundef_cong]
function no_match_ML (‹no'_matchML›) where "no_matchML ps os = (∃i < min (size os) (size ps). ∃nm nm' vs vs'. (rev ps)!i = CU nm vs ∧ (rev os)!i = CU nm' vs' ∧ (nm=nm' ⟶ no_matchML vs vs'))" by pat_completeness auto termination apply(relation "measure(%(vs::ml list,_). ∑v←vs. size v)") apply (auto simp:termination_no_match_ML) done
inductive_set
Red_ml :: "(ml * ml)set" and Red_ml_list :: "(ml list * ml list)set" and red_ml :: "[ml, ml] => bool" (infixl‹==>›50) and red_ml_list :: "[ml list, ml list] => bool" (infixl‹==>›50) and reds_ml :: "[ml, ml] => bool" (infixl‹==>*›50) where "s ==> t ≡ (s, t) ∈ Red_ml"
| "ss ==> ts ≡ (ss, ts) ∈ Red_ml_list"
| "s ==>* t ≡ (s, t) ∈ Red_ml^*"
― ‹ML $\beta$-reduction›
| "AML (LamML u) [v] ==> u[v/0]"
― ‹Execution of a compiled rewrite rule›
| "(nm,vs,v) : compR ==>∀ i. closedML 0 (σ i) ==> AML (CML nm) (map (substML σ) vs) ==> substML σ v"
― ‹default rule:›
| "∀i. closedML 0 (σ i) ==> vs = map VML [0..<arity nm] ==> vs' = map (substML σ) vs ==> no_match_compR nm vs' ==> AML (CML nm) vs' ==> substML σ (CU nm vs)"
― ‹Equations for function \texttt{apply}›
| apply_Clo1: "apply (Clo f vs (Suc 0)) v ==> AML f (v # vs)"
| apply_Clo2: "n > 0 ==> apply (Clo f vs (Suc n)) v ==> Clo f (v # vs) n"
| apply_C: "apply (CU nm vs) v ==> CU nm (v # vs)"
| apply_V: "apply (VU x vs) v ==> VU x (v # vs)"
― ‹Context rules›
| ctxt_C: "vs ==> vs' ==> CU nm vs ==> CU nm vs'"
| ctxt_V: "vs ==> vs' ==> VU x vs ==> VU x vs'"
| ctxt_Clo1: "f ==> f' ==> Clo f vs n ==> Clo f' vs n"
| ctxt_Clo3: "vs ==> vs' ==> Clo f vs n ==> Clo f vs' n"
| ctxt_apply1: "s ==> s' ==> apply s t ==> apply s' t"
| ctxt_apply2: "t ==> t' ==> apply s t ==> apply s t'"
| ctxt_A_ML1: "f ==> f' ==> AML f vs ==> AML f' vs"
| ctxt_A_ML2: "vs ==> vs' ==> AML f vs ==> AML f vs'"
| ctxt_list1: "v ==> v' ==> v#vs ==> v'#vs"
| ctxt_list2: "vs ==> vs' ==> v#vs ==> v#vs'"
inductive_set
Red_term :: "(tm * tm)set" and red_term :: "[tm, tm] => bool" (infixl‹==>›50) and reds_term :: "[tm, tm] => bool" (infixl‹==>*›50) where "s ==> t ≡ (s, t) ∈ Red_term"
| "s ==>* t ≡ (s, t) ∈ Red_term^*"
― ‹function \texttt{term}›
| term_C: "term (CU nm vs) ==> (C nm) ∙∙ (map term (rev vs))"
| term_V: "term (VU x vs) ==> (V x) ∙∙ (map term (rev vs))"
| term_Clo: "term(Clo vf vs n) ==> Λ (term (apply (lift 0 (Clo vf vs n)) (VU 0 [])))"
― ‹context rules›
| ctxt_Lam: "t ==> t' ==> Λ t ==> Λ t'"
| ctxt_At1: "s ==> s' ==> s ∙ t ==> s' ∙ t"
| ctxt_At2: "t ==> t' ==> s ∙ t ==> s ∙ t'"
| ctxt_term: "v ==> v' ==> term v ==> term v'"
section"Kernel"
text‹First a special size function and some lemmas for the
proof of the kernel function.›
fun size' :: "ml ==> nat"where "size' (CML nm) = 1" | "size' (VML X) = 1" | "size' (AML v vs) = (size' v + (∑v←vs. size' v))+1" | "size' (LamML v) = size' v + 1" | "size' (CU nm vs) = (∑v←vs. size' v)+1" | "size' (VU nm vs) = (∑v←vs. size' v)+1" | "size' (Clo f vs n) = (size' f + (∑v←vs. size' v))+1" | "size' (apply v w) = (size' v + size' w)+1"
lemma sum_list_size'[simp]: "v ∈ set vs ==> size' v < Suc(sum_list (map size' vs))" by(induct vs)(auto)
corollary cor_sum_list_size'[simp]: "v ∈ set vs ==> size' v < Suc(m + sum_list (map size' vs))" using sum_list_size'[of v vs] by arith
lemma size'_lift_ML: "size' (liftML k v) = size' v" apply(induct v arbitrary:k rule:size'.induct) apply simp_all apply(rule arg_cong[where f = sum_list]) apply(rule map_ext) apply simp apply(rule arg_cong[where f = sum_list]) apply(rule map_ext) apply simp apply(rule arg_cong[where f = sum_list]) apply(rule map_ext) apply simp apply(rule arg_cong[where f = sum_list]) apply(rule map_ext) apply simp done
lemma pure_foldl: "pure t ==>∀t∈set ts. pure t ==> (!!s t. pure s ==> pure t ==> pure(f s t)) ==> pure(foldl f t ts)" by(induct ts arbitrary: t) simp_all
lemma pure_kernel: fixes v :: ml shows"closedML 0 v ==> pure(v!)" proof(induct v rule:kernel.induct) case (3 v) hence"closedML (Suc 0) (lift 0 v)"by simp thenhave"substML (λn. VU 0 []) (lift 0 v) = lift 0 v[VU 0 []/0]" by(rule subst_ML_coincidence) simp moreoverhave"closedML 0 (substML (λn. VU 0 []) (lift 0 v))" by(simp add: closed_ML_subst_ML) ultimatelyhave"closedML 0 (lift 0 v[VU 0 []/0])"by simp thus ?caseusing3(1) by (simp add:pure_foldl) qed (simp_all add:pure_foldl)
corollary subst_V_kernel: fixes v :: ml shows "closedML 0 v ==> subst V (v!) = v!" by (metis pure_kernel subst_V)
lemma kernel_lift_tm: fixes v :: ml shows "closedML 0 v ==> (lift i v)! = lift i (v!)" apply(induct v arbitrary: i rule: kernel.induct) apply (simp_all add:list_eq_iff_nth_eq) apply(simp add: rev_nth) defer apply(simp add: rev_nth) apply(simp add: rev_nth) apply(simp add: rev_nth) apply(erule_tac x="Suc i"in meta_allE) apply(erule meta_impE) defer apply (simp add:lift_subst_ML) apply(subgoal_tac "lift (Suc i) ∘ (λn. if n = 0 then VU 0 [] else VML (n - 1)) = (λn. if n = 0 then VU 0 [] else VML (n - 1))") apply (simp add:lift_lift_ml) apply(rule ext) apply(simp) apply(subst closed_ML_subst_ML2[of "1"]) apply(simp) apply(simp) apply(simp) done
subsection"An auxiliary substitution"
text‹This function is only introduced to prove the involved susbtitution ‹kernel_subst1› below.›
fun subst_ml :: "(nat ==> nat) ==> ml ==> ml"where "subst_ml σ (CML nm) = CML nm" | "subst_ml σ (VML X) = VML X" | "subst_ml σ (AML v vs) = AML (subst_ml σ v) (map (subst_ml σ) vs)" | "subst_ml σ (LamML v) = LamML (subst_ml σ v)" | "subst_ml σ (CU nm vs) = CU nm (map (subst_ml σ) vs)" | "subst_ml σ (VU x vs) = VU (σ x) (map (subst_ml σ) vs)" | "subst_ml σ (Clo v vs n) = Clo (subst_ml σ v) (map (subst_ml σ) vs) n" | "subst_ml σ (apply u v) = apply (subst_ml σ u) (subst_ml σ v)"
lemma lift_ML_subst_ml: "liftML k (subst_ml σ v) = subst_ml σ (liftML k v)" apply (induct σ v arbitrary: k rule:subst_ml.induct) apply (simp_all add:list_eq_iff_nth_eq) done
text‹Maybe this should be the def of lift:› lemma lift_is_subst_ml: "lift k v = subst_ml (λn. if n<k then n else n+1) v" by(induct k v rule:lift_ml.induct)(simp_all add:list_eq_iff_nth_eq)
lemma subst_ml_comp: "subst_ml σ (subst_ml σ' v) = subst_ml (σ o σ') v" by(induct σ' v rule:subst_ml.induct)(simp_all add:list_eq_iff_nth_eq)
lemma subst_kernel: "closedML 0 v ==> subst (λn. V(σ n)) (v!) = (subst_ml σ v)!" apply (induct v arbitrary: σ rule:kernel.induct) apply (simp_all add:list_eq_iff_nth_eq) apply(simp add: rev_nth) defer apply(simp add: rev_nth) apply(simp add: rev_nth) apply(simp add: rev_nth) apply(erule_tac x="λn. case n of 0 ==> 0 | Suc k ==> Suc(σ k)"in meta_allE) apply(erule_tac meta_impE) apply(rule closed_ML_subst_ML2[where k="Suc 0"]) apply (metis closed_ML_lift) apply simp apply(subgoal_tac "(λn. V(case n of 0 ==> 0 | Suc k ==> Suc (σ k))) = (V 0 ## (λn. V(σ n)))") apply (simp add:subst_ml_subst_ML) defer apply(simp add:fun_eq_iff split:nat.split) apply(simp add:lift_is_subst_ml subst_ml_comp) apply(rule arg_cong[where f = kernel]) apply(subgoal_tac "(case_nat 0 (λk. Suc (σ k)) ∘ Suc) = Suc o σ") prefer2apply(simp add:fun_eq_iff split:nat.split) apply(subgoal_tac "(subst_ml (case_nat 0 (λk. Suc (σ k))) ∘ (λn. if n = 0 then VU 0 [] else VML (n - 1))) = (λn. if n = 0 then VU 0 [] else VML (n - 1))") apply simp apply(simp add: fun_eq_iff) done
(* Without this special rule one "also" in the next proof *diverges*,
probably because of HOU. *) lemma eq_Red_tm_trans: "s = t ==> t → t' ==> s → t'" by simp
text‹Soundness of reduction:› theoremfixes v :: ml shows Red_ml_sound: "v ==> v' ==> closedML 0 v ==> v! →* v'! ∧ closedML 0 v'"and "vs ==> vs' ==>∀v∈set vs. closedML 0 v ==> vs! →* vs'! ∧ (∀v'∈set vs'. closedML 0 v')" proof(induct rule:Red_ml_Red_ml_list.inducts) fix u v let ?v = "AML (LamML u) [v]" assume cl: "closedML 0 (AML (LamML u) [v])" let ?u' = "(lift_ml 0 u)[VU 0 []/0]" have"?v! = (Λ((?u')!)) ∙ (v !)"by simp alsohave"…→ (?u' !)[v!/0]" (is"_ → ?R") by(rule Red_tm.intros) also(eq_Red_tm_trans) have"?R = u[v/0]!"using cl apply(cut_tac u = "u"and v = "v"in kernel_subst1) apply(simp_all) done finallyhave"kernel(AML (LamML u) [v]) →* kernel(u[v/0])" (is ?A) by(rule r_into_rtrancl) moreoverhave"closedML 0 (u[v/0])" (is"?C") proof - let ?σ = "λn. if n = 0 then v else VML (n - 1)" let ?σ' = "λn. v" have clu: "closedML (Suc 0) u"and clv: "closedML 0 v"using cl by simp+ have"closedML 0 (substML ?σ' u)" by (metis closed_ML_subst_ML clv) hence"closedML 0 (substML ?σ u)" using subst_ML_coincidence[OF clu, of ?σ ?σ'] by auto thus ?thesis by simp qed ultimatelyshow"?A ∧ ?C" .. next fix σ :: "nat ==> ml"and nm vs v assume σ: "∀i. closedML 0 (σ i)"and compR: "(nm, vs, v) ∈ compR" have"map (subst V) (map (substML σ) (rev vs)!) = map (substML σ) (rev vs)!" by(simp add:list_eq_iff_nth_eq subst_V_kernel closed_ML_subst_ML[OF σ]) with compR_Red_tm[OF compR σ] have"(C nm) ∙∙ ((map (substML σ) (rev vs)) !) →* (substML σ v)!" by(simp add:subst_V_kernel closed_ML_subst_ML[OF σ]) hence"AML (CML nm) (map (substML σ) vs)! →* substML σ v!" (is ?A) by(simp add:rev_map) moreover have"closedML 0 (substML σ v)" (is ?C) by(metis closed_ML_subst_ML σ) ultimatelyshow"?A ∧ ?C" .. qed (auto simp:Reds_tm_list_foldl_At Red_tm_rev rev_map[symmetric])
theorem Red_term_sound: "t ==> t' ==> closedML 0 t ==> kernelt t →* kernelt t' ∧ closedML 0 t'" proof(induct rule:Red_term.inducts) case term_C thus ?case by (auto simp:closed_tm_ML_foldl_At) next case term_V thus ?case by (auto simp:closed_tm_ML_foldl_At) next case (term_Clo vf vs n) hence"(lift 0 vf!) ∙∙ map kernel (rev (map (lift 0) vs)) = lift 0 (vf! ∙∙ (rev vs)!)" apply (simp add:kernel_lift_tm list_eq_iff_nth_eq) apply(simp add:rev_nth rev_map kernel_lift_tm) done hence"term (Clo vf vs n)! →* Λ (term (apply (lift 0 (Clo vf vs n)) (VU 0 [])))!" using term_Clo by(simp del:lift_foldl_At add: r_into_rtrancl Red_tm.intros(2)) moreover have"closedML 0 (Λ (term (apply (lift 0 (Clo vf vs n)) (VU 0 []))))" using term_Clo by simp ultimatelyshow ?case .. next case ctxt_term thus ?caseby simp (metis Red_ml_sound) qed auto
lemma Red_term_hnf_induct[consumes 1]: assumes"(t::tm) ==> t'" "∧nm vs ts. P ((term (CU nm vs)) ∙∙ ts) ((C nm ∙∙ map term (rev vs)) ∙∙ ts)" "∧x vs ts. P (term (VU x vs) ∙∙ ts) ((V x ∙∙ map term (rev vs)) ∙∙ ts)" "∧vf vs n ts. P (term (Clo vf vs n) ∙∙ ts) ((Λ (term (apply (lift 0 (Clo vf vs n)) (VU 0 [])))) ∙∙ ts)" "∧t t' ts. [t ==> t'; P t t']==> P (Λ t ∙∙ ts) (Λ t' ∙∙ ts)" "∧v v' ts. v ==> v' ==> P (term v ∙∙ ts) (term v' ∙∙ ts)" "∧x i t' ts. i<size ts ==> ts!i ==> t' ==> P (ts!i) (t') ==> P (V x ∙∙ ts) (V x ∙∙ ts[i:=t'])" "∧nm i t' ts. i<size ts ==> ts!i ==> t' ==> P (ts!i) (t') ==> P (C nm ∙∙ ts) (C nm ∙∙ ts[i:=t'])" "∧t i t' ts. i<size ts ==> ts!i ==> t' ==> P (ts!i) (t') ==> P (Λ t ∙∙ ts) (Λ t ∙∙ ts[i:=t'])" "∧v i t' ts. i<size ts ==> ts!i ==> t' ==> P (ts!i) (t') ==> P (term v ∙∙ ts) (term v ∙∙ (ts[i:=t']))" shows"P t t'" proof-
{ fix ts from assms have"P (t ∙∙ ts) (t' ∙∙ ts)" proof(induct arbitrary: ts rule:Red_term.induct) case term_C thus ?caseby metis next case term_V thus ?caseby metis next case term_Clo thus ?caseby metis next case ctxt_Lam thus ?caseby simp (metis foldl_Nil) next case (ctxt_At1 s s' t ts) thus ?caseusing ctxt_At1(2)[of "t#ts"] by simp next case (ctxt_At2 t t' s ts)
{ fix n rs assume"s = V n ∙∙ rs" hence ?caseusing ctxt_At2(8)[of "size rs""rs @ t # ts" t' n] ctxt_At2 by simp (metis foldl_Nil)
} moreover
{ fix nm rs assume"s = C nm ∙∙ rs" hence ?caseusing ctxt_At2(9)[of "size rs""rs @ t # ts" t' nm] ctxt_At2 by simp (metis foldl_Nil)
} moreover
{ fix r rs assume"s = Λ r ∙∙ rs" hence ?caseusing ctxt_At2(10)[of "size rs""rs @ t # ts" t'] ctxt_At2 by simp (metis foldl_Nil)
} moreover
{ fix v rs assume"s = term v ∙∙ rs" hence ?caseusing ctxt_At2(11)[of "size rs""rs @ t # ts" t'] ctxt_At2 by simp (metis foldl_Nil)
} ultimatelyshow ?caseusing tm_vector_cases[of s] by blast qed
} from this[of "[]"] show ?thesis by simp qed
corollary Red_term_hnf_cases[consumes 1]: assumes"(t::tm) ==> t'" "∧nm vs ts. t = term (CU nm vs) ∙∙ ts ==> t' = (C nm ∙∙ map term (rev vs)) ∙∙ ts ==> P" "∧x vs ts. t = term (VU x vs) ∙∙ ts ==> t' = (V x ∙∙ map term (rev vs)) ∙∙ ts ==> P" "∧vf vs n ts. t = term (Clo vf vs n) ∙∙ ts ==> t' = Λ (term (apply (lift 0 (Clo vf vs n)) (VU 0 []))) ∙∙ ts ==> P" "∧s s' ts. t = Λ s ∙∙ ts ==> t' = Λ s' ∙∙ ts ==> s ==> s' ==> P" "∧v v' ts. t = term v ∙∙ ts ==> t' = term v' ∙∙ ts ==> v ==> v' ==> P" "∧x i r' ts. i<size ts ==> ts!i ==> r' ==> t = V x ∙∙ ts ==> t' = V x ∙∙ ts[i:=r'] ==> P" "∧nm i r' ts. i<size ts ==> ts!i ==> r' ==> t = C nm ∙∙ ts ==> t' = C nm ∙∙ ts[i:=r'] ==> P" "∧s i r' ts. i<size ts ==> ts!i ==> r' ==> t = Λ s ∙∙ ts ==> t' = Λ s ∙∙ ts[i:=r'] ==> P" "∧v i r' ts. i<size ts ==> ts!i ==> r' ==> t = term v ∙∙ ts ==> t' = term v ∙∙ (ts[i:=r']) ==> P" shows"P"using assms apply - apply(induct rule:Red_term_hnf_induct) apply metis+ done
lemma [simp]: "C_normal(term v ∙∙ ts) ⟷ C_normalML v ∧ ts = []" by(fastforce elim: C_normal.cases)
lemma [simp]: "C_normal(Λ t ∙∙ ts) ⟷ C_normal t ∧ ts = []" by(fastforce elim: C_normal.cases)
lemma not_pure_term[simp]: "¬ pure(term v)" proof assume"pure(term v)"thus False by cases qed
abbreviation RedMLs :: "tm list ==> tm list ==> bool" (infix‹[==>*]›50) where "ss [==>*] ts ≡ size ss = size ts ∧ (∀i<size ss. ss!i ==>* ts!i)"
fun C_U_args :: "tm ==> tm list" (‹CU'_args›) where "CU_args(s ∙ t) = CU_args s @ [t]" | "CU_args(term(CU nm vs)) = map term (rev vs)" | "CU_args _ = []"
lemma [simp]: "CU_args(C nm ∙∙ ts) = ts" by (induct ts rule:rev_induct) auto
lemma redts_term_cong: "v ==>* v' ==> term v ==>* term v'" apply(erule converse_rtrancl_induct) apply(rule rtrancl_refl) apply(fast intro: converse_rtrancl_into_rtrancl dest: ctxt_term) done
lemma C_Red_term_ML: "v ==> v' ==> C_normalML v ==> dtermML v = C nm ∙∙ ts ==> dtermML v' = C nm ∙∙ map dterm (CU_args(term v')) ∧ CU_args(term v) [==>*] CU_args(term v') ∧ ts = map dterm (CU_args(term v))"and "(vs:: ml list) ==> vs' ==> i < length vs ==> vs ! i ==>* vs' ! i" apply(induct arbitrary: nm ts and i rule:Red_ml_Red_ml_list.inducts) apply(simp_all add:Red_ml_list_length del: map_map) apply(frule Red_ml_list_length) apply(simp add: redts_term_cong rev_nth del: map_map) apply(simp add:nth_Cons' r_into_rtrancl del: map_map) apply(simp add:nth_Cons') done
lemma C_normal_subterm: "C_normal t ==> dterm t = C nm ∙∙ ts ==> s ∈ set(CU_args t) ==> C_normal s" apply(induct rule: C_normal.induct) apply auto apply(case_tac v) apply auto done
lemma C_normal_subterms: "C_normal t ==> dterm t = C nm ∙∙ ts ==> ts = map dterm (CU_args t)" apply(induct rule: C_normal.induct) apply auto apply(case_tac v) apply auto done
lemma Red_term_it: "(V x ∙∙ rs, r) : Red_term^^i ==>∃ts is. r = V x ∙∙ ts ∧ size ts = size rs & size is = size rs ∧ (∀j<size ts. (rs!j, ts!j) : Red_term^^(is!j) ∧ is!j <= i)" proof(induct i arbitrary:rs) case0 moreover have"∃is. length is = length rs ∧ (∀j<size rs. (rs!j, rs!j) ∈ Red_term ^^ is!j ∧ is!j = 0)" (is"∃is. ?P is") proof show"?P(replicate (size rs) 0)"by simp qed ultimatelyshow ?caseby auto next case (Suc i rs) from‹(V x ∙∙ rs, r) ∈ Red_term ^^ Suc i› obtain r' where r': "V x ∙∙ rs ==> r'"and"(r',r) ∈ Red_term ^^ i" by (metis relpow_Suc_D2) from r' have"∃k<size rs. ∃s. rs!k ==> s ∧ r' = V x ∙∙ rs[k:=s]" proof(induct rs arbitrary: r' rule:rev_induct) case Nil thus ?caseby(fastforce elim: Red_term.cases) next case (snoc r rs) hence"(V x ∙∙ rs) ∙ r ==> r'"by simp thus ?case proof(cases rule:Red_term.cases) case (ctxt_At1 s') thenobtain k s'' where aux: "k<length rs""rs ! k ==> s''""s' = V x ∙∙ rs[k := s'']" using snoc(1) by force show ?thesis (is"∃k < ?n. ∃s. ?P k s") proof- have"k<?n ∧ ?P k s''"using ctxt_At1 aux by (simp add:nth_append) (metis last_snoc butlast_snoc list_update_append1) thus ?thesis by blast qed next case (ctxt_At2 t') show ?thesis (is"∃k < ?n. ∃s. ?P k s") proof- have"size rs<?n ∧ ?P (size rs) t'"using ctxt_At2 by simp thus ?thesis by blast qed qed qed thenobtain k s where"k<size rs""rs!k ==> s"and [simp]: "r' = V x ∙∙ rs[k:=s]"by metis from Suc(1)[of "rs[k:=s]"] ‹(r',r) ∈ Red_term ^^ i› show ?caseusing‹k<size rs›‹rs!k ==> s› apply auto apply(rule_tac x="is[k := Suc(is!k)]"in exI) apply (auto simp:nth_list_update) apply(erule_tac x=k in allE) apply auto apply (metis relpow_Suc_I2 relpow.simps(2)) done qed
lemma C_Red_term_it: "(C nm ∙∙ rs, r) : Red_term^^i ==>∃ts is. r = C nm ∙∙ ts ∧ size ts = size rs ∧ size is = size rs ∧ (∀j<size ts. (rs!j, ts!j) ∈ Red_term^^(is!j) ∧ is!j ≤ i)" proof(induct i arbitrary:rs) case0 moreover have"∃is. length is = length rs ∧ (∀j<size rs. (rs!j, rs!j) ∈ Red_term ^^ is!j ∧ is!j = 0)" (is"∃is. ?P is") proof show"?P(replicate (size rs) 0)"by simp qed ultimatelyshow ?caseby auto next case (Suc i rs) from‹(C nm ∙∙ rs, r) ∈ Red_term ^^ Suc i› obtain r' where r': "C nm ∙∙ rs ==> r'"and"(r',r) ∈ Red_term ^^ i" by (metis relpow_Suc_D2) from r' have"∃k<size rs. ∃s. rs!k ==> s ∧ r' = C nm ∙∙ rs[k:=s]" proof(induct rs arbitrary: r' rule:rev_induct) case Nil thus ?caseby(fastforce elim: Red_term.cases) next case (snoc r rs) hence"(C nm ∙∙ rs) ∙ r ==> r'"by simp thus ?case proof(cases rule:Red_term.cases) case (ctxt_At1 s') thenobtain k s'' where aux: "k<length rs""rs ! k ==> s''""s' = C nm ∙∙ rs[k := s'']" using snoc(1) by force show ?thesis (is"∃k < ?n. ∃s. ?P k s") proof- have"k<?n ∧ ?P k s''"using ctxt_At1 aux by (simp add:nth_append) (metis last_snoc butlast_snoc list_update_append1) thus ?thesis by blast qed next case (ctxt_At2 t') show ?thesis (is"∃k < ?n. ∃s. ?P k s") proof- have"size rs<?n ∧ ?P (size rs) t'"using ctxt_At2 by simp thus ?thesis by blast qed qed qed thenobtain k s where"k<size rs""rs!k ==> s"and [simp]: "r' = C nm ∙∙ rs[k:=s]"by metis from Suc(1)[of "rs[k:=s]"] ‹(r',r) ∈ Red_term ^^ i› show ?caseusing‹k<size rs›‹rs!k ==> s› apply auto apply(rule_tac x="is[k := Suc(is!k)]"in exI) apply (auto simp:nth_list_update) apply(erule_tac x=k in allE) apply auto apply (metis relpow_Suc_I2 relpow.simps(2)) done qed
lemma pure_At[simp]: "pure(s ∙ t) ⟷ pure s ∧ pure t" by(fastforce elim: pure.cases)
lemma pure_foldl_At[simp]: "pure(s ∙∙ ts) ⟷ pure s ∧ (∀t∈set ts. pure t)" by(induct ts arbitrary: s) auto
lemma nbe_C_normal_ML: assumes"term v ==>* t'""C_normalML v""pure t'"shows"normal t'" proof -
{ fix t t' i v assume"(t,t') : Red_term^^i" hence"t = term v ==> C_normalML v ==> pure t' ==> normal t'" proof(induct i arbitrary: t t' v rule:less_induct) case (less k) show ?case proof (cases k) case0thus ?thesis using less by auto next case (Suc i) thenobtain i' s where"t ==> s"and red: "(s,t') : Red_term^^i'"and [arith]: "i' <= i" by (metis eq_imp_le less(5) Suc relpow_Suc_D2) hence"term v ==> s"using Suc less by simp thus ?thesis proof cases case (term_C nm vs) with less have0:"no_match_compR nm vs"by auto let ?n = "size vs" have1: "(C nm ∙∙ map term (rev vs),t') : Red_term^^i'" using term_C ‹(s,t') : Red_term^^i'›by simp with C_Red_term_it[OF 1] obtain ts ks where [simp]: "t' = C nm ∙∙ ts" and sz: "size ts = ?n ∧ size ks = ?n ∧ (∀i<?n. (term((rev vs)!i), ts!i) : Red_term^^(ks!i) ∧ ks ! i ≤ i')" by(auto cong:conj_cong) have pure_ts: "∀t∈set ts. pure t"using‹pure t'›by simp
{ fix i assume"i<size vs" moreoverhence"(term((rev vs)!i), ts!i) : Red_term^^(ks!i)"by(metis sz) ultimatelyhave"normal (ts!i)" apply - apply(rule less(1)) prefer5apply assumption using sz Suc apply fastforce apply(rule refl) using less term_C apply(auto) apply (metis in_set_conv_nth length_rev set_rev) apply (metis in_set_conv_nth pure_ts sz) done
} note2 = this have3: "no_match_R nm (map dterm (map term (rev vs)))" apply(subst map_dterm_term) apply(rule no_match_R_coincide) using0by simp have4: "map term (rev vs) [==>*] ts" proof - have"(C nm ∙∙ map term (rev vs),t'): Red_term^^i'" using red term_C by auto from C_Red_term_it[OF this] obtain ts' "is"where"t' = C nm ∙∙ ts'" and"length ts' = ?n ∧ length is =?n ∧ (∀j< ?n. (map term (rev vs) ! j, ts' ! j) ∈ Red_term ^^ is ! j ∧ is ! j ≤ i')" using sz by auto from‹t' = C nm ∙∙ ts'›‹t' = C nm ∙∙ ts›have"ts = ts'"by simp show ?thesis using sz by (auto simp: rtrancl_is_UN_relpow) qed have5: "∀t∈set(map term vs). C_normal t" using less term_C by auto have"no_match_R nm (map dterm ts)" apply auto apply(subgoal_tac "no_match aa (map dterm (map term (rev vs)))") prefer2 using3apply blast using45 no_match_preserved[OF _ _ _ refl, of "map term (rev vs)""ts"] by simp hence6: "no_match_R nm ts"by(metis map_dterm_pure[OF pure_ts]) thenshow"normal t'" apply(simp) apply(rule normal.intros(3)) using2 sz apply(fastforce simp:set_conv_nth) apply auto apply(subgoal_tac "no_match aa (take (size aa) ts)") apply (metis no_match) apply(fastforce intro:no_match_take) done next case (term_V x vs) let ?n = "size vs" have1: "(V x ∙∙ map term (rev vs),t') : Red_term^^i'" using term_V ‹(s,t') : Red_term^^i'›by simp with Red_term_it[OF 1] obtain ts "is"where [simp]: "t' = V x ∙∙ ts" and2: "length ts = ?n ∧ length is = ?n ∧ (∀j<?n. (term (rev vs ! j), ts ! j) ∈ Red_term ^^ is ! j ∧ is ! j ≤ i')" by (auto cong:conj_cong) have"∀j<?n. normal(ts!j)" proof(clarify) fix j assume0: "j < ?n" thenhave"is!j < k"using‹k=Suc i›2by auto have red: "(term (rev vs ! j), ts ! j) ∈ Red_term ^^ is ! j"using‹j < ?n›2by auto have pure: "pure (ts ! j)"using‹pure t'›02by auto have Cnm: "C_normalML (rev vs ! j)"using less term_V by simp (metis 0 in_set_conv_nth length_rev set_rev) from less(1)[OF ‹is!j < k› refl Cnm pure red] show"normal(ts!j)" . qed note3=this show ?thesis by simp (metis normal.intros(1) in_set_conv_nth 23) next case (term_Clo f vs n) let ?u = "apply (lift 0 (Clo f vs n)) (VU 0 [])" from term_Clo ‹(s,t') : Red_term^^i'› obtain t'' where [simp]: "t' = Λ t''"and1: "(term ?u, t'') : Red_term^^i'" by(metis Lam_Red_term_itE) have"i' < k"using‹k = Suc i›by arith have"pure t''"using‹pure t'›by simp have"C_normalML ?u"using less term_Clo by(simp) from less(1)[OF ‹i' < k› refl ‹C_normalML ?u›‹pure t''›1] show ?thesis by(simp add:normal.intros) next case (ctxt_term u') have"i' < k"using‹k = Suc i›by arith have"C_normalML u'"by (rule C_normal_ML_inv) (insert less ctxt_term, simp_all) have"(term u', t') ∈ Red_term ^^ i'"using red ctxt_term by auto from less(1)[OF ‹i' < k› refl ‹C_normalML u'›‹pure t'› this] show ?thesis . qed qed qed
} thus ?thesis using assms(2-) rtrancl_imp_relpow[OF assms(1)] by blast qed
lemma C_normal_ML_compile: "pure t ==>∀i. C_normalML(σ i) ==> C_normalML (compile t σ)" by(induct t arbitrary: σ) (simp_all add: C_normal_ML_lift_ML)
corollary nbe_normal: "pure t ==> term(comp_fixed t) ==>* t' ==> pure t' ==> normal t'" apply(erule nbe_C_normal_ML) apply(simp add: C_normal_ML_compile) apply assumption done
section‹Refinements›
text‹We ensure that all occurrences of @{term "CU nm vs"} satisfy
invariant @{prop"size vs = arity nm"}.›
text‹A constructor value:›
fun CUs :: "ml ==> bool"where "CUs(CU nm vs) = (size vs = arity nm ∧ (∀v∈set vs. CUs v))" | "CUs _ = False"
lemma pattern_subst_ML_coincidence: "pattern t ==>∀i∈fv t. σ i = σ' i ==> subst_ML σ (comp_pat t) = subst_ML σ' (comp_pat t)" by(induct pred:pattern) auto
lemma linpats_pattern: "linpats ts ==> patterns ts" proof(induct ts rule:linpats.induct) case (1 ts) show ?case proof fix t assume"t : set ts" thenobtain i where"i < size ts"and [simp]: "t = ts!i" by (auto simp: in_set_conv_nth) hence"(∃x. t = V x) ∨ (∃nm ts'. t = C nm ∙∙ ts' ∧ arity nm = size ts' & linpats ts')"
(is"?V | ?C") using1(2) by(simp add:linpats.simps[of ts]) thus"pattern t" proof assume"?V"thus ?thesis by(auto simp:pat_V) next assume"?C"thus ?thesis using1(1) ‹i < size ts› by auto (metis pat_C) qed qed qed
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.