definition LeftDerivationFix :: "sentence ==> nat ==> derivation ==> nat ==> sentence ==> bool" where "LeftDerivationFix α i D j β = (is_sentence α ∧ is_sentence β ∧ LeftDerivation α D β ∧ i < length α ∧ j < length β ∧ α ! i = β ! j ∧ (∃ E F. D = E@(derivation_shift F 0 (Suc j)) ∧ LeftDerivation (take i α) E (take j β) ∧ LeftDerivation (drop (Suc i) α) F (drop (Suc j) β)))"
definition LeftDerivationIntro :: "sentence ==> nat ==> rule ==> nat ==> derivation ==> nat ==> sentence ==> bool" where "LeftDerivationIntro α i r ix D j γ = (∃ β. LeftDerives1 α i r β ∧ ix < length (snd r) ∧ (snd r) ! ix = γ ! j ∧ LeftDerivationFix β (i + ix) D j γ)"
lemma LeftDerivationFix_empty[simp]: "is_sentence α ==> i < length α ==> LeftDerivationFix α i [] i α" apply (auto simp add: LeftDerivationFix_def) apply (rule_tac x="[]"in exI) apply auto done
lemma Derive_empty[simp]: "Derive a [] = a" by (auto simp add: Derive_def)
lemma LeftDerivation_append1: "LeftDerivation a (D@[(i, r)]) c ==>∃ b. LeftDerivation a D b ∧ LeftDerives1 b i r c" by (simp add: LeftDerivation_append)
lemma Derivation_append1: "Derivation a (D@[(i, r)]) c ==>∃ b. Derivation a D b ∧ Derives1 b i r c" by (simp add: Derivation_append)
lemma Derivation_take_derive: assumes"Derivation a D b" shows"Derivation a (take n D) (Derive a (take n D))" by (metis Derivation_append Derive append_take_drop_id assms)
lemma LeftDerivation_take_derive: assumes"LeftDerivation a D b" shows"LeftDerivation a (take n D) (Derive a (take n D))" by (metis Derive LeftDerivation_append LeftDerivation_implies_Derivation append_take_drop_id assms)
lemma Derivation_Derive_take_Derives1: assumes"N ≠ 0" assumes"N ≤ length D" assumes"Derivation a D b" assumes α: "α = Derive a (take (N - 1) D)" assumes"β = Derive a (take N D)" shows"Derives1 α (fst (D ! (N - 1))) (snd (D ! (N - 1))) β" proof - let ?D1 = "take (N - 1) D" let ?D2 = "take N D" from assms have app: "?D2 = ?D1 @ [D ! (N - 1)]" apply auto by (metis Suc_less_eq Suc_pred le_imp_less_Suc take_Suc_conv_app_nth) from assms have"Derivation a ?D2 β" using Derivation_take_derive by blast with app show ?thesis using Derivation.simps Derivation_append Derive α by auto qed
lemma LeftDerivation_Derive_take_LeftDerives1: assumes"N ≠ 0" assumes"N ≤ length D" assumes"LeftDerivation a D b" assumes α: "α = Derive a (take (N - 1) D)" assumes"β = Derive a (take N D)" shows"LeftDerives1 α (fst (D ! (N - 1))) (snd (D ! (N - 1))) β" proof - let ?D1 = "take (N - 1) D" let ?D2 = "take N D" from assms have app: "?D2 = ?D1 @ [D ! (N - 1)]" apply auto by (metis Suc_less_eq Suc_pred le_imp_less_Suc take_Suc_conv_app_nth) from assms have"LeftDerivation a ?D2 β" using LeftDerivation_take_derive by blast with app show ?thesis by (metis Derive LeftDerivation_append1 LeftDerivation_implies_Derivation α prod.collapse) qed
lemma LeftDerives1_skip_prefix: "length a ≤ i ==> LeftDerives1 (a@b) i r (a@c) ==> LeftDerives1 b (i - length a) r c" apply (auto simp add: LeftDerives1_def) using leftmost_skip_prefix apply blast by (simp add: Derives1_skip_prefix)
lemma LeftDerives1_skip_suffix: assumes i: "i < length a" assumes D: "LeftDerives1 (a@c) i r (b@c)" shows"LeftDerives1 a i r b" proof - note Derives1_def[where u="a@c"and v="b@c"and i=i and r=r] thenhave"∃x y N α. a @ c = x @ [N] @ y ∧ b @ c = x @ α @ y ∧ is_sentence x ∧ is_sentence y ∧ (N, α) ∈R∧ r = (N, α) ∧ i = length x" using D LeftDerives1_implies_Derives1 by auto thenobtain x y N α where split: "a @ c = x @ [N] @ y ∧ b @ c = x @ α @ y ∧ is_sentence x ∧ is_sentence y ∧ (N, α) ∈R∧ r = (N, α) ∧ i = length x" by blast from split have"length (a@c) = length (x @ [N] @ y)"by auto thenhave"length a + length c = length x + length y + 1"by simp with split have"length a + length c = i + length y + 1"by simp with i have len_c_y: "length c ≤ length y"by arith let ?y = "take (length y - length c) y" from split have ac: "a @ c = (x @ [N]) @ y"by auto note cancel_suffix[where a=a and c = c and b = "x@[N]"and d = "y", OF ac len_c_y] thenhave a: "a = x @ [N] @ ?y"by auto from split have bc: "b @ c = (x @ α) @ y"by auto note cancel_suffix[where a=b and c = c and b = "x@α"and d = "y", OF bc len_c_y] thenhave b: "b = x @ α @ ?y"by auto from split len_c_y a b show ?thesis apply (simp only: LeftDerives1_def Derives1_def) apply (rule_tac conjI) using D LeftDerives1_def i leftmost_cons_less apply blast apply (rule_tac x=x in exI) apply (rule_tac x="?y"in exI) apply (rule_tac x="N"in exI) apply (rule_tac x="α"in exI) apply auto by (rule is_sentence_take) qed
lemma LeftDerives1_X_is_part_of_rule[consumes 2, case_names Suffix Prefix]: assumes aXb: "LeftDerives1 δ i r (a@[X]@b)" assumes split: "splits_at δ i α N β" assumes prefix: "∧ β. δ = a @ [X] @ β ==> length a < i ==> is_word (a @ [X]) ==> LeftDerives1 β (i - length a - 1) r b ==> False" assumes suffix: "∧ α. δ = α @ [X] @ b ==> LeftDerives1 α i r a ==> False" shows"∃ u v. a = α @ u ∧ b = v @ β ∧ (snd r) = u@[X]@v" proof - have aXb_old: "Derives1 δ i r (a@[X]@b)" using LeftDerives1_implies_Derives1 aXb by blast have prefix_or: "is_prefix α a ∨ is_proper_prefix a α" by (metis Derives1_prefix split aXb_old is_prefix_eq_proper_prefix) have is_word_α: "is_word α" using LeftDerives1_splits_at_is_word aXb assms(2) by blast have"is_proper_prefix a α ==> False" proof - assume proper:"is_proper_prefix a α" thenhave"∃ u. u ≠ [] ∧ α = a@u"by (metis is_proper_prefix_def) thenobtain u where u: "u ≠ [] ∧ α = a@u"by blast note splits_at = splits_at_α[OF aXb_old split] splits_at_combine[OF split] from splits_at have α1: "α = take i δ"by blast from splits_at have α2: "α = take i (a@[X]@b)"by blast from splits_at have lenα: "length α = i"by blast with proper have lena: "length a < i" using append_eq_conv_conj drop_eq_Nil leI u by auto with is_word_α α2have is_word_aX: "is_word (a@[X])" by (simp add: is_word_terminals not_less take_Cons' u) from u α2have"a@u = take i (a@[X]@b)"by auto with lena have"u = take (i - length a) ([X]@b)"by (simp add: less_or_eq_imp_le) with lena have uX: "u = [X]@(take (i - length a - 1) b)"by (simp add: not_less take_Cons') let ?β = "(take (i - length a - 1) b) @ [N] @ β" from splits_at have f1: "δ = α @ [N] @ β"by blast with u uX have f2: "δ = a @ [X] @ ?β"by simp note skip = LeftDerives1_skip_prefix[where a = "a @ [X]"and b = "?β"and
r = r and i = i and c = b] thenhave D: "LeftDerives1 ?β (i - length a - 1) r b" using One_nat_def Suc_leI aXb append_assoc diff_diff_left f2 lena length_Cons
length_append length_append_singleton list.size(3) by fastforce note prefix[OF f2 lena is_word_aX D] thenshow"False" . qed with prefix_or have is_prefix: "is_prefix α a"by blast
from aXb have aXb': "LeftDerives1 δ i r ((a@[X])@b)"by auto thenhave aXb'_old: "Derives1 δ i r ((a@[X])@b)"by (simp add: LeftDerives1_implies_Derives1) note Derives1_suffix[OF aXb'_old split] thenhave suffix_or: "is_suffix β b ∨ is_proper_suffix b β" by (metis is_suffix_eq_proper_suffix) have"is_proper_suffix b β ==> False" proof - assume proper: "is_proper_suffix b β" thenhave"∃ u. u ≠ [] ∧ β = u@b"by (metis is_proper_suffix_def) thenobtain u where u: "u ≠ [] ∧ β = u@b"by blast note splits_at = splits_at_β[OF aXb_old split] splits_at_combine[OF split] from splits_at have β1: "β = drop (Suc i) δ"by blast from splits_at have β2: "β = drop (i + length (snd r)) (a @ [X] @ b)"by blast from splits_at have lenβ: "length β = length δ - i - 1"by blast with proper have lenb: "length b < length β"by (metis is_proper_suffix_length_cmp) from u β2have"u@b = drop (i + length (snd r)) ((a @ [X]) @ b)"by auto hence"u = drop (i + length (snd r)) (a @ [X])" by (metis drop_cancel_suffix) hence uX: "u = drop (i + length (snd r)) a @ [X]"by (metis drop_keep_last u) let ?α = "α @ [N] @ (drop (i + length (snd r)) a)" from splits_at have f1: "δ = α @ [N] @ β"by blast with u uX have f2: "δ = ?α @ [X] @ b"by simp note skip = LeftDerives1_skip_suffix[where a = "?α"and c = "[X]@b"and b="a"and
r = r and i = i] have f3: "i < length (α @ [N] @ drop (i + length (snd r)) a)" proof - have f1: "1 + i + length b = length [X] + length b + i" by (metis Groups.add_ac(2) Suc_eq_plus1_left length_Cons list.size(3) list.size(4) semiring_normalization_rules(22)) have f2: "length δ - i - 1 = length ((α @ [N] @ drop (i + length (snd r)) a) @ [X] @ b) - Suc i" by (metis f2 length_drop splits_at(1)) have"length ([]::symbol list) ≠ length δ - i - 1 - length b" by (metis add_diff_cancel_right' append_Nil2 append_eq_append_conv lenβ length_append u) thenhave"length ([]::symbol list) ≠ length α + length ([N] @ drop (i + length (snd r)) a) - i" using f2 f1 by (metis Suc_eq_plus1_left add_diff_cancel_right' diff_diff_left length_append) thenshow ?thesis by auto qed from aXb f2 have D: "LeftDerives1 (?α @ [X] @ b) i r (a@[X]@b)"by auto note skip[OF f3 D] note suffix[OF f2 skip[OF f3 D]] thenshow"False" . qed with suffix_or have is_suffix: "is_suffix β b"by blast
from is_prefix have"∃ u. a = α @ u"by (auto simp add: is_prefix_def) thenobtain u where u: "a = α @ u"by blast from is_suffix have"∃ v. b = v @ β"by (auto simp add: is_suffix_def) thenobtain v where v: "b = v @ β"by blast
from u v splits_at_combine[OF split] aXb have D:"LeftDerives1 (α@[N]@β) i r (α@(u@[X]@v)@β)" by simp from splits_at_α[OF aXb_old split] have i: "length α = i"by blast from i have i1: "length α ≤ i"and i2: "i ≤ length α"by auto note LeftDerives1_skip_suffix[OF _ LeftDerives1_skip_prefix[OF i1 D], simplified, OF i2] thenhave"LeftDerives1 [N] 0 r (u @ [X] @ v)"by auto thenhave"Derives1 [N] 0 r (u @ [X] @ v)" using LeftDerives1_implies_Derives1 by auto thenhave r: "snd r = u @ [X] @ v" by (metis Derives1_split append_Cons append_Nil length_0_conv list.inject self_append_conv) show ?thesis using u v r by auto qed
lemma LeftDerivationFix_grow_suffix: assumes LDF: "LeftDerivationFix (b1@[X]@b2) (length b1) D j c" assumes suffix_b2: "LeftDerives1 suffix e r b2" assumes is_word_b1X: "is_word (b1@[X])" shows"LeftDerivationFix (b1@[X]@suffix) (length b1) ((e + length (b1@[X]), r)#D) j c" proof - from LDF have LDF': "is_sentence (b1@[X]@b2) ∧ is_sentence c ∧ LeftDerivation (b1 @ [X] @ b2) D c ∧ length b1 < length (b1 @ [X] @ b2) ∧ j < length c ∧ (b1 @ [X] @ b2) ! length b1 = c ! j ∧ (∃E F. D = E @ derivation_shift F 0 (Suc j) ∧ LeftDerivation (take (length b1) (b1 @ [X] @ b2)) E (take j c) ∧ LeftDerivation (drop (Suc (length b1)) (b1 @ [X] @ b2)) F (drop (Suc j) c))" using LeftDerivationFix_def by blast thenobtain E F where EF: "D = E @ derivation_shift F 0 (Suc j) ∧ LeftDerivation (take (length b1) (b1 @ [X] @ b2)) E (take j c) ∧ LeftDerivation (drop (Suc (length b1)) (b1 @ [X] @ b2)) F (drop (Suc j) c)"by blast thenhave LD_b1_c: "LeftDerivation b1 E (take j c)"by simp with is_word_b1X have E: "E = []" using LeftDerivation_implies_Derivation is_word_Derivation is_word_append by blast thenhave b1_def: "b1 = take j c"using LD_b1_c by auto thenhave b1_len: "j = length b1" by (simp add: LDF' dual_order.strict_implies_order min.absorb2) have D: "D = derivation_shift F 0 (Suc j)"using EF E by simp have step: "LeftDerives1 (b1 @ [X] @ suffix) (Suc (e + length b1)) r (b1 @ [X] @ b2) ∧ LeftDerivation (b1 @ [X] @ b2) D c" by (metis LDF' LeftDerives1_append_prefix add_Suc_right append_assoc assms(2) is_word_b1X
length_append_singleton) thenhave is_sentence_b1Xsuffix: "is_sentence (b1 @ [X] @ suffix)" using Derives1_sentence1 LeftDerives1_implies_Derives1 by blast have X_eq_cj: "X = c ! j"using LDF' by auto show ?thesis apply (simp add: LeftDerivationFix_def) apply (rule conjI) using is_sentence_b1Xsuffix apply simp apply (rule conjI) using LDF' apply simp apply (rule conjI) using step apply force apply (rule conjI) using LDF' apply simp apply (rule conjI) apply (rule X_eq_cj) apply (rule_tac x="[]"in exI) apply (rule_tac x="(e, r)#F"in exI) apply auto apply (rule b1_len[symmetric]) apply (rule D) apply (rule b1_def) apply (rule_tac x="b2"in exI) apply (simp add: suffix_b2) using EF by auto qed
lemma Derives1_append_suffix: assumes Derives1: "Derives1 v i r w" assumes u: "is_sentence u" shows"Derives1 (v@u) i r (w@u)" proof - have"∃ α N β. splits_at v i α N β"using assms splits_at_ex by auto thenobtain α N β where split_v: "splits_at v i α N β"by blast have split_w: "w = α@(snd r)@β"using assms split_v splits_at_combine_dest by blast have split_uv: "splits_at (v@u) i α N (β@u)" by (simp add: split_v splits_at_append) have is_sentence_uv: "is_sentence (v@u)" using Derives1 Derives1_sentence1 is_sentence_concat u by blast show ?thesis by (metis Derives1 Derives1_nonterminal Derives1_rule append_assoc is_sentence_uv
split_uv split_v split_w splits_at_implies_Derives1) qed
lemma leftmost_append_suffix: "leftmost i v ==> leftmost i (v@u)" by (simp add: leftmost_def nth_append)
lemma LeftDerives1_append_suffix: assumes Derives1: "LeftDerives1 v i r w" assumes u: "is_sentence u" shows"LeftDerives1 (v@u) i r (w@u)" proof - have1: "Derives1 v i r w" by (simp add: Derives1 LeftDerives1_implies_Derives1) have2: "leftmost i v" using Derives1 LeftDerives1_def by blast have3: "is_sentence u"using u by fastforce have4: "Derives1 (v@u) i r (w@u)" by (simp add: "1""3" Derives1_append_suffix) have5: "leftmost i (v@u)" by (simp add: "2" leftmost_append_suffix u) show ?thesis by (simp add: "4""5" LeftDerives1_def) qed
lemma LeftDerivationFix_is_sentence: "LeftDerivationFix a i D j b ==> is_sentence a ∧ is_sentence b" using LeftDerivationFix_def by blast
lemma LeftDerivationIntro_is_sentence: "LeftDerivationIntro α i r ix D j γ ==> is_sentence α ∧ is_sentence γ" by (meson Derives1_sentence1 LeftDerivationFix_is_sentence LeftDerivationIntro_def
LeftDerives1_implies_Derives1)
lemma LeftDerivationFix_grow_prefix: assumes LDF: "LeftDerivationFix (b1@[X]@b2) (length b1) D j c" assumes prefix_b1: "LeftDerives1 prefix e r b1" shows"LeftDerivationFix (prefix@[X]@b2) (length prefix) ((e, r)#D) j c" proof - from LDF have LDF': "LeftDerivation (b1 @ [X] @ b2) D c ∧ length b1 < length (b1 @ [X] @ b2) ∧ j < length c ∧ (b1 @ [X] @ b2) ! length b1 = c ! j ∧ (∃E F. D = E @ derivation_shift F 0 (Suc j) ∧ LeftDerivation (take (length b1) (b1 @ [X] @ b2)) E (take j c) ∧ LeftDerivation (drop (Suc (length b1)) (b1 @ [X] @ b2)) F (drop (Suc j) c))" using LeftDerivationFix_def by blast thenobtain E F where EF: "D = E @ derivation_shift F 0 (Suc j) ∧ LeftDerivation (take (length b1) (b1 @ [X] @ b2)) E (take j c) ∧ LeftDerivation (drop (Suc (length b1)) (b1 @ [X] @ b2)) F (drop (Suc j) c)"by blast thenhave E_b1_c: "LeftDerivation b1 E (take j c)"by simp with EF have F_b2_c: "LeftDerivation b2 F (drop (Suc j) c)"by simp have step: "LeftDerives1 (prefix @ [X] @ b2) e r (b1 @ [X] @ b2)" using LDF LeftDerivationFix_is_sentence LeftDerives1_append_suffix
is_sentence_concat prefix_b1 by blast show ?thesis apply (simp add: LeftDerivationFix_def) apply (rule conjI) apply (metis Derives1_sentence1 LDF LeftDerivationFix_def LeftDerives1_implies_Derives1
is_sentence_concat is_sentence_cons prefix_b1) apply (rule conjI) using LDF LeftDerivationFix_is_sentence apply blast apply (rule conjI) apply (rule_tac x="b1@[X]@b2"in exI) using step apply simp using LDF' apply auto[1] apply (rule conjI) using LDF' apply simp apply (rule conjI) using LDF' apply auto[1] apply (rule_tac x="(e,r)#E"in exI) apply (rule_tac x="F"in exI) apply (auto simp add: EF F_b2_c) apply (rule_tac x="b1"in exI) apply (simp add: prefix_b1 E_b1_c) done qed
lemma LeftDerivationFixOrIntro: "LeftDerivation a D γ ==> is_sentence γ ==> j < length γ ==> (∃ i. LeftDerivationFix a i D j γ) ∨ (∃ d α ix. d < length D ∧ LeftDerivation a (take d D) α ∧ LeftDerivationIntro α (fst (D ! d)) (snd (D ! d)) ix (drop (Suc d) D) j γ)" proof (induct "length D" arbitrary: a D γ j rule: less_induct) (* The induction here is unnecessary, but we use it anyway for context reasons *) case less have"length D = 0 ∨ length D ≠ 0"by blast thenshow ?case proof (induct rule: disjCases2) case1 thenhave D: "D = []"by auto with less have"∃i. LeftDerivationFix a i D j γ" apply (rule_tac x=j in exI) by auto thenshow ?caseby blast next case2 note less2 = 2 have"∃ n β i. n ≤ length D ∧ β = Derive a (take n D) ∧ LeftDerivationFix β i (drop n D) j γ" apply (rule_tac x="length D"in exI) apply auto using Derive LeftDerivationFix_empty LeftDerivation_implies_Derivation less by blast thenshow ?case proof (induct rule: ex_minimal_witness) case (Minimal N) thenobtain β i where Minimal_N: "N ≤ length D ∧ β = Derive a (take N D) ∧ LeftDerivationFix β i (drop N D) j γ"by blast have"N = 0 ∨ N ≠ 0"by blast thenshow ?case proof (induct rule: disjCases2) case1 with Minimal_N have"β = a"by auto with1 Minimal_N show ?case apply (rule_tac disjI1) by auto next case2 let ?δ = "Derive a (take (N - 1) D)" have LeftDerives1_δ: "LeftDerives1 ?δ (fst (D ! (N - 1))) (snd (D ! (N - 1))) β" using"2.hyps" LeftDerivation_Derive_take_LeftDerives1 Minimal_N less.prems(1) by blast thenhave Derives1_δ: "Derives1 ?δ (fst (D ! (N - 1))) (snd (D ! (N - 1))) β" using LeftDerives1_implies_Derives1 by blast have i_len: "i < length β"using Minimal_N by (auto simp add: LeftDerivationFix_def) thenhave"∃ X β_1 β_2. splits_at β i β_1 X β_2" using splits_at_def by blast thenobtain X β_1 β_2where β_split: "splits_at β i β_1 X β_2"by blast thenhave β_combine: "β = β_1 @ [X] @ β_2"using splits_at_combine by blast thenhave LeftDerives1_δ_hyp: "LeftDerives1 ?δ (fst (D ! (N - 1))) (snd (D ! (N - 1))) (β_1 @ [X] @ β_2)" using LeftDerives1_δ by blast from β_split have i_def: "i = length β_1" by (simp add: dual_order.strict_implies_order min.absorb2 splits_at_def) have"∃ Y δ_1 δ_2. splits_at ?δ (fst (D ! (N - 1))) δ_1 Y δ_2" using Derives1_δ splits_at_ex by blast thenobtain Y δ_1 δ_2where δ_split: "splits_at ?δ (fst (D ! (N - 1))) δ_1 Y δ_2"by blast have NFix: "LeftDerivationFix (β_1 @ [X] @ β_2) (length β_1) (drop N D) j γ" using Minimal_N β_combine i_def by auto from LeftDerives1_δ_hyp δ_split have"∃u v. β_1 = δ_1 @ u ∧ β_2 = v @ δ_2 ∧ snd (snd (D ! (N - 1))) = u @ [X] @ v" proof (induct rule: LeftDerives1_X_is_part_of_rule) case (Suffix suffix) let ?k = "N - 1" let ?β = "Derive a (take ?k D)" let ?i = "length β_1" have k_less: "?k < length D"using"2.hyps" Minimal_N by linarith thenhave k_leq: "?k ≤ length D"by auto have drop_k_d: "drop ?k D = (D ! (N - 1))#(drop N D)" using"2.hyps" Cons_nth_drop_Suc k_less by fastforce from LeftDerivationFix_grow_suffix[OF NFix Suffix(4) Suffix(3)] Suffix(1) Suffix(2) 2 have"LeftDerivationFix ?β ?i (drop ?k D) j γ" apply auto by (metis One_nat_def drop_k_d) with Minimal(2)[where k="?k"] show"False" using"2.hyps" k_leq by auto next case (Prefix prefix) have collapse: "(fst (D ! (N - 1)), snd (D ! (N - 1))) # drop N D = drop (N - 1) D" by (metis "2.hyps" Cons_nth_drop_Suc Minimal_N Suc_diff_1 neq0_conv not_less
not_less_eq prod.collapse) from LeftDerivationFix_grow_prefix[OF NFix Prefix(2)] Prefix(1) collapse have"LeftDerivationFix ?δ (length prefix) (drop (N - 1) D) j γ"by auto with Minimal(2)[where k = "N - 1"] show"False" by (metis Minimal_N collapse diff_le_self le_neq_implies_less less_imp_diff_less
less_or_eq_imp_le not_Cons_self2) qed thenobtain u v where uv: "β_1 = δ_1 @ u ∧ β_2 = v @ δ_2 ∧ snd (snd (D ! (N - 1))) = u @ [X] @ v"by blast have X_1: "snd (snd (D ! (N - Suc 0))) ! length u = X"using uv by auto have X_2: "γ ! j = X"using LeftDerivationFix_def NFix by auto show ?case apply (rule disjI2) apply (rule_tac x="N - 1"in exI) apply (rule_tac x="?δ"in exI) apply (rule_tac x="length u"in exI) apply (rule conjI) using Minimal_N less2 apply linarith apply (rule conjI) using LeftDerivation_take_derive less.prems(1) apply blast apply (subst LeftDerivationIntro_def) apply (rule_tac x=β in exI) apply auto using LeftDerives1_δ One_nat_def apply presburger using uv apply auto[1] using X_1 X_2 apply auto[1] by (metis (no_types, lifting) "2.hyps" Derives1_δ Derives1_split Minimal_N One_nat_def
Suc_diff_1 δ_split append_eq_conv_conj i_def length_append neq0_conv splits_at_def uv) qed qed qed qed
definition ladder_j :: "ladder ==> nat ==> nat"where "ladder_j L index = deriv_j (L ! index)"
definition ladder_i :: "ladder ==> nat ==> nat"where "ladder_i L index = (if index = 0 then deriv_i (hd L) else ladder_j L (index - 1))"
definition ladder_n :: "ladder ==> nat ==> nat"where "ladder_n L index = deriv_n (L ! index)"
definition ladder_prev_n :: "ladder ==> nat ==> nat"where "ladder_prev_n L index = (if index = 0 then 0 else (ladder_n L (index - 1)))"
definition ladder_ix :: "ladder ==> nat ==> nat"where "ladder_ix L index = (if index = 0 then undefined else deriv_ix (L ! index))"
definition ladder_last_j :: "ladder ==> nat"where "ladder_last_j L = ladder_j L (length L - 1)"
definition ladder_last_n :: "ladder ==> nat"where "ladder_last_n L = ladder_n L (length L - 1)"
definition is_ladder :: "derivation ==> ladder ==> bool"where "is_ladder D L = (L ≠ [] ∧ (∀ u. u < length L ⟶ ladder_n L u ≤ length D) ∧ (∀ u v. u < v ∧ v < length L ⟶ ladder_n L u < ladder_n L v) ∧ ladder_last_n L = length D)"
definition ladder_γ :: "sentence ==> derivation ==> ladder ==> nat ==> sentence"where "ladder_γ a D L index = Derive a (take (ladder_n L index) D)"
definition ladder_α :: "sentence ==> derivation ==> ladder ==> nat ==> sentence"where "ladder_α a D L index = (if index = 0 then a else ladder_γ a D L (index - 1))"
definition LeftDerivationIntrosAt :: "sentence ==> derivation ==> ladder ==> nat ==> bool"where "LeftDerivationIntrosAt a D L index = ( let α = ladder_α a D L index in let i = ladder_i L index in let j = ladder_j L index in let ix = ladder_ix L index in let γ = ladder_γ a D L index in let n = ladder_n L (index - 1) in let m = ladder_n L index in let e = D ! n in let E = drop (Suc n) (take m D) in i = fst e ∧ LeftDerivationIntro α i (snd e) ix E j γ)"
definition LeftDerivationIntros :: "sentence ==> derivation ==> ladder ==> bool"where "LeftDerivationIntros a D L = ( ∀ index. 1 ≤ index ∧ index < length L ⟶ LeftDerivationIntrosAt a D L index)"
definition LeftDerivationLadder :: "sentence ==> derivation ==> ladder ==> sentence==> bool"where "LeftDerivationLadder a D L b = ( LeftDerivation a D b ∧ is_ladder D L ∧ LeftDerivationFix a (ladder_i L 0) (take (ladder_n L 0) D) (ladder_j L 0) (ladder_γ a D L 0) ∧ LeftDerivationIntros a D L)"
definition mk_deriv_fix :: "nat ==> nat ==> nat ==> deriv"where "mk_deriv_fix i n j = (n, j, i)"
definition mk_deriv_intro :: "nat ==> nat ==> nat ==> deriv"where "mk_deriv_intro ix n j = (n, j, ix)"
lemma mk_deriv_fix_i[simp]: "deriv_i (mk_deriv_fix i n j) = i" by (simp add: deriv_i_def mk_deriv_fix_def)
lemma mk_deriv_fix_j[simp]: "deriv_j (mk_deriv_fix i n j) = j" by (simp add: deriv_j_def mk_deriv_fix_def)
lemma mk_deriv_fix_n[simp]: "deriv_n (mk_deriv_fix i n j) = n" by (simp add: deriv_n_def mk_deriv_fix_def)
lemma mk_deriv_intro_i[simp]: "deriv_i (mk_deriv_intro i n j) = i" by (simp add: deriv_i_def mk_deriv_intro_def)
lemma mk_deriv_intro_ix[simp]: "deriv_ix (mk_deriv_intro ix n j) = ix" by (simp add: deriv_ix_def mk_deriv_intro_def)
lemma mk_deriv_intro_j[simp]: "deriv_j (mk_deriv_intro i n j) = j" by (simp add: deriv_j_def mk_deriv_intro_def)
lemma mk_deriv_intro_n[simp]: "deriv_n (mk_deriv_intro i n j) = n" by (simp add: deriv_n_def mk_deriv_intro_def)
lemma LeftDerivationFix_implies_ex_ladder: "LeftDerivationFix a i D j γ ==>∃ L. LeftDerivationLadder a D L γ ∧ ladder_last_j L = j ∧ ladder_last_n L = length D" apply (rule_tac x="[mk_deriv_fix i (length D) j]"in exI) apply (auto simp add: LeftDerivationLadder_def) apply (simp add: LeftDerivationFix_def) apply (simp add: is_ladder_def) apply (auto simp add: ladder_i_def ladder_j_def ladder_n_def ladder_γ_def) apply (simp add: ladder_last_n_def ladder_n_def) using Derive LeftDerivationFix_def LeftDerivation_implies_Derivation apply blast apply (simp add: LeftDerivationIntros_def) apply (simp add: ladder_last_j_def ladder_j_def) apply (simp add: ladder_last_n_def ladder_n_def) done
lemma trivP[case_names prems]: "P ==> P"by blast
lemma LeftDerivationLadder_ladder_n_bound: assumes"LeftDerivationLadder a D L b" assumes"index < length L" shows"ladder_n L index ≤ length D" using LeftDerivationLadder_def assms(1) assms(2) is_ladder_def by blast
lemma LeftDerivationLadder_deriv_n_bound: assumes"LeftDerivationLadder a D L b" assumes"index < length L" shows"deriv_n (L ! index) ≤ length D" using LeftDerivationLadder_def assms(1) assms(2) is_ladder_def ladder_n_def by auto
lemma ladder_n_simp1[simp]: "u < length L ==> ladder_n (L@L') u = ladder_n L u" by (simp add: ladder_n_def)
lemma ladder_γ_simp1[simp]: "u < length L ==> ladder_γ a D (L@L') u = ladder_γ a D L u" by (simp add: ladder_γ_def)
lemma ladder_γ_simp2[simp]: "u < length L ==> is_ladder D L ==> ladder_γ a (D@D') L u = ladder_γ a D L u" by (simp add: is_ladder_def ladder_γ_def)
lemma ladder_α_simp1[simp]: "u < length L ==> ladder_α a D (L@L') u = ladder_α a D L u" by (simp add: ladder_α_def)
lemma ladder_α_simp2[simp]: "u < length L ==> is_ladder D L ==> ladder_α a (D@D') L u = ladder_α a D L u" by (simp add: is_ladder_def ladder_α_def)
lemma ladder_n_minus_1_bound: "is_ladder D L ==> index ≥ 1 ==> index < length L ==> ladder_n L (index - Suc 0) < length D" by (metis (no_types, lifting) One_nat_def Suc_diff_1 Suc_le_lessD dual_order.strict_implies_order
is_ladder_def le_neq_implies_less not_less)
lemma LeftDerivationIntrosAt_ignore_appendix: assumes is_ladder: "is_ladder D L" assumes hyp: "LeftDerivationIntrosAt a D L index" assumes index_ge: "index ≥ 1" assumes index_less: "index < length L" shows"LeftDerivationIntrosAt a (D @ D') (L @ L') index" proof - have index_minus_1: "index - Suc 0 < length L" using index_less by arith have is_0: "ladder_n L index - length D = 0" using index_less is_ladder is_ladder_def by auto from index_ge index_less show ?thesis apply (simp add: LeftDerivationIntrosAt_def Let_def) apply (simp add: index_minus_1 is_ladder ladder_n_minus_1_bound is_0) using hyp apply (auto simp add: LeftDerivationIntrosAt_def Let_def) done qed
lemma ladder_last_n_intro: "L ≠ [] ==> ladder_n L (length L - Suc 0) = ladder_last_n L" by (simp add: ladder_last_n_def)
lemma is_ladder_not_empty: "is_ladder D L ==> L ≠ []" using is_ladder_def by blast
lemma last_ladder_γ: assumes is_ladder: "is_ladder D L" assumes ladder_last_n: "ladder_last_n L = length D" shows"ladder_γ a D L (length L - Suc 0) = Derive a D" proof - from is_ladder is_ladder_not_empty have"L ≠ []"by blast thenshow ?thesis by (simp add: ladder_γ_def ladder_last_n_intro ladder_last_n) qed
lemma ladder_α_full: assumes is_ladder: "is_ladder D L" assumes ladder_last_n: "ladder_last_n L = length D" shows"ladder_α a (D @ D') (L @ L') (length L) = Derive a D" proof - from is_ladder have L_not_empty: "L ≠ []"by (simp add: is_ladder_def) with is_ladder ladder_last_n show ?thesis apply (simp add: ladder_α_def) apply (simp add: last_ladder_γ) done qed
lemma LeftDerivationIntro_implies_LeftDerivation: "LeftDerivationIntro α i r ix D j γ ==> LeftDerivation α ((i,r)#D) γ" using LeftDerivationFix_def LeftDerivationIntro_def by auto
lemma LeftDerivationLadder_grow: "LeftDerivationLadder a D L α ==> ladder_last_j L = i ==> LeftDerivationIntro α i r ix E j γ ==> LeftDerivationLadder a (D@[(i, r)]@E) (L@[mk_deriv_intro ix (Suc(length D + length E)) j]) γ" proof (induct arbitrary: a D L α i r ix E j γ rule: trivP) case prems
{ fix u :: nat assume"u < Suc (length L)" thenhave"u < length L ∨ u = length L"by arith thenhave"ladder_n (L @ [mk_deriv_intro ix (Suc (length D + length E)) j]) u ≤ Suc (length D + length E)" proof (induct rule: disjCases2) case1 thenshow ?case apply simp by (meson LeftDerivationLadder_ladder_n_bound le_Suc_eq le_add1 le_trans prems(1)) next case2 thenshow ?case by (simp add: ladder_n_def) qed
} note ladder_n_ineqs = this
{ fix u :: nat fix v :: nat assume u_less_v: "u < v" assume"v < Suc (length L)" thenhave"v < length L ∨ v = length L"by arith thenhave"ladder_n (L @ [mk_deriv_intro ix (Suc (length D + length E)) j]) u < ladder_n (L @ [mk_deriv_intro ix (Suc (length D + length E)) j]) v" proof (induct rule: disjCases2) case1 with u_less_v have u_bound: "u < length L"by arith show ?caseusing1 u_bound apply simp using prems u_less_v LeftDerivationLadder_def is_ladder_def by auto next case2 with u_less_v have u_bound: "u < length L"by arith have"deriv_n (L ! u) ≤ length D" using LeftDerivationLadder_deriv_n_bound prems(1) u_bound by blast thenshow ?case apply (simp add: u_bound) apply (simp add: ladder_n_def 2) done qed
} note ladder_n_ineqs = ladder_n_ineqs this have is_ladder: "is_ladder (D @ (i, r) # E) (L @ [mk_deriv_intro ix (Suc (length D + length E)) j])" apply (auto simp add: is_ladder_def) using ladder_n_ineqs apply auto apply (simp add: ladder_last_n_def) done have is_ladder_L: "is_ladder D L" using LeftDerivationLadder_def prems.prems(1) by blast have ladder_last_n_eq_length: "ladder_last_n L = length D" using is_ladder_L is_ladder_def by blast have L_not_empty: "L ≠ []" using LeftDerivationLadder_def is_ladder_def prems(1) by blast
{ fix index :: nat assume index_ge: "Suc 0 ≤ index" assume"index < Suc (length L)" thenhave"index < length L ∨ index = length L"by arith thenhave"LeftDerivationIntrosAt a (D @ (i, r) # E) (L @ [mk_deriv_intro ix (Suc (length D + length E)) j]) index" proof (induct rule: disjCases2) case1 thenshow ?case using LeftDerivationIntrosAt_ignore_appendix
LeftDerivationIntros_def LeftDerivationLadder_def One_nat_def
index_ge prems.prems(1) by presburger next case2 have min_simp: "∧ n E. min n (Suc (n + length E)) = n" by auto with2 prems is_ladder_L ladder_last_n_eq_length show ?case apply (simp add: LeftDerivationIntrosAt_def) apply (simp add: L_not_empty ladder_i_eq_last_j ladder_last_n_intro) apply (simp add: ladder_α_full min_simp) apply (simp add: ladder_γ_def) by (metis Derive LeftDerivationIntro_implies_LeftDerivation LeftDerivationLadder_def
LeftDerivation_implies_Derivation LeftDerivation_implies_append) qed
} thenshow ?case apply (auto simp add: LeftDerivationLadder_def) using prems apply (auto simp add: LeftDerivationLadder_def)[1] using LeftDerivationFix_def LeftDerivationIntro_def LeftDerivation_append apply auto[1] using is_ladder apply simp using L_not_empty apply simp using LeftDerivationLadder_def LeftDerivationLadder_ladder_n_bound ladder_γ_def
prems.prems(1) apply auto[1] apply (subst LeftDerivationIntros_def) apply auto done qed
lemma LeftDerivationIntro_bounds_ij: "LeftDerivationIntro α i r ix D j β ==> i < length α ∧ j < length β" by (meson Derives1_bound LeftDerivationFix_def LeftDerivationIntro_def
LeftDerives1_implies_Derives1)
theorem LeftDerivationLadder_exists: "LeftDerivation a D γ ==> is_sentence γ ==> j < length γ ==> ∃ L. LeftDerivationLadder a D L γ ∧ ladder_last_j L = j" proof (induct "length D" arbitrary: a D γ j rule: less_induct) case less from LeftDerivationFixOrIntro[OF less(2,3,4)] show ?case proof (induct rule: disjCases2) case1 thenobtain i where"LeftDerivationFix a i D j γ"by blast show ?case using"1.hyps" LeftDerivationFix_implies_ex_ladder by blast next case2 thenobtain d α ix where inductrule: "d < length D ∧ LeftDerivation a (take d D) α ∧ LeftDerivationIntro α (fst (D ! d)) (snd (D ! d)) ix (drop (Suc d) D) j γ"by blast thenhave less_length_D: "length (take d D) < length D" and LeftDerivation_α: "LeftDerivation a (take d D) α"by auto have is_sentence_α: "is_sentence α"using LeftDerivationIntro_is_sentence inductrule by blast have"fst (D ! d) < length α"using LeftDerivationIntro_bounds_ij inductrule by blast from less(1)[OF less_length_D LeftDerivation_α is_sentence_α, where j=" fst (D ! d)", OF this] obtain L where induct_Ladder: "LeftDerivationLadder a (take d D) L α"and induct_last: "ladder_last_j L = fst (D ! d)" by blast have induct_intro: "LeftDerivationIntro α (fst (D ! d)) (snd (D ! d)) ix (drop (Suc d) D) j γ" using inductrule by blast have"d < length D"using inductrule by blast thenhave simp_to_D: "take d D @ D ! d # drop (Suc d) D = D" using id_take_nth_drop by force from LeftDerivationLadder_grow[OF induct_Ladder induct_last induct_intro] simp_to_D show ?case apply auto apply (rule_tac x= "L @ [mk_deriv_intro ix (Suc (min (length D) d + (length D - Suc d))) j]"in exI) apply (simp add: ladder_last_j_def) done qed qed
lemma LeftDerivationLadder_L_0: assumes"LeftDerivationLadder α D L β" assumes"length L = 1" shows"∃ i. LeftDerivationFix α i D (ladder_last_j L) β" proof - have"is_ladder D L"using assms by (auto simp add: LeftDerivationLadder_def) thenhave ladder_n: "ladder_n L 0 = length D" by (simp add: assms(2) is_ladder_def ladder_last_n_def) show ?thesis apply (rule_tac x = "ladder_i L 0"in exI) using assms(1) apply (auto simp add: LeftDerivationLadder_def) by (metis Derive LeftDerivationFix_def LeftDerivation_implies_Derivation One_nat_def assms(2)
diff_Suc_1 ladder_last_j_def ladder_n order_refl take_all) qed
lemma LeftDerivationFix_splits_at_derives: assumes"LeftDerivationFix a i D j b" shows"∃ U a1 a2 b1 b2. splits_at a i a1 U a2 ∧ splits_at b j b1 U b2 ∧ derives a1 b1 ∧ derives a2 b2" proof - note hyp = LeftDerivationFix_def[where α=a and β=b and D=D and i=i and j=j] from hyp obtain E F where EF: "D = E @ derivation_shift F 0 (Suc j) ∧ LeftDerivation (take i a) E (take j b) ∧ LeftDerivation (drop (Suc i) a) F (drop (Suc j) b)" using assms by blast show ?thesis apply (rule_tac x="a ! i"in exI) apply (rule_tac x="take i a"in exI) apply (rule_tac x="drop (Suc i) a"in exI) apply (rule_tac x="take j b"in exI) apply (rule_tac x="drop (Suc j) b"in exI) using Derivation_implies_derives LeftDerivation_implies_Derivation assms hyp
splits_at_def by blast qed
lemma LeftDerivation_append_suffix: "LeftDerivation a D b ==> is_sentence c ==> LeftDerivation (a@c) D (b@c)" proof (induct D arbitrary: a b c) case Nil thenshow ?caseby auto next case (Cons d D) thenshow ?case apply auto apply (rule_tac x="x@c"in exI) apply auto using LeftDerives1_append_suffix by simp qed
lemma LeftDerivation_impossible: "LeftDerivation a D b ==> i < length a ==> is_nonterminal (a ! i) ==> derivation_ge D (Suc i) ==> D = []" proof (induct D) case Nil thenshow ?caseby auto next case (Cons d D) thenhave lm: "∧ j. leftmost j a ==> j ≤ i" by (metis Derives1_sentence1 LeftDerivation.simps(2) LeftDerives1_implies_Derives1
leftmost_exists leftmost_unique) from Cons show ?case apply auto apply (auto simp add: derivation_ge_def LeftDerives1_def) using lm[where j="fst d"] by arith qed
lemma LeftDerivationFix_splits_at_nonterminal: assumes"LeftDerivationFix a i D j b" assumes"is_nonterminal (a ! i)" shows"∃ U a1 a2 b1. splits_at a i a1 U a2 ∧ splits_at b j b1 U a2 ∧ LeftDerivation a1 D b1" proof - note hyp = LeftDerivationFix_def[where α=a and β=b and D=D and i=i and j=j] from hyp obtain E F where EF: "D = E @ derivation_shift F 0 (Suc j) ∧ LeftDerivation (take i a) E (take j b) ∧ LeftDerivation (drop (Suc i) a) F (drop (Suc j) b)" using assms by blast have"∃ β. LeftDerivation a E β ∧ LeftDerivation β (derivation_shift F 0 (Suc j)) b" using EF LeftDerivation_append assms(1) hyp by blast thenobtain β where β_intro: "LeftDerivation a E β ∧ LeftDerivation β (derivation_shift F 0 (Suc j)) b"by blast have"LeftDerivation ((take i a)@(drop i a)) E ((take j b)@(drop i a))" by (metis EF LeftDerivation_append_suffix append_take_drop_id assms(1) hyp is_sentence_concat) thenhave"LeftDerivation a E ((take j b)@(drop i a))"by simp thenhave β_decomposed: "β = (take j b)@(drop i a)" using Derivation_unique_dest LeftDerivation_implies_Derivation β_intro by blast thenhave"β ! j = a ! i" by (metis Cons_nth_drop_Suc assms(1) hyp length_take min.absorb2 nth_append_length
order.strict_implies_order) thenhave is_nt: "is_nonterminal (β ! j)"by (simp add: assms(2)) have index_j: "j < length β"using β_decomposed assms(1) hyp by auto have derivation: "LeftDerivation β (derivation_shift F 0 (Suc j)) b" by (simp add: β_intro) from LeftDerivation_impossible[OF derivation index_j is_nt derivation_ge_shift] have F: "F = []"by (metis length_0_conv length_derivation_shift) thenhave β_is_b: "β = b"using β_intro by auto show ?thesis apply (rule_tac x="a ! i"in exI) apply (rule_tac x="take i a"in exI) apply (rule_tac x="drop (Suc i) a"in exI) apply (rule_tac x="take j b"in exI) using EF F assms(1) hyp splits_at_def by auto qed
lemma LeftDerivationIntro_implies_nonterminal: "LeftDerivationIntro α i (snd e) ix E j γ ==> is_nonterminal (α ! i)" by (simp add: LeftDerivationIntro_def LeftDerives1_def leftmost_is_nonterminal)
lemma LeftDerivationIntrosAt_implies_nonterminal: "LeftDerivationIntrosAt a D L index ==> is_nonterminal((ladder_α a D L index) ! (ladder_i L index))" by (meson LeftDerivationIntro_implies_nonterminal LeftDerivationIntrosAt_def)
lemma LeftDerivationIntro_examine_rule: "LeftDerivationIntro α i r ix D j γ ==> splits_at α i α1 M α2 ==> ∃ η. M = fst r ∧ η = snd r ∧ (M, η) ∈R" by (metis Derives1_nonterminal Derives1_rule LeftDerivationIntro_def LeftDerives1_implies_Derives1
prod.collapse)
lemma LeftDerivation_skip_prefixword_ex: assumes"LeftDerivation (u@v) D w" assumes"is_word u" shows"∃ w'. w = u@w' ∧ LeftDerivation v (derivation_shift D (length u) 0) w'" by (metis LeftDerivation.simps(1) LeftDerivation_breakdown LeftDerivation_implies_Derivation
LeftDerivation_skip_prefix append_eq_conv_conj assms(1) assms(2) is_word_Derivation
is_word_Derivation_derivation_ge)
definition ladder_cut :: "ladder ==> nat ==> ladder" where"ladder_cut L n = (let i = length L - 1 in L[i := (n, snd (L ! i))])"
definition ladder_shift :: "ladder ==> nat ==> nat ==> ladder" where"ladder_shift L dn dj = map (deriv_shift dn dj) L"
lemma splits_at_append_suffix_prevails: assumes"splits_at (a@b) i u N v" assumes"i < length a" shows"∃ v'. v = v'@b ∧ a=u@[N]@v'" proof - have"min (length a) (Suc i) = Suc i" using Suc_leI assms(2) min.absorb2 by blast thenshow ?thesis by (metis (no_types) append_assoc append_eq_conv_conj append_take_drop_id assms(1)
hd_drop_conv_nth length_take splits_at_def take_hd_drop) qed
lemma derivation_shift_right_left_cancel: "derivation_shift (derivation_shift D 0 r) r 0 = D" by (induct D, auto)
lemma derivation_shift_left_right_cancel: assumes"derivation_ge D r" shows"derivation_shift (derivation_shift D r 0) 0 r = D" using assms derivation_ge_shift_simp derivation_shift_0_shift by auto
lemma LeftDerivation_ge_take: assumes"derivation_ge D k" assumes"LeftDerivation a D b" assumes"D ≠ []" shows"take k a = take k b ∧ is_word (take k a)" proof - obtain d D' where d: "d#D' = D"using assms(3) list.exhaust by blast thenhave"∃ x. LeftDerives1 a (fst d) (snd d) x ∧ LeftDerivation x D' b" using LeftDerivation.simps(2) assms(2) by blast thenobtain x where x: "LeftDerives1 a (fst d) (snd d) x ∧ LeftDerivation x D' b"by blast have fst_d_k: "fst d ≥ k"using d assms(1) derivation_ge_cons by blast from x fst_d_k have is_word: "is_word (take k a)" by (metis LeftDerives1_def append_take_drop_id is_word_append leftmost_def
min.absorb2 take_append take_take) have is_eq: "take k a = take k b" using Derivation_take LeftDerivation_implies_Derivation assms(1) assms(2) by blast show ?thesis using is_word is_eq by blast qed
lemma LeftDerivationFix_splits_at_symbol: assumes"LeftDerivationFix a i D j b" shows"∃ U a1 a2 b1 b2 n. splits_at a i a1 U a2 ∧ splits_at b j b1 U b2 ∧ n ≤ length D ∧ LeftDerivation a1 (take n D) b1 ∧ derivation_ge (drop n D) (Suc(length b1)) ∧ LeftDerivation a2 (derivation_shift (drop n D) (Suc(length b1)) 0) b2 ∧ (n = length D ∨ (n < length D ∧ is_word (b1@[U])))" proof - note hyp = LeftDerivationFix_def[where α=a and β=b and D=D and i=i and j=j] from hyp obtain E F where EF: "D = E @ derivation_shift F 0 (Suc j) ∧ LeftDerivation (take i a) E (take j b) ∧ LeftDerivation (drop (Suc i) a) F (drop (Suc j) b)" using assms by blast have"∃ β. LeftDerivation a E β ∧ LeftDerivation β (derivation_shift F 0 (Suc j)) b" using EF LeftDerivation_append assms(1) hyp by blast thenobtain β where β_intro: "LeftDerivation a E β ∧ LeftDerivation β (derivation_shift F 0 (Suc j)) b"by blast have"LeftDerivation ((take i a)@(drop i a)) E ((take j b)@(drop i a))" by (metis EF LeftDerivation_append_suffix append_take_drop_id assms(1) hyp is_sentence_concat) thenhave"LeftDerivation a E ((take j b)@(drop i a))"by simp thenhave β_decomposed: "β = (take j b)@(drop i a)" using Derivation_unique_dest LeftDerivation_implies_Derivation β_intro by blast have derivation: "LeftDerivation β (derivation_shift F 0 (Suc j)) b" by (simp add: β_intro) have"∃ n. n ≤ length D ∧ E = take n D" by (metis EF append_eq_conv_conj is_prefix_length is_prefix_take) thenobtain n where n: "n ≤ length D ∧ E = take n D"by blast have F_def: "drop n D = derivation_shift F 0 (Suc j)" by (metis EF append_eq_conv_conj length_take min.absorb2 n) have min_j: "min (length b) j = j"using assms hyp by linarith have derivation_ge_Suc_j: "derivation_ge (drop n D) (Suc j)" using F_def derivation_ge_shift by simp have LeftDerivation_β_b: "LeftDerivation β (drop n D) b"by (simp add: F_def β_intro) have is_word_Suc_j_b: "n ≠ length D ==> is_word (take (Suc j) b)" by (metis EF F_def LeftDerivation_ge_take β_intro append_Nil2 derivation_ge_Suc_j
length_take min.absorb2 n) have take_Suc_j_b_decompose: "take (Suc j) b = take j b @ [a ! i]" using assms hyp take_Suc_conv_app_nth by auto show ?thesis apply (rule_tac x="a ! i"in exI) apply (rule_tac x="take i a"in exI) apply (rule_tac x="drop (Suc i) a"in exI) apply (rule_tac x="take j b"in exI) apply (rule_tac x="drop (Suc j) b"in exI) apply (rule_tac x="n"in exI) apply (auto simp add: min_j) using assms hyp splits_at_def apply blast using assms hyp splits_at_def apply blast using n apply blast using EF n apply simp using F_def apply simp using derivation_ge_shift apply blast using F_def derivation_shift_right_left_cancel apply simp using EF apply blast using n apply arith using is_word_Suc_j_b take_Suc_j_b_decompose is_word_append apply simp+ done qed
lemma LeftDerivation_breakdown': "LeftDerivation (u @ v) D w ==> ∃n w1 w2. n ≤ length D ∧ w = w1 @ w2 ∧ LeftDerivation u (take n D) w1 ∧ derivation_ge (drop n D) (length w1) ∧ LeftDerivation v (derivation_shift (drop n D) (length w1) 0) w2" proof - assume hyp: "LeftDerivation (u @ v) D w" from LeftDerivation_breakdown[OF hyp] obtain n w1 w2 where breakdown: "w = w1 @ w2 ∧ LeftDerivation u (take n D) w1 ∧ derivation_ge (drop n D) (length w1) ∧ LeftDerivation v (derivation_shift (drop n D) (length w1) 0) w2"by blast obtain m where m: "m = min (length D) n"by blast have take_m: "take m D = take n D"using m is_prefix_take take_prefix by fastforce have drop_m: "drop m D = drop n D" by (metis append_eq_conv_conj append_take_drop_id length_take m) have m_bound: "m ≤ length D"by (simp add: m) show ?thesis apply (rule_tac x="m"in exI) apply (rule_tac x="w1"in exI) apply (rule_tac x="w2"in exI) using breakdown m_bound take_m drop_m by auto qed
lemma LeftDerives1_append_replace_in_left: assumes ld1: "LeftDerives1 (α@δ) i r β" assumes i_bound: "i < length α" shows"∃ α'. β = α'@δ ∧ LeftDerives1 α i r α' ∧ i + length (snd r) ≤ length α'" proof - obtain α' where α': "α' = (take i α)@(snd r)@(drop (i+1) α)"by blast have fst_r: "fst r = α ! i" proof - have"∀ss n p ssa. ¬ LeftDerives1 ss n p ssa ∨ Derives1 ss n p ssa" using LeftDerives1_implies_Derives1 by blast thenhave"Derives1 (α @ δ) i r β" using ld1 by blast thenshow ?thesis using Derives1_nonterminal i_bound splits_at_def by auto qed have"Derives1 α i r α'" using i_bound ld1 apply (auto simp add: α' Derives1_def) apply (rule_tac x="take i α"in exI) apply (rule_tac x="drop (i+1) α"in exI) apply (rule_tac x="fst r"in exI) apply auto apply (simp add: fst_r) using id_take_nth_drop apply blast using Derives1_sentence1 LeftDerives1_implies_Derives1 is_sentence_concat
is_sentence_take apply blast apply (metis Derives1_sentence1 LeftDerives1_implies_Derives1 append_take_drop_id
is_sentence_concat) using Derives1_rule LeftDerives1_implies_Derives1 by blast thenhave leftderives1_α_α': "LeftDerives1 α i r α'" using LeftDerives1_def i_bound ld1 leftmost_cons_less by auto have i_bound_α': "i + length (snd r) ≤ length α'" using α' i_bound by (simp add: add_mono_thms_linordered_semiring(2) le_add1 less_or_eq_imp_le min.absorb2) have is_sentence_δ: "is_sentence δ" using Derives1_sentence1 LeftDerives1_implies_Derives1 is_sentence_concat ld1 by blast thenhave β: "β = α'@δ" using ld1 leftderives1_α_α' Derives1_append_suffix Derives1_unique_dest
LeftDerives1_implies_Derives1 by blast show ?thesis apply (rule_tac x="α'"in exI) using β i_bound_α' leftderives1_α_α' by blast qed
lemma LeftDerivationIntro_propagate: assumes intro: "LeftDerivationIntro (α@δ) i r ix D j γ" assumes i_α: "i < length α" assumes non: "is_nonterminal (γ ! j)" shows"∃ ψ. LeftDerivation α ((i,r)#D) ψ ∧ γ = ψ@δ ∧ j < length ψ" proof - from intro LeftDerivationIntro_def[where α="α@δ"and i=i and r=r and ix=ix and D=D and
j=j and γ=γ] obtain β where ld_β: "LeftDerives1 (α @ δ) i r β"and
ix: "ix < length (snd r) ∧ snd r ! ix = γ ! j"and
β_fix: "LeftDerivationFix β (i + ix) D j γ" by blast from LeftDerives1_append_replace_in_left[OF ld_β i_α] obtain α' where α': "β = α' @ δ ∧ LeftDerives1 α i r α' ∧ i + length (snd r) ≤ length α'" by blast have i_plus_ix_bound: "i + ix < length α'"using α' ix by linarith have ld_γ: "LeftDerivationFix (α' @ δ) (i + ix) D j γ" using β_fix α' by simp thenhave non_i_ix: "is_nonterminal ((α' @ δ) ! (i + ix))" by (simp add: LeftDerivationFix_def non) from LeftDerivationFix_splits_at_nonterminal[OF ld_γ non_i_ix] obtain U a1 a2 b1 where U: "splits_at (α' @ δ) (i + ix) a1 U a2 ∧ splits_at γ j b1 U a2 ∧ LeftDerivation a1 D b1" by blast have"∃ q. a2 = q@δ ∧ α' = a1 @ [U] @ q" using splits_at_append_suffix_prevails[OF _ i_plus_ix_bound, where b=δ] U by blast thenobtain q where q: "a2 = q@δ ∧ α' = a1 @ [U] @ q"by blast show ?thesis apply (rule_tac x="b1@[U]@q"in exI) apply auto apply (rule_tac x="α'"in exI) apply (metis LeftDerivationFix_def LeftDerivation_append_suffix U α'
q append_Cons append_Nil is_sentence_concat ld_γ) using U q splits_at_combine apply auto[1] using U splits_at_def by auto qed
lemma LeftDerivationIntro_finish: assumes intro: "LeftDerivationIntro (α@δ) i r ix D j γ" assumes i_α: "i < length α" shows"∃ k ψ δ'. k ≤ length D ∧ LeftDerivation α ((i, r)#(take k D)) ψ ∧ LeftDerivation (α @ δ) ((i, r)#(take k D)) (ψ @ δ) ∧ derivation_ge (drop k D) (length ψ) ∧ LeftDerivation δ (derivation_shift (drop k D) (length ψ) 0) δ' ∧ γ = ψ @ δ' ∧ j < length ψ" proof - from intro LeftDerivationIntro_def[where α="α@δ"and i=i and r=r and ix=ix and D=D and
j=j and γ=γ] obtain β where ld_β: "LeftDerives1 (α @ δ) i r β"and
ix: "ix < length (snd r) ∧ snd r ! ix = γ ! j"and
β_fix: "LeftDerivationFix β (i + ix) D j γ" by blast from LeftDerives1_append_replace_in_left[OF ld_β i_α] obtain α' where α': "β = α' @ δ ∧ LeftDerives1 α i r α' ∧ i + length (snd r) ≤ length α'" by blast have i_plus_ix_bound: "i + ix < length α'"using α' ix by linarith have ld_γ: "LeftDerivationFix (α' @ δ) (i + ix) D j γ" using β_fix α' by simp from LeftDerivationFix_splits_at_symbol[OF ld_γ] obtain U a1 a2 b1 b2 n where U: "splits_at (α' @ δ) (i + ix) a1 U a2 ∧ splits_at γ j b1 U b2 ∧ n ≤ length D ∧ LeftDerivation a1 (take n D) b1 ∧ derivation_ge (drop n D) (Suc (length b1)) ∧ LeftDerivation a2 (derivation_shift (drop n D) (Suc (length b1)) 0) b2 ∧ (n = length D ∨ n < length D ∧ is_word (b1 @ [U]))" by blast have n_bound: "n ≤ length D"using U by blast have"∃ q. a2 = q@δ ∧ α' = a1 @ [U] @ q" using splits_at_append_suffix_prevails[OF _ i_plus_ix_bound, where b=δ] U by blast thenobtain q where q: "a2 = q@δ ∧ α' = a1 @ [U] @ q"by blast have j: "j = length b1" using U by (simp add: dual_order.strict_implies_order min.absorb2 splits_at_def) have"n = length D ∨ n < length D ∧ is_word (b1 @ [U])"using U by blast thenshow ?thesis proof (induct rule: disjCases2) case1 from1have drop_n_D: "drop n D = []"by (simp add: U) thenhave"LeftDerivation a2 [] b2"using U by simp thenhave a2_eq_b2: "a2 = b2"by simp show ?case apply (rule_tac x="n"in exI) apply (rule_tac x="b1@[U]@q"in exI) apply (rule_tac x="δ"in exI) apply auto apply (simp add: 1) apply (rule_tac x="α'"in exI) apply (metis LeftDerivationFix_is_sentence LeftDerivation_append_suffix U α'
append_Cons append_Nil is_sentence_concat ld_γ q) apply (rule_tac x="α' @ δ"in exI) apply (metis "1.hyps" LeftDerivationFix_def U α' a2_eq_b2 id_take_nth_drop ld_β
ld_γ q splits_at_def take_all) apply (simp add: drop_n_D)+ apply (metis U a2_eq_b2 id_take_nth_drop q splits_at_def) using j apply arith done next case2 obtain E where E: "E = (derivation_shift (drop n D) (Suc (length b1)) 0)"by blast thenhave"LeftDerivation (q@δ) E b2"using U q by simp from LeftDerivation_breakdown'[OF this] obtain n' w1 w2 where w1w2: "n' ≤ length E ∧ b2 = w1 @ w2 ∧ LeftDerivation q (take n' E) w1 ∧ derivation_ge (drop n' E) (length w1) ∧ LeftDerivation δ (derivation_shift (drop n' E) (length w1) 0) w2"by blast have length_E_D: "length E = length D - n"using E n_bound by simp have n_plus_n'_bound: "n + n' ≤ length D"using length_E_D w1w2 n_bound by arith have take_breakdown: "take (n + n') D = (take n D) @ (take n' (drop n D))" using take_add by blast have q_w1: "LeftDerivation q (take n' E) w1"using w1w2 by blast have isw: "is_word (b1 @ [U])"using2by blast have take_n': "take n' (drop n D) = derivation_shift (take n' E) 0 (Suc (length b1))" by (metis E U derivation_shift_left_right_cancel take_derivation_shift) have α'_derives_b1_U_w1: "LeftDerivation α' (take (n + n') D) (b1 @ U # w1)" apply (subst take_breakdown) apply (rule_tac LeftDerivation_implies_append[where b="b1@[U]@q"]) apply (metis LeftDerivationFix_is_sentence LeftDerivation_append_suffix U
is_sentence_concat ld_γ q) apply (simp add: take_n') by (rule LeftDerivation_append_prefix[OF q_w1, where u = "b1@[U]", OF isw, simplified]) have dge: "derivation_ge (drop (n + n') D) (Suc (length b1 + length w1))" proof - have"derivation_ge (drop n' (drop n D)) (length b1 + 1 + length w1)" by (metis (no_types) E Suc_eq_plus1 U append_take_drop_id derivation_ge_append derivation_ge_shift_plus drop_derivation_shift w1w2) thenshow"derivation_ge (drop (n + n') D) (Suc (length b1 + length w1))" by (metis (no_types) Suc_eq_plus1 add.commute drop_drop semiring_normalization_rules(23)) qed show ?case apply (rule_tac x="n+n'"in exI) apply (rule_tac x="b1 @ [U] @ w1"in exI) apply (rule_tac x=w2 in exI) apply auto using n_plus_n'_bound apply simp apply (rule_tac x="α'"in exI) using α' α'_derives_b1_U_w1 apply blast apply (rule_tac x="α' @ δ"in exI) apply (metis Cons_eq_appendI LeftDerivationFix_is_sentence LeftDerivation_append_suffix
α' α'_derives_b1_U_w1 append_assoc is_sentence_concat ld_β ld_γ) apply (rule dge) apply (metis E Suc_eq_plus1 add.commute derivation_shift_0_shift drop_derivation_shift
drop_drop w1w2) using U splits_at_combine w1w2 apply auto[1] by (simp add: j) qed qed
lemma LeftDerivationLadder_propagate: "LeftDerivationLadder (α@δ) D L γ ==> ladder_i L 0 < length α ==> n = ladder_n L index ==> index < length L ==> if (index + 1 < length L) then (∃ β. LeftDerivation α (take n D) β ∧ ladder_γ (α@δ) D L index = β@δ ∧ ladder_j L index < length β) else (∃ n' β δ'. (index = 0 ∨ ladder_prev_n L index < n') ∧ n' ≤ n ∧ LeftDerivation α (take n' D) β ∧ LeftDerivation (α@δ) (take n' D) (β@δ) ∧ derivation_ge (drop n' D) (length β) ∧ LeftDerivation δ (derivation_shift (drop n' D) (length β) 0) δ' ∧ ladder_γ (α@δ) D L index = β@δ' ∧ ladder_j L index < length β)" proof (induct index arbitrary: n) case0 have ldfix: "LeftDerivationFix (α@δ) (ladder_i L 0) (take n D) (ladder_j L 0) (ladder_γ (α@δ) D L 0)" using"0.prems"(1) "0.prems"(3) LeftDerivationLadder_def by blast from0have"1 < length L ∨ 1 = length L"by arith thenshow ?case proof (induct rule: disjCases2) case1 have"LeftDerivationIntrosAt (α@δ) D L 1" using"0.prems"(1) "1.hyps" LeftDerivationIntros_def LeftDerivationLadder_def by blast from LeftDerivationIntrosAt_implies_nonterminal[OF this] have"is_nonterminal (ladder_γ (α @ δ) D L 0 ! ladder_j L 0)" by (simp add: ladder_α_def ladder_i_def) with ldfix have"is_nonterminal ((α@δ) ! (ladder_i L 0))"by (simp add: LeftDerivationFix_def) from LeftDerivationFix_splits_at_nonterminal[OF ldfix this] obtain U a1 a2 b where thesplit: "splits_at (α @ δ) (ladder_i L 0) a1 U a2 ∧ splits_at (ladder_γ (α @ δ) D L 0) (ladder_j L 0) b U a2 ∧ LeftDerivation a1 (take n D) b"by blast have"∃ δ'. a2 = δ' @ δ ∧ α = a1 @ [U] @ δ'" using thesplit splits_at_append_suffix_prevails using"0.prems"(2) by blast thenobtain δ' where δ': "a2 = δ' @ δ ∧ α = a1 @ ([U] @ δ')"by blast obtain β where β: "β = b @ ([U] @ δ')"by blast have"is_sentence α"using LeftDerivationFix_is_sentence is_sentence_concat ldfix by blast thenhave"is_sentence ([U] @ δ')"using δ' is_sentence_concat by blast with δ' thesplit have"LeftDerivation (a1 @ ([U] @ δ')) (take n D) (b @ ([U] @ δ'))" using LeftDerivation_append_suffix by blast thenhave α_derives_β: "LeftDerivation α (take n D) β"using β δ' by blast have β_append_δ: "ladder_γ (α @ δ) D L 0 = β@δ" by (metis β δ' append_assoc splits_at_combine thesplit) have ladder_j_bound: "ladder_j L 0 < length β" by (metis One_nat_def β diff_add_inverse dual_order.strict_implies_order leD le_add1
length_Cons length_append length_take list.size(3) min.absorb2 neq0_conv splits_at_def
thesplit zero_less_diff zero_less_one) show ?case using1apply simp apply (rule_tac x="β"in exI) by (auto simp add: α_derives_β β_append_δ ladder_j_bound) next case2 note case_2 = 2 have n_def: "n = length D" by (metis "0.prems"(1) "0.prems"(3) "2.hyps" LeftDerivationLadder_def One_nat_def
diff_Suc_1 is_ladder_def ladder_last_n_intro) thenhave take_n_D: "take n D = D"by (simp add: eq_imp_le) from LeftDerivationFix_splits_at_symbol[OF ldfix] obtain U a1 a2 b1 b2 m where U: "splits_at (α @ δ) (ladder_i L 0) a1 U a2 ∧ splits_at (ladder_γ (α @ δ) D L 0) (ladder_j L 0) b1 U b2 ∧ m ≤ length (take n D) ∧ LeftDerivation a1 (take m (take n D)) b1 ∧ derivation_ge (drop m (take n D)) (Suc (length b1)) ∧ LeftDerivation a2 (derivation_shift (drop m (take n D)) (Suc (length b1)) 0) b2 ∧ (m = length (take n D) ∨ (m < length (take n D) ∧ is_word (b1 @ [U])))"by blast obtain D' where D': "D' = derivation_shift (drop m D) (Suc (length b1)) 0"by blast thenhave a2_derives_b2: "LeftDerivation a2 D' b2"using U take_n_D by auto from U have m_leq_n: "m ≤ n" by (simp add: "0.prems"(1) "0.prems"(3) "0.prems"(4) LeftDerivationLadder_def is_ladder_def
min.absorb2) from U have"splits_at (α @ δ) (ladder_i L 0) a1 U a2"by blast from splits_at_append_suffix_prevails[OF this 0(2)] obtain v' where
v': "a2 = v' @ δ ∧ α = a1 @ [U] @ v'"by blast have a1_derives_b1: "LeftDerivation a1 (take m D) b1"using m_leq_n U by (metis "0.prems"(1) "0.prems"(3) "2.hyps" LeftDerivationLadder_def One_nat_def
cancel_comm_monoid_add_class.diff_cancel is_ladder_def ladder_last_n_intro order_refl
take_all) have"LeftDerivation (v' @ δ) D' b2"using a2_derives_b2 v' by simp from LeftDerivation_breakdown'[OF this] obtain m' w1 w2 where w12: "b2 = w1 @ w2 ∧ m' ≤ length D' ∧ LeftDerivation v' (take m' D') w1 ∧ derivation_ge (drop m' D') (length w1) ∧ LeftDerivation δ (derivation_shift (drop m' D') (length w1) 0) w2"by blast have"length D' ≤ length D - m"by (simp add: D') thenhave"m' ≤ length D - m"using w12 dual_order.trans by blast thenhave m_m'_leq_n: "m + m' ≤ n"using n_def m_leq_n le_diff_conv2 add.commute by linarith obtain β where β: "β = b1 @ ([U] @ w1)"by blast have"is_sentence ([U] @ v')" using LeftDerivationFix_is_sentence is_sentence_concat ldfix v' by blast thenhave"LeftDerivation (a1 @ ([U] @ v')) (take m D) (b1 @ ([U] @ v'))" using LeftDerivation_append_suffix a1_derives_b1 by blast thenhave α_derives_pre_β: "LeftDerivation α (take m D) (b1 @ ([U] @ v'))" using v' by blast have"m = n ∨ (m < n ∧ is_word (b1 @ [U]))" using U n_def[symmetric] take_n_D by simp thenhave pre_β_derives_β: "LeftDerivation (b1 @ ([U] @ v')) (take m' (drop m D)) β" proof (induct rule: disjCases2) case1 thenhave"m' = 0"using m_m'_leq_n by arith thenshow ?case apply (simp add: β) using w12 by simp next case2 thenhave is_word_prefix: "is_word (b1 @ [U])"by blast have take_drop_eq: "take m' (drop m D) = derivation_shift (take m' D') 0 (length (b1 @ [U]))" apply (simp add: D' take_derivation_shift) by (metis U derivation_shift_left_right_cancel take_derivation_shift take_n_D) have v'_derives_w1: "LeftDerivation v' (take m' D') w1" by (simp add: w12) with is_word_prefix have "LeftDerivation ((b1 @ [U]) @ v') (derivation_shift (take m' D') 0 (length (b1 @ [U]))) ((b1 @ [U]) @ w1)" using LeftDerivation_append_prefix by blast with take_drop_eq show ?caseby (simp add: β) qed have"(take m D) @ (take m' (drop m D)) = (take (m + m') D)" by (simp add: take_add) thenhave α_derives_β: "LeftDerivation α (take (m + m') D) β" using LeftDerivation_implies_append α_derives_pre_β pre_β_derives_β by fastforce have derivation_ge_drop_m_m': "derivation_ge (drop (m + m') D) (length β)" proof - have f1: "drop m' (drop m D) = drop (m + m') D" by (simp add: add.commute) have"derivation_ge (drop m' (drop m D)) (Suc (length b1))" by (metis (no_types) U append_take_drop_id derivation_ge_append take_n_D) thenshow"derivation_ge (drop (m + m') D) (length β)" using f1 by (metis (no_types) D' β append_assoc derivation_ge_shift_plus
drop_derivation_shift length_append length_append_singleton w12) qed have δ_derives_w2: "LeftDerivation δ (derivation_shift (drop (m + m') D) (length β) 0) w2" proof - have"derivation_shift (drop m' D') (length w1) 0 = derivation_shift (drop (m + m') D) (length β) 0" by (simp add: D' β add.commute derivation_shift_0_shift drop_derivation_shift) thenshow"LeftDerivation δ (derivation_shift (drop (m + m') D) (length β) 0) w2" using w12 by presburger qed have ladder_γ_def: "ladder_γ (α @ δ) D L 0 = β @ w2" using U β splits_at_combine w12 by auto have ladder_j_bound: "ladder_j L 0 < length β"using U β splits_at_def by auto show ?case using2apply simp apply (rule_tac x="m + m'"in exI) apply (auto simp add: m_m'_leq_n) apply (rule_tac x="β"in exI) apply (auto simp add: α_derives_β) using LeftDerivationFix_is_sentence LeftDerivation_append_suffix α_derives_β
is_sentence_concat ldfix apply blast using derivation_ge_drop_m_m' apply blast apply (rule_tac x="w2"in exI) apply auto using δ_derives_w2 apply blast using ladder_γ_defapply blast using ladder_j_bound apply blast done qed next case (Suc index) have step: "LeftDerivationIntrosAt (α@δ) D L (Suc index)" by (metis LeftDerivationIntros_def LeftDerivationLadder_def Suc.prems(1) Suc.prems(4)
Suc_eq_plus1_left le_add1) have index_plus_1_bound: "index + 1 < length L" using Suc.prems(4) by linarith thenhave index_bound: "index < length L"by arith obtain n' where n': "n' = ladder_n L index"by blast from Suc.hyps[OF Suc.prems(1) Suc.prems(2) n' index_bound] index_plus_1_bound have"∃ α'. LeftDerivation α (take n' D) α' ∧ ladder_γ (α@δ) D L index = α'@δ ∧ ladder_j L index < length α'" by auto thenobtain α' where α': "LeftDerivation α (take n' D) α' ∧ ladder_γ (α@δ) D L index = α'@δ ∧ ladder_j L index < length α'" by blast have Suc_index_bound: "Suc index < length L"using Suc.prems by auto have is_ladder: "is_ladder D L"using Suc.prems LeftDerivationLadder_def by auto have n_def: "n = ladder_n L (Suc index)" using Suc_index_bound n' by (simp add: Suc.prems(3)) with n' have n'_less_n: "n' < n"using is_ladder Suc_index_bound is_ladder_def lessI by blast have ladder_α_is_γ: "ladder_α (α@δ) D L (Suc index) = ladder_γ (α@δ) D L index" by (simp add: ladder_α_def) obtain i where i: "i = ladder_i L (Suc index)"by blast obtain e where e: "e = (D ! n')"by blast obtain E where E: "E = drop (Suc n') (take n D)"by blast obtain ix where ix: "ix = ladder_ix L (Suc index)"by blast obtain j where j: "j = ladder_j L (Suc index)"by blast obtain γ where γ: "γ = ladder_γ (α@δ) D L (Suc index)"by blast have intro: "LeftDerivationIntro (α'@δ) i (snd e) ix E j γ" by (metis E LeftDerivationIntrosAt_def α' γ ladder_α_is_γ
diff_Suc_1 e i ix j local.step n' n_def) have is_eq_fst_e: "i = fst e" by (metis LeftDerivationIntrosAt_def diff_Suc_1 e i local.step n') have i_less_α': "i < length α'"using i α' ladder_i_def by simp have"(Suc index) + 1 < length L ∨ (Suc index) + 1 = length L" using Suc_index_bound by arith thenshow ?case proof (induct rule: disjCases2) case1 from1have"LeftDerivationIntrosAt (α@δ) D L (Suc (Suc index))" by (metis LeftDerivationIntros_def LeftDerivationLadder_def Suc.prems(1)
Suc_eq_plus1 Suc_eq_plus1_left le_add1) from LeftDerivationIntrosAt_implies_nonterminal[OF this] have "is_nonterminal (ladder_α (α @ δ) D L (Suc (Suc index)) ! ladder_i L (Suc (Suc index)))" by blast thenhave non_γ_j: "is_nonterminal (γ ! j)"by (simp add: γ j ladder_α_def ladder_i_def) from LeftDerivationIntro_propagate[OF intro i_less_α' non_γ_j] obtain ψ where ψ: "LeftDerivation α' ((i, snd e) # E) ψ ∧ γ = ψ @ δ ∧ j < length ψ" by blast have α_ψ: "LeftDerivation α ((take n' D)@((i, snd e) # E)) ψ" using α' ψ LeftDerivation_implies_append by blast have i_e: "(i, snd e) = e"by (simp add: is_eq_fst_e) have take_n_D_e: "((take n' D)@(e # E)) = take n D" proof - (* automatically found, then modified *) have f2: "ladder_last_n L = length D" using is_ladder is_ladder_def by blast have f3: "min (ladder_last_n L) n = n" using is_ladder_def by (metis (no_types) Suc_eq_plus1 index_plus_1_bound is_ladder min.absorb2 n_def) thenhave"take n' (take n D) @ take n D ! n' # E = take n D" using f2 by (metis E id_take_nth_drop length_take n'_less_n) thenshow ?thesis using f3 f2 by (metis (no_types) append_assoc append_eq_conv_conj
dual_order.strict_implies_order e length_take min.absorb2 n'_less_n nth_append) qed from1show ?case apply auto apply (rule_tac x=ψ in exI) apply auto using α_ψ i_e take_n_D_e apply auto[1] using γ ψ apply blast using ψ j by blast next case2 from LeftDerivationIntro_finish[OF intro i_less_α'] obtain k ψ δ' where kwδ': "k ≤ length E ∧ LeftDerivation α' ((i, snd e) # take k E) ψ ∧ LeftDerivation (α' @ δ) ((i, snd e) # take k E) (ψ @ δ) ∧ derivation_ge (drop k E) (length ψ) ∧ LeftDerivation δ (derivation_shift (drop k E) (length ψ) 0) δ' ∧ γ = ψ @ δ' ∧ j < length ψ"by blast have ladder_last_n_1: "ladder_last_n L = n" by (metis "2.hyps" Suc_eq_plus1 diff_Suc_1 ladder_last_n_def n_def) from is_ladder have ladder_last_n_2: "ladder_last_n L = length D" using is_ladder_def by blast from ladder_last_n_1 ladder_last_n_2 have n_eq_length_D: "n = length D"by blast have take_split: "take (Suc (n' + k)) D = (take n' D) @ ((i, snd e) # take k E)" apply (simp add: E n_eq_length_D) by (metis (no_types, lifting) Cons_eq_appendI add_Suc append_eq_appendI e
is_eq_fst_e n'_less_n n_eq_length_D prod.collapse
self_append_conv2 take_Suc_conv_app_nth take_add) have α_ψ: "LeftDerivation α (take (Suc (n' + k)) D) ψ" apply (subst take_split) apply (rule LeftDerivation_implies_append[where b="α'"]) apply (simp add: α') using kwδ' by blast have Suc_n'_k_bound: "Suc (n' + k) ≤ n"using E kwδ' n'_less_n by auto[1] from2show ?case apply auto apply (rule_tac x="Suc (n' + k)"in exI) apply auto apply (simp add: ladder_prev_n_def n') using Suc_n'_k_bound apply blast apply (rule_tac x="ψ"in exI) apply auto using α_ψ apply blast using α_ψ LeftDerivationFix_def LeftDerivationLadder_def LeftDerivation_append_suffix
Suc.prems(1) is_sentence_concat apply auto[1] apply (metis E add.commute add_Suc_right drop_drop kwδ' n_eq_length_D nat_le_linear
take_all) apply (rule_tac x="δ'"in exI) apply auto apply (metis E LeftDerivationLadder_ladder_n_bound Suc.prems(1) Suc_index_bound
add.commute add_Suc_right drop_drop kwδ' n_def n_eq_length_D take_all) using γ kwδ' apply blast using j kwδ' by blast qed qed
lemma ladder_i_of_cut_at_0: assumes L_non_empty: "L ≠ []" shows"ladder_i (ladder_cut L n) 0 = ladder_i L 0" proof - have"length L ≠ 0"using L_non_empty by auto thenhave"length L = 1 ∨ length L > 1"by arith thenshow ?thesis proof (induct rule: disjCases2) case1 thenshow ?case apply (simp add: ladder_cut_def ladder_i_def deriv_i_def) by (simp add: assms hd_conv_nth) next case2 thenshow ?case apply (simp add: ladder_cut_def ladder_i_def deriv_i_def) by (metis diff_is_0_eq hd_conv_nth leD list_update_nonempty nth_list_update_neq) qed qed
lemma ladder_last_j_of_cut: assumes L_non_empty: "L ≠ []" shows"ladder_last_j (ladder_cut L n) = ladder_last_j L" proof - have length_L_nonzero: "length L ≠ 0"using L_non_empty by auto thenhave length_ladder_cut: "length (ladder_cut L n) = length L" by (metis ladder_cut_def length_list_update) show ?thesis apply (simp add: ladder_last_j_def length_ladder_cut) apply (simp add: ladder_cut_def ladder_j_def deriv_j_def) by (metis length_L_nonzero diff_less neq0_conv nth_list_update_eq snd_conv zero_less_Suc) qed
lemma length_ladder_cut: assumes L_non_empty: "L ≠ []" shows"length (ladder_cut L n) = length L" by (metis ladder_cut_def length_list_update)
lemma ladder_last_n_of_cut: assumes L_non_empty: "L ≠ []" shows"ladder_last_n (ladder_cut L n) = n" proof - show ?thesis apply (simp add: ladder_last_n_def length_ladder_cut[OF L_non_empty]) apply (simp add: ladder_n_def ladder_cut_def deriv_n_def) by (metis assms diff_Suc_less fst_conv length_greater_0_conv nth_list_update_eq) qed
lemma ladder_n_of_cut: assumes L_non_empty: "L ≠ []" assumes"index < length L - 1" shows"ladder_n (ladder_cut L n) index = ladder_n L index" by (metis assms(2) ladder_cut_def ladder_n_def nat_neq_iff nth_list_update_neq)
lemma ladder_n_prev_bound: assumes ladder: "is_ladder D L" assumes u_bound: "u < length L - 1" shows"ladder_n L u ≤ ladder_prev_n L (length L - 1)" proof - have"ladder_n L u ≤ ladder_n L (length L - 2)" proof - have"u < Suc (length L - 2)" using u_bound by linarith thenshow ?thesis by (metis (no_types) diff_Suc_less is_ladder_def ladder leI length_greater_0_conv
not_less_eq numeral_2_eq_2 order.order_iff_strict) qed thenshow ?thesis by (metis One_nat_def Suc_diff_Suc diff_Suc_1 ladder_prev_n_def neq0_conv not_less0
numeral_2_eq_2 u_bound zero_less_diff) qed
lemma ladder_n_last_is_length: assumes"is_ladder D L" shows"ladder_n L (length L - 1) = length D" using assms is_ladder_def ladder_last_n_intro by auto
lemma derivation_ge_shift_implies_derivation_ge: assumes dge: "derivation_ge (derivation_shift F 0 j) k" shows"derivation_ge F (k - j)" proof - have"∧ i r. (i, r) ∈ set (derivation_shift F 0 j) ==> i ≥ k" using dge derivation_ge_def by auto
{ fix i :: nat fix r :: "symbol × (symbol list)" assume ir: "(i, r) ∈ set F" thenhave"(i + j, r) ∈ set (derivation_shift F 0 j)" proof - have"(i + j, r) ∈ (λp. (fst p - 0 + j, snd p)) ` set F" by (metis (lifting) ir diff_zero image_eqI prod.collapse prod.inject) thenshow ?thesis by (simp add: derivation_shift_def) qed thenhave"i + j ≥ k"using dge derivation_ge_def by auto thenhave"i ≥ k - j"by auto
} thenshow ?thesis using derivation_ge_def by auto qed
lemma Derives1_bound': "Derives1 a i r b ==> i ≤ length b" by (metis Derives1_bound Derives1_take append_Nil2 append_take_drop_id drop_eq_Nil
dual_order.strict_implies_order length_take min.absorb2 nat_le_linear)
lemma LeftDerivation_Derives1_last: assumes"LeftDerivation a D b" assumes"D ≠ []" shows"Derives1 (Derive a (take (length D - 1) D)) (fst (last D)) (snd (last D)) b" by (metis Derive LeftDerivation_Derive_take_LeftDerives1 LeftDerivation_implies_Derivation
LeftDerives1_implies_Derives1 assms(1) assms(2) last_conv_nth le_refl length_0_conv take_all)
lemma last_of_prefix_in_set: assumes"n < length E" assumes"D = E@F" shows"last E ∈ set (drop n D)" proof - have f1: "last (drop n E) = last E" by (simp add: assms(1)) have"drop n E ≠ []" by (metis (no_types) Cons_nth_drop_Suc assms(1) list.simps(3)) thenshow ?thesis using f1 by (metis (no_types) append.simps(2) append_butlast_last_id append_eq_conv_conj assms(2) drop_append in_set_dropD insertCI list.set(2)) qed
lemma LeftDerivationFix_cut_appendix: assumes ldfix: "LeftDerivationFix (α@δ) i D j (β@δ')" assumes α_β: "LeftDerivation α (take n D) β" assumes n_bound: "n ≤ length D" assumes dge: "derivation_ge (drop n D) (length β)" assumes i_in: "i < length α" assumes j_in: "j < length β" shows"LeftDerivationFix α i (take n D) j β" proof - from LeftDerivationFix_def[where α="α@δ"and i=i and D=D and j=j and β="β@δ'"] obtain E F where EF: "is_sentence (α @ δ) ∧ is_sentence (β @ δ') ∧ LeftDerivation (α @ δ) D (β @ δ') ∧ i < length (α @ δ) ∧ j < length (β @ δ') ∧ (α @ δ) ! i = (β @ δ') ! j ∧ D = E @ derivation_shift F 0 (Suc j) ∧ LeftDerivation (take i (α @ δ)) E (take j (β @ δ')) ∧ LeftDerivation (drop (Suc i) (α @ δ)) F (drop (Suc j) (β @ δ'))"using ldfix by auto with i_in j_in have take_i_E_take_j: "LeftDerivation (take i α) E (take j β)" by (simp add: less_or_eq_imp_le) obtain m where m: "m = length E"by blast
{ assume n_less_m: "n < m" thenhave E_nonempty: "E ≠ []"using gr_implies_not0 list.size(3) m by auto have last_E_in_set: "last E ∈ set (drop n D)" using last_of_prefix_in_set n_less_m m EF by blast obtain k r where kr: "(k, r) = last E"by (metis old.prod.exhaust) have k_lower_bound: "k ≥ length β"using dge last_E_in_set kr by (metis derivation_ge_def fst_conv) have"∃ α'. Derives1 α' k r (take j β)"using LeftDerivation_Derives1_last take_i_E_take_j by (metis E_nonempty kr fst_conv snd_conv) thenhave"k ≤ j"by (metis Derives1_bound' j_in length_take less_imp_le_nat min.absorb2) thenhave k_upper_bound: "k < length β"using j_in by arith from k_lower_bound k_upper_bound have"False"by arith
} thenhave m_le_n: "m ≤ n"by arith have take_i_E_take_j: "LeftDerivation (take i α) E (take j β)" by (simp add: take_i_E_take_j) have"take n D = E @ (take (n - m) (derivation_shift F 0 (Suc j)))" using EF m m_le_n by auto thenhave take_n_D: "take n D = E @ (derivation_shift (take (n - m) F) 0 (Suc j))" using take_derivation_shift by auto obtain F' where F': "F' = derivation_shift (take (n - m) F) 0 (Suc j)"by blast have"LeftDerivation ((take i α)@(drop i α)) E ((take j β)@(drop i α))" using take_i_E_take_j by (metis EF LeftDerivation_append_suffix append_take_drop_id is_sentence_concat) thenhave"LeftDerivation α E ((take j β)@(drop i α))"by simp with take_n_D have take_j_drop_i: "LeftDerivation ((take j β)@(drop i α)) F' β"using F' by (metis Derivation_unique_dest LeftDerivation_append LeftDerivation_implies_Derivation α_β) have F'_ge: "derivation_ge F' (Suc j)"using F' derivation_ge_shift by blast have drop_append: "drop i α = [α!i] @ (drop (Suc i) α)"by (simp add: Cons_nth_drop_Suc i_in) have take_append: "take j β @ [α!i] = take (Suc j) β" by (metis LeftDerivationFix_def i_in j_in ldfix nth_superfluous_append take_Suc_conv_app_nth) have take_drop_Suc: "(take j β)@(drop i α) = (take (Suc j) β)@(drop (Suc i) α)" by (simp add: drop_append take_append) with take_drop_Suc take_j_drop_i have"LeftDerivation ((take (Suc j) β)@(drop (Suc i) α)) F' β" by auto note helper = LeftDerivation_skip_prefix[OF this] have len_take: "length (take (Suc j) β) = Suc j"by (simp add: Suc_leI j_in min.absorb2) have F'_shift: "derivation_shift F' (Suc j) 0 = take (n - m) F" using F' derivation_shift_right_left_cancel by blast have LeftDerivation_drop: "LeftDerivation (drop (Suc i) α) (take (n - m) F) (drop (Suc j) β)" using helper len_take F'_shift F'_ge by auto show ?thesis apply (auto simp add: LeftDerivationFix_def) using LeftDerivationFix_is_sentence is_sentence_concat ldfix apply blast using LeftDerivationFix_is_sentence is_sentence_concat ldfix apply blast using α_β apply blast using i_in apply blast using j_in apply blast using LeftDerivationFix_def i_in j_in ldfix apply auto[1] apply (rule_tac x=E in exI) apply (rule_tac x="take (n - m) F"in exI) apply auto using take_n_D apply blast using take_i_E_take_j apply blast using LeftDerivation_drop by blast qed
lemma LeftDerivationFix_cut_appendix': assumes ldfix: "LeftDerivationFix (α@δ) i D j (β@δ')" assumes α_β: "LeftDerivation α D β" assumes i_in: "i < length α" assumes j_in: "j < length β" shows"LeftDerivationFix α i D j β" proof - obtain n where n: "n = length D"by blast have"LeftDerivationFix α i (take n D) j β" apply (rule_tac LeftDerivationFix_cut_appendix) apply (rule ldfix) using α_β n apply auto[1] using n apply auto[1] using n apply auto[1] using i_in apply blast using j_in apply blast done thenshow ?thesis using n by auto qed
lemma LeftDerivationIntro_cut_appendix: assumes ldfix: "LeftDerivationIntro (α@δ) i r ix D j (β@δ')" assumes α_β: "LeftDerivation α ((i,r)#(take n D)) β" assumes n_bound: "n ≤ length D" assumes dge: "derivation_ge (drop n D) (length β)" assumes i_in: "i < length α" assumes j_in: "j < length β" shows"LeftDerivationIntro α i r ix (take n D) j β" proof - from LeftDerivationIntro_def[where α="α@δ"and i=i and r=r and ix=ix and D=D and j=j and γ="β@δ'"] obtain ψ where ψ: "LeftDerives1 (α @ δ) i r ψ ∧ ix < length (snd r) ∧ snd r ! ix = (β @ δ') ! j ∧ LeftDerivationFix ψ (i + ix) D j (β @ δ')" using ldfix by blast thenhave"∃ α'. ψ = α' @ δ ∧ i + length (snd r) ≤ length α'" using i_in using LeftDerives1_append_replace_in_left by blast thenobtain α' where α': "ψ = α' @ δ ∧ i + length (snd r) ≤ length α'"by blast have α_α': "LeftDerives1 α i r α'"using α' ψ using LeftDerives1_skip_suffix i_in by blast from α_β obtain u where u: "LeftDerives1 α i r u ∧ LeftDerivation u (take n D) β"by auto with α_α' have"u = α'"using Derives1_unique_dest LeftDerives1_implies_Derives1 by blast with u have α'_β: "LeftDerivation α' (take n D) β"by auto have ldfix_append: "LeftDerivationFix (α' @ δ) (i + ix) D j (β @ δ')"using α' ψ by blast have i_plus_ix_bound: "i + ix < length α'"using ψ α' using add_lessD1 le_add_diff_inverse less_asym' linorder_neqE_nat nat_add_left_cancel_less by linarith from LeftDerivationFix_cut_appendix[OF ldfix_append α'_β n_bound dge i_plus_ix_bound j_in] have ldfix: "LeftDerivationFix α' (i + ix) (take n D) j β" . show ?thesis apply (simp add: LeftDerivationIntro_def) apply (rule_tac x="α'"in exI) apply auto using α_α' apply blast using ψ apply blast apply (simp add: ψ j_in) using ldfix by blast qed
lemma LeftDerivationIntro_cut_appendix': assumes ldfix: "LeftDerivationIntro (α@δ) i r ix D j (β@δ')" assumes α_β: "LeftDerivation α ((i,r)#D) β" assumes i_in: "i < length α" assumes j_in: "j < length β" shows"LeftDerivationIntro α i r ix D j β" proof - obtain n where n: "n = length D"by blast have"LeftDerivationIntro α i r ix (take n D) j β" apply (rule_tac LeftDerivationIntro_cut_appendix) apply (rule ldfix) using α_β n apply auto[1] using n apply auto[1] using n apply auto[1] using i_in apply blast using j_in apply blast done thenshow ?thesis using n by auto qed
lemma ladder_n_monotone: "is_ladder D L ==> u ≤ v ==> v < length L ==> ladder_n L u≤ ladder_n L v" by (metis is_ladder_def le_neq_implies_less linear not_less)
lemma ladder_i_cut: assumes index_bound: "index < length L" shows"ladder_i (ladder_cut L n) index = ladder_i L index" proof - have"index = 0 ∨ index > 0"by arith thenshow ?thesis proof (induct rule: disjCases2) case1 with index_bound have"L ≠ []"by (simp add: less_numeral_extra(3)) thenshow ?caseusing1by (simp add: ladder_i_of_cut_at_0) next case2 thenshow ?case apply (auto simp add: ladder_i_def ladder_cut_def ladder_j_def deriv_j_def Let_def) using index_bound by auto qed qed
lemma ladder_j_cut: assumes index_bound: "index < length L" shows"ladder_j (ladder_cut L n) index = ladder_j L index" by (metis gr_implies_not0 index_bound ladder_cut_def ladder_j_def ladder_last_j_def
ladder_last_j_of_cut length_ladder_cut list.size(3) nth_list_update_neq)
lemma ladder_ix_cut: assumes index_lower_bound: "index > 0" assumes index_upper_bound: "index < length L" shows"ladder_ix (ladder_cut L n) index = ladder_ix L index" proof - show ?thesis using index_lower_bound apply (simp add: ladder_ix_def deriv_ix_def) by (metis index_upper_bound ladder_cut_def nth_list_update_eq nth_list_update_neq snd_conv) qed
lemma LeftDerivation_from_in_between: assumes α_β: "LeftDerivation α (take u D) β" assumes α_γ: "LeftDerivation α (take v D) γ" assumes u_le_v: "u ≤ v" shows"LeftDerivation β (drop u (take v D)) γ" proof - have take_split: "take v D = take u D @ (drop u (take v D))" by (metis u_le_v add_diff_cancel_left' drop_take le_Suc_ex take_add) thenshow ?thesis using α_γ α_β by (metis (no_types, lifting) Derivation_unique_dest LeftDerivation_append
LeftDerivation_implies_Derivation) qed
lemma LeftDerivationLadder_cut_appendix_helper: assumes LDLadder: "LeftDerivationLadder (α@δ) D L γ" assumes ladder_i_in_α: "ladder_i L 0 < length α" shows"∃ E F γ1 γ2 L'. D = E@F ∧ γ = γ1 @ γ2 ∧ LeftDerivationLadder α E L' γ1 ∧ derivation_ge F (length γ1) ∧ LeftDerivation δ (derivation_shift F (length γ1) 0) γ2 ∧ L' = ladder_cut L (length E)" proof - have is_ladder_D_L: "is_ladder D L"using LDLadder LeftDerivationLadder_def by blast obtain n where n: "n = ladder_last_n L"by blast thenhave n_eq_ladder_n: "n = ladder_n L (length L - 1)"using ladder_last_n_def by blast have length_L_nonzero: "length L > 0" using LeftDerivationLadder_def assms(1) is_ladder_def by blast from LeftDerivationLadder_propagate[OF LDLadder ladder_i_in_α n_eq_ladder_n] obtain n' β δ' where finish: "(length L - 1 = 0 ∨ ladder_prev_n L (length L - 1) < n') ∧ n' ≤ n ∧ LeftDerivation α (take n' D) β ∧ LeftDerivation (α @ δ) (take n' D) (β @ δ) ∧ derivation_ge (drop n' D) (length β) ∧ LeftDerivation δ (derivation_shift (drop n' D) (length β) 0) δ' ∧ ladder_γ (α @ δ) D L (length L - 1) = β @ δ' ∧ ladder_j L (length L - 1) < length β" using length_L_nonzero by auto obtain E where E: "E = take n' D"by blast obtain F where F: "F = drop n' D"by blast obtain L' where L': "L' = ladder_cut L (length E)"by blast have γ_ladder: "γ = ladder_γ (α @ δ) D L (length L - 1)" by (metis Derive LDLadder LeftDerivationLadder_def LeftDerivation_implies_Derivation
append_Nil2 append_take_drop_id drop_eq_Nil is_ladder_def ladder_γ_def le_refl n
n_eq_ladder_n) thenhave γ: "γ = β @ δ'"using finish by auto have"is_sentence (α@δ)" using LDLadder LeftDerivationFix_is_sentence LeftDerivationLadder_def by blast thenhave is_sentence_α: "is_sentence α"using is_sentence_concat by blast have"is_sentence γ" using Derivation_implies_derives LDLadder LeftDerivationFix_is_sentence
LeftDerivationLadder_def LeftDerivation_implies_Derivation derives_is_sentence by blast thenhave is_sentence_β: "is_sentence β"using γ is_sentence_concat by blast have length_L': "length L' = length L" by (metis L' ladder_cut_def length_list_update) have ladder_last_n_L': "ladder_last_n L' = length E" using L' ladder_last_n_of_cut length_L_nonzero by blast have length_D_eq_n: "length D = n" using LDLadder LeftDerivationLadder_def is_ladder_def n by auto thenhave length_E_eq_n': "length E = n'"by (simp add: E finish min.absorb2)
{ fix u :: nat assume"u < length L'" thenhave"u < length L' - 1 ∨ u = length L' - 1"by arith thenhave"ladder_n L' u ≤ length E" proof (induct rule: disjCases2) case1 have u_bound: "u < length L - 1"using1by (simp add: length_L') thenhave L'_eq_L: "ladder_n L' u = ladder_n L u"using L' ladder_n_of_cut
length_L_nonzero length_greater_0_conv by blast from u_bound have"ladder_n L u ≤ ladder_prev_n L (length L - 1)" using ladder_n_prev_bound LeftDerivationLadder_def assms(1) by blast thenshow ?case using L'_eq_L finish length_E_eq_n' u_bound by linarith next case2 thenhave"ladder_n L' u = length E"using ladder_last_n_L' ladder_last_n_def by auto thenshow ?caseby auto qed
} note ladder_n_bound = this
{ fix u :: nat fix v :: nat assume u_less_v: "u < v" assume v_bound: "v < length L'" have"v < length L' - 1 ∨ v = length L' - 1"using v_bound by arith thenhave"ladder_n L' u < ladder_n L' v" proof (induct rule: disjCases2) case1 show ?case using"1.hyps" L' LeftDerivationLadder_def assms(1) is_ladder_def ladder_n_of_cut
length_L' u_less_v by auto next case2 note v_def = 2 have"v = 0 ∨ v ≠ 0"by arith thenshow ?case proof (induct rule: disjCases2) case1 thenshow ?caseusing u_less_v by auto next case2 thenhave"ladder_prev_n L (length L - 1) < n'"using finish v_def length_L' by linarith thenshow ?case by (metis (no_types, lifting) L' LeftDerivationLadder_def assms(1)
ladder_last_n_L' ladder_last_n_def ladder_n_of_cut ladder_n_prev_bound
le_neq_implies_less length_E_eq_n' length_L' length_greater_0_conv
less_trans u_less_v v_def) qed qed
} note ladder_n_pairwise_bound = this
have is_ladder_E_L': "is_ladder E L'" apply (auto simp add: is_ladder_def ladder_last_n_L') using length_L_nonzero length_L' apply simp using ladder_n_bound apply blast using ladder_n_pairwise_bound by blast
{ fix index :: nat assume index_bound: "index + 1 < length L" thenhave index_le: "index < length L"by arith from index_bound have len_L_minus_1: "length L - 1 ≠ 0"by arith obtain m where m: "m = ladder_n L index"by blast from LeftDerivationLadder_propagate[OF LDLadder ladder_i_in_α m index_le] obtain ψ where
ψ: "LeftDerivation α (take m D) ψ ∧ ladder_γ (α @ δ) D L index = ψ @ δ ∧ ladder_j L index < length ψ"using index_bound by auto have L'_Derive: "ladder_γ α E L' index = Derive α (take (ladder_n L' index) E)" by (simp add: ladder_γ_def) have ladder_n_L'_eq_L: "ladder_n L' index = ladder_n L index" using L' index_bound ladder_n_of_cut length_L_nonzero by auto have"ladder_prev_n L (length L - 1) < n'"using finish len_L_minus_1 by blast thenhave n'_is_upper_bound: "ladder_n L (length L - 2) < n'"using index_bound by (metis diff_diff_left ladder_prev_n_def len_L_minus_1 one_add_one) have index_upper_bound: "index ≤ length L - 2"using index_bound by linarith have ladder_n_upper_bound: "ladder_n L index ≤ ladder_n L (length L - 2)" apply (rule_tac ladder_n_monotone) apply (rule_tac is_ladder_D_L) apply (rule index_upper_bound) using length_L_nonzero by linarith
withn_ havem_le_n >n'" using dual_order.strict_implies_order le_ unfokbo_ef b ysmp then have by (metis E le_take_same length_E_eq_n' order_refl take_all) kdminus (rvaluStx) z = None" by( add'_ m)
hen Derive_eq_: "Derive α (simp ad: DeDer LeftDerivation_implies_Derivation <o>) then have t1: "ladder_ storage_update_def
y(dd)
omega_eq: "ψ E L' index"by( add Derive_eq_\omega L'_Derive) then balances_update_def simp using ψ (in Contract storage_update_diff[wpsimps]: have t3(akeadder_ne(ladder_nLindex D by( : mtake_helper) have:" L index <length (ladderγ E L' index)" \omega> \omega>_eq have t5: "E ! (ladder_n L' index) = D ! (ladder_n L index)" using E ladder_n_L'q_L_ adder_n_upper_bound's_upper_bounduto note =t1 t3 t5
} note ladder_early_stage = this
{ fix index : wp_def ( "execute f s"ruleresult_cases[]: assume index_bound have i: "ladder_i L' index = ladder_i L index" using L' ladder_i_cut by (simpadd: index_boundndex_bound have j: "ladder_j L' index = ladder_j L index"thenave"P a s''''" wp_def "g a"P **bysimp using L' ladder_j_cut by (simp add: index_bound) haveix:"index <> ladder_ nx =lde_ix inex" using L' ladder_ix_cut by (simp add
<: "ladder_α e_<> <al>L'idx @ \delta simp add: index ladder_α aveibund index > 0 \\Long> ladder_i L' index < length (ladder_α α E L' index)" using i index_bound ladder_α_ shows" lfo x) P Es note ij s) } note ladder_every_stage = this
fix u :: nat ix : nt u: " le v" assume v_bound: "v < length L" have "ladder_n L u ≤ ladder_n L v" using is_ladder_D_L ladder_n_monotone u_le_v v_bound by blast } note ladder_L_n_pairwise_le = this
{ index ::n assume index_lower_bound: "index false_monad_def by( wp_bool_monad assume index_upper_bound: "index + 1 < length L" note derivation "P(k msg_value) s" " α\gamma> α 0))" using derivation[of "index - Suc 0"] index_lower_bound index_upper_bound
using " (Soli.c bm (return Empty) th Err) P E s" have derivation2:
(Somea using derivation[of index] index_upper_bound by blast have ladder_ using index_lower_bound ladder_α PEs" l: "ladder_n (index Suc)\le> ladder_n " apply (rule_tac ladder_L_n_pairwise_le) apply arith using index_upper_bound by ar P E) from LeftDerivation_from_in_between[OF derivation1 derivation2 ladder_n_le] ladder_α[wprules]: "LeftDerivationladder_<alpha α (ladder_n index - Suc 0
(take (ladder_n L' index) E)) (ladder_γ (metis(1) assms)execute_assert)execute_assert(2) wp_simp1java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78 by (metis L' Suc_leI add_lessD1 index_lower_boundassumes"effect (m \<ss ladder_n_of_cut le_add_diff_inverse2 length_L_nonzero length_greater_0_conv less_diff_conv) } note LeftDerivation_delta_early = this eLfDrvatini_<>0 LeftDerivationFix \<alpha L' 0) E) L' 0 (laddeγ E L'0)" proof - have:\alpha@δ
(ladder_γ>δ) using LDLadder LeftDerivationLadder_def by blast have ladder_i_L': "ladder_i L' 0 = ladder_i L 0" using L - have ladder_j_L': "ladder_j L' 0 = ladder_j L 0"
metisLladder_cut_def ladder_last_j_def ladder_last_j_of_cut
length_L' length_greater_0_conv: "execute (equals_monad c t) ss = Nor (kdbool False, s''" have"length L = 1 ∨execute (return Empty) s'' = Normal (a, s')› then ss f nuc u dsCse case 1 from 1 have ladder_n_L'_0: "ladder_n L' 0next using diff_is_0_eq
length_L' less_or_eq_imp_le by auto have take_n'_E: "take n' E = E"by (simp add: length_E_eq_n from ladder_n_L have"ladder_n L 0 = length D"
showscaseoneRightarrow a | Some \Rightarrow b x) P E s" then have take_ladder_n_L_0: "take (ladder_n L 0) D = D" by simp have ladder_γ_α: "ladder_γoldd
yaddadder__def take_ladder_n_L by (simp add: Derive E LeftDerivation_implies_Derivation finish) have ladder_j_in_β using finish "1.hyps"by auto have ldfix_1: "LeftDerivationFix (α"x. t = SType.TValue<> rrs" using "1. assumes v s" avev LfDeiai <> ladriL0 lder_ )\beta shows nblnenpPEs length_D_eq_n) then sho cse by (simp add: ladder_i_L' ladder_j_L' take_ladder_n_L' ladder_γ next case 2 have h: "0 +(inContract p_assign_storage2: note stage = ladder_early_stage have ldfix0: "LeftDerivationFix (α@δ) (ladder_i L 0) (take (ladder_n L 0) D) (ladder_j L 0) ((ladder_γ using ladder_i_L' ladder_j_L' ldfix stage(1) stage(3) by auto from LeftDerivationFix_cut_appendix'[OF ldfix0 stage(2) ladder_i_in_α stage(4)] show ?case by (simp add: ladder_i_L' ladder_j_L' stage(3)) qed qed
{ fix index :: nat assume index_bounds: "1≤ have introsAt_appendixrivationIntrosAtalpha@δ usingadderderrivationIntros_deftDerivationLadder_defessD1undsds by blast have index_plus_1_upper_bound
oterly_stage dder_early_stagely_stagelus_1_upper_bound have ladder_i_L_index_eq_fst and\Andack$Someme)<Longrightarrow using introsAt_appendix LeftDerivationIntrosAt_def byetis have E_at_D_at: "(E ! ladder_n L' (index - Suc 0)) = (D ! ladder_n L (index - Suc 0))"
java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50 by (metis One_nat_def add_lessD1 index_bounds le_add_diff_inverse2) thenhave ladder_i_L'_index_eq_fst: "ladder_i L' index = fst (E ! ladder_n L' (index - Suc 0))" using index_bounds ladder_i_L_index_eq_fst ladder_every_stage(1 assmsding ect_defefexecute have same_derivation: "rop(u ldrnL (e u 0) tk ldder_ ' ex)) E) (drop (Suc (ladder_n L (index - Suc using L' early_stage(3) index_bounsddrnof_ct lhLnoner y uto have deriv_split: "(drop (ladder_n L' (index - Suc 0 (ContractrayLength
((ladder_i L' index, snd (E ! ladder_n L' (index - Suc 0))) #
drop (Suc (<>xs by (metis Cons_nth_drop_Suc One_nat_def Suc_le_lessD add_lessD1 diff_Suc_less index_bounds
ladder_i_Lw)
ngth_takeoddcollapse have"LeftDerivationIntrosAt α E L' index"
pplyd:LeftDerivationIntrosAt_def_ef using ladder_i_L (inontractorearrayLength apply (rule_tac LeftDerivationIntro_cut_appendix'[where δ=δsa. return(rvalueValue lengthStoragesthis)) K throwErr
pply_atrivationIntrosAt_deffSuc_le_lessDD1
early_staget_appendixpendixndixy_stage
ladder_every_stage(3) ladder_every_stage(4) ladder_i_L'_index_eq_fst same_derivation) defer1 wppion<>s using index_bounds ladder_every_stage(5) apply auto[1] using early_stage(4) index_bounds ladder_every_stage(2) apply auto[1] using LeftDerivation_delta_earlyrvalue(ints)<Rightarrow by (metis One_nat_def Suc_le_eq index_bounds)
} note LeftDerivationIntrosAt_early = this
{ fix indexand> e. Q e sa" assume index_bounds: "1≤ have(nContractontractwp_assign_stack_kdvalueassign_stack_kdvalues: usingLadderftDerivationIntros_deferivationIntros_defos_defer_defsD1boundsounds by (metis Suc_eq_plus1 not_less_eq) have ladder_i_L_index_eq_fst: "ladder_i L index = fst (D ! ladder_n L (index - Suc 0))" usingosAt_appendixx eftDerivationIntrosAt_defx_boundsisOne_nat_def
_D_atL' dexexx uc ) D! adder_nx-Suc0)" using ladder_early_stage[of "index - Suc 0"] by (metis One_nat_def Suc_eq_plus1 index_bounds le_add_diff_inverse2 lessI) then have ladder_i_L'_index_eq_fst: "ladder_i L' index = fst (E ! ladder_n L' (index - Suc 0))" using index_bounds ladder_i_L_index_eq_fst ladder_every_stage(1) le_add1 le_less_trans by auto obtain D' where D': "D' = (drop (Suc (ladder_n L (index - Suc 0))) (take (ladder_n L index) D))" by blast obtain k where k: "k = (ladder_n L' index) - (Suc (ladder_n L' (index - Suc 0)))" by blast have ladder_n_L'_index: "ladder_n L' index = length E" by (metis diff_add_inverse2 index_bounds ladder_last_n_L' ladder_last_n_def length_L') have take_is_E: "take (ladder_n L' index) E = E" by (simp add: ladder_n_L'_index) have ladder_n_L_index: "ladder_n L index = length D" by (metis diff_add_inverse2 index_bounds length_D_eq_n n_eq_ladder_n) have take_is_D: "take (ladder_n L index) D = D" by (simp add: ladder_n_L_index) have write_as_take_k_D': "(drop (Suc (ladder_n L' (index - Suc 0))) E) = take k D'" using take_is_D by (metis D' E L' One_nat_def Suc_le_lessD add_diff_cancel_right' diff_Suc_less drop_take index_bounds k ladder_n_L'_index ladder_n_of_cut length_E_eq_n' length_L_nonzero length_greater_0_conv) have k_bound: "k ≤ length D'" by (metis le_iff_add append_take_drop_id k ladder_n_L'_index length_append length_drop write_as_take_k_D') have D'_alt: "D' = drop (Suc (ladder_n L (index - Suc 0))) D" by (simp add: D' take_is_D) have "LeftDerivationIntrosAt α E L' index" apply (auto simp add: LeftDerivationIntrosAt_def Let_def) using ladder_i_L'_index_eq_fst apply blast apply (subst take_is_E) apply (subst write_as_take_k_D') apply (rule_tac LeftDerivationIntro_cut_appendix[where δ=δ and δ' = δ']) apply (metis D' Derive E E_at_D_at LeftDerivationIntrosAt_def LeftDerivation_implies_Derivation One_nat_def Suc_le_lessD add_diff_cancel_right' diff_Suc_less finish index_bounds introsAt_appendix ladder_γ_def ladder_every_stage(2) ladder_every_stage(3) ladder_every_stage(4) ladder_i_L'_index_eq_fst length_L_nonzero take_is_E) apply (metis Cons_nth_drop_Suc E L' LeftDerivation_from_in_between LeftDerivation_take_derive One_nat_def Suc_le_lessD add_diff_cancel_right' diff_Suc_less finish index_bounds ladder_α_def ladder_γ_def ladder_i_L'_index_eq_fst ladder_n_L'_index ladder_n_of_cut ladder_prev_n_def length_E_eq_n' length_L_nonzero less_imp_le_nat less_numeral_extra(3) list.size(3) prod.collapse take_is_E write_as_take_k_D') using k_bound apply blast using D'_alt apply (metis (no_types, lifting) Derive E L' LeftDerivation_implies_Derivation One_nat_def Suc_leI Suc_le_lessD add_diff_cancel_right' diff_Suc_less drop_drop finish index_bounds k ladder_γ_def ladder_n_L'_index ladder_n_of_cut ladder_prev_n_def le_add_diff_inverse2 length_E_eq_n' length_L_nonzero length_greater_0_conv less_not_refl2 take_is_E) using index_bounds ladder_every_stage(5) apply auto[1] by (metis Derive E LeftDerivation_implies_Derivation One_nat_def add_diff_cancel_right' diff_Suc_less finish index_bounds ladder_γ_def ladder_every_stage(2) length_L_nonzero take_is_E) } note LeftDerivationIntrosAt_last = this
have ladder_E_L': "LeftDerivationLadder α E L' β" apply (auto simp add: LeftDerivationLadder_def) using finish E apply blast using is_ladder_E_L' apply blast using LeftDerivationFix_α_0 apply blast using LeftDerivationIntros_def LeftDerivationIntrosAt_early LeftDerivationIntrosAt_last by (metis Suc_eq_plus1 Suc_leI le_neq_implies_less length_L') show ?thesis apply (rule_tac x=E in exI) apply (rule_tac x=F in exI) apply (rule_tac x=β in exI) apply (rule_tac x=δ' in exI) apply (rule_tac x=L' in exI) apply auto using E F apply simp apply (rule γ) using ladder_E_L' apply blast using F finish apply blast using F finish apply blast by (rule L') qed
theorem LeftDerivationLadder_cut_appendix: assumes LDLadder: "LeftDerivationLadder (α@δ) D L γ" assumes ladder_i_in_α: "ladder_i L 0 < length α" shows "∃ E F γ1 γ2 L'. D = E@F ∧
γ = γ1 @ γ2∧
LeftDerivationLadder α E L' γ1∧
derivation_ge F (length γ1) ∧
LeftDerivation δ (derivation_shift F (length γ1) 0) γ2∧
length L' = length L ∧ ladder_i L' 0 = ladder_i L 0∧
ladder_last_j L' = ladder_last_j L" proof - from LeftDerivationLadder_cut_appendix_helper[OF LDLadder ladder_i_in_α] obtain E F γ1 γ2 L' where helper: "D = E @ F ∧
γ = γ1 @ γ2∧
LeftDerivationLadder α E L' γ1∧
derivation_ge F (length γ1) ∧
LeftDerivation δ (derivation_shift F (length γ1) 0) γ2∧ L' = ladder_cut L (length E)" by blast show ?thesis apply (rule_tac x=E in exI) apply (rule_tac x=F in exI) apply (rule_tac x=γ1 in exI) apply (rule_tac x=γ2 in exI) apply (rule_tac x=L' in exI) using helper LDLadder LeftDerivationLadder_def is_ladder_def ladder_i_of_cut_at_0 ladder_last_j_of_cut length_ladder_cut by force qed
definition ladder_stepdown_diff :: "ladder ==> nat" where "ladder_stepdown_diff L = Suc (ladder_n L 0)"
definition ladder_stepdown_α_0 :: "sentence ==> derivation ==> ladder ==> sentence" where "ladder_stepdown_α_0 a D L = Derive a (take (ladder_stepdown_diff L) D)"
lemma LeftDerivationIntro_LeftDerives1: assumes "LeftDerivationIntro α i r ix D j γ" assumes "splits_at α i a1 A a2" shows "LeftDerives1 α i r (a1@(snd r)@a2)" by (metis LeftDerivationIntro_def LeftDerivationIntro_examine_rule LeftDerivationIntro_is_sentence LeftDerives1_def assms(1) assms(2) prod.collapse splits_at_implies_Derives1)
lemma LeftDerives1_Derive: assumes "LeftDerives1 α i r γ" shows "Derive α [(i, r)] = γ" by (metis Derive LeftDerivation.simps(1) LeftDerivation_LeftDerives1 LeftDerivation_implies_Derivation append_Nil assms)
lemma ladder_stepdown_α_0_altdef: assumes ladder: "LeftDerivationLadder α D L γ" assumes length_L: "length L > 1" assumes split: "splits_at (ladder_α α D L 1) (ladder_i L 1) a1 A a2" shows "ladder_stepdown_α_0 α D L = a1 @ (snd (snd (D ! (ladder_n L 0)))) @ a2" proof - have 1: "ladder_α α D L 1 = Derive α (take (ladder_n L 0) D)" by (simp add: ladder_α_def ladder_γ_def) obtain rule where rule: "rule = snd (D ! (ladder_n L 0))" by blast have "∃ E ψ. LeftDerivationIntro (ladder_α α D L 1) (ladder_i L 1) rule (ladder_ix L 1)
E (ladder_j L 1) ψ" by (metis LeftDerivationIntrosAt_def LeftDerivationIntros_def LeftDerivationLadder_def One_nat_def diff_Suc_1 ladder length_L order_refl rule) then obtain E ψ where intro: "LeftDerivationIntro (ladder_α α D L 1) (ladder_i L 1) rule (ladder_ix L 1) E (ladder_j L 1) ψ" by blast then have 2: "LeftDerives1 (ladder_α α D L 1) (ladder_i L 1) rule (a1@(snd rule)@a2)" using LeftDerivationIntro_LeftDerives1 split by blast have fst_D: "fst (D ! (ladder_n L 0)) = ladder_i L 1" by (metis LeftDerivationIntrosAt_def LeftDerivationIntros_def LeftDerivationLadder_def One_nat_def diff_Suc_1 ladder le_numeral_extra(4) length_L) have derive_derive: "Derive α (take (Suc (ladder_n L 0)) D) =
Derive (Derive α (take (ladder_n L 0) D)) [D ! (ladder_n L 0)]" proof - have f1: "Derivation α (take (Suc (ladder_n L 0)) D) (Derive α (take (Suc (ladder_n L 0)) D))" using Derivation_take_derive LeftDerivationLadder_def LeftDerivation_implies_Derivation ladder by blast have f2: "length L - 1 < length L" using length_L by linarith have "0 < length L - 1" using length_L by linarith then have f3: "take (Suc (ladder_n L 0)) D = take (ladder_n L 0) D @ [D ! ladder_n L 0]" using f2 by (metis (full_types) LeftDerivationLadder_def is_ladder_def ladder ladder_last_n_def take_Suc_conv_app_nth) obtain sss :: "symbol list ==> (nat × symbol × symbol list) list ==> (nat × symbol × symbol list) list ==> symbol list ==> symbol list" where "∀x0 x1 x2 x3. (∃v4. Derivation x3 x2 v4 ∧ Derivation v4 x1 x0) = (Derivation x3 x2 (sss x0 x1 x2 x3) ∧Derivation (sss x0 x1 x2 x3) x1 x0)" by moura then show ?thesis using f3 f1 Derivation_append Derive by auto qed then have 3: "ladder_stepdown_α_0 α D L = Derive (ladder_α α D L 1) [D ! (ladder_n L 0)]" using 1 by (simp add: ladder_stepdown_α_0_def ladder_stepdown_diff_def) have 4: "D ! (ladder_n L 0) = (ladder_i L 1, rule)" using rule fst_D by (metis prod.collapse) then show ?thesis using 2 3 4 LeftDerives1_Derive snd_conv by auto qed
lemma ladder_i_0_bound: assumes ld: "LeftDerivationLadder α D L γ" shows "ladder_i L 0 < length α" proof - have "LeftDerivationFix α (ladder_i L 0) (take (ladder_n L 0) D)
(ladder_j L 0) (ladder_γ α D L 0)" using ld LeftDerivationLadder_def by simp then show ?thesis using LeftDerivationFix_def by simp qed
lemma ladder_j_bound: assumes ld: "LeftDerivationLadder α D L γ" assumes index_bound: "index < length L" shows "ladder_j L index < length (ladder_γ α D L index)" proof - have ld': "LeftDerivationLadder (α@[]) D L γ" using ld by simp have ladder_i_0: "ladder_i L 0 < length α" using ladder_i_0_bound ld by auto obtain n where n: "n = ladder_n L index" by blast note propagate = LeftDerivationLadder_propagate[OF ld' ladder_i_0 n index_bound] from index_bound have "index + 1 < length L ∨ index + 1 = length L" by arith then show ?thesis proof (induct rule: disjCases2) case 1 then have "∃β. LeftDerivation α (take n D) β ∧
ladder_γ (α @ []) D L index = β @ [] ∧ ladder_j L index < length β" using propagate by auto then show ?case by auto next case 2 then have " ∃n' β δ'.
(index = 0∨ ladder_prev_n L index < n') ∧
n' ≤ n ∧
LeftDerivation α (take n' D) β ∧
LeftDerivation (α @ []) (take n' D) (β @ []) ∧
derivation_ge (drop n' D) (length β) ∧
LeftDerivation [] (derivation_shift (drop n' D) (length β) 0) δ' ∧
ladder_γ (α @ []) D L index = β @ δ' ∧ ladder_j L index < length β" using propagate by auto then show ?case by auto qed qed lemma ladder_last_j_bound: assumes ld: "LeftDerivationLadder α D L γ" shows "ladder_last_j L < length γ" proof - have "length L - 1 < length L" using LeftDerivationLadder_def assms is_ladder_def by auto from ladder_j_bound[OF ld this] show ?thesis by (metis Derive LeftDerivationLadder_def LeftDerivation_implies_Derivation One_nat_def is_ladder_def ladder_last_j_def last_ladder_γ ld) qed
fun ladder_shift_n :: "nat ==> ladder ==> ladder" where "ladder_shift_n N [] = []" | "ladder_shift_n N ((n, j, i)#L) = ((n - N, j, i)#(ladder_shift_n N L))"
lemma ladder_stepdown_prepare: assumes "length L > 1" shows "L = (ladder_n L 0, ladder_j L 0, ladder_i L 0)#
(ladder_n L 1, ladder_j L 1, ladder_ix L 1)#(drop 2 L)" proof - have "∃ n0 j0 i0 n1 j1 ix1 L'. L = ((n0, j0, i0)#(n1, j1, ix1)#L')" by (metis One_nat_def Suc_eq_plus1 assms ladder_stepdown.cases less_not_refl list.size(3) list.size(4) not_less0) then obtain n0 j0 i0 n1 j1 ix1 L' where L': "L = ((n0, j0, i0)#(n1, j1, ix1)#L')" by blast have n0: "n0 = ladder_n L 0" using L' by (auto simp add: ladder_n_def deriv_n_def) show ?thesis using L' by (auto simp add: ladder_n_def deriv_n_def ladder_j_def deriv_j_def ladder_i_def deriv_i_def ladder_ix_def deriv_ix_def) qed
lemma ladder_stepdown_length: assumes "length L > 1" shows "length (ladder_stepdown L) = length L - 1" apply (subst ladder_stepdown_prepare[OF assms(1)]) apply (simp add: ladder_shift_n_length) using assms apply arith done
lemma ladder_stepdown_i_0: assumes "length L > 1" shows "ladder_i (ladder_stepdown L) 0 = ladder_i L 1 + ladder_ix L 1" using ladder_stepdown_prepare[OF assms] ladder_i_def ladder_j_def deriv_j_def by (metis One_nat_def deriv_i_def diff_Suc_1 ladder_stepdown.simps(3) list.sel(1) snd_conv zero_neq_one)
lemma ladder_shift_n_cons: "ladder_shift_n N (x#L) = (fst x - N, snd x)#(ladder_shift_n N L)" apply (induct L) by (cases x, simp)+
lemma ladder_shift_n_drop: "ladder_shift_n N (drop n L) = drop n (ladder_shift_n N L)" proof (induct L arbitrary: n) case Nil then show ?case by simp next case (Cons x L) show ?case proof (cases n) case 0 then show ?thesis by simp next case (Suc n) then show ?thesis by (simp add: ladder_shift_n_cons Cons) qed qed
lemma drop_2_shift: assumes "index > 0" assumes "length L > 1" shows "drop 2 L ! (index - Suc 0) = L ! Suc index" proof - define l1 l2 and L' where "l1 = L ! 0" "l2 = L ! 1" and "L' = drop 2 L" with ‹length L > 1› have "L = l1 # l2 # L'" by (cases L) (auto simp add: neq_Nil_conv) with ‹index > 0› show ?thesis by simp qed
lemma ladder_shift_n_at: "index<lengthL\<Longrightarrow>(ladder_shift_nNL)!index=(fst(L!index)-N,snd(L!index))" proof(inductLarbitrary:index) caseNilthenshow?casebyauto next case(ConsxL) show?case apply(simpadd:ladder_shift_n_cons) apply(casesindex) apply(auto) apply(rule_tacCons(1)) usingCons(2)byauto qed
lemmaladder_stepdown_j: assumeslength_L_greater_1:"lengthL>1" assumesL':"L'=ladder_stepdownL" assumesindex_bound:"index<lengthL'" shows"ladder_jL'index=ladder_jL(Sucindex)" proof- noteL_prepare=ladder_stepdown_prepare[OFlength_L_greater_1] haveladder_stepdown_L_def:"ladder_stepdownL=((ladder_nL(Suc0)-Suc(ladder_nL0),ladder_jL(Suc0),ladder_jL0+ladder_ixL(Suc0))# ladder_shift_n(Suc(ladder_nL0))(drop2L))" by(substL_prepare,simp) have"index=0\<or>index>0"byarith thenshow"ladder_jL'index=ladder_jL(Sucindex)" proof(inductrule:disjCases2) case1 show?case by(simpadd:L'ladder_stepdown_L_def1ladder_j_defderiv_j_def) next case2 haveindex_bound':"Sucindex<lengthL" usingindex_boundL'ladder_stepdown_lengthlength_L_greater_1byauto show?case apply(simpadd:L'ladder_stepdown_L_def2ladder_j_defladder_shift_n_dropdrop_2_shift) apply(substdrop_2_shift) apply(simpadd:2) usinglength_L_greater_1apply(simpadd:ladder_shift_n_length) apply(simpadd:deriv_j_def) apply(simpadd:ladder_shift_n_at[OFindex_bound']) done qed qed
definitionladder_cut_prefix::"nat\<Rightarrow>ladder\<Rightarrow>ladder" where "ladder_cut_prefixdL= (ladder_shift_jdL)[0:=(ladder_nL0,ladder_jL0-d,ladder_iL0-d)]"
¤ 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.0.268Bemerkung:
(vorverarbeitet am 2026-06-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.