text‹This theory defines the construction of product machines.
A product machine of two finite state machines essentially represents all possible parallel
executions of those two machines.›
thenhave p1a: "fsm_impl.initial A ∈ fsm_impl.states A" and p2a: "finite (fsm_impl.states A)" and p3a: "finite (fsm_impl.inputs A)" and p4a: "finite (fsm_impl.outputs A)" and p5a: "finite (fsm_impl.transitions A)" and p6a: "(∀t∈fsm_impl.transitions A. t_source t ∈ fsm_impl.states A ∧ t_input t ∈ fsm_impl.inputs A ∧ t_target t ∈ fsm_impl.states A ∧ t_output t ∈ fsm_impl.outputs A)" and p1b: "fsm_impl.initial B ∈ fsm_impl.states B" and p2b: "finite (fsm_impl.states B)" and p3b: "finite (fsm_impl.inputs B)" and p4b: "finite (fsm_impl.outputs B)" and p5b: "finite (fsm_impl.transitions B)" and p6b: "(∀t∈fsm_impl.transitions B. t_source t ∈ fsm_impl.states B ∧ t_input t ∈ fsm_impl.inputs B ∧ t_target t ∈ fsm_impl.states B ∧ t_output t ∈ fsm_impl.outputs B)" by simp+
let ?P = "FSM_Impl.product A B"
have"fsm_impl.initial ?P ∈ fsm_impl.states ?P" using p1a p1b by auto moreoverhave"finite (fsm_impl.states ?P)" using p2a p2b by auto moreoverhave"finite (fsm_impl.inputs ?P)" using p3a p3b by auto moreoverhave"finite (fsm_impl.outputs ?P)" using p4a p4b by auto moreoverhave"finite (fsm_impl.transitions ?P)" using p5a p5b unfolding product_code_naive by auto moreoverhave"(∀t∈fsm_impl.transitions ?P. t_source t ∈ fsm_impl.states ?P ∧ t_input t ∈ fsm_impl.inputs ?P ∧ t_target t ∈ fsm_impl.states ?P ∧ t_output t ∈ fsm_impl.outputs ?P)" using p6a p6b by auto
ultimatelyshow"well_formed_fsm (FSM_Impl.product A B)" by blast qed
lemma product_simps[simp]: "initial (product A B) = (initial A, initial B)" "states (product A B) = (states A) × (states B)" "inputs (product A B) = inputs A ∪ inputs B" "outputs (product A B) = outputs A ∪ outputs B" by (transfer; simp)+
lemma product_transitions_def : "transitions (product A B) = {((qA,qB),x,y,(qA',qB')) | qA qB x y qA' qB' . (qA,x,y,qA') ∈ transitions A ∧ (qB,x,y,qB') ∈ transitions B}" by (transfer; simp)+
lemma product_transitions_alt_def : "transitions (product A B) = {((t_source tA, t_source tB),t_input tA, t_output tA, (t_target tA, t_target tB)) | tA tB . tA ∈ transitions A ∧ tB ∈ transitions B ∧ t_input tA = t_input tB ∧ t_output tA = t_output tB}"
(is"?T1 = ?T2") proof - have"∧ t . t ∈ ?T1 ==> t ∈ ?T2" proof - fix tt assume"tt ∈ ?T1" thenobtain qA qB x y qA' qB' where"tt = ((qA,qB),x,y,(qA',qB'))"and"(qA,x,y,qA') ∈ transitions A"and"(qB,x,y,qB') ∈ transitions B" unfolding product_transitions_def by blast thenhave"((t_source (qA,x,y,qA'), t_source (qB,x,y,qB')),t_input (qA,x,y,qA'), t_output (qA,x,y,qA'), (t_target (qA,x,y,qA'), t_target (qB,x,y,qB'))) ∈ ?T2" by auto thenshow"tt ∈ ?T2" unfolding‹tt = ((qA,qB),x,y,(qA',qB'))› fst_conv snd_conv by assumption qed moreoverhave"∧ t . t ∈ ?T2 ==> t ∈ ?T1" proof - fix tt assume"tt ∈ ?T2" thenobtain tA tB where"tt = ((t_source tA, t_source tB),t_input tA, t_output tA, (t_target tA, t_target tB))" and"tA ∈ transitions A"and"tB ∈ transitions B"and"t_input tA = t_input tB"and"t_output tA = t_output tB" by blast thenhave"(t_source tA, t_input tA, t_output tA, t_target tA) ∈ transitions A" and"(t_source tB, t_input tA, t_output tA, t_target tB) ∈ transitions B" by (metis prod.collapse)+ thenshow"tt ∈ ?T1" unfolding product_transitions_def ‹tt = ((t_source tA, t_source tB),t_input tA, t_output tA, (t_target tA, t_target tB))›by blast qed ultimatelyshow ?thesis by blast qed
lemma product_path_from_paths : assumes"path A (initial A) p1" and"path B (initial B) p2" and"p_io p1 = p_io p2" shows"path (product A B) (initial (product A B)) (zip_path p1 p2)" and"target (initial (product A B)) (zip_path p1 p2) = (target (initial A) p1, target (initial B) p2)" proof - have"initial (product A B) = (initial A, initial B)"by auto thenhave"(initial A, initial B) ∈ states (product A B)" by (metis fsm_initial)
have"length p1 = length p2"using assms(3) using map_eq_imp_length_eq by blast thenhave c: "path (product A B) (initial (product A B)) (zip_path p1 p2) ∧ target (initial (product A B)) (zip_path p1 p2) = (target (initial A) p1, target (initial B) p2)" using assms proof (induction p1 p2 rule: rev_induct2) case Nil
thenhave"path (product A B) (initial (product A B)) (zip_path [] [])" using‹initial (product A B) = (initial A, initial B)›‹(initial A, initial B) ∈states (product A B)› by (metis Nil_is_map_conv path.nil zip_Nil) moreoverhave"target (initial (product A B)) (zip_path [] []) = (target (initial A) [], target (initial B) [])" using‹initial (product A B) = (initial A, initial B)›by auto ultimatelyshow ?caseby fast next case (snoc x xs y ys)
have"path A (initial A) xs"using snoc.prems(1) by auto moreoverhave"path B (initial B) ys"using snoc.prems(2) by auto moreoverhave"p_io xs = p_io ys"using snoc.prems(3) by auto ultimatelyhave *:"path (product A B) (initial (product A B)) (zip_path xs ys)" and **:"target (initial (product A B)) (zip_path xs ys) = (target (initial A) xs, target (initial B) ys)" using snoc.IH by blast+ thenhave"(target (initial A) xs, target (initial B) ys) ∈ states (product A B)" by (metis (no_types, lifting) path_target_is_state) thenhave"(t_source x, t_source y) ∈ states (product A B)" using snoc.prems(1-2) by (metis path_cons_elim path_suffix)
have"x ∈ transitions A"using snoc.prems(1) by auto moreoverhave"y ∈ transitions B"using snoc.prems(2) by auto moreoverhave"t_input x = t_input y"using snoc.prems(3) by auto moreoverhave"t_output x = t_output y"using snoc.prems(3) by auto ultimatelyhave"((t_source x, t_source y), t_input x, t_output x, (t_target x, t_target y)) ∈ transitions (product A B)" unfolding product_transitions_alt_def by blast
moreoverhave"t_source x = target (initial A) xs"using snoc.prems(1) by auto moreoverhave"t_source y = target (initial B) ys"using snoc.prems(2) by auto ultimatelyhave"((target (initial A) xs, target (initial B) ys), t_input x, t_output x, (t_target x, t_target y)) ∈ transitions (product A B)" using‹(t_source x, t_source y) ∈ states (product A B)› by simp thenhave ***: "path (product A B) (initial (product A B)) ((zip_path xs ys)@[((target (initial A) xs, target (initial B) ys), t_input x, t_output x, (t_target x, t_target y))])" using * ** by (metis (no_types, lifting) fst_conv path_append_transition)
have"t_target x = target (initial A) (xs@[x])"by auto moreoverhave"t_target y = target (initial B) (ys@[y])"by auto ultimatelyhave ****: "target (initial (product A B)) ((zip_path xs ys)@[((target (initial A) xs, target (initial B) ys), t_input x, t_output x, (t_target x, t_target y))]) = (target (initial A) (xs@[x]), target (initial B) (ys@[y]))" by fastforce
have"(zip_path [x] [y]) = [((target (initial A) xs, target (initial B) ys), t_input x, t_output x, (t_target x, t_target y))]" using‹t_source x = target (initial A) xs›‹t_source y = target (initial B) ys›by auto moreoverhave"(zip_path (xs @ [x]) (ys @ [y])) = (zip_path xs ys)@(zip_path [x] [y])" using zip_path_last[of xs ys x y, OF snoc.hyps] by assumption ultimatelyhave *****:"(zip_path (xs@[x]) (ys@[y])) = (zip_path xs ys)@[((target (initial A) xs, target (initial B) ys), t_input x, t_output x, (t_target x, t_target y))]" by auto thenhave"path (product A B) (initial (product A B)) (zip_path (xs@[x]) (ys@[y]))" using *** by presburger moreoverhave"target (initial (product A B)) (zip_path (xs@[x]) (ys@[y])) = (target (initial A) (xs@[x]), target (initial B) (ys@[y]))" using **** ***** by auto ultimatelyshow ?caseby linarith qed
from c show"path (product A B) (initial (product A B)) (zip_path p1 p2)" by auto from c show"target (initial (product A B)) (zip_path p1 p2) = (target (initial A) p1, target (initial B) p2)" by auto qed
lemma paths_from_product_path : assumes"path (product A B) (initial (product A B)) p" shows"path A (initial A) (left_path p)" and"path B (initial B) (right_path p)" and"target (initial A) (left_path p) = fst (target (initial (product A B)) p)" and"target (initial B) (right_path p) = snd (target (initial (product A B)) p)" proof - have"path A (initial A) (left_path p) ∧ path B (initial B) (right_path p) ∧ target (initial A) (left_path p) = fst (target (initial (product A B)) p) ∧ target (initial B) (right_path p) = snd (target (initial (product A B)) p)" using assms proof (induction p rule: rev_induct) case Nil thenshow ?caseby auto next case (snoc t p) thenhave"path (product A B) (initial (product A B)) p"by fast thenhave"path A (initial A) (left_path p)" and"path B (initial B) (right_path p)" and"target (initial A) (left_path p) = fst (target (initial (product A B)) p)" and"target (initial B) (right_path p) = snd (target (initial (product A B)) p)" using snoc.IH by fastforce+
thenhave"t_source t = (target (initial A) (left_path p), target (initial B) (right_path p))" using snoc.prems by (metis (no_types, lifting) path_cons_elim path_suffix prod.collapse)
have ***: "target (initial A) (left_path (p@[t]))= fst (target (initial (product A B)) (p@[t]))" by fastforce have ****: "target (initial B) (right_path (p@[t]))= snd (target (initial (product A B)) (p@[t]))" by fastforce
have"t ∈ transitions (product A B)"using snoc.prems by auto
thenhave"(fst (t_source t), t_input t, t_output t, fst (t_target t)) ∈ transitions A" unfolding product_transitions_alt_def by force moreoverhave"target (initial A) (left_path p) = fst (t_source t)" using‹t_source t = (target (initial A) (left_path p), target (initial B) (right_path p))›by auto ultimatelyhave"path A (initial A) ((left_path p)@[(fst (t_source t), t_input t, t_output t, fst (t_target t))])" by (simp add: ‹path A (initial A) (map (λt. (fst (t_source t), t_input t, t_output t, fst (t_target t))) p)› path_append_transition) thenhave *: "path A (initial A) (left_path (p@[t]))"by auto
have"(snd (t_source t), t_input t, t_output t, snd (t_target t)) ∈ transitions B" using‹t ∈ transitions (product A B)›unfolding product_transitions_alt_def by auto moreoverhave"target (initial B) (right_path p) = snd (t_source t)" using‹t_source t = (target (initial A) (left_path p), target (initial B) (right_path p))›by auto ultimatelyhave"path B (initial B) ((right_path p)@[(snd (t_source t), t_input t, t_output t, snd (t_target t))])" by (simp add: ‹path B (initial B) (map (λt. (snd (t_source t), t_input t, t_output t, snd (t_target t))) p)› path_append_transition) thenhave **: "path B (initial B) (right_path (p@[t]))"by auto
show ?caseusing * ** *** **** by blast qed
thenshow"path A (initial A) (left_path p)" and"path B (initial B) (right_path p)" and"target (initial A) (left_path p) = fst (target (initial (product A B)) p)" and"target (initial B) (right_path p) = snd (target (initial (product A B)) p)"by linarith+ qed
lemma product_reachable_state_paths : assumes"(q1,q2) ∈ reachable_states (product A B)" obtains p1 p2 where"path A (initial A) p1" and"path B (initial B) p2" and"target (initial A) p1 = q1" and"target (initial B) p2 = q2" and"p_io p1 = p_io p2" and"path (product A B) (initial (product A B)) (zip_path p1 p2)" and"target (initial (product A B)) (zip_path p1 p2) = (q1,q2)" proof - let ?P = "product A B" from assms obtain p where"path ?P (initial ?P) p"and"target (initial ?P) p = (q1,q2)" unfolding reachable_states_def by auto
have"path A (initial A) (left_path p)" and"path B (initial B) (right_path p)" and"target (initial A) (left_path p) = q1" and"target (initial B) (right_path p) = q2" using paths_from_product_path[OF ‹path ?P (initial ?P) p›] ‹target (initial ?P) p = (q1,q2)›by auto
moreoverhave"p_io (left_path p) = p_io (right_path p)"by auto moreoverhave"path (product A B) (initial (product A B)) (zip_path (left_path p) (right_path p))" using‹path ?P (initial ?P) p›by auto moreoverhave"target (initial (product A B)) (zip_path (left_path p) (right_path p)) = (q1,q2)" using‹target (initial ?P) p = (q1,q2)›by auto ultimatelyshow ?thesis using that by blast qed
lemma product_reachable_states[iff] : "(q1,q2) ∈ reachable_states (product A B) ⟷ (∃ p1 p2 . path A (initial A) p1 ∧ path B (initial B) p2 ∧ target (initial A) p1 = q1 ∧ target (initial B) p2 = q2 ∧p_io p1 = p_io p2)" proof show"(q1,q2) ∈ reachable_states (product A B) ==> (∃ p1 p2 . path A (initial A) p1 ∧ path B (initial B) p2 ∧ target (initial A) p1 = q1 ∧ target (initial B) p2 = q2 ∧ p_io p1 = p_io p2)" using product_reachable_state_paths[of q1 q2 A B] by blast show"(∃ p1 p2 . path A (initial A) p1 ∧ path B (initial B) p2 ∧ target (initial A) p1 = q1 ∧ target (initial B) p2 = q2 ∧ p_io p1 = p_io p2) ==> (q1,q2) ∈ reachable_states (product A B)" proof - assume"(∃ p1 p2 . path A (initial A) p1 ∧ path B (initial B) p2 ∧ target (initial A) p1 = q1 ∧ target (initial B) p2 = q2 ∧ p_io p1 = p_io p2)" thenobtain p1 p2 where"path A (initial A) p1 ∧ path B (initial B) p2 ∧ target (initial A) p1 = q1 ∧ target (initial B) p2 = q2 ∧ p_io p1 = p_io p2" by blast thenshow ?thesis using product_path_from_paths[of A p1 B p2] unfolding reachable_states_def by (metis (mono_tags, lifting) mem_Collect_eq) qed qed
lemma zip_path_append_left_right : "length p1 = length p2 ==> zip_path (p1@(left_path p)) (p2@(right_path p)) = (zip_path p1 p2)@p" proof (induction p1 p2 rule: list_induct2) case Nil thenshow ?caseby (induction p; simp) next case (Cons x xs y ys) thenshow ?caseby simp qed
lemma product_path: "path (product A B) (q1,q2) p ⟷ (path A q1 (left_path p) ∧ path B q2 (right_path p))" proof (induction p arbitrary: q1 q2) case Nil thenshow ?caseby auto next case (Cons t p)
have"path (Product_FSM.product A B) (q1, q2) (t # p) ==> (path A q1 (left_path (t # p)) ∧ path B q2 (right_path (t # p)))" proof - assume"path (Product_FSM.product A B) (q1, q2) (t # p)" thenobtain x y qA' qB' where"t = ((q1,q2),x,y,(qA',qB'))"using prod.collapse by (metis path_cons_elim) thenhave"((q1,q2),x,y,(qA',qB')) ∈ transitions (product A B)" using‹path (Product_FSM.product A B) (q1, q2) (t # p)›by auto thenhave"(q1, x, y, qA') ∈ FSM.transitions A"and"(q2, x, y, qB') ∈ FSM.transitions B" unfolding product_transitions_def by blast+ moreoverhave"(path A qA' (left_path p) ∧ path B qB' (right_path p))" using Cons.IH[of qA' qB'] ‹path (Product_FSM.product A B) (q1, q2) (t # p)›unfolding‹t = ((q1,q2),x,y,(qA',qB'))›by auto ultimatelyshow ?thesis unfolding‹t = ((q1,q2),x,y,(qA',qB'))› by (simp add: path_prepend_t) qed
moreoverhave"path A q1 (left_path (t # p)) ==> path B q2 (right_path (t # p)) ==> path (Product_FSM.product A B) (q1, q2) (t # p)" proof - assume"path A q1 (left_path (t # p))"and"path B q2 (right_path (t # p))" thenobtain x y qA' qB' where"t = ((q1,q2),x,y,(qA',qB'))"using prod.collapse by (metis (no_types, lifting) fst_conv list.simps(9) path_cons_elim) thenhave"(q1, x, y, qA') ∈ FSM.transitions A"and"(q2, x, y, qB') ∈ FSM.transitions B" using‹path A q1 (left_path (t # p))›‹path B q2 (right_path (t # p))›by auto thenhave"((q1,q2),x,y,(qA',qB')) ∈ transitions (product A B)" unfolding product_transitions_def by blast moreoverhave"path (Product_FSM.product A B) (qA', qB') p" using Cons.IH[of qA' qB'] ‹path A q1 (left_path (t # p))›‹path B q2 (right_path (t # p))›unfolding‹t = ((q1,q2),x,y,(qA',qB'))›by auto ultimatelyshow"path (Product_FSM.product A B) (q1, q2) (t # p)" unfolding‹t = ((q1,q2),x,y,(qA',qB'))› by (simp add: path_prepend_t) qed
ultimatelyshow ?caseby force qed
lemma product_path_rev: assumes"p_io p1 = p_io p2" shows"path (product A B) (q1,q2) (zip_path p1 p2) ⟷ (path A q1 p1 ∧ path B q2 p2)" proof - have"length p1 = length p2"using assms using map_eq_imp_length_eq by blast thenhave"(map (λ t . (fst (t_source t), t_input t, t_output t, fst (t_target t))) (map (λ t . ((t_source (fst t), t_source (snd t)), t_input (fst t), t_output (fst t), (t_target (fst t), t_target (snd t)))) (zip p1 p2))) = p1" by (induction p1 p2 arbitrary: q1 q2 rule: list_induct2; auto)
ultimatelyshow ?thesis using product_path[of A B q1 q2 "(map (λ t . ((t_source (fst t), t_source (snd t)), t_input (fst t), t_output (fst t), (t_target (fst t), t_target (snd t)))) (zip p1 p2))"] by auto qed
lemma product_language_state : shows"LS (product A B) (q1,q2) = LS A q1 ∩ LS B q2" proof show"LS (product A B) (q1, q2) ⊆ LS A q1 ∩ LS B q2" proof fix io assume"io ∈ LS (product A B) (q1, q2)" thenobtain p where"io = p_io p" and"path (product A B) (q1,q2) p" by auto thenobtain p1 p2 where"path A q1 p1" and"path B q2 p2" and"io = p_io p1" and"io = p_io p2" using product_path[of A B q1 q2 p] by fastforce thenshow"io ∈ LS A q1 ∩ LS B q2" unfolding LS.simps by blast qed
show"LS A q1 ∩ LS B q2 ⊆ LS (product A B) (q1, q2)" proof fix io assume"io ∈ LS A q1 ∩ LS B q2" thenobtain p1 p2 where"path A q1 p1" and"path B q2 p2" and"io = p_io p1" and"io = p_io p2" and"p_io p1 = p_io p2" by auto
let ?p = "zip_path p1 p2"
have"length p1 = length p2" using‹p_io p1 = p_io p2› map_eq_imp_length_eq by blast moreoverhave"p_io ?p = p_io (map fst (zip p1 p2))"by auto ultimatelyhave"p_io ?p = p_io p1"by auto
thenhave"p_io ?p = io" using‹io = p_io p1›by auto moreoverhave"path (product A B) (q1, q2) ?p" using product_path_rev[OF ‹p_io p1 = p_io p2›, of A B q1 q2] ‹path A q1 p1›‹path B q2 p2›by auto ultimatelyshow"io ∈ LS (product A B) (q1, q2)" unfolding LS.simps by blast qed qed
lemma product_language : "L (product A B) = L A ∩ L B" unfolding product_simps product_language_state by blast
lemma product_transition_split_ob : assumes"t ∈ transitions (product A B)" obtains t1 t2 where"t1 ∈ transitions A ∧ t_source t1 = fst (t_source t) ∧ t_input t1 = t_input t ∧ t_output t1 = t_output t ∧ t_target t1 = fst (t_target t)" and"t2 ∈ transitions B ∧ t_source t2 = snd (t_source t) ∧ t_input t2 = t_input t∧ t_output t2 = t_output t ∧ t_target t2 = snd (t_target t)" using assms unfolding product_transitions_alt_def by auto
subsection‹Product Machines and Changing Initial States›
lemma product_from_reachable_next : assumes"((q1,q2),x,y,(q1',q2')) ∈ transitions (product (from_FSM M q1) (from_FSM M q2))" and"q1 ∈ states M" and"q2 ∈ states M" shows"(from_FSM (product (from_FSM M q1) (from_FSM M q2)) (q1', q2')) = (product (from_FSM M q1') (from_FSM M q2'))"
(is"?P1 = ?P2") proof - have"(q1,x,y,q1') ∈ transitions (from_FSM M q1)" and"(q2,x,y,q2') ∈ transitions (from_FSM M q2)" using assms(1) unfolding product_transitions_def by blast+ thenhave"q1' ∈ states (from_FSM M q1)"and"q2' ∈ states (from_FSM M q2)" using fsm_transition_target by auto
have"q1' ∈ states (from_FSM M q1')"and"q1' ∈ states M"and"q1 ∈ states M" using‹q1' ∈ FSM.states (FSM.from_FSM M q1)› assms(2) reachable_state_is_state by fastforce+ have"q2' ∈ states (from_FSM M q2')"and"q2' ∈ states M"and"q2 ∈ states M" using‹q2' ∈ FSM.states (FSM.from_FSM M q2)› assms(3) reachable_state_is_state by fastforce+
have"initial ?P1 = initial ?P2" and"states ?P1 = states ?P2" and"inputs ?P1 = inputs ?P2" and"outputs ?P1 = outputs ?P2" and"transitions ?P1 = transitions ?P2" using from_FSM_simps[OF fsm_transition_target[OF assms(1)]] unfolding snd_conv unfolding product_simps unfolding product_transitions_def unfolding from_FSM_simps[OF ‹q1' ∈ states M›] from_FSM_simps[OF ‹q2' ∈ states M›] unfolding from_FSM_simps[OF ‹q1 ∈ states M›] from_FSM_simps[OF ‹q2 ∈ states M›] by auto
thenshow ?thesis by (transfer; auto) qed
lemma from_FSM_product_inputs : assumes"q1 ∈ states M"and"q2 ∈ states M" shows"(inputs (product (from_FSM M q1) (from_FSM M q2))) = (inputs M)" by (simp add: assms(1) assms(2))
lemma from_FSM_product_outputs : assumes"q1 ∈ states M"and"q2 ∈ states M" shows"(outputs (product (from_FSM M q1) (from_FSM M q2))) = (outputs M)" by (simp add: assms(1) assms(2))
lemma from_FSM_product_initial : assumes"q1 ∈ states M"and"q2 ∈ states M" shows"initial (product (from_FSM M q1) (from_FSM M q2)) = (q1,q2)" by (simp add: assms(1) assms(2))
lemma product_from_reachable_next' : assumes"t ∈ transitions (product (from_FSM M (fst (t_source t))) (from_FSM M (snd (t_source t))))" and"fst (t_source t) ∈ states M" and"snd (t_source t) ∈ states M" shows"(from_FSM (product (from_FSM M (fst (t_source t))) (from_FSM M (snd (t_source t)))) (fst (t_target t),snd (t_target t))) = (product (from_FSM M (fst (t_target t))) (from_FSM M (snd (t_target t))))" proof - have"((fst (t_source t), snd (t_source t)), t_input t, t_output t, fst (t_target t), snd (t_target t)) = t" by simp thenshow ?thesis by (metis (no_types) assms(1) assms(2) assms(3) product_from_reachable_next) qed
lemma product_from_reachable_next'_path : assumes"t ∈ transitions (product (from_FSM M (fst (t_source t))) (from_FSM M (snd (t_source t))))" and"fst (t_source t) ∈ states M" and"snd (t_source t) ∈ states M" shows"path (from_FSM (product (from_FSM M (fst (t_source t))) (from_FSM M (snd (t_source t)))) (fst (t_target t),snd (t_target t))) (fst (t_target t),snd (t_target t)) p = path (product (from_FSM M (fst (t_target t))) (from_FSM M (snd (t_target t)))) (fst (t_target t),snd (t_target t)) p"
(is"path ?P1 ?q p = path ?P2 ?q p") proof - have i1: "initial ?P1 = ?q" using assms(1) fsm_transition_target by fastforce have i2: "initial ?P2 = ?q" proof - have"((fst (t_source t), snd (t_source t)), t_input t, t_output t, fst (t_target t), snd (t_target t)) = t" by auto thenshow ?thesis by (metis (no_types) assms(1) assms(2) assms(3) i1 product_from_reachable_next) qed
have h12: "transitions ?P1 = transitions ?P2"using product_from_reachable_next'[OF assms] by simp
show ?thesis proof (induction p rule: rev_induct) case Nil thenshow ?case by (metis (full_types) i1 i2 fsm_initial path.nil) next case (snoc t p) show ?case by (metis h12 path_append_transition path_append_transition_elim(1) path_append_transition_elim(2) path_append_transition_elim(3) snoc.IH) qed qed
lemma product_from_transition: assumes"(q1',q2') ∈ states (product (from_FSM M q1) (from_FSM M q2))" and"q1 ∈ states M" and"q2 ∈ states M" shows"transitions (product (from_FSM M q1') (from_FSM M q2')) = transitions (product (from_FSM M q1) (from_FSM M q2))" proof - have"q1' ∈ states M"and"q2' ∈ states M" using assms(1) unfolding product_simps from_FSM_simps[OF assms(2)] from_FSM_simps[OF assms(3)] by auto show ?thesis unfolding product_transitions_def from_FSM_simps[OF ‹q1 ∈ states M›] from_FSM_simps[OF ‹q1' ∈ states M›] from_FSM_simps[OF ‹q2 ∈ states M›] from_FSM_simps[OF ‹q2' ∈ states M›] by blast qed
lemma product_from_path: assumes"(q1',q2') ∈ states (product (from_FSM M q1) (from_FSM M q2))" and"q1 ∈ states M" and"q2 ∈ states M" and"path (product (from_FSM M q1') (from_FSM M q2')) (q1',q2') p" shows"path (product (from_FSM M q1) (from_FSM M q2)) (q1',q2') p" by (metis (no_types, lifting) assms(1) assms(2) assms(3) assms(4) from_FSM_path_initial from_FSM_simps(5) from_from mem_Sigma_iff product_path product_simps(2))
lemma product_from_path_previous : assumes"path (product (from_FSM M (fst (t_target t))) (from_FSM M (snd (t_target t)))) (t_target t) p" (is"path ?Pt (t_target t) p") and"t ∈ transitions (product (from_FSM M q1) (from_FSM M q2))" and"q1 ∈ states M" and"q2 ∈ states M" shows"path (product (from_FSM M q1) (from_FSM M q2)) (t_target t) p" (is"path ?P (t_target t) p") by (metis assms(1) assms(2) assms(3) assms(4) fsm_transition_target prod.collapse product_from_path)
lemma product_from_transition_shared_state : assumes"t ∈ transitions (product (from_FSM M q1') (from_FSM M q2'))" and"(q1',q2') ∈ states (product (from_FSM M q1) (from_FSM M q2))" and"q1 ∈ states M" and"q2 ∈ states M" shows"t ∈ transitions (product (from_FSM M q1) (from_FSM M q2))" by (metis assms product_from_transition)
lemma product_from_not_completely_specified : assumes"¬ completely_specified_state (product (from_FSM M q1) (from_FSM M q2)) (q1',q2')" and"(q1',q2') ∈ states (product (from_FSM M q1) (from_FSM M q2))" and"q1 ∈ states M" and"q2 ∈ states M" shows"¬ completely_specified_state (product (from_FSM M q1') (from_FSM M q2')) (q1',q2')" proof - have"q1' ∈ states M"and"q2' ∈ states M" using assms(2) unfolding product_simps from_FSM_simps[OF assms(3)] from_FSM_simps[OF assms(4)] by auto show ?thesis
using from_FSM_product_inputs[OF assms(3) assms(4)] using from_FSM_product_inputs[OF ‹q1' ∈ states M›‹q2' ∈ states M› ] proof - have"FSM.transitions (Product_FSM.product (FSM.from_FSM M q1') (FSM.from_FSM M q2')) = FSM.transitions (Product_FSM.product (FSM.from_FSM M q1) (FSM.from_FSM M q2))" by (metis (no_types) ‹(q1', q2') ∈ FSM.states (Product_FSM.product (FSM.from_FSM M q1) (FSM.from_FSM M q2))› assms(3) assms(4) product_from_transition) thenshow ?thesis using‹FSM.inputs (Product_FSM.product (FSM.from_FSM M q1') (FSM.from_FSM M q2')) = FSM.inputs M›‹FSM.inputs (Product_FSM.product (FSM.from_FSM M q1) (FSM.from_FSM M q2)) = FSM.inputs M›‹¬ completely_specified_state (Product_FSM.product (FSM.from_FSM M q1) (FSM.from_FSM M q2)) (q1', q2')›by fastforce qed qed
lemma from_product_initial_paths_ex : assumes"q1 ∈ states M" and"q2 ∈ states M" shows"(∃p1 p2. path (from_FSM M q1) (initial (from_FSM M q1)) p1 ∧ path (from_FSM M q2) (initial (from_FSM M q2)) p2 ∧ target (initial (from_FSM M q1)) p1 = q1 ∧ target (initial (from_FSM M q2)) p2 = q2 ∧ p_io p1 = p_io p2)" proof - have"path (from_FSM M q1) (initial (from_FSM M q1)) []"by blast moreoverhave"path (from_FSM M q2) (initial (from_FSM M q2)) []"by blast moreoverhave" target (initial (from_FSM M q1)) [] = q1 ∧ target (initial (from_FSM M q2)) [] = q2 ∧ p_io [] = p_io []" unfolding from_FSM_simps[OF assms(1)] from_FSM_simps[OF assms(2)] by auto ultimatelyshow ?thesis by blast qed
lemma product_observable_self_transitions : assumes"q ∈ reachable_states (product M M)" and"observable M" shows"fst q = snd q" proof - let ?P = "product M M"
have"∧ p . path ?P (initial ?P) p ==> fst (target (initial ?P) p) = snd (target (initial ?P) p)" proof - fix p assume"path ?P (initial ?P) p" thenshow"fst (target (initial ?P) p) = snd (target (initial ?P) p)" proof (induction p rule: rev_induct) case Nil thenshow ?caseby simp next case (snoc t p)
have"path ?P (initial ?P) p"and"path ?P (target (initial ?P) p) [t]" using path_append_elim[of ?P "initial ?P" p "[t]", OF ‹path (product M M) (initial (product M M)) (p @ [t])›] by blast+ thenhave"t ∈ transitions ?P" by blast have"t_source t = target (initial ?P) p" using snoc.prems by fastforce
let ?t1 = "(fst (t_source t), t_input t, t_output t, fst (t_target t))" let ?t2 = "(snd (t_source t), t_input t, t_output t, snd (t_target t))" have"?t1 ∈ transitions M"and"?t2 ∈ transitions M" using product_transition_split[OF ‹t ∈ transitions ?P›] by auto moreoverhave"t_source ?t1 = t_source ?t2" using‹t_source t = target (initial ?P) p› snoc.IH[OF ‹path ?P (initial ?P) p›] by (metis fst_conv) moreoverhave"t_input ?t1 = t_input ?t2" by auto moreoverhave"t_output ?t1 = t_output ?t2" by auto ultimatelyhave"t_target ?t1 = t_target ?t2" using‹observable M›unfolding observable.simps by blast thenhave"fst (t_target t) = snd (t_target t)" by auto thenshow ?caseunfolding target.simps visited_states.simps proof - show"fst (last (initial (product M M) # map t_target (p @ [t]))) = snd (last (initial (product M M) # map t_target (p @ [t])))" using‹fst (t_target t) = snd (t_target t)› last_map last_snoc length_append_singleton length_map by force qed qed qed
thenshow ?thesis using assms(1) unfolding reachable_states_def by blast qed
lemma product_from_reachable_path' : assumes"path (product (from_FSM M q1) (from_FSM M q2)) (q1', q2') p" and"q1 ∈ reachable_states M" and"q2 ∈ reachable_states M" shows"path (product (from_FSM M q1') (from_FSM M q2')) (q1', q2') p" by (meson assms(1) assms(2) assms(3) from_FSM_path from_FSM_path_rev_initial product_path reachable_state_is_state)
lemma product_from : assumes"q1 ∈ states M" and"q2 ∈ states M" shows"product (from_FSM M q1) (from_FSM M q2) = from_FSM (product M M) (q1,q2)" (is"?PF = ?FP") proof - have"(q1,q2) ∈ states (product M M)" using assms unfolding product_simps by auto
have"initial ?FP = initial ?PF" and"inputs ?FP = inputs ?PF" and"outputs ?FP = outputs ?PF" and"states ?FP = states ?PF" and"transitions ?FP = transitions ?PF" unfolding product_simps
from_FSM_simps[OF assms(1)]
from_FSM_simps[OF assms(2)]
from_FSM_simps[OF ‹(q1,q2) ∈ states (product M M)›]
product_transitions_def by auto thenshow ?thesis by (transfer; auto) qed
lemma product_from_from : assumes"(q1',q2') ∈ states (product (from_FSM M q1) (from_FSM M q2))" and"q1 ∈ states M" and"q2 ∈ states M" shows"(product (from_FSM M q1') (from_FSM M q2')) = (from_FSM (product (from_FSM M q1) (from_FSM M q2)) (q1',q2'))" using product_from by (metis (no_types, lifting) assms(1) assms(2) assms(3) from_FSM_simps(5) from_from mem_Sigma_iff product_simps(2))
lemma submachine_transition_product_from : assumes"is_submachine S (product (from_FSM M q1) (from_FSM M q2))" and"((q1,q2),x,y,(q1',q2')) ∈ transitions S" and"q1 ∈ states M" and"q2 ∈ states M" shows"is_submachine (from_FSM S (q1',q2')) (product (from_FSM M q1') (from_FSM M q2'))" proof - have"((q1,q2),x,y,(q1',q2')) ∈ transitions (product (from_FSM M q1) (from_FSM M q2))" using assms(1) assms(2) by auto have"(q1',q2') ∈ states S"using fsm_transition_target assms(2) by auto show ?thesis using product_from_reachable_next[OF ‹((q1,q2),x,y,(q1',q2')) ∈ transitions (product (from_FSM M q1) (from_FSM M q2))› assms(3,4)]
submachine_from[OF assms(1) ‹(q1',q2') ∈ states S›] by simp qed
lemma submachine_transition_complete_product_from : assumes"is_submachine S (product (from_FSM M q1) (from_FSM M q2))" and"completely_specified S" and"((q1,q2),x,y,(q1',q2')) ∈ transitions S" and"q1 ∈ states M" and"q2 ∈ states M" shows"completely_specified (from_FSM S (q1',q2'))" proof - let ?P = "(product (from_FSM M q1) (from_FSM M q2))" let ?P' = "(product (from_FSM M q1') (from_FSM M q2'))" let ?F = "(from_FSM S (q1',q2'))"
have"initial ?P = (q1,q2)" by (simp add: assms(4) assms(5) reachable_state_is_state)
thenhave"initial S = (q1,q2)" using assms(1) by (metis is_submachine.simps) thenhave"(q1',q2') ∈ states S" using assms(3) using fsm_transition_target by fastforce thenhave"states ?F = states S" using from_FSM_simps(5) by simp moreoverhave"inputs ?F = inputs S" using from_FSM_simps(2) ‹(q1',q2') ∈ states S›by simp ultimatelyshow"completely_specified ?F" using assms(2) unfolding completely_specified.simps by (meson assms(2) completely_specified.elims(2) from_FSM_completely_specified) qed
lemma acyclic_product : assumes"acyclic B" shows"acyclic (product A B)" proof - show"acyclic (product A B)" proof (rule ccontr) assume"¬ FSM.acyclic (Product_FSM.product A B)" thenobtain p where"path (product A B) (initial (product A B)) p"and"¬ distinct (visited_states (initial (product A B)) p)" by auto
have"path B (initial B) (right_path p)" using product_path[of A B] ‹path (product A B) (initial (product A B)) p› unfolding product_simps by auto
moreoverhave"¬ distinct (visited_states (initial B) (right_path p))" proof - obtain i j where"i < j"and"j < length ((initial A, initial B) # map t_target p)"and"((initial A, initial B) # map t_target p) ! i = ((initial A, initial B) # map t_target p) ! j" using‹¬ distinct (visited_states (initial (product A B)) p)› unfolding visited_states.simps product_simps using non_distinct_repetition_indices by blast
thenhave"snd (((initial A, initial B) # map t_target p) ! i) = snd (((initial A, initial B) # map t_target p) ! j)" by simp
have * :"i < length ((initial B) # map t_target (right_path p))" and **:"j < length ((initial B) # map t_target (right_path p))" using‹i < j›‹j < length ((initial A, initial B) # map t_target p)›by auto
have right_nth: "∧ i . i < length ((initial B) # map t_target (right_path p)) ==> ((initial B) # map t_target (right_path p)) ! i = snd (((initial A, initial B) # map t_target p) ! i)" proof - have"((initial B) # map t_target (right_path p)) ! 0 = snd (((initial A, initial B) # map t_target p) ! 0)" by simp moreoverhave"∧ i . Suc i < length ((initial B) # map t_target (right_path p)) ==> ((initial B) # map t_target (right_path p)) ! Suc i = snd (((initial A, initial B) # map t_target p) ! Suc i)" by auto ultimatelyshow"∧ i . i < length ((initial B) # map t_target (right_path p)) ==> ((initial B) # map t_target (right_path p)) ! i = snd (((initial A, initial B) # map t_target p) ! i)" using less_Suc_eq_0_disj by auto qed
have"((initial B) # map t_target (right_path p)) ! i = ((initial B) # map t_target (right_path p)) ! j" using‹snd (((initial A, initial B) # map t_target p) ! i) = snd (((initial A, initial B) # map t_target p) ! j)› unfolding right_nth[OF *] right_nth[OF **] by assumption thenshow ?thesis unfolding visited_states.simps product_simps using non_distinct_repetition_indices_rev[OF ‹i < j› **] by blast qed ultimatelyshow"False" using‹acyclic B›unfolding acyclic.simps by blast qed qed
lemma acyclic_product_path_length : assumes"acyclic B" and"path (product A B) (initial (product A B)) p" shows"length p < size B" proof - have *:"path B (initial B) (right_path p)" using product_path[of A B] ‹path (product A B) (initial (product A B)) p› unfolding product_simps by auto thenhave **: "distinct (visited_states (initial B) (right_path p))" using assms unfolding acyclic.simps by blast
have"length (right_path p) < size B" using acyclic_path_length_limit[OF * **] by assumption thenshow"length p < size B" by auto qed
lemma acyclic_language_alt_def : assumes"acyclic A" shows"image p_io (acyclic_paths_up_to_length A (initial A) (size A - 1)) = L A" proof - let ?ps = "acyclic_paths_up_to_length A (initial A) (size A - 1)" have"∧ p . path A (initial A) p ==> length p ≤ FSM.size A - 1" using acyclic_path_length_limit assms unfolding acyclic.simps by fastforce thenhave"?ps = {p. path A (initial A) p}" using assms unfolding acyclic_paths_up_to_length.simps acyclic.simps by blast thenshow ?thesis unfolding LS.simps by blast qed
definition acyclic_language_intersection :: "('a,'b,'c) fsm ==> ('d,'b,'c) fsm ==>('b × 'c) list set"where "acyclic_language_intersection M A = (let P = product M A in image p_io (acyclic_paths_up_to_length P (initial P) (size A - 1)))"
lemma acyclic_language_intersection_completeness : assumes"acyclic A" shows"acyclic_language_intersection M A = L M ∩ L A" proof - let ?P = "product M A" let ?ps = "acyclic_paths_up_to_length ?P (initial ?P) (size A - 1)"
have"L ?P = L M ∩ L A" using product_language by blast
have"∧ p . path ?P (initial ?P) p ==> length p ≤ FSM.size A - 1" using acyclic_product_path_length[OF assms] by fastforce thenhave"?ps = {p. path ?P (initial ?P) p}" using acyclic_product[OF assms] unfolding acyclic_paths_up_to_length.simps acyclic.simps by blast thenhave"image p_io ?ps = L ?P" unfolding LS.simps by blast thenshow ?thesis using product_language unfolding acyclic_language_intersection_def Let_def 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.