lemma state_cnt_pos: "state_cnt r > 0" by (induction r rule: state_cnt.induct) auto
fun collect_subfmlas :: "('a, 'b :: timestamp) regex ==> ('a, 'b) formula list ==> ('a, 'b) formula list"where "collect_subfmlas (Lookahead φ) phis = (if φ ∈ set phis then phis else phis @ [φ])"
| "collect_subfmlas (Symbol φ) phis = (if φ ∈ set phis then phis else phis @ [φ])"
| "collect_subfmlas (Plus r s) phis = collect_subfmlas s (collect_subfmlas r phis)"
| "collect_subfmlas (Times r s) phis = collect_subfmlas s (collect_subfmlas r phis)"
| "collect_subfmlas (Star r) phis = collect_subfmlas r phis"
lemma bf_collect_subfmlas: "bounded_future_regex r ==> phi ∈ set (collect_subfmlas r phis) ==> phi ∈ set phis ∨ bounded_future_fmla phi" by (induction r phis rule: collect_subfmlas.induct) (auto split: if_splits)
lemma collect_subfmlas_atms: "set (collect_subfmlas r phis) = set phis ∪ atms r" by (induction r phis rule: collect_subfmlas.induct) (auto split: if_splits)
lemma collect_subfmlas_set: "set (collect_subfmlas r phis) = set (collect_subfmlas r []) ∪ set phis" proof (induction r arbitrary: phis) case (Plus r1 r2) show ?case using Plus(1)[of phis] Plus(2)[of "collect_subfmlas r1 phis"]
Plus(2)[of "collect_subfmlas r1 []"] by auto next case (Times r1 r2) show ?case using Times(1)[of phis] Times(2)[of "collect_subfmlas r1 phis"]
Times(2)[of "collect_subfmlas r1 []"] by auto next case (Star r) show ?case using Star[of phis] by auto qed auto
lemma collect_subfmlas_size: "x ∈ set (collect_subfmlas r []) ==> size x < size r" proof (induction r) case (Plus r1 r2) thenshow ?case by (auto simp: collect_subfmlas_set[of r2 "collect_subfmlas r1 []"]) next case (Times r1 r2) thenshow ?case by (auto simp: collect_subfmlas_set[of r2 "collect_subfmlas r1 []"]) next case (Star r) thenshow ?case by fastforce qed (auto split: if_splits)
lemma collect_subfmlas_app: "∃phis'. collect_subfmlas r phis = phis @ phis'" by (induction r phis rule: collect_subfmlas.induct) auto
lemma length_collect_subfmlas: "length (collect_subfmlas r phis) ≥ length phis" by (induction r phis rule: collect_subfmlas.induct) auto
fun pos :: "'a ==> 'a list ==> nat option"where "pos a [] = None"
| "pos a (x # xs) = (if a = x then Some 0 else (case pos a xs of Some n ==> Some (Suc n) | _ ==> None))"
lemma pos_sound: "pos a xs = Some i ==> i < length xs ∧ xs ! i = a" by (induction a xs arbitrary: i rule: pos.induct) (auto split: if_splits option.splits)
lemma pos_complete: "pos a xs = None ==> a ∉ set xs" by (induction a xs rule: pos.induct) (auto split: if_splits option.splits)
fun build_nfa_impl :: "('a, 'b :: timestamp) regex ==> (state × state × ('a, 'b) formula list) ==> transition list"where "build_nfa_impl (Lookahead φ) (q0, qf, phis) = (case pos φ phis of Some n ==> [eps_trans qf n] | None ==> [eps_trans qf (length phis)])"
| "build_nfa_impl (Symbol φ) (q0, qf, phis) = (case pos φ phis of Some n ==> [eps_trans (Suc q0) n, symb_trans qf] | None ==> [eps_trans (Suc q0) (length phis), symb_trans qf])"
| "build_nfa_impl (Plus r s) (q0, qf, phis) = ( let ts_r = build_nfa_impl r (q0 + 1, qf, phis); ts_s = build_nfa_impl s (q0 + 1 + state_cnt r, qf, collect_subfmlas r phis) in split_trans (q0 + 1) (q0 + 1 + state_cnt r) # ts_r @ ts_s)"
| "build_nfa_impl (Times r s) (q0, qf, phis) = ( let ts_r = build_nfa_impl r (q0, q0 + state_cnt r, phis); ts_s = build_nfa_impl s (q0 + state_cnt r, qf, collect_subfmlas r phis) in ts_r @ ts_s)"
| "build_nfa_impl (Star r) (q0, qf, phis) = ( let ts_r = build_nfa_impl r (q0 + 1, q0, phis) in split_trans (q0 + 1) qf # ts_r)"
lemma build_nfa_impl_state_cnt: "length (build_nfa_impl r (q0, qf, phis)) = state_cnt r" by (induction r "(q0, qf, phis)" arbitrary: q0 qf phis rule: build_nfa_impl.induct)
(auto split: option.splits)
lemma build_nfa_impl_not_Nil: "build_nfa_impl r (q0, qf, phis) ≠ []" by (induction r "(q0, qf, phis)" arbitrary: q0 qf phis rule: build_nfa_impl.induct)
(auto split: option.splits)
lemma build_nfa_impl_state_set: "t ∈ set (build_nfa_impl r (q0, qf, phis)) ==> state_set t ⊆ {q0..<q0 + length (build_nfa_impl r (q0, qf, phis))} ∪ {qf}" by (induction r "(q0, qf, phis)" arbitrary: q0 qf phis t rule: build_nfa_impl.induct)
(fastforce simp add: build_nfa_impl_state_cnt state_cnt_pos build_nfa_impl_not_Nil
split: option.splits)+
lemma build_nfa_impl_fmla_set: "t ∈ set (build_nfa_impl r (q0, qf, phis)) ==> n ∈ fmla_set t ==> n < length (collect_subfmlas r phis)" proof (induction r "(q0, qf, phis)" arbitrary: q0 qf phis t rule: build_nfa_impl.induct) case (1 φ q0 qf phis) thenshow ?case using pos_sound pos_complete by (force split: option.splits) next case (2 φ q0 qf phis) thenshow ?case using pos_sound pos_complete by (force split: option.splits) next case (3 r s q0 qf phis) thenshow ?case using length_collect_subfmlas dual_order.strict_trans1 by fastforce next case (4 r s q0 qf phis) thenshow ?case using length_collect_subfmlas dual_order.strict_trans1 by fastforce next case (5 r q0 qf phis) thenshow ?case using length_collect_subfmlas dual_order.strict_trans1 by fastforce qed
context MDL begin
definition"IH r q0 qf phis transs bss bs i ≡ let n = length (collect_subfmlas r phis) in transs = build_nfa_impl r (q0, qf, phis) ∧ (∀cs ∈ set bss. length cs ≥ n) ∧ length bs ≥ n ∧ qf ∉ NFA.SQ q0 (build_nfa_impl r (q0, qf, phis)) ∧ (∀k < n. (bs ! k ⟷ sat (collect_subfmlas r phis ! k) (i + length bss))) ∧ (∀j < length bss. ∀k < n. ((bss ! j) ! k ⟷ sat (collect_subfmlas r phis ! k) (i + j)))"
lemma nfa_correct: "IH r q0 qf phis transs bss bs i ==> NFA.run_accept_eps q0 qf transs {q0} bss bs ⟷ (i, i + length bss) ∈ match r" proof (induct r arbitrary: q0 qf phis transs bss bs i rule: regex_induct) case (Lookahead φ) have qf_not_in_SQ: "qf ∉ NFA.SQ q0 transs" using Lookahead unfolding IH_def by (auto simp: Let_def) have qf_not_q0_Suc_q0: "qf ∉ {q0}" using Lookahead unfolding IH_def by (auto simp: NFA.SQ_def split: option.splits) have transs_def: "transs = build_nfa_impl (Lookahead φ) (q0, qf, phis)" using Lookahead(1) by (auto simp: Let_def IH_def) interpret base: nfa q0 qf transs apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding IH_def NFA.Q_def NFA.SQ_def transs_def by (auto split: option.splits)
define n where"n ≡ case pos φ phis of Some n ==> n | _ ==> length phis" thenhave collect: "n < length (collect_subfmlas (Lookahead φ) phis)" "(collect_subfmlas (Lookahead φ) phis) ! n = φ" using pos_sound pos_complete by (force split: option.splits)+ have"∧cs q. base.step_eps cs q0 q ⟷ n < length cs ∧ cs ! n ∧ q = qf""∧cs q. ¬base.step_eps cs qf q" using base.q0_sub_SQ qf_not_in_SQ by (auto simp: NFA.step_eps_def transs_def n_def split: option.splits) thenhave base_eps: "base.step_eps_closure_set {q0} cs = (if n < length cs ∧ cs ! n then {q0, qf} else {q0})"for cs using NFA.step_eps_closure_set_unfold[where ?X="{qf}"] using NFA.step_eps_closure_set_step_id[where ?R="{q0}"] using NFA.step_eps_closure_set_step_id[where ?R="{qf}"] by auto have base_delta: "base.delta {q0} cs = {}"for cs unfolding NFA.delta_def NFA.step_symb_set_def base_eps by (auto simp: NFA.step_symb_def NFA.SQ_def transs_def split: option.splits) show ?case proof (cases bss) case Nil have sat: "n < length bs ∧ bs ! n ⟷ sat φ i" using Lookahead(1) collect by (auto simp: Let_def IH_def Nil) show ?thesis using qf_not_q0_Suc_q0 unfolding NFA.run_accept_eps_def NFA.run_def NFA.accept_eps_def Nil by (auto simp: base_eps sat) next case bss_def: (Cons cs css) show ?thesis using NFA.run_accept_eps_empty unfolding NFA.run_accept_eps_def NFA.run_def NFA.accept_eps_def bss_def by (auto simp: bss_def base_delta) qed next case (Symbol φ) have qf_not_in_SQ: "qf ∉ NFA.SQ q0 transs" using Symbol unfolding IH_def by (auto simp: Let_def) have qf_not_q0_Suc_q0: "qf ∉ {q0, Suc q0}" using Symbol unfolding IH_def by (auto simp: NFA.SQ_def split: option.splits) have transs_def: "transs = build_nfa_impl (Symbol φ) (q0, qf, phis)" using Symbol(1) by (auto simp: Let_def IH_def) interpret base: nfa q0 qf transs apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding IH_def NFA.Q_def NFA.SQ_def transs_def by (auto split: option.splits)
define n where"n ≡ case pos φ phis of Some n ==> n | _ ==> length phis" thenhave collect: "n < length (collect_subfmlas (Symbol φ) phis)" "(collect_subfmlas (Symbol φ) phis) ! n = φ" using pos_sound pos_complete by (force split: option.splits)+ have"∧cs q. base.step_eps cs q0 q ⟷ n < length cs ∧ cs ! n ∧ q = Suc q0""∧cs q. ¬base.step_eps cs (Suc q0) q" using base.q0_sub_SQ by (auto simp: NFA.step_eps_def transs_def n_def split: option.splits) thenhave base_eps: "base.step_eps_closure_set {q0} cs = (if n < length cs ∧ cs ! n then {q0, Suc q0} else {q0})"for cs using NFA.step_eps_closure_set_unfold[where ?X="{Suc q0}"] using NFA.step_eps_closure_set_step_id[where ?R="{q0}"] using NFA.step_eps_closure_set_step_id[where ?R="{Suc q0}"] by auto have base_delta: "base.delta {q0} cs = (if n < length cs ∧ cs ! n then {qf} else {})"for cs unfolding NFA.delta_def NFA.step_symb_set_def base_eps by (auto simp: NFA.step_symb_def NFA.SQ_def transs_def split: option.splits) show ?case proof (cases bss) case Nil show ?thesis using qf_not_q0_Suc_q0 unfolding NFA.run_accept_eps_def NFA.run_def NFA.accept_eps_def Nil by (auto simp: base_eps) next case bss_def: (Cons cs css) have sat: "n < length cs ∧ cs ! n ⟷ sat φ i" using Symbol(1) collect by (auto simp: Let_def IH_def bss_def) show ?thesis proof (cases css) case Nil show ?thesis unfolding NFA.run_accept_eps_def NFA.run_def NFA.accept_eps_def bss_def Nil by (auto simp: base_delta sat NFA.step_eps_closure_set_def NFA.step_eps_closure_def) next case css_def: (Cons ds dss) have"base.delta {} ds = {}""base.delta {qf} ds = {}" using base.step_eps_closure_qf qf_not_in_SQ step_symb_dest by (fastforce simp: NFA.delta_def NFA.step_eps_closure_set_def NFA.step_symb_set_def)+ thenshow ?thesis using NFA.run_accept_eps_empty unfolding NFA.run_accept_eps_def NFA.run_def NFA.accept_eps_def bss_def css_def by (auto simp: base_delta) qed qed next case (Plus r s) obtain phis' where collect: "collect_subfmlas (Plus r s) phis = collect_subfmlas r phis @ phis'" using collect_subfmlas_app by auto have qf_not_in_SQ: "qf ∉ NFA.SQ q0 (build_nfa_impl (Plus r s) (q0, qf, phis))" using Plus unfolding IH_def by auto interpret base: nfa q0 qf "build_nfa_impl (Plus r s) (q0, qf, phis)" apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt by fast+ interpret left: nfa "q0 + 1" qf "build_nfa_impl r (q0 + 1, qf, phis)" apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt by fastforce+ interpret right: nfa "q0 + 1 + state_cnt r" qf "build_nfa_impl s (q0 + 1 + state_cnt r, qf, collect_subfmlas r phis)" apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt by fastforce+ from Plus(3) have"IH r (q0 + 1) qf phis (build_nfa_impl r (q0 + 1, qf, phis)) bss bs i" unfolding Let_def IH_def collect using left.qf_not_in_SQ by (auto simp: nth_append) thenhave left_IH: "left.run_accept_eps {q0 + 1} bss bs ⟷ (i, i + length bss) ∈ match r" using Plus(1) build_nfa_impl_state_cnt by auto have"IH s (q0 + 1 + state_cnt r) qf (collect_subfmlas r phis) (build_nfa_impl s (q0 + 1 + state_cnt r, qf, collect_subfmlas r phis)) bss bs i" using right.qf_not_in_SQ IH_def Plus by (auto simp: Let_def) thenhave right_IH: "right.run_accept_eps {q0 + 1 + state_cnt r} bss bs ⟷ (i, i + length bss) ∈ match s" using Plus(2) build_nfa_impl_state_cnt by auto interpret cong: nfa_cong_Plus q0 "q0 + 1""q0 + 1 + state_cnt r" qf qf qf "build_nfa_impl (Plus r s) (q0, qf, phis)""build_nfa_impl r (q0 + 1, qf, phis)" "build_nfa_impl s (q0 + 1 + state_cnt r, qf, collect_subfmlas r phis)" apply unfold_locales unfolding NFA.SQ_def build_nfa_impl_state_cnt
NFA.step_eps_def NFA.step_symb_def by (auto simp add: nth_append build_nfa_impl_state_cnt) show ?case using cong.run_accept_eps_cong left_IH right_IH Plus by (auto simp: Let_def IH_def) next case (Times r s) obtain phis' where collect: "collect_subfmlas (Times r s) phis = collect_subfmlas r phis @ phis'" using collect_subfmlas_app by auto have transs_def: "transs = build_nfa_impl (Times r s) (q0, qf, phis)" using Times unfolding IH_def by (auto simp: Let_def) have qf_not_in_SQ: "qf ∉ NFA.SQ q0 (build_nfa_impl (Times r s) (q0, qf, phis))" using Times unfolding IH_def by auto interpret base: nfa q0 qf "build_nfa_impl (Times r s) (q0, qf, phis)" apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt by fast+ interpret left: nfa "q0""q0 + state_cnt r""build_nfa_impl r (q0, q0 + state_cnt r, phis)" apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt by fastforce+ interpret right: nfa "q0 + state_cnt r" qf "build_nfa_impl s (q0 + state_cnt r, qf, collect_subfmlas r phis)" apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt by fastforce+ from Times(3) have left_IH: "IH r q0 (q0 + state_cnt r) phis (build_nfa_impl r (q0 , q0 + state_cnt r, phis)) bss bs i" unfolding Let_def IH_def collect using left.qf_not_in_SQ by (auto simp: nth_append) from Times(3) have left_IH_take: "∧n. n < length bss ==> IH r q0 (q0 + state_cnt r) phis (build_nfa_impl r (q0, q0 + state_cnt r, phis)) (take n bss) (hd (drop n bss)) i" unfolding Let_def IH_def collect using left.qf_not_in_SQ apply (auto simp: nth_append min_absorb2 hd_drop_conv_nth) apply (meson in_set_takeD le_add1 le_trans) by (meson le_add1 le_trans nth_mem) have left_IH_match: "left.run_accept_eps {q0} bss bs ⟷ (i, i + length bss) ∈ match r" using Times(1) build_nfa_impl_state_cnt left_IH by auto have left_IH_match_take: "∧n. n < length bss ==> left.run_accept_eps {q0} (take n bss) (hd (drop n bss)) ⟷ (i, i + n) ∈ match r" using Times(1) build_nfa_impl_state_cnt left_IH_take by (fastforce simp add: nth_append min_absorb2) have"IH s (q0 + state_cnt r) qf (collect_subfmlas r phis) (build_nfa_impl s (q0 + state_cnt r, qf, collect_subfmlas r phis)) bss bs i" using right.qf_not_in_SQ IH_def Times by (auto simp: Let_def) thenhave right_IH: "∧n. n ≤ length bss ==> IH s (q0 + state_cnt r) qf (collect_subfmlas r phis) (build_nfa_impl s (q0 + state_cnt r, qf, collect_subfmlas r phis)) (drop n bss) bs (i + n)" unfolding Let_def IH_def by (auto simp: nth_append add.assoc) (meson in_set_dropD) have right_IH_match: "∧n. n ≤ length bss ==> right.run_accept_eps {q0 + state_cnt r} (drop n bss) bs ⟷ (i + n, i + length bss) ∈ match s" using Times(2)[OF right_IH] build_nfa_impl_state_cnt by (auto simp: IH_def) interpret cong: nfa_cong_Times q0 "q0 + state_cnt r" qf "build_nfa_impl (Times r s) (q0, qf, phis)" "build_nfa_impl r (q0, q0 + state_cnt r, phis)" "build_nfa_impl s (q0 + state_cnt r, qf, collect_subfmlas r phis)" apply unfold_locales using NFA.Q_def NFA.SQ_def NFA.step_eps_def NFA.step_symb_def build_nfa_impl_state_set by (fastforce simp add: nth_append build_nfa_impl_state_cnt build_nfa_impl_not_Nil
state_cnt_pos)+ have right_IH_Nil: "right.run_accept_eps {q0 + state_cnt r} [] bs ⟷ (i + length bss, i + length bss) ∈ match s" using right_IH_match by fastforce show ?case unfolding match_Times transs_def cong.run_accept_eps_cong left_IH_match right_IH_Nil using left_IH_match_take right_IH_match less_imp_le_nat le_eq_less_or_eq by auto next case (Star r) thenshow ?case proof (induction"length bss" arbitrary: bss bs i rule: nat_less_induct) case1 have transs_def: "transs = build_nfa_impl (Star r) (q0, qf, phis)" using1unfolding IH_def by (auto simp: Let_def) have qf_not_in_SQ: "qf ∉ NFA.SQ q0 (build_nfa_impl (Star r) (q0, qf, phis))" using1unfolding IH_def by auto interpret base: nfa q0 qf "build_nfa_impl (Star r) (q0, qf, phis)" apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt by fast+ interpret left: nfa "q0 + 1" q0 "build_nfa_impl r (q0 + 1, q0, phis)" apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt by fastforce+ from1(3) have left_IH: "IH r (q0 + 1) q0 phis (build_nfa_impl r (q0 + 1, q0, phis)) bss bs i" using left.qf_not_in_SQ unfolding Let_def IH_def by (auto simp add: nth_append) from1(3) have left_IH_take: "∧n. n < length bss ==> IH r (q0 + 1) q0 phis (build_nfa_impl r (q0 + 1, q0, phis)) (take n bss) (hd (drop n bss)) i" using left.qf_not_in_SQ unfolding Let_def IH_def by (auto simp add: nth_append min_absorb2 hd_drop_conv_nth) (meson in_set_takeD) have left_IH_match: "left.run_accept_eps {q0 + 1} bss bs ⟷ (i, i + length bss) ∈ match r" using1(2) left_IH unfolding build_nfa_impl_state_cnt NFA.SQ_def by auto have left_IH_match_take: "∧n. n < length bss ==> left.run_accept_eps {q0 + 1} (take n bss) (hd (drop n bss)) ⟷ (i, i + n) ∈ match r" using1(2) left_IH_take unfolding build_nfa_impl_state_cnt NFA.SQ_def by (fastforce simp add: nth_append min_absorb2) interpret cong: nfa_cong_Star q0 "q0 + 1" qf "build_nfa_impl (Star r) (q0, qf, phis)" "build_nfa_impl r (q0 + 1, q0, phis)" apply unfold_locales unfolding NFA.SQ_def build_nfa_impl_state_cnt NFA.step_eps_def NFA.step_symb_def by (auto simp add: nth_append build_nfa_impl_state_cnt) show ?case using cong.run_accept_eps_Nil proof (cases bss) case Nil show ?thesis unfolding transs_def Nil using cong.run_accept_eps_Nil run_Nil run_accept_eps_Nil by auto next case (Cons cs css) have aux: "∧n j x P. n < x ==> j < x - n ==> (∀j < Suc x. P j) ==> P (Suc (n + j))" by auto from1(3) have star_IH: "∧n. n < length css ==> IH (Star r) q0 qf phis transs (drop n css) bs (i + n + 1)" unfolding Cons Let_def IH_def using aux[of _ _ _ "λj. ∀k<length (collect_subfmlas r phis). (cs # css) ! j ! k = sat (collect_subfmlas r phis ! k) (i + j)"] by (auto simp add: nth_append add.assoc dest: in_set_dropD) have IH_inst: "∧xs i. length xs ≤ length css ==> IH (Star r) q0 qf phis transs xs bs i ⟶ (base.run_accept_eps {q0} xs bs ⟷ (i, i + length xs) ∈ match (Star r))" using1 unfolding Cons by (auto simp add: nth_append less_Suc_eq_le transs_def) have"∧n. n < length css ==> base.run_accept_eps {q0} (drop n css) bs ⟷ (i + n + 1, i + length (cs # css)) ∈ match (Star r)" proof - fix n assume assm: "n < length css" thenshow"base.run_accept_eps {q0} (drop n css) bs ⟷ (i + n + 1, i + length (cs # css)) ∈ match (Star r)" using IH_inst[of "drop n css""i + n + 1"] star_IH by (auto simp add: nth_append) qed thenshow ?thesis using match_Star length_Cons Cons cong.run_accept_eps_cong_Cons using cong.run_accept_eps_Nil left_IH_match left_IH_match_take apply (auto simp add: Cons transs_def) apply (metis Suc_less_eq add_Suc_right drop_Suc_Cons less_imp_le_nat take_Suc_Cons) apply (metis Suc_less_eq add_Suc_right drop_Suc_Cons le_eq_less_or_eq lessThan_iff
take_Suc_Cons) done qed qed qed
lemma step_eps_closure_set_empty_list: assumes"wf_regex r""IH r q0 qf phis transs bss bs i""NFA.step_eps_closure q0 transs bs q qf" shows"NFA.step_eps_closure q0 transs [] q qf" using assms proof (induction r arbitrary: q0 qf phis transs q) case (Symbol φ) have qf_not_in_SQ: "qf ∉ NFA.SQ q0 transs" using Symbol unfolding IH_def by (auto simp: Let_def) have qf_not_q0_Suc_q0: "qf ∉ {q0, Suc q0}" using Symbol unfolding IH_def by (auto simp: NFA.SQ_def split: option.splits) have transs_def: "transs = build_nfa_impl (Symbol φ) (q0, qf, phis)" using Symbol(2) by (auto simp: Let_def IH_def) interpret base: nfa q0 qf transs apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding IH_def NFA.Q_def NFA.SQ_def transs_def by (auto split: option.splits)
define n where"n ≡ case pos φ phis of Some n ==> n | _ ==> length phis" thenhave collect: "n < length (collect_subfmlas (Symbol φ) phis)" "(collect_subfmlas (Symbol φ) phis) ! n = φ" using pos_sound pos_complete by (force split: option.splits)+ have SQD: "q ∈ NFA.SQ q0 transs ==> q = q0 ∨ q = Suc q0"for q by (auto simp: NFA.SQ_def transs_def split: option.splits) have"¬base.step_eps cs q qf"if"q ∈ NFA.SQ q0 transs"for cs q using SQD[OF that] qf_not_q0_Suc_q0 by (auto simp: NFA.step_eps_def transs_def split: option.splits transition.splits) thenshow ?case using Symbol(3) by (auto simp: NFA.step_eps_closure_def) (metis rtranclp.simps step_eps_dest) next case (Plus r s) have transs_def: "transs = build_nfa_impl (Plus r s) (q0, qf, phis)" using Plus(4) by (auto simp: IH_def Let_def)
define ts_l where"ts_l = build_nfa_impl r (q0 + 1, qf, phis)"
define ts_r where"ts_r = build_nfa_impl s (q0 + 1 + state_cnt r, qf, collect_subfmlas r phis)" have len_ts: "length ts_l = state_cnt r""length ts_r = state_cnt s""length transs = Suc (state_cnt r + state_cnt s)" by (auto simp: ts_l_def ts_r_def transs_def build_nfa_impl_state_cnt) have transs_eq: "transs = split_trans (q0 + 1) (q0 + 1 + state_cnt r) # ts_l @ ts_r" by (auto simp: transs_def ts_l_def ts_r_def) have ts_nonempty: "ts_l = [] ==> False""ts_r = [] ==> False" by (auto simp: ts_l_def ts_r_def build_nfa_impl_not_Nil) obtain phis' where collect: "collect_subfmlas (Plus r s) phis = collect_subfmlas r phis @ phis'" using collect_subfmlas_app by auto have qf_not_in_SQ: "qf ∉ NFA.SQ q0 (build_nfa_impl (Plus r s) (q0, qf, phis))" using Plus unfolding IH_def by auto interpret base: nfa q0 qf transs apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt transs_def by fast+ interpret left: nfa "Suc q0" qf ts_l apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt ts_l_def by fastforce+ interpret right: nfa "Suc (q0 + state_cnt r)" qf ts_r apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt ts_r_def by fastforce+ interpret cong: nfa_cong_Plus q0 "Suc q0""Suc (q0 + state_cnt r)" qf qf qf transs ts_l ts_r apply unfold_locales unfolding NFA.SQ_def build_nfa_impl_state_cnt
NFA.step_eps_def NFA.step_symb_def transs_def ts_l_def ts_r_def by (auto simp add: nth_append build_nfa_impl_state_cnt) have"IH s (Suc (q0 + state_cnt r)) qf (collect_subfmlas r phis) ts_r bss bs i" using right.qf_not_in_SQ IH_def Plus by (auto simp: Let_def ts_r_def) thenhave case_right: "base.step_eps_closure [] q qf"if"base.step_eps_closure bs q qf""q ∈ right.Q"for q using cong.right.eps_nfa'_step_eps_closure[OF that] Plus(2,3) cong.right.nfa'_eps_step_eps_closure[OF _ that(2)] by auto from Plus(4) have"IH r (Suc q0) qf phis ts_l bss bs i" using left.qf_not_in_SQ unfolding Let_def IH_def collect ts_l_def by (auto simp: nth_append) thenhave case_left: "base.step_eps_closure [] q qf"if"base.step_eps_closure bs q qf""q ∈ left.Q"for q using cong.eps_nfa'_step_eps_closure[OF that] Plus(1,3) cong.nfa'_eps_step_eps_closure[OF _ that(2)] by auto have"q = q0 ∨ q ∈ left.Q ∨ q ∈ right.Q" using Plus(5) by (auto simp: NFA.Q_def NFA.SQ_def len_ts dest!: NFA.step_eps_closure_dest) moreoverhave ?caseif q_q0: "q = q0" proof - have"q0 ≠ qf" using qf_not_in_SQ by (auto simp: NFA.SQ_def) thenobtain q' where q'_def: "base.step_eps bs q q'""base.step_eps_closure bs q' qf" using Plus(5) by (auto simp: q_q0 NFA.step_eps_closure_def elim: converse_rtranclpE) have fst_step_eps: "base.step_eps [] q q'" using q'_def(1) by (auto simp: q_q0 NFA.step_eps_def transs_eq) have"q' ∈ left.Q ∨ q' ∈ right.Q" using q'_def(1) by (auto simp: NFA.step_eps_def NFA.Q_def NFA.SQ_def q_q0 transs_eq dest: ts_nonempty split: transition.splits) thenshow ?case using fst_step_eps case_left[OF q'_def(2)] case_right[OF q'_def(2)] by (auto simp: NFA.step_eps_closure_def) qed ultimatelyshow ?case using Plus(5) case_left case_right by auto next case (Times r s) obtain phis' where collect: "collect_subfmlas (Times r s) phis = collect_subfmlas r phis @ phis'" using collect_subfmlas_app by auto have transs_def: "transs = build_nfa_impl (Times r s) (q0, qf, phis)" using Times unfolding IH_def by (auto simp: Let_def)
define ts_l where"ts_l = build_nfa_impl r (q0, q0 + state_cnt r, phis)"
define ts_r where"ts_r = build_nfa_impl s (q0 + state_cnt r, qf, collect_subfmlas r phis)" have len_ts: "length ts_l = state_cnt r""length ts_r = state_cnt s""length transs = state_cnt r + state_cnt s" by (auto simp: ts_l_def ts_r_def transs_def build_nfa_impl_state_cnt) have transs_eq: "transs = ts_l @ ts_r" by (auto simp: transs_def ts_l_def ts_r_def) have ts_nonempty: "ts_l = [] ==> False""ts_r = [] ==> False" by (auto simp: ts_l_def ts_r_def build_nfa_impl_not_Nil) have qf_not_in_SQ: "qf ∉ NFA.SQ q0 (build_nfa_impl (Times r s) (q0, qf, phis))" using Times unfolding IH_def by auto interpret base: nfa q0 qf transs apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt transs_def by fast+ interpret left: nfa "q0""q0 + state_cnt r" ts_l apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt ts_l_def by fastforce+ interpret right: nfa "q0 + state_cnt r" qf ts_r apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt ts_r_def by fastforce+ interpret cong: nfa_cong_Times q0 "q0 + state_cnt r" qf transs ts_l ts_r apply unfold_locales using NFA.Q_def NFA.SQ_def NFA.step_eps_def NFA.step_symb_def build_nfa_impl_state_set by (auto simp add: nth_append build_nfa_impl_state_cnt build_nfa_impl_not_Nil
state_cnt_pos len_ts transs_eq) have"qf ∉ base.SQ" using Times(4) by (auto simp: IH_def Let_def) thenhave qf_left_Q: "qf ∈ left.Q ==> False" by (auto simp: NFA.Q_def NFA.SQ_def len_ts state_cnt_pos) have left_IH: "IH r q0 (q0 + state_cnt r) phis ts_l bss bs i" using left.qf_not_in_SQ Times unfolding Let_def IH_def collect by (auto simp: nth_append ts_l_def) have case_left: "base.step_eps_closure [] q (q0 + state_cnt r)"if"left.step_eps_closure bs q (q0 + state_cnt r)""q ∈ left.Q"and wf: "wf_regex r"for q using that(1) Times(1)[OF wf left_IH] cong.nfa'_step_eps_closure_cong[OF _ that(2)] by auto have left_IH: "IH s (q0 + state_cnt r) qf (collect_subfmlas r phis) ts_r bss bs i" using right.qf_not_in_SQ IH_def Times by (auto simp: Let_def ts_r_def) thenhave case_right: "base.step_eps_closure [] q qf"if"base.step_eps_closure bs q qf""q ∈ right.Q"for q using cong.right.eps_nfa'_step_eps_closure[OF that] Times(2,3) cong.right.nfa'_eps_step_eps_closure[OF _ that(2)] by auto have init_right: "q0 + state_cnt r ∈ right.Q" by (auto simp: NFA.Q_def NFA.SQ_def dest: ts_nonempty)
{ assume q_left_Q: "q ∈ left.Q" thenhave split: "left.step_eps_closure bs q (q0 + state_cnt r)""base.step_eps_closure bs (q0 + state_cnt r) qf" using cong.eps_nfa'_step_eps_closure_cong[OF Times(5)] by (auto dest: qf_left_Q) have empty_IH: "IH s (q0 + state_cnt r) qf (collect_subfmlas r phis) ts_r [] bs (i + length bss)" using left_IH by (auto simp: IH_def Let_def ts_r_def) have"right.step_eps_closure bs (q0 + state_cnt r) qf" using cong.right.eps_nfa'_step_eps_closure[OF split(2) init_right] by auto thenhave"right.run_accept_eps {q0 + state_cnt r} [] bs" by (auto simp: NFA.run_accept_eps_def NFA.accept_eps_def NFA.step_eps_closure_set_def NFA.run_def) thenhave wf: "wf_regex r" using nfa_correct[OF empty_IH] Times(3) match_refl_eps by auto have ?case using case_left[OF split(1) q_left_Q wf] case_right[OF split(2) init_right] by (auto simp: NFA.step_eps_closure_def)
} moreoverhave"q ∈ left.Q ∨ q ∈ right.Q" using Times(5) by (auto simp: NFA.Q_def NFA.SQ_def transs_eq len_ts dest!: NFA.step_eps_closure_dest) ultimatelyshow ?case using case_right[OF Times(5)] by auto next case (Star r) have transs_def: "transs = build_nfa_impl (Star r) (q0, qf, phis)" using Star unfolding IH_def by (auto simp: Let_def) obtain ts_r where ts_r: "transs = split_trans (q0 + 1) qf # ts_r""ts_r = build_nfa_impl r (Suc q0, q0, phis)" using Star(3) by (auto simp: Let_def IH_def) have qf_not_in_SQ: "qf ∉ NFA.SQ q0 transs" using Star unfolding IH_def transs_def by auto interpret base: nfa q0 qf transs apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt transs_def by fast+ interpret left: nfa "Suc q0" q0 ts_r apply unfold_locales using build_nfa_impl_state_set build_nfa_impl_not_Nil qf_not_in_SQ unfolding NFA.Q_def NFA.SQ_def build_nfa_impl_state_cnt ts_r(2) by fastforce+ interpret cong: nfa_cong_Star q0 "Suc q0" qf transs ts_r apply unfold_locales unfolding NFA.SQ_def build_nfa_impl_state_cnt NFA.step_eps_def NFA.step_symb_def by (auto simp add: nth_append build_nfa_impl_state_cnt ts_r(1)) have IH: "wf_regex r""IH r (Suc q0) q0 phis ts_r bss bs i" using Star(2,3) by (auto simp: Let_def IH_def NFA.SQ_def ts_r(2)) have step_eps_q'_qf: "q' = q0"if"base.step_eps bs q' qf"for q' proof (rule ccontr) assume"q' ≠ q0" thenhave"q' ∈ left.SQ" using that by (auto simp: NFA.step_eps_def NFA.SQ_def ts_r(1)) thenhave"left.step_eps bs q' qf" using cong.step_eps_cong_SQ that by simp thenshow"False" using qf_not_in_SQ by (metis NFA.Q_def UnE base.q0_sub_SQ cong.SQ_sub left.step_eps_closed subset_eq) qed show ?case proof (cases "q = qf") case False thenhave base_q_q0: "base.step_eps_closure bs q q0""base.step_eps bs q0 qf" using Star(4) step_eps_q'_qf by (auto simp: NFA.step_eps_closure_def) (metis rtranclp.cases)+ have base_Nil_q0_qf: "base.step_eps [] q0 qf" by (auto simp: NFA.step_eps_def NFA.SQ_def ts_r(1)) have q_left_Q: "q ∈ left.Q" using base_q_q0 by (auto simp: NFA.Q_def NFA.SQ_def ts_r(1) dest: step_eps_closure_dest) have"left.step_eps_closure [] q q0" using cong.eps_nfa'_step_eps_closure_cong[OF base_q_q0(1) q_left_Q] Star(1)[OF IH] by auto thenshow ?thesis using cong.nfa'_step_eps_closure_cong[OF _ q_left_Q] base_Nil_q0_qf by (auto simp: NFA.step_eps_closure_def) (meson rtranclp.rtrancl_into_rtrancl) qed (auto simp: NFA.step_eps_closure_def) qed auto
lemma accept_eps_iff_accept: assumes"wf_regex r""IH r q0 qf phis transs bss bs i" shows"NFA.accept_eps q0 qf transs R bs = NFA.accept q0 qf transs R" using step_eps_closure_set_empty_list[OF assms] step_eps_closure_set_mono' unfolding NFA.accept_eps_def NFA.accept_def by (fastforce simp: NFA.accept_eps_def NFA.accept_def NFA.step_eps_closure_set_def)
definition pred_option' :: "('a ==> bool) ==> 'a option ==> bool"where "pred_option' P z = (case z of Some z' ==> P z' | None ==> False)"
definition map_option' :: "('b ==> 'c option) ==> 'b option ==> 'c option"where "map_option' f z = (case z of Some z' ==> f z' | None ==> None)"
definition while_break :: "('a ==> bool) ==> ('a ==> 'a option) ==> 'a ==> 'a option"where "while_break P f x = while (pred_option' P) (map_option' f) (Some x)"
lemma wf_while_break: assumes"wf {(t, s). P s ∧ b s ∧ Some t = c s}" shows"wf {(t, s). pred_option P s ∧ pred_option' b s ∧ t = map_option' c s}" proof - have sub: "{(t, s). pred_option P s ∧ pred_option' b s ∧ t = map_option' c s} ⊆ map_prod Some Some ` {(t, s). P s ∧ b s ∧ Some t = c s} ∪ ({None} × (Some ` UNIV))" by (auto simp: pred_option'_def map_option'_def split: option.splits)
(smt (z3) case_prodI map_prod_imageI mem_Collect_eq not_Some_eq) show ?thesis apply (rule wf_subset[OF _ sub]) apply (rule wf_union_compatible) apply (rule wf_map_prod_image) apply (fastforce simp: wf_def intro: assms)+ done qed
lemma wf_while_break': assumes"wf {(t, s). P s ∧ b s ∧ Some t = c s}" shows"wf {(t, s). pred_option' P s ∧ pred_option' b s ∧ t = map_option' c s}" by (rule wf_subset[OF wf_while_break[OF assms]]) (auto simp: pred_option'_def split: option.splits)
lemma while_break_sound: assumes"∧s s'. P s ==> b s ==> c s = Some s' ==> P s'""∧s. P s ==>¬ b s ==> Q s""wf {(t, s). P s ∧ b s ∧ Some t = c s}""P s" shows"pred_option Q (while_break b c s)" proof - have aux: "P t ==> b t ==> pred_option P (c t)"for t using assms(1) by (cases "c t") auto show ?thesis using assms aux by (auto simp: while_break_def pred_option'_def map_option'_def split: option.splits
intro!: while_rule_lemma[where ?P="pred_option P"and ?Q="pred_option Q"and ?b="pred_option' b"and ?c="map_option' c", OF _ _ wf_while_break]) qed
lemma while_break_complete: "(∧s. P s ==> b s ==> pred_option' P (c s)) ==> (∧s. P s ==>¬ b s ==> Q s) ==> wf {(t, s). P s ∧ b s ∧ Some t = c s} ==> P s ==> pred_option' Q (while_break b c s)" unfolding while_break_def by (rule while_rule_lemma[where ?P="pred_option' P"and ?Q="pred_option' Q"and ?b="pred_option' b"and ?c="map_option' c", OF _ _ wf_while_break'])
(force simp: pred_option'_def map_option'_def split: option.splits elim!: case_optionE)+
context fixes args :: "(bool iarray, nat set, 'd :: timestamp, 't, 'e) args" begin
abbreviation"reach_w ≡ reach_window args"
qualified definition"in_win = init_window args"
definition valid_window_matchP :: "'d I==> 't ==> 'e ==> ('d × bool iarray) list ==> nat ==> (bool iarray, nat set, 'd, 't, 'e) window ==> bool"where "valid_window_matchP I t0 sub rho j w ⟷ j = w_j w ∧ valid_window args t0 sub rho w ∧ reach_w t0 sub rho (w_i w, w_ti w, w_si w, w_j w, w_tj w, w_sj w) ∧ (case w_read_t args (w_tj w) of None ==> True | Some t ==> (∀l < w_i w. memL (ts_at rho l) t I))"
lemma valid_window_matchP_reach_tj: "valid_window_matchP I t0 sub rho i w ==> reaches_on (w_run_t args) t0 (map fst rho) (w_tj w)" using reach_window_run_tj by (fastforce simp: valid_window_matchP_def simp del: reach_window.simps)
lemma valid_window_matchP_reach_sj: "valid_window_matchP I t0 sub rho i w ==> reaches_on (w_run_sub args) sub (map snd rho) (w_sj w)" using reach_window_run_sj by (fastforce simp: valid_window_matchP_def simp del: reach_window.simps)
lemma valid_window_matchP_len_rho: "valid_window_matchP I t0 sub rho i w ==> length rho = i" by (auto simp: valid_window_matchP_def)
definition"matchP_loop_cond I t = (λw. w_i w < w_j w ∧ memL (the (w_read_t args (w_ti w))) t I)"
definition"matchP_loop_inv I t0 sub rho j0 tj0 sj0 t = (λw. valid_window args t0 sub rho w ∧ w_j w = j0 ∧ w_tj w = tj0 ∧ w_sj w = sj0 ∧ (∀l < w_i w. memL (ts_at rho l) t I))"
fun ex_key :: "('c, 'd) mmap ==> ('d ==> bool) ==> ('c ==> bool) ==> ('c, bool) mapping ==> (bool × ('c, bool) mapping)"where "ex_key [] time accept ac = (False, ac)"
| "ex_key ((q, t) # qts) time accept ac = (if time t then (case cac accept ac q of (β, ac') ==> if β then (True, ac') else ex_key qts time accept ac') else ex_key qts time accept ac)"
lemma ex_key_sound: assumes inv: "∧q. case Mapping.lookup ac q of None ==> True | Some v ==> accept q = v" and distinct: "distinct (map fst qts)" and eval: "ex_key qts time accept ac = (b, ac')" shows"b = (∃q ∈ mmap_keys qts. time (the (mmap_lookup qts q)) ∧ accept q) ∧ (∀q. case Mapping.lookup ac' q of None ==> True | Some v ==> accept q = v)" using assms proof (induction qts arbitrary: ac) case (Cons a qts) obtain q t where qt_def: "a = (q, t)" by fastforce show ?case proof (cases "time t") case True note time_t = True obtain β ac'' where ac''_def: "cac accept ac q = (β, ac'')" by fastforce have accept: "β = accept q""∧q. case Mapping.lookup ac'' q of None ==> True | Some v ==> accept q = v" using ac''_def Cons(2) by (fastforce simp: cac_def Let_def Mapping.lookup_update' split: option.splits if_splits)+ show ?thesis proof (cases β) case True thenshow ?thesis using accept(2) time_t Cons(4) by (auto simp: qt_def mmap_keys_def accept(1) mmap_lookup_def ac''_def) next case False have ex_key: "ex_key qts time accept ac'' = (b, ac')" using Cons(4) time_t False by (auto simp: qt_def ac''_def) show ?thesis using Cons(1)[OF accept(2) _ ex_key] False[unfolded accept(1)] Cons(3) by (auto simp: mmap_keys_def mmap_lookup_def qt_def) qed next case False have ex_key: "ex_key qts time accept ac = (b, ac')" using Cons(4) False by (auto simp: qt_def) show ?thesis using Cons(1)[OF Cons(2) _ ex_key] False Cons(3) by (auto simp: mmap_keys_def mmap_lookup_def qt_def) qed qed (auto simp: mmap_keys_def)
fun eval_matchP :: "'d I==> (bool iarray, nat set, 'd, 't, 'e) window ==> (('d × bool) × (bool iarray, nat set, 'd, 't, 'e) window) option"where "eval_matchP I w = (case w_read_t args (w_tj w) of None ==> None | Some t ==> (case adv_end args w of None ==> None | Some w' ==> let w'' = while (matchP_loop_cond I t) (adv_start args) w'; (β, ac') = ex_key (w_e w'') (λt'. memR t' t I) (w_accept args) (w_ac w'') in Some ((t, β), w''(w_ac := ac'))))"
definition valid_window_matchF :: "'d I==> 't ==> 'e ==> ('d × bool iarray) list ==> nat ==> (bool iarray, nat set, 'd, 't, 'e) window ==> bool"where "valid_window_matchF I t0 sub rho i w ⟷ i = w_i w ∧ valid_window args t0 sub rho w ∧ reach_w t0 sub rho (w_i w, w_ti w, w_si w, w_j w, w_tj w, w_sj w) ∧ (∀l ∈ {w_i w..<w_j w}. memR (ts_at rho i) (ts_at rho l) I)"
lemma valid_window_matchF_reach_tj: "valid_window_matchF I t0 sub rho i w ==> reaches_on (w_run_t args) t0 (map fst rho) (w_tj w)" using reach_window_run_tj by (fastforce simp: valid_window_matchF_def simp del: reach_window.simps)
lemma valid_window_matchF_reach_sj: "valid_window_matchF I t0 sub rho i w ==> reaches_on (w_run_sub args) sub (map snd rho) (w_sj w)" using reach_window_run_sj by (fastforce simp: valid_window_matchF_def simp del: reach_window.simps)
definition"matchF_loop_cond I t = (λw. case w_read_t args (w_tj w) of None ==> False | Some t' ==> memR t t' I)"
definition"matchF_loop_inv I t0 sub rho i ti si tjm sjm = (λw. valid_window args t0 sub (take (w_j w) rho) w ∧ w_i w = i ∧ w_ti w = ti ∧ w_si w = si ∧ reach_window args t0 sub rho (w_j w, w_tj w, w_sj w, length rho, tjm, sjm) ∧ (∀l ∈ {w_i w..<w_j w}. memR (ts_at rho i) (ts_at rho l) I))"
definition"matchF_loop_inv' t0 sub rho i ti si j tj sj = (λw. w_i w = i ∧ w_ti w = ti ∧ w_si w = si ∧ (∃rho'. valid_window args t0 sub (rho @ rho') w ∧ reach_window args t0 sub (rho @ rho') (j, tj, sj, w_j w, w_tj w, w_sj w)))"
fun eval_matchF :: "'d I==> (bool iarray, nat set, 'd, 't, 'e) window ==> (('d × bool) × (bool iarray, nat set, 'd, 't, 'e) window) option"where "eval_matchF I w = (case w_read_t args (w_ti w) of None ==> None | Some t ==> (case while_break (matchF_loop_cond I t) (adv_end args) w of None ==> None | Some w' ==> (case w_read_t args (w_tj w') of None ==> None | Some t' ==> let β = (case snd (the (mmap_lookup (w_s w') {0})) of None ==> False | Some tstp ==> memL t (fst tstp) I) in Some ((t, β), adv_start args w'))))"
end
locale MDL_window = MDL σ for σ :: "('a, 'd :: timestamp) trace" + fixes r :: "('a, 'd :: timestamp) regex" and t0 :: 't and sub :: 'e and args :: "(bool iarray, nat set, 'd, 't, 'e) args" assumes init_def: "w_init args = {0 :: nat}" and step_def: "w_step args = NFA.delta' (IArray (build_nfa_impl r (0, state_cnt r, []))) (state_cnt r)" and accept_def: "w_accept args = NFA.accept' (IArray (build_nfa_impl r (0, state_cnt r, []))) (state_cnt r)" and run_t_sound: "reaches_on (w_run_t args) t0 ts t ==> w_run_t args t = Some (t', x) ==> x = τ σ (length ts)" and run_sub_sound: "reaches_on (w_run_sub args) sub bs s ==> w_run_sub args s = Some (s', b) ==> b = IArray (map (λphi. sat phi (length bs)) (collect_subfmlas r []))" and run_t_read: "w_run_t args t = Some (t', x) ==> w_read_t args t = Some x" and read_t_run: "w_read_t args t = Some x ==>∃t'. w_run_t args t = Some (t', x)" begin
lemma run_t_sound': assumes"reaches_on (w_run_t args) t0 ts t""i < length ts" shows"ts ! i = τ σ i" proof - obtain t' t'' where t'_def: "reaches_on (w_run_t args) t0 (take i ts) t'" "w_run_t args t' = Some (t'', ts ! i)" using reaches_on_split[OF assms] by auto show ?thesis using run_t_sound[OF t'_def] assms(2) by simp qed
lemma run_sub_sound': assumes"reaches_on (w_run_sub args) sub bs s""i < length bs" shows"bs ! i = IArray (map (λphi. sat phi i) (collect_subfmlas r []))" proof - obtain s' s'' where s'_def: "reaches_on (w_run_sub args) sub (take i bs) s'" "w_run_sub args s' = Some (s'', bs ! i)" using reaches_on_split[OF assms] by auto show ?thesis using run_sub_sound[OF s'_def] assms(2) by simp qed
lemma run_ts: "reaches_on (w_run_t args) t ts t' ==> t = t0 ==> chain_le ts" proof (induction t ts t' rule: reaches_on_rev_induct) case (2 s s' v vs s'') show ?case proof (cases vs rule: rev_cases) case (snoc zs z) show ?thesis using2(3)[OF 2(4)] using chain_le_app[OF _ τ_mono[of "length zs""Suc (length zs)" σ]]
run_t_sound'[OF reaches_on_app[OF 2(1,2), unfolded 2(4)], of "length zs"]
run_t_sound'[OF reaches_on_app[OF 2(1,2), unfolded 2(4)], of "Suc (length zs)"] unfolding snoc by (auto simp: nth_append) qed (auto intro: chain_le.intros) qed (auto intro: chain_le.intros)
lemma ts_at_tau: "reaches_on (w_run_t args) t0 (map fst rho) t ==> i < length rho ==> ts_at rho i = τ σ i" using run_t_sound' unfolding ts_at_def by fastforce
lemma length_bs_at: "reaches_on (w_run_sub args) sub (map snd rho) s ==> i < length rho ==> IArray.length (bs_at rho i) = length (collect_subfmlas r [])" using run_sub_sound' unfolding bs_at_def by fastforce
lemma bs_at_nth: "reaches_on (w_run_sub args) sub (map snd rho) s ==> i < length rho ==> n < IArray.length (bs_at rho i) ==> IArray.sub (bs_at rho i) n ⟷ sat (collect_subfmlas r [] ! n) i" using run_sub_sound' unfolding bs_at_def by fastforce
lemma ts_at_mono: "∧i j. reaches_on (w_run_t args) t0 (map fst rho) t ==> i ≤ j ==> j < length rho ==> ts_at rho i ≤ ts_at rho j" using ts_at_tau by fastforce
lemma iarray_list_of: "IArray (IArray.list_of xs) = xs" by (cases xs) auto
lemma map_iarray_list_of: "map IArray (map IArray.list_of bss) = bss" using iarray_list_of by (induction bss) auto
lemma acc_match: fixes ts :: "'d list" assumes"reaches_on (w_run_sub args) sub (map snd rho) s""i ≤ j""j ≤ length rho""wf_regex r" shows"wacc rho {0} (i, j) ⟷ (i, j) ∈ match r" proof - have j_eq: "j = i + length (sub_bs rho (i, j))" using assms by auto
define bs where"bs = map (λphi. sat phi j) (collect_subfmlas r [])" have IH: "IH r 0 qf [] transs (map IArray.list_of (sub_bs rho (i, j))) bs i" unfolding IH_def transs_def qf_def NFA.SQ_def build_nfa_impl_state_cnt bs_def using assms run_sub_sound bs_at_nth length_bs_at by fastforce interpret NFA_array: nfa_array transs "IArray transs" qf by unfold_locales (auto simp: qf_def transs_def build_nfa_impl_state_cnt) have run_run': "NFA_array.run R (map IArray.list_of (sub_bs rho (i, j))) = NFA_array.run' R (sub_bs rho (i, j))"for R using NFA_array.run'_eq[of "sub_bs rho (i, j)""map IArray.list_of (sub_bs rho (i, j))"] unfolding map_iarray_list_of by auto show ?thesis using nfa_correct[OF IH, unfolded NFA.run_accept_def] unfolding run_accept_eps_iff_run_accept[OF assms(4) IH] acc_is_accept NFA.run_accept_def run_run' NFA_array.accept'_eq by (simp add: j_eq[symmetric] accept_def assms(2) qf_def transs_def) qed
lemma accept_match: fixes ts :: "'d list" shows"reaches_on (w_run_sub args) sub (map snd rho) s ==> i ≤ j ==> j ≤ length rho ==> wf_regex r ==> w_accept args (steps (w_step args) rho {0} (i, j)) ⟷ (i, j) ∈ match r" using acc_match acc_is_accept steps_is_run by metis
lemma drop_take_drop: "i ≤ j ==> j ≤ length rho ==> drop i (take j rho) @ drop j rho = drop i rho" apply (induction i arbitrary: j rho) by auto (metis append_take_drop_id diff_add drop_drop drop_take)
lemma take_Suc: "drop n xs = y # ys ==> take n xs @ [y] = take (Suc n) xs" by (metis drop_all list.distinct(1) list.sel(1) not_less take_hd_drop)
lemma valid_init_matchP: "valid_matchP I t0 sub [] 0 (init_window args t0 sub)" using valid_init_window by (fastforce simp: valid_window_matchP_def Let_def intro: reaches_on.intros split: option.splits)
lemma valid_init_matchF: "valid_matchF I t0 sub [] 0 (init_window args t0 sub)" using valid_init_window by (fastforce simp: valid_window_matchF_def Let_def intro: reaches_on.intros split: option.splits)
lemma valid_eval_matchP: assumes valid_before': "valid_matchP I t0 sub rho j w" and before_end: "w_run_t args (w_tj w) = Some (tj''', t)""w_run_sub args (w_sj w) = Some (sj''', b)" and wf: "wf_regex r" shows"∃w'. eval_mP I w = Some ((τ σ j, sat (MatchP I r) j), w') ∧ t = τ σ j ∧ valid_matchP I t0 sub (rho @ [(t, b)]) (Suc j) w'" proof - obtain w' where w'_def: "adv_end args w = Some w'" using before_end by (fastforce simp: adv_end_def Let_def split: prod.splits)
define st where"st = w_st w'"
define i where"i = w_i w'"
define ti where"ti = w_ti w'"
define si where"si = w_si w'"
define tj where"tj = w_tj w'"
define sj where"sj = w_sj w'"
define s where"s = w_s w'"
define e where"e = w_e w'"
define rho' where"rho' = rho @ [(t, b)]" have reaches_on': "reaches_on (w_run_t args) t0 (map fst rho') tj'''" using valid_before' reach_window_run_tj[OF reach_window_app[OF _ before_end]] by (auto simp: valid_window_matchP_def rho'_def) have rho_mono: "∧t'. t' ∈ set (map fst rho) ==> t' ≤ t" using ts_at_mono[OF reaches_on'] nat_less_le by (fastforce simp: rho'_def ts_at_def nth_append in_set_conv_nth split: list.splits) have valid_adv_end_w: "valid_window args t0 sub rho' w'" using valid_before' valid_adv_end[OF _ before_end rho_mono] by (auto simp: valid_window_matchP_def rho'_def w'_def) have w_ij_adv_end: "w_i w' = w_i w""w_j w' = Suc j" using valid_before' w'_def by (auto simp: valid_window_matchP_def adv_end_def Let_def before_end split: prod.splits) have valid_before: "rw t0 sub rho' (i, ti, si, Suc j, tj, sj)" "∧i j. i ≤ j ==> j < length rho' ==> ts_at rho' i ≤ ts_at rho' j" "∀q. mmap_lookup e q = sup_leadsto init step rho' i (Suc j) q" "valid_s init step st accept rho' i i (Suc j) s" "w_j w' = Suc j""i ≤ Suc j" using valid_adv_end_w unfolding valid_window_def Let_def ti_def si_def i_def tj_def sj_def s_def e_def w_ij_adv_end st_def by auto note read_t_def = run_t_read[OF before_end(1)] have t_props: "∀l < i. memL (ts_at rho' l) t I" using valid_before' by (auto simp: valid_window_matchP_def i_def w_ij_adv_end read_t_def rho'_def ts_at_def nth_append)
note reaches_on_tj = reach_window_run_tj[OF valid_before(1)] note reaches_on_sj = reach_window_run_sj[OF valid_before(1)] have length_rho': "length rho' = Suc j""length rho = j" using valid_before by (auto simp: rho'_def) have j_len_rho': "j < length rho'" by (auto simp: length_rho') have tj_eq: "t = τ σ j""t = ts_at rho' j" using run_t_sound'[OF reaches_on_tj, of j] by (auto simp: rho'_def length_rho' nth_append ts_at_def) have bj_def: "b = bs_at rho' j" using run_sub_sound'[OF reaches_on_sj, of j] by (auto simp: rho'_def length_rho' nth_append bs_at_def)
define w'' where loop_def: "w'' = while (matchP_cond I t) (adv_start args) w'" have inv_before: "matchP_inv I t0 sub rho' (Suc j) tj sj t w'" using valid_adv_end_w valid_before t_props unfolding matchP_loop_inv_def by (auto simp: tj_def sj_def i_def) have loop: "matchP_inv I t0 sub rho' (Suc j) tj sj t w'' ∧¬matchP_cond I t w''" unfolding loop_def proof (rule while_rule_lemma[of "matchP_inv I t0 sub rho' (Suc j) tj sj t"]) fix w_cur :: "(bool iarray, nat set, 'd, 't, 'e) window" assume assms: "matchP_inv I t0 sub rho' (Suc j) tj sj t w_cur""matchP_cond I t w_cur"
define st_cur where"st_cur = w_st w_cur"
define i_cur where"i_cur = w_i w_cur"
define ti_cur where"ti_cur = w_ti w_cur"
define si_cur where"si_cur = w_si w_cur"
define s_cur where"s_cur = w_s w_cur"
define e_cur where"e_cur = w_e w_cur" have valid_loop: "rw t0 sub rho' (i_cur, ti_cur, si_cur, Suc j, tj, sj)" "∧i j. i ≤ j ==> j < length rho' ==> ts_at rho' i ≤ ts_at rho' j" "∀q. mmap_lookup e_cur q = sup_leadsto init step rho' i_cur (Suc j) q" "valid_s init step st_cur accept rho' i_cur i_cur (Suc j) s_cur" "w_j w_cur = Suc j" using assms(1)[unfolded matchP_loop_inv_def valid_window_matchP_def] valid_before(6)
ti_cur_def si_cur_def i_cur_def s_cur_def e_cur_def by (auto simp: valid_window_def Let_def init_def step_def st_cur_def accept_def
split: option.splits) obtain ti'_cur si'_cur t_cur b_cur where run_si_cur: "w_run_t args ti_cur = Some (ti'_cur, t_cur)""w_run_sub args si_cur = Some (si'_cur, b_cur)" "t_cur = ts_at rho' i_cur""b_cur = bs_at rho' i_cur" using assms(2) reach_window_run_si[OF valid_loop(1)] reach_window_run_ti[OF valid_loop(1)] unfolding matchP_loop_cond_def valid_loop(5) i_cur_def by auto have"∧l. l < i_cur ==> memL (ts_at rho' l) t I" using assms(1) unfolding matchP_loop_inv_def i_cur_def by auto thenhave"∧l. l < Suc (i_cur) ==> memL (ts_at rho' l) t I" using assms(2) run_t_read[OF run_si_cur(1), unfolded run_si_cur(3)] unfolding matchP_loop_cond_def i_cur_def ti_cur_def by (auto simp: less_Suc_eq) thenshow"matchP_inv I t0 sub rho' (Suc j) tj sj t (adv_start args w_cur)" using assms i_cur_def valid_adv_start valid_adv_start_bounds unfolding matchP_loop_inv_def matchP_loop_cond_def by fastforce next
{ fix w1 w2 assume lassms: "matchP_inv I t0 sub rho' (Suc j) tj sj t w1""matchP_cond I t w1" "w2 = adv_start args w1"
define i_cur where"i_cur = w_i w1"
define ti_cur where"ti_cur = w_ti w1"
define si_cur where"si_cur = w_si w1" have valid_loop: "rw t0 sub rho' (i_cur, ti_cur, si_cur, Suc j, tj, sj)""w_j w1 = Suc j" using lassms(1)[unfolded matchP_loop_inv_def valid_window_matchP_def] valid_before(6)
ti_cur_def si_cur_def i_cur_def by (auto simp: valid_window_def Let_def) obtain ti'_cur si'_cur t_cur b_cur where run_si_cur: "w_run_t args ti_cur = Some (ti'_cur, t_cur)" "w_run_sub args si_cur = Some (si'_cur, b_cur)" using lassms(2) reach_window_run_si[OF valid_loop(1)] reach_window_run_ti[OF valid_loop(1)] unfolding matchP_loop_cond_def valid_loop i_cur_def by auto have w1_ij: "w_i w1 < Suc j""w_j w1 = Suc j" using lassms unfolding matchP_loop_inv_def matchP_loop_cond_def by auto have w2_ij: "w_i w2 = Suc (w_i w1)""w_j w2 = Suc j" using w1_ij lassms(3) run_si_cur(1,2) unfolding ti_cur_def si_cur_def by (auto simp: adv_start_def Let_def split: option.splits prod.splits if_splits) have"w_j w2 - w_i w2 < w_j w1 - w_i w1" using w1_ij w2_ij by auto
} thenhave"{(s', s). matchP_inv I t0 sub rho' (Suc j) tj sj t s ∧ matchP_cond I t s ∧ s' = adv_start args s} ⊆ measure (λw. w_j w - w_i w)" by auto thenshow"wf {(s', s). matchP_inv I t0 sub rho' (Suc j) tj sj t s ∧ matchP_cond I t s ∧ s' = adv_start args s}" using wf_measure wf_subset by auto qed (auto simp: inv_before) have valid_w': "valid_window args t0 sub rho' w''" using conjunct1[OF loop] unfolding matchP_loop_inv_def by auto have w_tsj_w': "w_tj w'' = tj""w_sj w'' = sj""w_j w'' = Suc j" using loop by (auto simp: matchP_loop_inv_def)
define st' where"st' = w_st w''"
define ac where"ac = w_ac w''"
define i' where"i' = w_i w''"
define ti' where"ti' = w_ti w''"
define si' where"si' = w_si w''"
define s' where"s' = w_s w''"
define e' where"e' = w_e w''"
define tj' where"tj' = w_tj w''"
define sj' where"sj' = w_sj w''" have i'_le_Suc_j: "i' ≤ Suc j" using loop unfolding matchP_loop_inv_def by (auto simp: valid_window_def Let_def i'_def) have valid_after: "rw t0 sub rho' (i', ti', si', Suc j, tj', sj')" "∧i j. i ≤ j ==> j < length rho' ==> ts_at rho' i ≤ ts_at rho' j" "distinct (map fst e')" "∀q. mmap_lookup e' q = sup_leadsto init step rho' i' (Suc j) q" "∧q. case Mapping.lookup ac q of None ==> True | Some v ==> accept q = v" "valid_s init step st' accept rho' i' i' (Suc j) s'""i' ≤ Suc j""Suc j ≤ length rho'" using valid_w' i'_le_Suc_j unfolding valid_window_def Let_def i'_def ti'_def si'_def s'_def e'_def tj'_def sj'_def ac_def st'_def w_tsj_w' by auto note lookup_e' = valid_after(3,4,5,6) obtain β ac' where ac'_def: "ex_key e' (λt'. memR t' t I) (w_accept args) ac = (β, ac')" by fastforce have β_def: "β = (∃q∈mmap_keys e'. memR (the (mmap_lookup e' q)) t I ∧ accept q)" "∧q. case Mapping.lookup ac' q of None ==> True | Some v ==> accept q = v" using ex_key_sound[OF valid_after(5) valid_after(3) ac'_def] by auto have i'_set: "∧l. l < w_i w'' ==> memL (ts_at rho' l) (ts_at rho' j) I" using loop length_rho' i'_le_Suc_j unfolding matchP_loop_inv_def by (auto simp: ts_at_def rho'_def nth_append i'_def) have b_alt: "(∃q ∈ mmap_keys e'. memR (the (mmap_lookup e' q)) t I ∧ accept q) ⟷ sat (MatchP I r) j" proof (rule iffI) assume"∃q ∈ mmap_keys e'. memR (the (mmap_lookup e' q)) t I ∧ accept q" thenobtain q where q_def: "q ∈ mmap_keys e'" "memR (the (mmap_lookup e' q)) t I""accept q" by auto thenobtain ts' where ts_def: "mmap_lookup e' q = Some ts'" by (auto dest: Mapping_keys_dest) have"sup_leadsto init step rho' i' (Suc j) q = Some ts'" using lookup_e' ts_def q_def valid_after(4,7,8) by (auto simp: rho'_def sup_leadsto_app_cong) thenobtain l where l_def: "l < i'""steps step rho' init (l, Suc j) = q" "ts_at rho' l = ts'" using sup_leadsto_SomeE[OF i'_le_Suc_j] unfolding i'_def by fastforce have l_le_j: "l ≤ j"and l_le_Suc_j: "l ≤ Suc j" using l_def(1) i'_le_Suc_j by (auto simp: i'_def) have tau_l: "l < j ==> fst (rho ! l) = τ σ l" using run_t_sound'[OF reaches_on_tj, of l] length_rho' by (auto simp: rho'_def nth_append) have tau_l_left: "memL ts' t I" unfolding l_def(3)[symmetric] tj_eq(2) using i'_set l_def(1) by (auto simp: i'_def) have"(l, Suc j) ∈ match r" using accept_match[OF reaches_on_sj l_le_Suc_j _ wf] q_def(3) length_rho' init_def l_def(2)
rho'_def by auto thenshow"sat (MatchP I r) j" using l_le_j q_def(2) ts_at_tau[OF reaches_on_tj] tau_l_left by (auto simp: mem_def tj_eq rho'_def ts_def l_def(3)[symmetric] tau_l tj_def ts_at_def
nth_append length_rho' intro: exI[of _ l] split: if_splits) next assume"sat (MatchP I r) j" thenobtain l where l_def: "l ≤ j""l ≤ Suc j""mem (τ σ l) (τ σ j) I""(l, Suc j) ∈ match r" by auto show"(∃q∈mmap_keys e'. memR (the (mmap_lookup e' q)) t I ∧ accept q)" proof - have l_lt_j: "l < Suc j" using l_def(1) by auto thenhave ts_at_l_j: "ts_at rho' l ≤ ts_at rho' j" using ts_at_mono[OF reaches_on' _ j_len_rho'] by (auto simp: rho'_def length_rho') have ts_j_l: "memL (ts_at rho' l) (ts_at rho' j) I" using l_def(3) ts_at_tau[OF reaches_on_tj] l_lt_j length_rho' tj_eq unfolding rho'_def mem_def by auto have"i' = Suc j ∨¬memL (ts_at rho' i') (ts_at rho' j) I" proof (rule Meson.disj_comm, rule disjCI) assume"i' ≠ Suc j" thenhave i'_j: "i' < Suc j" using valid_after by auto obtain t' b' where tbi_cur_def: "w_read_t args ti' = Some t'" "t' = ts_at rho' i'""b' = bs_at rho' i'" using reach_window_run_ti[OF valid_after(1) i'_j]
reach_window_run_si[OF valid_after(1) i'_j] run_t_read by auto show"¬memL (ts_at rho' i') (ts_at rho' j) I" using loop tbi_cur_def(1) i'_j length_rho' unfolding matchP_loop_inv_def matchP_loop_cond_def tj_eq(2) ti'_def[symmetric] by (auto simp: i'_def tbi_cur_def) qed thenhave l_lt_i': "l < i'" proof (rule disjE) assume assm: "¬memL (ts_at rho' i') (ts_at rho' j) I" show"l < i'" proof (rule ccontr) assume"¬l < i'" thenhave ts_at_i'_l: "ts_at rho' i' ≤ ts_at rho' l" using ts_at_mono[OF reaches_on'] l_lt_j length_rho' by (auto simp: rho'_def length_rho') show False using assm memL_mono[OF ts_j_l ts_at_i'_l] by auto qed qed (auto simp add: l_lt_j)
define q where q_def: "q = steps step rho' init (l, Suc j)" thenobtain l' where l'_def: "sup_leadsto init step rho' i' (Suc j) q = Some (ts_at rho' l')" "l ≤ l'""l' < i'" using sup_leadsto_SomeI[OF l_lt_i'] by fastforce have ts_j_l': "memR (ts_at rho' l') (ts_at rho' j) I" proof - have ts_at_l_l': "ts_at rho' l ≤ ts_at rho' l'" using ts_at_mono[OF reaches_on' l'_def(2)] l'_def(3) valid_after(4,7,8) by (auto simp add: rho'_def length_rho' dual_order.order_iff_strict) show ?thesis using l_def(3) memR_mono[OF _ ts_at_l_l']
ts_at_tau[OF reaches_on_tj] l'_def(2,3) valid_after(4,7,8) by (auto simp: mem_def rho'_def length_rho') qed have lookup_e'_q: "mmap_lookup e' q = Some (ts_at rho' l')" using lookup_e' l'_def(1) valid_after(4,7,8) by (auto simp: rho'_def sup_leadsto_app_cong) show ?thesis using accept_match[OF reaches_on_sj l_def(2) _ wf] l_def(4) ts_j_l' lookup_e'_q tj_eq(2) by (auto simp: bs_at_def nth_append init_def length_rho'(1) q_def intro!: bexI[of _ q] Mapping_keys_intro) qed qed have read_tj_Some: "∧t' l. w_read_t args tj = Some t' ==> l < i' ==> memL (ts_at rho' l) t' I" proof - fix t' l assume lassms: "(w_read_t args) tj = Some t'""l < i'" obtain tj'''' where reaches_on_tj'''': "reaches_on (w_run_t args) t0 (map fst (rho' @ [(t', undefined)])) tj''''" using reaches_on_app[OF reaches_on_tj] read_t_run[OF lassms(1)] by auto have"t ≤ t'" using ts_at_mono[OF reaches_on_tj'''', of "length rho""length rho'"] by (auto simp: ts_at_def nth_append rho'_def) thenshow"memL (ts_at rho' l) t' I" using memL_mono' lassms(2) loop unfolding matchP_loop_inv_def by (fastforce simp: i'_def) qed
define w''' where"w''' = w''(w_ac := ac')" have"rw t0 sub rho' (w_i w''', w_ti w''', w_si w''', w_j w''', w_tj w''', w_sj w''')" using valid_after(1) by (auto simp del: reach_window.simps simp: w'''_def i'_def ti'_def si'_def tj'_def sj'_defw_tsj_w') moreoverhave"valid_window args t0 sub rho' w'''" using valid_w' by (auto simp: w'''_def valid_window_def Let_def β_def(2)) ultimatelyhave"valid_matchP I t0 sub rho' (Suc j) w'''" using i'_set read_tj_Some by (auto simp: valid_window_matchP_def w'''_def w_tsj_w' i'_def split: option.splits) moreoverhave"eval_mP I w = Some ((t, sat (MatchP I r) j), w''')" by (simp add: read_t_def Let_def loop_def[symmetric] ac'_def[unfolded e'_def ac_def] w'''_def w'_def trans[OF β_def(1) b_alt]) ultimatelyshow ?thesis by (auto simp: tj_eq rho'_def) qed
lemma valid_eval_matchF_Some: assumes valid_before': "valid_matchF I t0 sub rho i w" and eval: "eval_mF I w = Some ((t, b), w'')" and bounded: "right I ∈ tfin" shows"∃rho' tm. reaches_on (w_run_t args) (w_tj w) (map fst rho') (w_tj w'') ∧ reaches_on (w_run_sub args) (w_sj w) (map snd rho') (w_sj w'') ∧ (w_read_t args) (w_ti w) = Some t ∧ (w_read_t args) (w_tj w'') = Some tm ∧ ¬memR t tm I" proof -
define st where"st = w_st w"
define ti where"ti = w_ti w"
define si where"si = w_si w"
define j where"j = w_j w"
define tj where"tj = w_tj w"
define sj where"sj = w_sj w"
define s where"s = w_s w"
define e where"e = w_e w" have valid_before: "rw t0 sub rho (i, ti, si, j, tj, sj)" "∧i j. i ≤ j ==> j < length rho ==> ts_at rho i ≤ ts_at rho j" "∀q. mmap_lookup e q = sup_leadsto init step rho i j q" "valid_s init step st accept rho i i j s" "i = w_i w""i ≤ j""length rho = j" using valid_before'[unfolded valid_window_matchF_def] ti_def
si_def j_def tj_def sj_def s_def e_def by (auto simp: valid_window_def Let_def init_def step_def st_def accept_def) obtain ti''' where tbi_def: "w_run_t args ti = Some (ti''', t)" using eval read_t_run by (fastforce simp: Let_def ti_def si_def split: option.splits if_splits) have t_tau: "t = τ σ i" using run_t_sound[OF _ tbi_def] valid_before(1) by auto note t_def = run_t_read[OF tbi_def(1)] obtain w' where loop_def: "while_break (matchF_cond I t) (adv_end args) w = Some w'" using eval by (auto simp: ti_def[symmetric] t_def split: option.splits) have adv_start_last: "adv_start args w' = w''" using eval loop_def[symmetric] run_t_read[OF tbi_def(1)] by (auto simp: ti_def split: option.splits prod.splits if_splits) have inv_before: "matchF_inv' t0 sub rho i ti si j tj sj w" using valid_before(1) valid_before' unfolding matchF_loop_inv'_def valid_before(6) valid_window_matchF_def by (auto simp add: ti_def si_def j_def tj_def sj_def simp del: reach_window.simps
dest: reach_window_shift_all intro!: exI[of _ "[]"]) have i_j: "i ≤ j""length rho = j" using valid_before by auto
define j'' where"j'' = w_j w''"
define tj'' where"tj'' = w_tj w''"
define sj'' where"sj'' = w_sj w''" have loop: "matchF_inv' t0 sub rho i ti si j tj sj w' ∧¬ matchF_cond I t w'" proof (rule while_break_sound[of "matchF_inv' t0 sub rho i ti si j tj sj""matchF_cond I t""adv_end args""λw'. matchF_inv' t0 sub rho i ti si j tj sj w' ∧¬ matchF_cond I t w'" w, unfolded loop_def, simplified]) fix w_cur w_cur' :: "(bool iarray, nat set, 'd, 't, 'e) window" assume assms: "matchF_inv' t0 sub rho i ti si j tj sj w_cur""matchF_cond I t w_cur""adv_end args w_cur = Some w_cur'"
define j_cur where"j_cur = w_j w_cur"
define tj_cur where"tj_cur = w_tj w_cur"
define sj_cur where"sj_cur = w_sj w_cur" obtain rho' where rho'_def: "valid_window args t0 sub (rho @ rho') w_cur" "rw t0 sub (rho @ rho') (j, tj, sj, w_j w_cur, w_tj w_cur, w_sj w_cur)" using assms(1)[unfolded matchF_loop_inv'_def valid_window_matchF_def] by auto obtain tj' x sj' y where append: "w_run_t args tj_cur = Some (tj', x)" "w_run_sub args sj_cur = Some (sj', y)" using assms(3) unfolding tj_cur_def sj_cur_def by (auto simp: adv_end_def Let_def split: option.splits) note append' = append[unfolded tj_cur_def sj_cur_def]
define rho'' where"rho'' = rho @ rho'" have reach: "reaches_on (w_run_t args) t0 (map fst (rho'' @ [(x, undefined)])) tj'" using reaches_on_app[OF reach_window_run_tj[OF rho'_def(2)] append'(1)] by (auto simp: rho''_def) have mono: "∧t'. t' ∈ set (map fst rho'') ==> t' ≤ x" using ts_at_mono[OF reach, of _ "length rho''"] nat_less_le by (fastforce simp: ts_at_def nth_append in_set_conv_nth split: list.splits) show"matchF_inv' t0 sub rho i ti si j tj sj w_cur'" using assms(1,3) reach_window_app[OF rho'_def(2) append[unfolded tj_cur_def sj_cur_def]]
valid_adv_end[OF rho'_def(1) append' mono] adv_end_bounds[OF append'] unfolding matchF_loop_inv'_def matchF_loop_cond_def rho''_def by auto next obtain l where l_def: "¬τ σ l ≤ t + right I" unfolding t_tau using ex_lt_τ[OF bounded] by auto
{ fix w1 w2 assume lassms: "matchF_inv' t0 sub rho i ti si j tj sj w1""matchF_cond I t w1" "Some w2 = adv_end args w1"
define j_cur where"j_cur = w_j w1"
define tj_cur where"tj_cur = w_tj w1"
define sj_cur where"sj_cur = w_sj w1" obtain rho' where rho'_def: "valid_window args t0 sub (rho @ rho') w1" "rw t0 sub (rho @ rho') (j, tj, sj, w_j w1, w_tj w1, w_sj w1)" using lassms(1)[unfolded matchF_loop_inv'_def valid_window_matchF_def] by auto obtain tj' x sj' y where append: "w_run_t args tj_cur = Some (tj', x)" "w_run_sub args sj_cur = Some (sj', y)" using lassms(3) unfolding tj_cur_def sj_cur_def by (auto simp: adv_end_def Let_def split: option.splits) note append' = append[unfolded tj_cur_def sj_cur_def]
define rho'' where"rho'' = rho @ rho'" have reach: "reaches_on (w_run_t args) t0 (map fst (rho'' @ [(x, undefined)])) tj'" using reaches_on_app[OF reach_window_run_tj[OF rho'_def(2)] append'(1)] by (auto simp: rho''_def) have mono: "∧t'. t' ∈ set (map fst rho'') ==> t' ≤ x" using ts_at_mono[OF reach, of _ "length rho''"] nat_less_le by (fastforce simp: ts_at_def nth_append in_set_conv_nth split: list.splits) have t_cur_tau: "x = τ σ j_cur" using ts_at_tau[OF reach, of "length rho''"] rho'_def(2) by (auto simp: ts_at_def j_cur_def rho''_def) have"j_cur < l" using lassms(2)[unfolded matchF_loop_cond_def] l_def memR_mono'[OF _ τ_mono[of l j_cur σ]] unfolding run_t_read[OF append(1), unfolded t_cur_tau tj_cur_def] by (fastforce dest: memR_dest) moreoverhave"w_j w2 = Suc j_cur" using adv_end_bounds[OF append'] unfolding lassms(3)[symmetric] j_cur_def by auto ultimatelyhave"l - w_j w2 < l - w_j w1" unfolding j_cur_def by auto
} thenhave"{(ta, s). matchF_inv' t0 sub rho i ti si j tj sj s ∧ matchF_cond I t s ∧ Some ta = adv_end args s} ⊆ measure (λw. l - w_j w)" by auto thenshow"wf {(ta, s). matchF_inv' t0 sub rho i ti si j tj sj s ∧ matchF_cond I t s ∧ Some ta = adv_end args s}" using wf_measure wf_subset by auto qed (auto simp: inv_before)
define i' where"i' = w_i w'"
define ti' where"ti' = w_ti w'"
define si' where"si' = w_si w'"
define j' where"j' = w_j w'"
define tj' where"tj' = w_tj w'"
define sj' where"sj' = w_sj w'" obtain rho' where rho'_def: "valid_window args t0 sub (rho @ rho') w'" "rw t0 sub (rho @ rho') (j, tj, sj, j', tj', sj')" "i = i'""j ≤ j'" using loop unfolding matchF_loop_inv'_def i'_def j'_def tj'_def sj'_def by auto obtain tje tm where tm_def: "w_read_t args tj' = Some tm""w_run_t args tj' = Some (tje, tm)" using eval read_t_run loop_def t_def ti_def by (auto simp: t_def Let_def tj'_def split: option.splits if_splits) have drop_j_rho: "drop j (map fst (rho @ rho')) = map fst rho'" using i_j by auto have"reaches_on (w_run_t args) ti (drop i (map fst rho)) tj" using valid_before(1) by auto thenhave"reaches_on (w_run_t args) ti (drop i (map fst rho) @ (drop j (map fst (rho @ rho')))) tj'" using rho'_def reaches_on_trans by fastforce thenhave"reaches_on (w_run_t args) ti (drop i (map fst (rho @ rho'))) tj'" unfolding drop_j_rho by (auto simp: i_j) thenhave reach_tm: "reaches_on (w_run_t args) ti (drop i (map fst (rho @ rho')) @ [tm]) tje" using reaches_on_app tm_def(2) by fastforce have run_tsi': "w_run_t args ti' ≠ None" using tbi_def loop by (auto simp: matchF_loop_inv'_def ti'_def si'_def) have memR_t_tm: "¬ memR t tm I" using loop tm_def by (auto simp: tj'_def matchF_loop_cond_def) have i_le_rho: "i ≤ length rho" using valid_before by auto
define rho'' where"rho'' = rho @ rho'" have t_tfin: "t ∈ tfin" using τ_fin by (auto simp: t_tau) have i'_lt_j': "i' < j'" using rho'_def(1,2,3)[folded rho''_def] i_j reach_tm[folded rho''_def] memR_t_tm tbi_def memR_tfin_refl[OF t_tfin] by (cases "i' = j'") (auto dest!: reaches_on_NilD elim!: reaches_on.cases[of _ _ "[tm]"]) have adv_last_bounds: "j'' = j'""tj'' = tj'""sj'' = sj'" using valid_adv_start_bounds[OF rho'_def(1) i'_lt_j'[unfolded i'_def j'_def]] unfolding adv_start_last j'_def j''_def tj'_def tj''_def sj'_def sj''_def by auto show ?thesis using eval rho'_def run_tsi' i_j(2) adv_last_bounds tj''_def tj_def sj''_def sj_def
loop_def t_def ti_def tj'_def tm_def memR_t_tm by (auto simp: drop_map run_t_read[OF tbi_def(1)] Let_def
split: option.splits prod.splits if_splits intro!: exI[of _ rho']) qed
lemma valid_eval_matchF_complete: assumes valid_before': "valid_matchF I t0 sub rho i w" and before_end: "reaches_on (w_run_t args) (w_tj w) (map fst rho') tj'''" "reaches_on (w_run_sub args) (w_sj w) (map snd rho') sj'''" "w_read_t args (w_ti w) = Some t""w_read_t args tj''' = Some tm""¬memR t tm I" and wf: "wf_regex r" shows"∃w'. eval_mF I w = Some ((τ σ i, sat (MatchF I r) i), w') ∧ valid_matchF I t0 sub (take (w_j w') (rho @ rho')) (Suc i) w'" proof -
define st where"st = w_st w"
define ti where"ti = w_ti w"
define si where"si = w_si w"
define j where"j = w_j w"
define tj where"tj = w_tj w"
define sj where"sj = w_sj w"
define s where"s = w_s w"
define e where"e = w_e w" have valid_before: "rw t0 sub rho (i, ti, si, j, tj, sj)" "∧i j. i ≤ j ==> j < length rho ==> ts_at rho i ≤ ts_at rho j" "∀q. mmap_lookup e q = sup_leadsto init step rho i j q" "valid_s init step st accept rho i i j s" "i = w_i w""i ≤ j""length rho = j" using valid_before'[unfolded valid_window_matchF_def] ti_def
si_def j_def tj_def sj_def s_def e_def by (auto simp: valid_window_def Let_def init_def step_def st_def accept_def)
define rho'' where"rho'' = rho @ rho'" have ij_le: "i ≤ j""j = length rho" using valid_before by auto have reach_tj: "reaches_on (w_run_t args) t0 (take j (map fst rho'')) tj" using valid_before(1) ij_le by (auto simp: take_map rho''_def simp del: reach_window.simps dest!: reach_window_run_tj) have reach_ti: "reaches_on (w_run_t args) t0 (take i (map fst rho'')) ti" using valid_before(1) ij_le by (auto simp: take_map rho''_def) have reach_si: "reaches_on (w_run_sub args) sub (take i (map snd rho'')) si" using valid_before(1) ij_le by (auto simp: take_map rho''_def) have reach_sj: "reaches_on (w_run_sub args) sub (take j (map snd rho'')) sj" using valid_before(1) ij_le by (auto simp: take_map rho''_def simp del: reach_window.simps dest!: reach_window_run_sj) have reach_tj''': "reaches_on (w_run_t args) t0 (map fst rho'') tj'''" using reaches_on_trans[OF reach_tj before_end(1)[folded tj_def]] ij_le(2) by (auto simp del: map_append simp: rho''_def take_map drop_map map_append[symmetric]) have rho''_mono: "∧i j. i ≤ j ==> j < length rho'' ==> ts_at rho'' i ≤ ts_at rho'' j" using ts_at_mono[OF reach_tj'''] . obtain tm' where reach_tm: "reaches_on (w_run_t args) t0 (map fst (rho'' @ [(tm, undefined)])) tm'" using reaches_on_app[OF reach_tj'''] read_t_run[OF before_end(4)] by auto have tj'''_eq: "∧tj_cur. reaches_on (w_run_t args) t0 (map fst rho'') tj_cur ==> tj_cur = tj'''" using reaches_on_inj[OF reach_tj'''] by blast have reach_sj''': "reaches_on (w_run_sub args) sub (map snd rho'') sj'''" using reaches_on_trans[OF reach_sj before_end(2)[folded sj_def]] ij_le(2) by (auto simp del: map_append simp: rho''_def take_map drop_map map_append[symmetric]) have sj'''_eq: "∧sj_cur. reaches_on (w_run_sub args) sub (map snd rho'') sj_cur ==> sj_cur = sj'''" using reaches_on_inj[OF reach_sj'''] by blast have reach_window_i: "rw t0 sub rho'' (i, ti, si, length rho'', tj''', sj''')" using reach_windowI[OF reach_ti reach_si reach_tj''' reach_sj''' _ refl] ij_le by (auto simp: rho''_def) have reach_window_j: "rw t0 sub rho'' (j, tj, sj, length rho'', tj''', sj''')" using reach_windowI[OF reach_tj reach_sj reach_tj''' reach_sj''' _ refl] ij_le by (auto simp: rho''_def) have t_def: "t = τ σ i" using valid_before(6) read_t_run[OF before_end(3)] reaches_on_app[OF reach_ti]
ts_at_tau[where ?rho="take i rho'' @ [(t, undefined)]"] by (fastforce simp: ti_def rho''_def valid_before(5,7) take_map ts_at_def nth_append) have t_tfin: "t ∈ tfin" using τ_fin by (auto simp: t_def) have i_lt_rho'': "i < length rho''" using ij_le before_end(3,4,5) reach_window_i memR_tfin_refl[OF t_tfin] by (cases "i = length rho''") (auto simp: rho''_def ti_def dest!: reaches_on_NilD) obtain ti''' si''' b where tbi_def: "w_run_t args ti = Some (ti''', t)" "w_run_sub args si = Some (si''', b)""t = ts_at rho'' i""b = bs_at rho'' i" using reach_window_run_ti[OF reach_window_i i_lt_rho'']
reach_window_run_si[OF reach_window_i i_lt_rho'']
read_t_run[OF before_end(3), folded ti_def] by auto note before_end' = before_end(5) have read_ti: "w_read_t args ti = Some t" using run_t_read[OF tbi_def(1)] . have inv_before: "matchF_inv I t0 sub rho'' i ti si tj''' sj''' w" using valid_before' before_end(1,2,3) reach_window_j ij_le ti_def si_def j_def tj_def sj_def unfolding matchF_loop_inv_def valid_window_matchF_def by (auto simp: rho''_def ts_at_def nth_append) have i_j: "i ≤ j" using valid_before by auto have loop: "pred_option' (λw'. matchF_inv I t0 sub rho'' i ti si tj''' sj''' w' ∧¬ matchF_cond I t w') (while_break (matchF_cond I t) (adv_end args) w)" proof (rule while_break_complete[of "matchF_inv I t0 sub rho'' i ti si tj''' sj'''", OF _ _ _ inv_before]) fix w_cur :: "(bool iarray, nat set, 'd, 't, 'e) window" assume assms: "matchF_inv I t0 sub rho'' i ti si tj''' sj''' w_cur""matchF_cond I t w_cur"
define j_cur where"j_cur = w_j w_cur"
define tj_cur where"tj_cur = w_tj w_cur"
define sj_cur where"sj_cur = w_sj w_cur"
define s_cur where"s_cur = w_s w_cur"
define e_cur where"e_cur = w_e w_cur" have loop: "valid_window args t0 sub (take (w_j w_cur) rho'') w_cur" "rw t0 sub rho'' (j_cur, tj_cur, sj_cur, length rho'', tj''', sj''')" "∧l. l∈{w_i w_cur..<w_j w_cur} ==> memR (ts_at rho'' i) (ts_at rho'' l) I" using j_cur_def tj_cur_def sj_cur_def s_cur_def e_cur_def
assms(1)[unfolded matchF_loop_inv_def] by auto have j_cur_lt_rho'': "j_cur < length rho''" using assms tj'''_eq before_end(4,5) unfolding matchF_loop_inv_def matchF_loop_cond_def by (cases "j_cur = length rho''") (auto simp: j_cur_def split: option.splits) obtain tj_cur' sj_cur' x b_cur where tbi_cur_def: "w_run_t args tj_cur = Some (tj_cur', x)" "w_run_sub args sj_cur = Some (sj_cur', b_cur)" "x = ts_at rho'' j_cur""b_cur = bs_at rho'' j_cur" using reach_window_run_ti[OF loop(2) j_cur_lt_rho'']
reach_window_run_si[OF loop(2) j_cur_lt_rho''] by auto note reach_window_j'_cur = reach_window_shift[OF loop(2) j_cur_lt_rho'' tbi_cur_def(1,2)] note tbi_cur_def' = tbi_cur_def(1,2)[unfolded tj_cur_def sj_cur_def] have mono: "∧t'. t' ∈ set (map fst (take (w_j w_cur) rho'')) ==> t' ≤ x" using rho''_mono[of _ j_cur] j_cur_lt_rho'' nat_less_le by (fastforce simp: tbi_cur_def(3) j_cur_def ts_at_def nth_append in_set_conv_nth
split: list.splits) have take_unfold: "take (w_j w_cur) rho'' @ [(x, b_cur)] = (take (Suc (w_j w_cur)) rho'')" using j_cur_lt_rho'' unfolding tbi_cur_def(3,4) by (auto simp: ts_at_def bs_at_def j_cur_def take_Suc_conv_app_nth) obtain w_cur' where w_cur'_def: "adv_end args w_cur = Some w_cur'" by (fastforce simp: adv_end_def Let_def tj_cur_def[symmetric] sj_cur_def[symmetric] tbi_cur_def(1,2) split: prod.splits) have"∧l. l ∈{w_i w_cur'..<w_j w_cur'} ==> memR (ts_at rho'' i) (ts_at rho'' l) I" using loop(3) assms(2) w_cur'_def unfolding adv_end_bounds[OF tbi_cur_def' w_cur'_def] matchF_loop_cond_def
run_t_read[OF tbi_cur_def(1)[unfolded tj_cur_def]] tbi_cur_def(3) tbi_def(3) by (auto simp: j_cur_def elim: less_SucE) thenshow"pred_option' (matchF_inv I t0 sub rho'' i ti si tj''' sj''') (adv_end args w_cur)" using assms(1) reach_window_j'_cur valid_adv_end[OF loop(1) tbi_cur_def' mono]
w_cur'_def adv_end_bounds[OF tbi_cur_def' w_cur'_def] unfolding matchF_loop_inv_def j_cur_def take_unfold by (auto simp: pred_option'_def) next
{ fix w1 w2 assume lassms: "matchF_inv I t0 sub rho'' i ti si tj''' sj''' w1""matchF_cond I t w1" "Some w2 = adv_end args w1"
define j_cur where"j_cur = w_j w1"
define tj_cur where"tj_cur = w_tj w1"
define sj_cur where"sj_cur = w_sj w1"
define s_cur where"s_cur = w_s w1"
define e_cur where"e_cur = w_e w1" have loop: "valid_window args t0 sub (take (w_j w1) rho'') w1" "rw t0 sub rho'' (j_cur, tj_cur, sj_cur, length rho'', tj''', sj''')" "∧l. l∈{w_i w1..<w_j w1} ==> memR (ts_at rho'' i) (ts_at rho'' l) I" using j_cur_def tj_cur_def sj_cur_def s_cur_def e_cur_def
lassms(1)[unfolded matchF_loop_inv_def] by auto have j_cur_lt_rho'': "j_cur < length rho''" using lassms tj'''_eq ij_le before_end(4,5) unfolding matchF_loop_inv_def matchF_loop_cond_def by (cases "j_cur = length rho''") (auto simp: j_cur_def split: option.splits) obtain tj_cur' sj_cur' x b_cur where tbi_cur_def: "w_run_t args tj_cur = Some (tj_cur', x)" "w_run_sub args sj_cur = Some (sj_cur', b_cur)" "x = ts_at rho'' j_cur""b_cur = bs_at rho'' j_cur" using reach_window_run_ti[OF loop(2) j_cur_lt_rho'']
reach_window_run_si[OF loop(2) j_cur_lt_rho''] by auto note tbi_cur_def' = tbi_cur_def(1,2)[unfolded tj_cur_def sj_cur_def] have"length rho'' - w_j w2 < length rho'' - w_j w1" using j_cur_lt_rho'' adv_end_bounds[OF tbi_cur_def', folded lassms(3)] unfolding j_cur_def by auto
} thenhave"{(ta, s). matchF_inv I t0 sub rho'' i ti si tj''' sj''' s ∧ matchF_cond I t s ∧ Some ta = adv_end args s} ⊆ measure (λw. length rho'' - w_j w)" by auto thenshow"wf {(ta, s). matchF_inv I t0 sub rho'' i ti si tj''' sj''' s ∧ matchF_cond I t s ∧ Some ta = adv_end args s}" using wf_measure wf_subset by auto qed (auto simp add: inv_before) obtain w' where w'_def: "while_break (matchF_cond I t) (adv_end args) w = Some w'" using loop by (auto simp: pred_option'_def split: option.splits)
define w'' where adv_start_last: "w'' = adv_start args w'"
define st' where"st' = w_st w'"
define i' where"i' = w_i w'"
define ti' where"ti' = w_ti w'"
define si' where"si' = w_si w'"
define j' where"j' = w_j w'"
define tj' where"tj' = w_tj w'"
define sj' where"sj' = w_sj w'"
define s' where"s' = w_s w'"
define e' where"e' = w_e w'" have valid_after: "valid_window args t0 sub (take (w_j w') rho'') w'" "rw t0 sub rho'' (j', tj', sj', length rho'', tj''', sj''')" "∧l. l∈{i..<j'} ==> memR (ts_at rho'' i) (ts_at rho'' l) I" "i' = i""ti' = ti""si' = si" using loop unfolding matchF_loop_inv_def w'_def i'_def ti'_def si'_def j'_def tj'_def sj'_def by (auto simp: pred_option'_def)
define i'' where"i'' = w_i w''"
define j'' where"j'' = w_j w''"
define tj'' where"tj'' = w_tj w''"
define sj'' where"sj'' = w_sj w''" have j'_le_rho'': "j' ≤ length rho''" using loop unfolding matchF_loop_inv_def valid_window_matchF_def w'_def j'_def by (auto simp: pred_option'_def) obtain te where tbj'_def: "w_read_t args tj' = Some te" "te = ts_at (rho'' @ [(tm, undefined)]) j'" proof (cases "j' < length rho''") case True show ?thesis using reach_window_run_ti[OF valid_after(2) True] that True by (auto simp: ts_at_def nth_append dest!: run_t_read) next case False thenhave"tj' = tj'''""j' = length rho''" using valid_after(2) j'_le_rho'' tj'''_eq by auto thenshow ?thesis using that before_end(4) by (auto simp: ts_at_def nth_append) qed have not_ets_te: "¬memR (ts_at rho'' i) te I" using loop unfolding w'_def by (auto simp: pred_option'_def matchF_loop_cond_def tj'_def[symmetric] tbj'_def(1) tbi_def(3) split: option.splits) have i'_set: "∧l. l ∈ {i..<j'} ==> memR (ts_at rho'' i) (ts_at rho'' l) I" "¬memR (ts_at rho'' i) (ts_at (rho'' @ [(tm, undefined)]) j') I" using loop tbj'_def not_ets_te valid_after atLeastLessThan_iff unfolding matchF_loop_inv_def matchF_loop_cond_def tbi_def(3) by (auto simp: tbi_def tj'_def split: option.splits) have i_le_j': "i ≤ j'" using valid_after(1) unfolding valid_after(4)[symmetric] by (auto simp: valid_window_def Let_def i'_def j'_def) have i_lt_j': "i < j'" using i_le_j' i'_set(2) i_lt_rho'' using memR_tfin_refl[OF τ_fin] ts_at_tau[OF reach_tj''', of j'] by (cases "i = j'") (auto simp: ts_at_def nth_append) thenhave i'_lt_j': "i' < j'" unfolding valid_after by auto have adv_last_bounds: "i'' = Suc i'""w_ti w'' = ti'''""w_si w'' = si'''""j'' = j'" "tj'' = tj'""sj'' = sj'" using valid_adv_start_bounds[OF valid_after(1) i'_lt_j'[unfolded i'_def j'_def]]
valid_adv_start_bounds'[OF valid_after(1) tbi_def(1,2)[folded valid_after(5,6),
unfolded ti'_def si'_def]] unfolding adv_start_last i'_def i''_def j'_def j''_def tj'_def tj''_def sj'_def sj''_def by auto have i''_i: "i'' = i + 1" using valid_after adv_last_bounds by auto have i_le_j': "i ≤ j'" using valid_after i'_lt_j' by auto thenhave i_le_rho: "i ≤ length rho''" using valid_after(2) by auto have"valid_s init step st' accept (take j' rho'') i i j' s'" using valid_after(1,4) i'_def by (auto simp: valid_window_def Let_def init_def step_def st'_def accept_def j'_def s'_def) note valid_s' = this[unfolded valid_s_def] have q0_in_keys: "{0} ∈ mmap_keys s'" using valid_s' init_def steps_refl by auto thenobtain q' tstp where lookup_s': "mmap_lookup s' {0} = Some (q', tstp)" by (auto dest: Mapping_keys_dest) have lookup_sup_acc: "snd (the (mmap_lookup s' {0})) = sup_acc step accept (take j' rho'') {0} i j'" using conjunct2[OF valid_s'] lookup_s' by auto (smt case_prodD option.simps(5)) have b_alt: "(case snd (the (mmap_lookup s' {0})) of None ==> False | Some tstp ==> memL t (fst tstp) I) ⟷ sat (MatchF I r) i" proof (rule iffI) assume assm: "case snd (the (mmap_lookup s' {0})) of None ==> False | Some tstp ==> memL t (fst tstp) I" thenobtain ts tp where tstp_def: "sup_acc step accept (take j' rho'') {0} i j' = Some (ts, tp)" "memL (ts_at rho'' i) ts I" unfolding lookup_sup_acc by (auto simp: tbi_def split: option.splits) thenhave sup_acc_rho'': "sup_acc step accept rho'' {0} i j' = Some (ts, tp)" using sup_acc_concat_cong[of j' "take j' rho''" step accept "drop j' rho''"] j'_le_rho'' by auto have tp_props: "tp ∈ {i..<j'}""acc step accept rho'' {0} (i, Suc tp)" using sup_acc_SomeE[OF sup_acc_rho''] by auto have ts_ts_at: "ts = ts_at rho'' tp" using sup_acc_Some_ts[OF sup_acc_rho''] . have i_le_tp: "i ≤ Suc tp" using tp_props by auto have"memR (ts_at rho'' i) (ts_at rho'' tp) I" using i'_set(1)[OF tp_props(1)] . thenhave"mem (ts_at rho'' i) (ts_at rho'' tp) I" using tstp_def(2) unfolding ts_ts_at mem_def by auto thenshow"sat (MatchF I r) i" using i_le_tp acc_match[OF reach_sj''' i_le_tp _ wf] tp_props(2) ts_at_tau[OF reach_tj''']
tp_props(1) j'_le_rho'' by auto next assume"sat (MatchF I r) i" thenobtain l where l_def: "l ≥ i""mem (τ σ i) (τ σ l) I""(i, Suc l) ∈ match r" by auto have l_lt_rho: "l < length rho''" proof (rule ccontr) assume contr: "¬l < length rho''" have"tm = ts_at (rho'' @ [(tm, undefined)]) (length rho'')" using i_le_rho by (auto simp add: ts_at_def rho''_def) moreoverhave"…≤ τ σ l" using τ_mono ts_at_tau[OF reach_tm] i_le_rho contr by (metis One_nat_def Suc_eq_plus1 length_append lessI list.size(3)
list.size(4) not_le_imp_less) moreoverhave"memR (τ σ i) (τ σ l) I" using l_def(2) unfolding mem_def by auto ultimatelyhave"memR (τ σ i) tm I" using memR_mono' by auto thenshow"False" using before_end' ts_at_tau[OF reach_tj''' i_lt_rho''] tbi_def(3) by (auto simp: rho''_def) qed have l_lt_j': "l < j'" proof (rule ccontr) assume contr: "¬l < j'" thenhave ts_at_j'_l: "ts_at rho'' j' ≤ ts_at rho'' l" using ts_at_mono[OF reach_tj'''] l_lt_rho by (auto simp add: order.not_eq_order_implies_strict) have ts_at_l_iu: "memR (ts_at rho'' i) (ts_at rho'' l) I" using l_def(2) ts_at_tau[OF reach_tj''' l_lt_rho] ts_at_tau[OF reach_tj''' i_lt_rho''] unfolding mem_def by auto show"False" using i'_set(2) ts_at_j'_l ts_at_l_iu contr l_lt_rho memR_mono' by (auto simp: ts_at_def nth_append split: if_splits) qed have i_le_Suc_l: "i ≤ Suc l" using l_def(1) by auto obtain tp where tstp_def: "sup_acc step accept rho'' {0} i j' = Some (ts_at rho'' tp, tp)" "l ≤ tp""tp < j'" using l_def(1,3) l_lt_j' l_lt_rho by (meson accept_match[OF reach_sj''' i_le_Suc_l _ wf, unfolded steps_is_run] sup_acc_SomeI[unfolded acc_is_accept, of step accept] acc_is_accept atLeastLessThan_iff less_eq_Suc_le) have"memL (ts_at rho'' i) (ts_at rho'' l) I" using l_def(2) unfolding ts_at_tau[OF reach_tj''' i_lt_rho'', symmetric]
ts_at_tau[OF reach_tj''' l_lt_rho, symmetric] mem_def by auto thenhave"memL (ts_at rho'' i) (ts_at rho'' tp) I" using ts_at_mono[OF reach_tj''' tstp_def(2)] tstp_def(3) j'_le_rho'' memL_mono' by auto thenshow"case snd (the (mmap_lookup s' {0})) of None ==> False | Some tstp ==> memL t (fst tstp) I" using lookup_sup_acc tstp_def j'_le_rho''
sup_acc_concat_cong[of j' "take j' rho''" step accept "drop j' rho''"] by (auto simp: tbi_def split: option.splits) qed have"valid_matchF I t0 sub (take j'' rho'') i'' (adv_start args w')" proof - have"∀l ∈ {i'..<j'}. memR (ts_at rho'' i') (ts_at rho'' l) I" using loop i'_def j'_def valid_after unfolding matchF_loop_inv_def by auto thenhave"∀l ∈ {i''..<j''}. memR (ts_at rho'' i'') ( ts_at rho'' l) I" unfolding i''_i valid_after adv_last_bounds apply safe
subgoal for l apply (drule ballE[of _ _ l]) using ts_at_mono[OF reach_tj''', of i "Suc i"] j'_le_rho'' memR_mono apply auto done done moreoverhave"rw t0 sub (take j'' rho'') (i'', ti''', si''', j'', tj'', sj'')" proof - have rw: "rw t0 sub (take j' rho'') (i', ti', si', j', tj', sj')" using valid_after(1) by (auto simp: valid_window_def Let_def i'_def ti'_def si'_def j'_def tj'_def sj'_def) show ?thesis using reach_window_shift[OF rw i'_lt_j'
tbi_def(1,2)[unfolded valid_after(5,6)[symmetric]]] adv_last_bounds by auto qed moreoverhave"valid_window args t0 sub (take j' rho'') w''" using valid_adv_start[OF valid_after(1) i'_lt_j'[unfolded i'_def j'_def]] unfolding adv_start_last j'_def . ultimatelyshow"valid_matchF I t0 sub (take j'' rho'') i'' (adv_start args w')" using j'_le_rho'' unfolding valid_window_matchF_def adv_last_bounds adv_start_last[symmetric] i''_def[symmetric]
j'_def j''_def[symmetric] tj'_def tj''_def[symmetric] sj'_def sj''_def[symmetric] by (auto simp: ts_at_def) qed moreoverhave"eval_mF I w = Some ((τ σ i, sat (MatchF I r) i), w'')" unfolding j''_def adv_start_last[symmetric] adv_last_bounds valid_after rho''_def
eval_matchF.simps run_t_read[OF tbi_def(1)[unfolded ti_def]] using tbj'_def[unfolded tj'_def] not_ets_te[folded tbi_def(3)]
b_alt[unfolded s'_def] t_def adv_start_last w'_def by (auto simp only: Let_def split: option.splits if_splits) ultimatelyshow ?thesis unfolding j''_def adv_start_last[symmetric] adv_last_bounds valid_after rho''_def by auto qed
lemma valid_eval_matchF_sound: assumes valid_before: "valid_matchF I t0 sub rho i w" and eval: "eval_mF I w = Some ((t, b), w'')" and bounded: "right I ∈ tfin" and wf: "wf_regex r" shows"t = τ σ i ∧ b = sat (MatchF I r) i ∧ (∃rho'. valid_matchF I t0 sub rho' (Suc i) w'')" proof - obtain rho' t tm where rho'_def: "reaches_on (w_run_t args) (w_tj w) (map fst rho') (w_tj w'')" "reaches_on (w_run_sub args) (w_sj w) (map snd rho') (w_sj w'')" "w_read_t args (w_ti w) = Some t" "w_read_t args (w_tj w'') = Some tm" "¬memR t tm I" using valid_eval_matchF_Some[OF assms(1-3)] by auto show ?thesis using valid_eval_matchF_complete[OF assms(1) rho'_def wf] unfolding eval by blast qed
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.