Theory Derivations
theory Derivations
imports
CFG
begin
section βΉAdjusted content from AFP/LocalLexingβΊ
type_synonym 'a derivation = "(nat Γ 'a rule) list"
lemma is_word_empty: "is_word π’ []" by (auto simp add: is_word_def)
lemma derives1_implies_derives[simp]:
"derives1 π’ a b βΉ derives π’ a b"
by (auto simp add: derives_def derivations_def derivations1_def)
lemma derives_trans:
"derives π’ a b βΉ derives π’ b c βΉ derives π’ a c"
by (auto simp add: derives_def derivations_def)
lemma derives1_eq_derivations1:
"derives1 π’ x y = ((x, y) β derivations1 π’)"
by (simp add: derivations1_def)
lemma derives_induct[consumes 1, case_names Base Step]:
assumes derives: "derives π’ a b"
assumes Pa: "P a"
assumes induct: "βy z. derives π’ a y βΉ derives1 π’ y z βΉ P y βΉ P z"
shows "P b"
proof -
note rtrancl_lemma = rtrancl_induct[where a = a and b = b and r = "derivations1 π’" and P=P]
from derives Pa induct rtrancl_lemma show "P b"
by (metis derives_def derivations_def derives1_eq_derivations1)
qed
definition Derives1 :: "'a cfg β 'a list β nat β 'a rule β 'a list β bool" where
"Derives1 π’ u i r v β‘ β x y A Ξ±.
u = x @ [A] @ y β§
v = x @ Ξ± @ y β§
(A, Ξ±) β set (β π’) β§ r = (A, Ξ±) β§ i = length x"
lemma Derives1_split:
"Derives1 π’ u i r v βΉ β x y. u = x @ [fst r] @ y β§ v = x @ (snd r) @ y β§ length x = i"
by (metis Derives1_def fst_conv snd_conv)
lemma Derives1_implies_derives1: "Derives1 π’ u i r v βΉ derives1 π’ u v"
by (auto simp add: Derives1_def derives1_def)
lemma derives1_implies_Derives1: "derives1 π’ u v βΉ β i r. Derives1 π’ u i r v"
by (auto simp add: Derives1_def derives1_def)
fun Derivation :: "'a cfg β 'a list β 'a derivation β 'a list β bool" where
"Derivation _ a [] b = (a = b)"
| "Derivation π’ a (d#D) b = (β x. Derives1 π’ a (fst d) (snd d) x β§ Derivation π’ x D b)"
lemma Derivation_implies_derives: "Derivation π’ a D b βΉ derives π’ a b"
proof (induct D arbitrary: a b)
case Nil thus ?case
by (simp add: derives_def derivations_def)
next
case (Cons d D)
note ihyps = this
from ihyps have "β x. Derives1 π’ a (fst d) (snd d) x β§ Derivation π’ x D b" by auto
then obtain x where "Derives1 π’ a (fst d) (snd d) x" and xb: "Derivation π’ x D b" by blast
with Derives1_implies_derives1 have d1: "derives π’ a x" by fastforce
from ihyps xb have d2:"derives π’ x b" by simp
show "derives π’ a b" by (rule derives_trans[OF d1 d2])
qed
lemma Derivation_Derives1: "Derivation π’ a S y βΉ Derives1 π’ y i r z βΉ Derivation π’ a (S@[(i,r)]) z"
proof (induct S arbitrary: a y z i r)
case Nil thus ?case by simp
next
case (Cons s S) thus ?case
by (metis Derivation.simps(2) append_Cons)
qed
lemma derives_implies_Derivation: "derives π’ a b βΉ β D. Derivation π’ a D b"
proof (induct rule: derives_induct)
case Base
show ?case by (rule exI[where x="[]"], simp)
next
case (Step y z)
note ihyps = this
from ihyps obtain D where ay: "Derivation π’ a D y" by blast
from ihyps derives1_implies_Derives1 obtain i r where yz: "Derives1 π’ y i r z" by blast
from Derivation_Derives1[OF ay yz] show ?case by auto
qed
lemma Derives1_rule [elim]: "Derives1 π’ a i r b βΉ r β set (β π’)"
using Derives1_def by metis
lemma Derivation_append: "Derivation π’ a (D@E) c = (β b. Derivation π’ a D b β§ Derivation π’ b E c)"
by (induct D arbitrary: a c E) auto
lemma Derivation_implies_append:
"Derivation π’ a D b βΉ Derivation π’ b E c βΉ Derivation π’ a (D@E) c"
using Derivation_append by blast
section βΉAdditional derivation lemmasβΊ
lemma Derives1_prepend:
assumes "Derives1 π’ u i r v"
shows "Derives1 π’ (w@u) (i + length w) r (w@v)"
proof -
obtain x y A Ξ± where *:
"u = x @ [A] @ y" "v = x @ Ξ± @ y"
"(A, Ξ±) β set (β π’)" "r = (A, Ξ±)" "i = length x"
using assms Derives1_def by (smt (verit))
hence "w@u = w @ x @ [A] @ y" "w@v = w @ x @ Ξ± @ y"
by auto
thus ?thesis
unfolding Derives1_def using *
apply (rule_tac exI[where x="w@x"])
apply (rule_tac exI[where x="y"])
by simp
qed
lemma Derivation_prepend:
"Derivation π’ b D b' βΉ Derivation π’ (a@b) (map (Ξ»(i, r). (i + length a, r)) D) (a@b')"
using Derives1_prepend by (induction D arbitrary: b b') (auto, fast)
lemma Derives1_append:
assumes "Derives1 π’ u i r v"
shows "Derives1 π’ (u@w) i r (v@w)"
proof -
obtain x y A Ξ± where *:
"u = x @ [A] @ y" "v = x @ Ξ± @ y"
"(A, Ξ±) β set (β π’)" "r = (A, Ξ±)" "i = length x"
using assms Derives1_def by (smt (verit))
hence "u@w = x @ [A] @ y @ w" "v@w = x @ Ξ± @ y @ w"
by auto
thus ?thesis
unfolding Derives1_def using *
apply (rule_tac exI[where x="x"])
apply (rule_tac exI[where x="y@w"])
by blast
qed
lemma Derivation_append':
"Derivation π’ a D a' βΉ Derivation π’ (a@b) D (a'@b)"
using Derives1_append by (induction D arbitrary: a a') (auto, fast)
lemma Derivation_append_rewrite:
assumes "Derivation π’ a D (b @ c @ d) " "Derivation π’ c E c'"
shows "βF. Derivation π’ a F (b @ c' @ d)"
using assms Derivation_append' Derivation_prepend Derivation_implies_append by fast
lemma derives1_if_valid_rule:
"(A, Ξ±) β set (β π’) βΉ derives1 π’ [A] Ξ±"
unfolding derives1_def
apply (rule_tac exI[where x="[]"])
apply (rule_tac exI[where x="[]"])
by simp
lemma derives_if_valid_rule:
"(A, Ξ±) β set (β π’) βΉ derives π’ [A] Ξ±"
using derives1_if_valid_rule by fastforce
lemma Derivation_from_empty:
"Derivation π’ [] D a βΉ a = []"
by (cases D) (auto simp: Derives1_def)
lemma Derivation_concat_split:
"Derivation π’ (a@b) D c βΉ βE F a' b'. Derivation π’ a E a' β§ Derivation π’ b F b' β§
c = a' @ b' β§ length E β€ length D β§ length F β€ length D"
proof (induction D arbitrary: a b)
case Nil
thus ?case
by (metis Derivation.simps(1) order_refl)
next
case (Cons d D)
then obtain ab where *: "Derives1 π’ (a@b) (fst d) (snd d) ab" "Derivation π’ ab D c"
by auto
then obtain x y A Ξ± where #:
"a@b = x @ [A] @ y" "ab = x @ Ξ± @ y" "(A,Ξ±) β set (β π’)" "snd d = (A,Ξ±)" "fst d = length x"
using * unfolding Derives1_def by blast
show ?case
proof (cases "length a β€ length x")
case True
hence ab_def:
"a = take (length a) x"
"b = drop (length a) x @ [A] @ y"
"ab = take (length a) x @ drop (length a) x @ Ξ± @ y"
using #(1,2) True by (metis append_eq_append_conv_if)+
then obtain E F a' b' where IH:
"Derivation π’ (take (length a) x) E a'"
"Derivation π’ (drop (length a) x @ Ξ± @ y) F b'"
"c = a' @ b'"
"length E β€ length D"
"length F β€ length D"
using Cons *(2) by blast
have "Derives1 π’ b (fst d - length a) (snd d) (drop (length a) x @ Ξ± @ y)"
unfolding Derives1_def using *(1) #(3-5) ab_def(2) by (metis length_drop)
hence "Derivation π’ b ((fst d - length a, snd d) # F) b'"
using IH(2) by force
moreover have "Derivation π’ a E a'"
using IH(1) ab_def(1) by fastforce
ultimately show ?thesis
using IH(3-5) by fastforce
next
case False
hence a_def: "a = x @ [A] @ take (length a - length x - 1) y"
using #(1) append_eq_conv_conj[of a b "x @ [A] @ y"] take_all_iff take_append
by (metis append_Cons append_Nil diff_is_0_eq le_cases take_Cons')
hence b_def: "b = drop (length a - length x - 1) y"
using #(1) by (metis List.append.assoc append_take_drop_id same_append_eq)
have "ab = x @ Ξ± @ take (length a - length x - 1) y @ drop (length a - length x - 1) y"
using #(2) by force
then obtain E F a' b' where IH:
"Derivation π’ (x @ Ξ± @ take (length a - length x - 1) y) E a'"
"Derivation π’ (drop (length a - length x - 1) y) F b'"
"c = a' @ b'"
"length E β€ length D"
"length F β€ length D"
using Cons.IH[of "x @ Ξ± @ take (length a - length x - 1) y" "drop (length a - length x - 1) y"] *(2) by auto
have "Derives1 π’ a (fst d) (snd d) (x @ Ξ± @ take (length a - length x - 1) y)"
unfolding Derives1_def using #(3-5) a_def by blast
hence "Derivation π’ a ((fst d, snd d) # E) a'"
using IH(1) by fastforce
moreover have "Derivation π’ b F b'"
using b_def IH(2) by blast
ultimately show ?thesis
using IH(3-5) by fastforce
qed
qed
lemma Derivation_π1:
assumes "Derivation π’ [π π’] D Ο" "is_word π’ Ο"
shows "βΞ± E. Derivation π’ Ξ± E Ο β§ (π π’,Ξ±) β set (β π’)"
proof (cases D)
case Nil
thus ?thesis
using assms by (auto simp: is_word_def nonterminals_def)
next
case (Cons d D)
then obtain Ξ± where "Derives1 π’ [π π’] (fst d) (snd d) Ξ±" "Derivation π’ Ξ± D Ο"
using assms by auto
hence "(π π’, Ξ±) β set (β π’)"
unfolding Derives1_def
by (simp add: Cons_eq_append_conv)
thus ?thesis
using βΉDerivation π’ Ξ± D ΟβΊ by auto
qed
end