diff --git a/thys/Buchi_Complementation/Complementation.thy b/thys/Buchi_Complementation/Complementation.thy --- a/thys/Buchi_Complementation/Complementation.thy +++ b/thys/Buchi_Complementation/Complementation.thy @@ -1,606 +1,605 @@ section \Complementation\ theory Complementation imports "Transition_Systems_and_Automata.Maps" "Ranking" begin subsection \Level Rankings and Complementation States\ type_synonym 'state lr = "'state \ nat" definition lr_succ :: "('label, 'state) nba \ 'label \ 'state lr \ 'state lr set" where "lr_succ A a f \ {g. dom g = \ (transition A a ` dom f) \ (\ p \ dom f. \ q \ transition A a p. the (g q) \ the (f p)) \ (\ q \ dom g. accepting A q \ even (the (g q)))}" type_synonym 'state st = "'state set" definition st_succ :: "('label, 'state) nba \ 'label \ 'state lr \ 'state st \ 'state st" where "st_succ A a g P \ {q \ if P = {} then dom g else \ (transition A a ` P). even (the (g q))}" type_synonym 'state cs = "'state lr \ 'state st" definition complement_succ :: "('label, 'state) nba \ 'label \ 'state cs \ 'state cs set" where "complement_succ A a \ \ (f, P). {(g, st_succ A a g P) |g. g \ lr_succ A a f}" definition complement :: "('label, 'state) nba \ ('label, 'state cs) nba" where "complement A \ nba (alphabet A) ({const (Some (2 * card (nodes A))) |` initial A} \ {{}}) (complement_succ A) (\ (f, P). P = {})" lemma dom_nodes: assumes "fP \ nodes (complement A)" shows "dom (fst fP) \ nodes A" using assms unfolding complement_def complement_succ_def lr_succ_def by (induct) (auto, blast) lemma ran_nodes: assumes "fP \ nodes (complement A)" shows "ran (fst fP) \ {0 .. 2 * card (nodes A)}" using assms proof induct case (initial fP) show ?case using initial unfolding complement_def by (auto) (metis eq_refl option.inject ran_restrictD) next case (execute fP agQ) obtain f P where 1: "fP = (f, P)" by force have 2: "ran f \ {0 .. 2 * card (nodes A)}" using execute(2) unfolding 1 by auto obtain a g Q where 3: "agQ = (a, (g, Q))" using prod_cases3 by this have 4: "p \ dom f \ q \ transition A a p \ the (g q) \ the (f p)" for p q using execute(3) unfolding 1 3 complement_def nba.simps complement_succ_def lr_succ_def by simp have 8: "dom g = \((transition A a) ` (dom f))" using execute(3) unfolding 1 3 complement_def nba.simps complement_succ_def lr_succ_def by simp show ?case unfolding 1 3 ran_def proof safe fix q k assume 5: "fst (snd (a, (g, Q))) q = Some k" have 6: "q \ dom g" using 5 by auto obtain p where 7: "p \ dom f" "q \ transition A a p" using 6 unfolding 8 by auto have "k = the (g q)" using 5 by auto also have "\ \ the (f p)" using 4 7 by this also have "\ \ 2 * card (nodes A)" using 2 7(1) by (simp add: domD ranI subset_eq) finally show "k \ {0 .. 2 * card (nodes A)}" by auto qed qed lemma states_nodes: assumes "fP \ nodes (complement A)" shows "snd fP \ nodes A" using assms proof induct case (initial fP) show ?case using initial unfolding complement_def by auto next case (execute fP agQ) obtain f P where 1: "fP = (f, P)" by force have 2: "P \ nodes A" using execute(2) unfolding 1 by auto obtain a g Q where 3: "agQ = (a, (g, Q))" using prod_cases3 by this have 11: "a \ alphabet A" using execute(3) unfolding 3 complement_def by auto have 10: "(g, Q) \ nodes (complement A)" using execute(1, 3) unfolding 1 3 by auto have 4: "dom g \ nodes A" using dom_nodes[OF 10] by simp have 5: "\ (transition A a ` P) \ nodes A" using 2 11 by auto have 6: "Q \ nodes A" using execute(3) unfolding 1 3 complement_def nba.simps complement_succ_def st_succ_def using 4 5 by (auto split: if_splits) show ?case using 6 unfolding 3 by auto qed theorem complement_finite: assumes "finite (nodes A)" shows "finite (nodes (complement A))" proof - let ?lrs = "{f. dom f \ nodes A \ ran f \ {0 .. 2 * card (nodes A)}}" have 1: "finite ?lrs" using finite_set_of_finite_maps' assms by auto let ?states = "Pow (nodes A)" have 2: "finite ?states" using assms by simp have "nodes (complement A) \ ?lrs \ ?states" by (force dest: dom_nodes ran_nodes states_nodes) also have "finite \" using 1 2 by simp finally show ?thesis by this qed lemma complement_trace_snth: assumes "run (complement A) (w ||| r) p" defines "m \ p ## trace (w ||| r) p" obtains "fst (m !! Suc k) \ lr_succ A (w !! k) (fst (m !! k))" "snd (m !! Suc k) = st_succ A (w !! k) (fst (m !! Suc k)) (snd (m !! k))" proof have 1: "r !! k \ transition (complement A) (w !! k) (m !! k)" using nba.run_snth assms by force show "fst (m !! Suc k) \ lr_succ A (w !! k) (fst (m !! k))" using assms(2) 1 unfolding complement_def complement_succ_def nba.trace_alt_def by auto show "snd (m !! Suc k) = st_succ A (w !! k) (fst (m !! Suc k)) (snd (m !! k))" using assms(2) 1 unfolding complement_def complement_succ_def nba.trace_alt_def by auto qed subsection \Word in Complement Language Implies Ranking\ lemma complement_ranking: assumes "w \ language (complement A)" obtains f where "ranking A w f" proof - obtain r p where 1: "run (complement A) (w ||| r) p" "p \ initial (complement A)" "infs (accepting (complement A)) (p ## r)" using assms by rule let ?m = "p ## r" obtain 100: "fst (?m !! Suc k) \ lr_succ A (w !! k) (fst (?m !! k))" "snd (?m !! Suc k) = st_succ A (w !! k) (fst (?m !! Suc k)) (snd (?m !! k))" for k using complement_trace_snth 1(1) unfolding nba.trace_alt_def szip_smap_snd by metis define f where "f \ \ (k, q). the (fst (?m !! k) q)" define P where "P k \ snd (?m !! k)" for k have 2: "snd v \ dom (fst (?m !! fst v))" if "v \ gunodes A w" for v using that proof induct case (initial v) then show ?case using 1(2) unfolding complement_def by auto next case (execute v u) - have "snd u \ \ ((transition A (w !! fst v)) ` (dom (fst (?m !! fst v))))" + have "snd u \ \ (transition A (w !! fst v) ` dom (fst (?m !! fst v)))" using execute(2, 3) by auto also have "\ = dom (fst (?m !! Suc (fst v)))" using 100 unfolding lr_succ_def by simp also have "Suc (fst v) = fst u" using execute(3) by auto finally show ?case by this qed have 3: "f u \ f v" if 10: "v \ gunodes A w" and 11: "u \ gusuccessors A w v" for u v proof - have 15: "snd u \ transition A (w !! fst v) (snd v)" using 11 by auto have 16: "snd v \ dom (fst (?m !! fst v))" using 2 10 by this have "f u = the (fst (?m !! fst u) (snd u))" unfolding f_def by (simp add: case_prod_beta) also have "fst u = Suc (fst v)" using 11 by auto also have "the (fst (?m !! \) (snd u)) \ the (fst (?m !! fst v) (snd v))" using 100 15 16 unfolding lr_succ_def by auto also have "\ = f v" unfolding f_def by (simp add: case_prod_beta) finally show "f u \ f v" by this qed have 4: "\ l \ k. P l = {}" for k proof - have 15: "infs (\ (k, P). P = {}) ?m" using 1(3) unfolding complement_def by auto obtain l where 17: "l \ k" "snd (?m !! l) = {}" using 15 unfolding infs_snth by force have 19: "P l = {}" unfolding P_def using 17 by auto show ?thesis using 19 17(1) by auto qed show ?thesis proof (rule that, unfold ranking_def, intro conjI ballI impI allI) fix v assume "v \ gunodes A w" then show "f v \ 2 * card (nodes A)" proof induct case (initial v) then show ?case using 1(2) unfolding complement_def f_def by auto next case (execute v u) have "f u \ f v" using 3[OF execute(1)] execute(3) by simp also have "\ \ 2 * card (nodes A)" using execute(2) by this finally show ?case by this qed next fix v u assume 10: "v \ gunodes A w" assume 11: "u \ gusuccessors A w v" show "f u \ f v" using 3 10 11 by this next fix v assume 10: "v \ gunodes A w" assume 11: "gaccepting A v" show "even (f v)" using 10 proof cases case (initial) then show ?thesis using 1(2) unfolding complement_def f_def by auto next case (execute u) have 12: "snd v \ dom (fst (?m !! fst v))" using execute graph.nodes.execute 2 by blast have 12: "snd v \ dom (fst (?m !! Suc (fst u)))" using 12 execute(2) by auto have 13: "accepting A (snd v)" using 11 by auto have "f v = the (fst (?m !! fst v) (snd v))" unfolding f_def by (simp add: case_prod_beta) also have "fst v = Suc (fst u)" using execute(2) by auto also have "even (the (fst (?m !! Suc (fst u)) (snd v)))" using 100 12 13 unfolding lr_succ_def by simp finally show ?thesis by this qed next fix v s k assume 10: "v \ gunodes A w" assume 11: "gurun A w s v" assume 12: "smap f (gtrace s v) = sconst k" show "odd k" proof assume 13: "even k" obtain t u where 14: "u \ ginitial A" "gupath A w t u" "v = gtarget t u" using 10 by auto obtain l where 15: "l \ length t" "P l = {}" using 4 by auto - obtain l' where 16: "l' \ Suc l" "P l' = {}" using 4 by auto have 30: "gurun A w (t @- s) u" using 11 14 by auto have 21: "fst (gtarget (stake (Suc l) (t @- s)) u) = Suc l" for l unfolding sscan_snth[symmetric] using 30 14(1) by (auto elim!: grun_elim) have 17: "snd (gtarget (stake (Suc l + i) (t @- s)) u) \ P (Suc l + i)" for i proof (induct i) case (0) have 20: "gtarget (stake (Suc l) (t @- s)) u \ gunodes A w" using 14 11 by (force simp add: 15(1) le_SucI graph.run_stake stake_shift) have "snd (gtarget (stake (Suc l) (t @- s)) u) \ dom (fst (?m !! fst (gtarget (stake (Suc l) (t @- s)) u)))" using 2[OF 20] by this also have "fst (gtarget (stake (Suc l) (t @- s)) u) = Suc l" using 21 by this finally have 22: "snd (gtarget (stake (Suc l) (t @- s)) u) \ dom (fst (?m !! Suc l))" by this have "gtarget (stake (Suc l) (t @- s)) u = gtrace (t @- s) u !! l" unfolding sscan_snth by rule also have "\ = gtrace s v !! (l - length t)" using 15(1) by simp also have "f \ = smap f (gtrace s v) !! (l - length t)" by simp also have "smap f (gtrace s v) = sconst k" unfolding 12 by rule also have "sconst k !! (l - length t) = k" by simp finally have 23: "even (f (gtarget (stake (Suc l) (t @- s)) u))" using 13 by simp - have 24: "snd (gtarget (stake (Suc l) (t @- s)) u) \ + have "snd (gtarget (stake (Suc l) (t @- s)) u) \ {p \ dom (fst (?m !! Suc l)). even (f (Suc l, p))}" using 21 22 23 by (metis (mono_tags, lifting) mem_Collect_eq prod.collapse) also have "\ = st_succ A (w !! l) (fst (?m !! Suc l)) (P l)" unfolding 15(2) st_succ_def f_def by simp also have "\ = P (Suc l)" using 100(2) unfolding P_def by rule - also have "P (Suc l) = P (l + Suc 0)" by simp finally show ?case by auto next case (Suc i) have 20: "P (Suc l + i) \ {}" using Suc by auto have 21: "fst (gtarget (stake (Suc l + Suc i) (t @- s)) u) = Suc l + Suc i" using 21 by (simp add: stake_shift) have "gtarget (stake (Suc l + Suc i) (t @- s)) u = gtrace (t @- s) u !! (l + Suc i)" unfolding sscan_snth by simp also have "\ \ gusuccessors A w (gtarget (stake (Suc (l + i)) (t @- s)) u)" using graph.run_snth[OF 30, of "l + Suc i"] by simp finally have 220: "snd (gtarget (stake (Suc (Suc l + i)) (t @- s)) u) \ transition A (w !! (Suc l + i)) (snd (gtarget (stake (Suc (l + i)) (t @- s)) u))" using 21 by auto have 22: "snd (gtarget (stake (Suc l + Suc i) (t @- s)) u) \ \ (transition A (w !! (Suc l + i)) ` P (Suc l + i))" using 220 Suc by auto have "gtarget (stake (Suc l + Suc i) (t @- s)) u = gtrace (t @- s) u !! (l + Suc i)" unfolding sscan_snth by simp also have "\ = gtrace s v !! (l + Suc i - length t)" using 15(1) by (metis add.commute shift_snth_ge sscan_const trans_le_add2) also have "f \ = smap f (gtrace s v) !! (l + Suc i - length t)" by simp also have "smap f (gtrace s v) = sconst k" unfolding 12 by rule also have "sconst k !! (l + Suc i - length t) = k" by simp finally have 23: "even (f (gtarget (stake (Suc l + Suc i) (t @- s)) u))" using 13 by auto have "snd (gtarget (stake (Suc l + Suc i) (t @- s)) u) \ {p \ \ (transition A (w !! (Suc l + i)) ` P (Suc l + i)). even (f (Suc (Suc l + i), p))}" using 21 22 23 by (metis (mono_tags) add_Suc_right mem_Collect_eq prod.collapse) also have "\ = st_succ A (w !! (Suc l + i)) (fst (?m !! Suc (Suc l + i))) (P (Suc l + i))" unfolding st_succ_def f_def using 20 by simp also have "\ = P (Suc (Suc l + i))" unfolding 100(2)[folded P_def] by rule also have "\ = P (Suc l + Suc i)" by simp finally show ?case by this qed + obtain l' where 16: "l' \ Suc l" "P l' = {}" using 4 by auto show "False" using 16 17 using nat_le_iff_add by auto qed qed qed subsection \Ranking Implies Word in Complement Language\ definition reach where "reach A w i \ {target r p |r p. path A r p \ p \ initial A \ map fst r = stake i w}" lemma reach_0[simp]: "reach A w 0 = initial A" unfolding reach_def by auto lemma reach_Suc_empty: assumes "w !! n \ alphabet A" shows "reach A w (Suc n) = {}" proof safe fix q assume 1: "q \ reach A w (Suc n)" obtain r p where 2: "q = target r p" "path A r p" "p \ initial A" "map fst r = stake (Suc n) w" using 1 unfolding reach_def by blast have 3: "path A (take n r @ drop n r) p" using 2(2) by simp have 4: "map fst r = stake n w @ [w !! n]" using 2(4) stake_Suc by auto have 5: "map snd r = take n (map snd r) @ [q]" using 2(1, 4) 4 by (metis One_nat_def Suc_inject Suc_neq_Zero Suc_pred append.right_neutral append_eq_conv_conj drop_map id_take_nth_drop last_ConsR last_conv_nth length_0_conv length_map length_stake lessI nba.target_alt_def nba.states_alt_def zero_less_Suc) have 6: "drop n r = [(w !! n, q)]" using 4 5 by (metis append_eq_conv_conj append_is_Nil_conv append_take_drop_id drop_map length_greater_0_conv length_stake stake_cycle_le stake_invert_Nil take_map zip_Cons_Cons zip_map_fst_snd) show "q \ {}" using assms 3 unfolding 6 by auto qed lemma reach_Suc_succ: assumes "w !! n \ alphabet A" - shows "reach A w (Suc n) = \((transition A (w !! n) ` (reach A w n)))" + shows "reach A w (Suc n) = \ (transition A (w !! n) ` reach A w n)" proof safe fix q assume 1: "q \ reach A w (Suc n)" obtain r p where 2: "q = target r p" "path A r p" "p \ initial A" "map fst r = stake (Suc n) w" using 1 unfolding reach_def by blast have 3: "path A (take n r @ drop n r) p" using 2(2) by simp have 4: "map fst r = stake n w @ [w !! n]" using 2(4) stake_Suc by auto have 5: "map snd r = take n (map snd r) @ [q]" using 2(1, 4) 4 by (metis One_nat_def Suc_inject Suc_neq_Zero Suc_pred append.right_neutral append_eq_conv_conj drop_map id_take_nth_drop last_ConsR last_conv_nth length_0_conv length_map length_stake lessI nba.target_alt_def nba.states_alt_def zero_less_Suc) have 6: "drop n r = [(w !! n, q)]" using 4 5 by (metis append_eq_conv_conj append_is_Nil_conv append_take_drop_id drop_map length_greater_0_conv length_stake stake_cycle_le stake_invert_Nil take_map zip_Cons_Cons zip_map_fst_snd) show "q \ \((transition A (w !! n) ` (reach A w n)))" unfolding reach_def proof (intro UN_I CollectI exI conjI) show "target (take n r) p = target (take n r) p" by rule show "path A (take n r) p" using 3 by blast show "p \ initial A" using 2(3) by this show "map fst (take n r) = stake n w" using 2 by (metis length_stake lessI nat.distinct(1) stake_cycle_le stake_invert_Nil take_map take_stake) show "q \ transition A (w !! n) (target (take n r) p)" using 3 unfolding 6 by auto qed next fix p q assume 1: "p \ reach A w n" "q \ transition A (w !! n) p" obtain r x where 2: "p = target r x" "path A r x" "x \ initial A" "map fst r = stake n w" using 1(1) unfolding reach_def by blast show "q \ reach A w (Suc n)" unfolding reach_def proof (intro CollectI exI conjI) show "q = target (r @ [(w !! n, q)]) x" using 1 2 by auto show "path A (r @ [(w !! n, q)]) x" using assms 1(2) 2(1, 2) by auto show "x \ initial A" using 2(3) by this show "map fst (r @ [(w !! n, q)]) = stake (Suc n) w" using 1 2 by (metis eq_fst_iff list.simps(8) list.simps(9) map_append stake_Suc) qed qed lemma reach_Suc[simp]: "reach A w (Suc n) = (if w !! n \ alphabet A - then \((transition A (w !! n) ` (reach A w n))) else {})" + then \ (transition A (w !! n) ` reach A w n) else {})" using reach_Suc_empty reach_Suc_succ by metis lemma reach_nodes: "reach A w i \ nodes A" by (induct i) (auto) lemma reach_gunodes: "{i} \ reach A w i \ gunodes A w" by (induct i) (auto intro: graph.nodes.execute) lemma ranking_complement: assumes "finite (nodes A)" "w \ streams (alphabet A)" "ranking A w f" shows "w \ language (complement A)" proof - define f' where "f' \ \ (k, p). if k = 0 then 2 * card (nodes A) else f (k, p)" have 0: "ranking A w f'" unfolding ranking_def proof (intro conjI ballI impI allI) show "\ v. v \ gunodes A w \ f' v \ 2 * card (nodes A)" using assms(3) unfolding ranking_def f'_def by auto show "\ v u. v \ gunodes A w \ u \ gusuccessors A w v \ f' u \ f' v" using assms(3) unfolding ranking_def f'_def by fastforce show "\ v. v \ gunodes A w \ gaccepting A v \ even (f' v)" using assms(3) unfolding ranking_def f'_def by auto next have 1: "v \ gunodes A w \ gurun A w r v \ smap f (gtrace r v) = sconst k \ odd k" for v r k using assms(3) unfolding ranking_def by meson fix v r k assume 2: "v \ gunodes A w" "gurun A w r v" "smap f' (gtrace r v) = sconst k" have 20: "shd r \ gureachable A w v" using 2 by (auto) (metis graph.reachable.reflexive graph.reachable_trace gtrace_alt_def subsetD shd_sset) obtain 3: "shd r \ gunodes A w" "gurun A w (stl r) (shd r)" "smap f' (gtrace (stl r) (shd r)) = sconst k" using 2 20 by (metis (no_types, lifting) eq_id_iff graph.nodes_trans graph.run_scons_elim siterate.simps(2) sscan.simps(2) stream.collapse stream.map_sel(2)) have 4: "k \ 0" if "(k, p) \ sset r" for k p proof - obtain ra ka pa where 1: "r = fromN (Suc ka) ||| ra" "v = (ka, pa)" using grun_elim[OF 2(2)] by this have 2: "k \ sset (fromN (Suc ka))" using 1(1) that by (metis image_eqI prod.sel(1) szip_smap_fst stream.set_map) show ?thesis using 2 by simp qed have 5: "smap f' (gtrace (stl r) (shd r)) = smap f (gtrace (stl r) (shd r))" proof (rule stream.map_cong) show "gtrace (stl r) (shd r) = gtrace (stl r) (shd r)" by rule next fix z assume 1: "z \ sset (gtrace (stl r) (shd r))" have 2: "fst z \ 0" using 4 1 by (metis gtrace_alt_def prod.collapse stl_sset) show "f' z = f z" using 2 unfolding f'_def by (auto simp: case_prod_beta) qed show "odd k" using 1 3 5 by simp qed define g where "g i p \ if p \ reach A w i then Some (f' (i, p)) else None" for i p have g_dom[simp]: "dom (g i) = reach A w i" for i unfolding g_def by (auto) (metis option.simps(3)) have g_0[simp]: "g 0 = const (Some (2 * card (nodes A))) |` initial A" unfolding g_def f'_def by auto have g_Suc[simp]: "g (Suc n) \ lr_succ A (w !! n) (g n)" for n unfolding lr_succ_def proof (intro CollectI conjI ballI impI) show "dom (g (Suc n)) = \ (transition A (w !! n) ` dom (g n))" using snth_in assms(2) by auto next fix p q assume 100: "p \ dom (g n)" "q \ transition A (w !! n) p" have 101: "q \ reach A w (Suc n)" using snth_in assms(2) 100 by auto have 102: "(n, p) \ gunodes A w" using 100(1) reach_gunodes g_dom by blast have 103: "(Suc n, q) \ gusuccessors A w (n, p)" using snth_in assms(2) 102 100(2) by auto have 104: "p \ reach A w n" using 100(1) by simp have "g (Suc n) q = Some (f' (Suc n, q))" using 101 unfolding g_def by simp also have "the \ = f' (Suc n, q)" by simp also have "\ \ f' (n, p)" using 0 unfolding ranking_def using 102 103 by simp also have "\ = the (Some (f' (n, p)))" by simp also have "Some (f' (n, p)) = g n p" using 104 unfolding g_def by simp finally show "the (g (Suc n) q) \ the (g n p)" by this next fix p assume 100: "p \ dom (g (Suc n))" "accepting A p" have 101: "p \ reach A w (Suc n)" using 100(1) by simp have 102: "(Suc n, p) \ gunodes A w" using 101 reach_gunodes by blast have 103: "gaccepting A (Suc n, p)" using 100(2) by simp have "the (g (Suc n) p) = f' (Suc n, p)" using 101 unfolding g_def by simp also have "even \" using 0 unfolding ranking_def using 102 103 by auto finally show "even (the (g (Suc n) p))" by this qed define P where "P \ rec_nat {} (\ n. st_succ A (w !! n) (g (Suc n)))" have P_0[simp]: "P 0 = {}" unfolding P_def by simp have P_Suc[simp]: "P (Suc n) = st_succ A (w !! n) (g (Suc n)) (P n)" for n unfolding P_def by simp have P_reach: "P n \ reach A w n" for n using snth_in assms(2) by (induct n) (auto simp add: st_succ_def) have "P n \ reach A w n" for n using P_reach by auto also have "\ n \ nodes A" for n using reach_nodes by this also have "finite (nodes A)" using assms(1) by this finally have P_finite: "finite (P n)" for n by this define s where "s \ smap g nats ||| smap P nats" show ?thesis proof show "run (complement A) (w ||| stl s) (shd s)" proof (intro nba.snth_run conjI, simp_all del: stake.simps stake_szip) fix k show "w !! k \ alphabet (complement A)" using snth_in assms(2) unfolding complement_def by auto have "stl s !! k = s !! Suc k" by simp also have "\ \ complement_succ A (w !! k) (s !! k)" unfolding complement_succ_def s_def using P_Suc by simp also have "\ = complement_succ A (w !! k) (target (stake k (w ||| stl s)) (shd s))" unfolding sscan_scons_snth[symmetric] nba.trace_alt_def by simp also have "\ = transition (complement A) (w !! k) (target (stake k (w ||| stl s)) (shd s))" unfolding complement_def nba.sel by rule finally show "stl s !! k \ transition (complement A) (w !! k) (target (stake k (w ||| stl s)) (shd s))" by this qed show "shd s \ initial (complement A)" unfolding complement_def s_def using P_0 by simp show "infs (accepting (complement A)) (shd s ## stl s)" proof - have 10: "\ n. \ k \ n. P k = {}" proof (rule ccontr) assume 20: "\ (\ n. \ k \ n. P k = {})" obtain k where 22: "P (k + n) \ {}" for n using 20 using le_add1 by blast - define m where "m n S \ {p \ \((transition A (w !! n) ` S)). even (the (g (Suc n) p))}" for n S + define m where "m n S \ {p \ \ (transition A (w !! n) ` S). even (the (g (Suc n) p))}" for n S define R where "R i n S \ rec_nat S (\ i. m (n + i)) i" for i n S have R_0[simp]: "R 0 n = id" for n unfolding R_def by auto have R_Suc[simp]: "R (Suc i) n = m (n + i) \ R i n" for i n unfolding R_def by auto have R_Suc': "R (Suc i) n = R i (Suc n) \ m n" for i n unfolding R_Suc by (induct i) (auto) have R_reach: "R i n S \ reach A w (n + i)" if "S \ reach A w n" for i n S using snth_in assms(2) that m_def by (induct i) (auto) have P_R: "P (k + i) = R i k (P k)" for i using 22 by (induct i) (auto simp add: case_prod_beta' m_def st_succ_def) have 50: "R i n S = (\ p \ S. R i n {p})" for i n S by (induct i) (auto simp add: m_def prod.case_eq_if) have 51: "R (i + j) n S = {}" if "R i n S = {}" for i j n S using that by (induct j) (auto simp add: m_def prod.case_eq_if) have 52: "R j n S = {}" if "i \ j" "R i n S = {}" for i j n S using 51 by (metis le_add_diff_inverse that(1) that(2)) have 1: "\ p \ S. \ i. R i n {p} \ {}" if assms: "finite S" "\ i. R i n S \ {}" for n S proof (rule ccontr) assume 1: "\ (\ p \ S. \ i. R i n {p} \ {})" obtain f where 3: "\ p. p \ S \ R (f p) n {p} = {}" using 1 by metis have 4: "R (Sup (f ` S)) n {p} = {}" if "p \ S" for p proof (rule 52) show "f p \ Sup (f ` S)" using assms(1) that by (auto intro: le_cSup_finite) show "R (f p) n {p} = {}" using 3 that by this qed have "R (Sup (f ` S)) n S = (\ p \ S. R (Sup (f ` S)) n {p})" using 50 by this also have "\ = {}" using 4 by simp finally have 5: "R (Sup (f ` S)) n S = {}" by this show "False" using that(2) 5 by auto qed have 2: "\ i. R i (k + 0) (P k) \ {}" using 22 P_R by simp obtain p where 3: "p \ P k" "\ i. R i k {p} \ {}" using 1[OF P_finite 2] by auto define Q where "Q n p \ (\ i. R i (k + n) {p} \ {}) \ p \ P (k + n)" for n p have 5: "\ q \ transition A (w !! (k + n)) p. Q (Suc n) q" if "Q n p" for n p proof - have 11: "p \ P (k + n)" "\ i. R i (k + n) {p} \ {}" using that unfolding Q_def by auto have 12: "R (Suc i) (k + n) {p} \ {}" for i using 11(2) by this have 13: "R i (k + Suc n) (m (k + n) {p}) \ {}" for i using 12 unfolding R_Suc' by simp have "{p} \ P (k + n)" using 11(1) by auto also have "\ \ reach A w (k + n)" using P_reach by this finally have "R 1 (k + n) {p} \ reach A w (k + n + 1)" using R_reach by blast also have "\ \ nodes A" using reach_nodes by this also have "finite (nodes A)" using assms(1) by this finally have 14: "finite (m (k + n) {p})" by simp obtain q where 14: "q \ m (k + n) {p}" "\ i. R i (k + Suc n) {q} \ {}" using 1[OF 14 13] by auto show ?thesis unfolding Q_def prod.case proof (intro bexI conjI allI) show "\ i. R i (k + Suc n) {q} \ {}" using 14(2) by this show "q \ P (k + Suc n)" using 14(1) 11(1) 22 unfolding m_def by (auto simp add: st_succ_def) show "q \ transition A (w !! (k + n)) p" using 14(1) unfolding m_def by simp qed qed obtain r where 23: "run A r p" "\ i. Q i ((p ## trace r p) !! i)" "\ i. fst (r !! i) = w !! (k + i)" proof (rule nba.invariant_run_index[of Q 0 p A "\ n p a. fst a = w !! (k + n)"]) show "Q 0 p" unfolding Q_def using 3 by auto show "\ a. (fst a \ alphabet A \ snd a \ transition A (fst a) p) \ Q (Suc n) (snd a) \ fst a = w !! (k + n)" if "Q n p" for n p using snth_in assms(2) 5 that by fastforce qed auto have 20: "smap fst r = sdrop k w" using 23(3) by (intro eqI_snth) (simp add: case_prod_beta) have 21: "(p ## smap snd r) !! i \ P (k + i)" for i using 23(2) unfolding Q_def unfolding nba.trace_alt_def by simp obtain r where 23: "run A (sdrop k w ||| stl r) (shd r)" "\ i. r !! i \ P (k + i)" using 20 21 23(1) by (metis stream.sel(1) stream.sel(2) szip_smap) let ?v = "(k, shd r)" let ?r = "fromN (Suc k) ||| stl r" have "shd r = r !! 0" by simp also have "\ \ P k" using 23(2)[of 0] by simp also have "\ \ reach A w k" using P_reach by this finally have 24: "?v \ gunodes A w" using reach_gunodes by blast have 25: "gurun A w ?r ?v" using run_grun 23(1) by this obtain l where 26: "Ball (sset (smap f' (gtrace (sdrop l ?r) (gtarget (stake l ?r) ?v)))) odd" using ranking_stuck_odd 0 24 25 by this have 27: "f' (Suc (k + l), r !! Suc l) = shd (smap f' (gtrace (sdrop l ?r) (gtarget (stake l ?r) ?v)))" by (simp add: algebra_simps) also have "\ \ sset (smap f' (gtrace (sdrop l ?r) (gtarget (stake l ?r) ?v)))" using shd_sset by this finally have 28: "odd (f' (Suc (k + l), r !! Suc l))" using 26 by auto have "r !! Suc l \ P (Suc (k + l))" using 23(2) by (metis add_Suc_right) also have "\ = {p \ \ (transition A (w !! (k + l)) ` P (k + l)). even (the (g (Suc (k + l)) p))}" using 23(2) by (auto simp: st_succ_def) also have "\ \ {p. even (the (g (Suc (k + l)) p))}" by auto finally have 29: "even (the (g (Suc (k + l)) (r !! Suc l)))" by auto have 30: "r !! Suc l \ reach A w (Suc (k + l))" using 23(2) P_reach by (metis add_Suc_right subsetCE) have 31: "even (f' (Suc (k + l), r !! Suc l))" using 29 30 unfolding g_def by simp show "False" using 28 31 by simp qed have 11: "infs (\ k. P k = {}) nats" using 10 unfolding infs_snth by simp have "infs (\ S. S = {}) (smap snd (smap g nats ||| smap P nats))" using 11 by (simp add: comp_def) then have "infs (\ x. snd x = {}) (smap g nats ||| smap P nats)" by (simp add: comp_def del: szip_smap_snd) then have "infs (\ (f, P). P = {}) (smap g nats ||| smap P nats)" by (simp add: case_prod_beta') then have "infs (\ (f, P). P = {}) (stl (smap g nats ||| smap P nats))" by blast then have "infs (\ (f, P). P = {}) (smap snd (w ||| stl (smap g nats ||| smap P nats)))" by simp then have "infs (\ (f, P). P = {}) (stl s)" unfolding s_def by simp then show ?thesis unfolding complement_def by auto qed qed qed subsection \Correctness Theorem\ theorem complement_language: assumes "finite (nodes A)" shows "language (complement A) = streams (alphabet A) - language A" proof (safe del: notI) have 1: "alphabet (complement A) = alphabet A" unfolding complement_def nba.sel by rule show "w \ streams (alphabet A)" if "w \ language (complement A)" for w using nba.language_alphabet that 1 by force show "w \ language A" if "w \ language (complement A)" for w using complement_ranking ranking_language that by metis show "w \ language (complement A)" if "w \ streams (alphabet A)" "w \ language A" for w using language_ranking ranking_complement assms that by blast qed end diff --git a/thys/Transition_Systems_and_Automata/Transition_Systems/Transition_System_Construction.thy b/thys/Transition_Systems_and_Automata/Transition_Systems/Transition_System_Construction.thy --- a/thys/Transition_Systems_and_Automata/Transition_Systems/Transition_System_Construction.thy +++ b/thys/Transition_Systems_and_Automata/Transition_Systems/Transition_System_Construction.thy @@ -1,99 +1,91 @@ section \Constructing Paths and Runs in Transition Systems\ theory Transition_System_Construction imports "../Basic/Sequence_LTL" "Transition_System" begin context transition_system begin lemma invariant_run: assumes "P p" "\ p. P p \ \ a. enabled a p \ P (execute a p) \ Q p a" obtains r where "run r p" "pred_stream P (p ## trace r p)" "stream_all2 Q (p ## trace r p) r" proof - - obtain f where 1: - "P p" - "\ p. P p \ enabled (f p) p" - "\ p. P p \ P (execute (f p) p)" - "\ p. P p \ Q p (f p)" - using assms by metis - let ?r = "\ p. smap f (siterate (\ p. execute (f p) p) p)" + obtain f where 1: "enabled (f p) p" "P (execute (f p) p)" "Q p (f p)" if "P p" for p using assms(2) by metis + let ?g = "\ p. execute (f p) p" + let ?r = "\ p. smap f (siterate ?g p)" show ?thesis proof - show "run (?r p) p" using 1 by (coinduction arbitrary: p) (auto) - show "pred_stream P (p ## trace (?r p) p)" using 1 by (coinduction arbitrary: p) (auto) - show "stream_all2 Q (p ## trace (?r p) p) (?r p)" using 1 by (coinduction arbitrary: p) (auto) + show "run (?r p) p" using assms(1) 1 by (coinduction arbitrary: p) (auto) + show "pred_stream P (p ## trace (?r p) p)" using assms(1) 1 by (coinduction arbitrary: p) (auto) + show "stream_all2 Q (p ## trace (?r p) p) (?r p)" using assms(1) 1 by (coinduction arbitrary: p) (auto) qed qed lemma recurring_condition: assumes "P p" "\ p. P p \ \ r. r \ [] \ path r p \ P (target r p)" obtains r where "run r p" "infs P (p ## trace r p)" proof - - obtain f where 1: - "P p" - "\ p. P p \ f p \ []" - "\ p. P p \ path (f p) p" - "\ p. P p \ P (target (f p) p)" - using assms by metis - let ?r = "\ p. flat (smap f (siterate (\ p. target (f p) p) p))" - have 2: "?r p = f p @- ?r (target (f p) p)" if "P p" for p using that 1(2) by (simp add: flat_unfold) + obtain f where 1: "f p \ []" "path (f p) p" "P (target (f p) p)" if "P p" for p using assms(2) by metis + let ?g = "\ p. target (f p) p" + let ?r = "\ p. flat (smap f (siterate ?g p))" + have 2: "?r p = f p @- ?r (?g p)" if "P p" for p using that 1(1) by (simp add: flat_unfold) show ?thesis proof - show "run (?r p) p" using 1 2 by (coinduction arbitrary: p rule: run_coinduct_shift) (blast) - show "infs P (p ## trace (?r p) p)" using 1 2 by (coinduction arbitrary: p rule: infs_sscan_coinduct) (blast) + show "run (?r p) p" using assms(1) 1 2 by (coinduction arbitrary: p rule: run_coinduct_shift) (blast) + show "infs P (p ## trace (?r p) p)" using assms(1) 1 2 by (coinduction arbitrary: p rule: infs_sscan_coinduct) (blast) qed qed lemma invariant_run_index: assumes "P n p" "\ n p. P n p \ \ a. enabled a p \ P (Suc n) (execute a p) \ Q n p a" obtains r where "run r p" "\ i. P (n + i) (target (stake i r) p)" "\ i. Q (n + i) (target (stake i r) p) (r !! i)" proof - define s where "s \ (n, p)" have 1: "case_prod P s" using assms(1) unfolding s_def by auto obtain f where 2: "\ n p. P n p \ enabled (f n p) p" "\ n p. P n p \ P (Suc n) (execute (f n p) p)" "\ n p. P n p \ Q n p (f n p)" using assms(2) by metis define g where "g \ \ (n, p). (Suc n, execute (f n p) p)" let ?r = "smap (case_prod f) (siterate g s)" have 3: "run ?r (snd s)" using 1 2(1, 2) unfolding g_def by (coinduction arbitrary: s) (auto) have 4: "case_prod P (compow k g s)" for k using 1 2(2) unfolding g_def by (induct k) (auto) have 5: "case_prod Q (compow k g s) (?r !! k)" for k using 2(3) 4 by (simp add: case_prod_beta) have 6: "compow k g (n, p) = (n + k, target (stake k ?r) p)" for k unfolding s_def g_def by (induct k) (auto simp add: stake_Suc simp del: stake.simps(2)) show ?thesis using that 3 4 5 unfolding s_def 6 by simp qed lemma koenig: assumes "infinite (reachable p)" assumes "\ q. q \ reachable p \ finite (successors q)" obtains r where "run r p" proof (rule invariant_run[where ?P = "\ q. q \ reachable p \ infinite (reachable q)"]) show "p \ reachable p \ infinite (reachable p)" using assms(1) by auto next fix q assume 1: "q \ reachable p \ infinite (reachable q)" have 2: "finite (successors q)" using assms(2) 1 by auto have 3: "infinite (insert q (\(reachable ` (successors q))))" using reachable_step 1 by metis obtain s where 4: "s \ successors q" "infinite (reachable s)" using 2 3 by auto show "\ a. enabled a q \ (execute a q \ reachable p \ infinite (reachable (execute a q))) \ True" using 1 4 by auto qed end end