diff --git a/thys/LTL_Master_Theorem/Code_Export.thy b/thys/LTL_Master_Theorem/Code_Export.thy --- a/thys/LTL_Master_Theorem/Code_Export.thy +++ b/thys/LTL_Master_Theorem/Code_Export.thy @@ -1,63 +1,55 @@ (* Author: Benedikt Seidl License: BSD *) section \Code export to Standard ML\ theory Code_Export imports "LTL_to_DRA/DRA_Implementation" LTL.Code_Equations "HOL-Library.Code_Target_Numeral" begin subsection \LTL to DRA\ -lemma dgba_degen_code [code]: - "DGBA.degen A = dba (DGBA.alphabet A) (DGBA.initial A, 0) (DGBA.dexecute A) (DGBA.daccepting A)" - by (metis DGBA.degen_def DGBA.degen_simps(2) dba.sel(2)) - -lemma dgca_degen_code [code]: - "DGCA.degen A = dca (DGCA.alphabet A) (DGCA.initial A, 0) (DGCA.dexecute A) (DGCA.drejecting A)" - by (metis DGCA.degen_def DGCA.degen_simps(2) dca.sel(2)) - export_code ltlc_to_draei checking declare ltl_to_dra.af_letter\<^sub>F_lifted_semantics [code] declare ltl_to_dra.af_letter\<^sub>G_lifted_semantics [code] declare ltl_to_dra.af_letter\<^sub>\_lifted_semantics [code] definition atoms_ltlc_list_literals :: "String.literal ltlc \ String.literal list" where "atoms_ltlc_list_literals = atoms_ltlc_list" definition ltlc_to_draei_literals :: "String.literal ltlc \ (String.literal set, nat) draei" where "ltlc_to_draei_literals = ltlc_to_draei" definition sort_transitions :: "(nat \ String.literal set \ nat) list \ (nat \ String.literal set \ nat) list" where "sort_transitions = sort_key fst" export_code True_ltlc Iff_ltlc ltlc_to_draei_literals alphabetei initialei transei acceptingei integer_of_nat atoms_ltlc_list_literals sort_transitions set in SML module_name LTL file_prefix LTL_to_DRA subsection \LTL to NBA\ (* TODO *) subsection \LTL to LDBA\ (* TODO *) end diff --git a/thys/LTL_Master_Theorem/LTL_to_DRA/DRA_Construction.thy b/thys/LTL_Master_Theorem/LTL_to_DRA/DRA_Construction.thy --- a/thys/LTL_Master_Theorem/LTL_to_DRA/DRA_Construction.thy +++ b/thys/LTL_Master_Theorem/LTL_to_DRA/DRA_Construction.thy @@ -1,440 +1,440 @@ (* Author: Benedikt Seidl License: BSD *) section \Constructing DRAs for LTL Formulas\ theory DRA_Construction imports Transition_Functions "../Quotient_Type" "../Omega_Words_Fun_Stream" "../Logical_Characterization/Master_Theorem" Transition_Systems_and_Automata.DBA_Combine Transition_Systems_and_Automata.DCA_Combine Transition_Systems_and_Automata.DRA_Combine begin \ \We use prefix and suffix on infinite words.\ hide_const Sublist.prefix Sublist.suffix locale dra_construction = transition_functions eq + quotient eq Rep Abs for eq :: "'a ltln \ 'a ltln \ bool" (infix "\" 75) and Rep :: "'ltlq \ 'a ltln" and Abs :: "'a ltln \ 'ltlq" begin subsection \Lifting Setup\ abbreviation true\<^sub>n_lifted :: "'ltlq" ("\true\<^sub>n") where "\true\<^sub>n \ Abs true\<^sub>n" abbreviation false\<^sub>n_lifted :: "'ltlq" ("\false\<^sub>n") where "\false\<^sub>n \ Abs false\<^sub>n" abbreviation af_letter_lifted :: "'a set \ 'ltlq \ 'ltlq" ("\afletter") where "\afletter \ \ \ Abs (af_letter (Rep \) \)" abbreviation af_lifted :: "'ltlq \ 'a set list \ 'ltlq" ("\af") where "\af \ w \ fold \afletter w \" abbreviation GF_advice_lifted :: "'ltlq \ 'a ltln set \ 'ltlq" ("_\[_]\<^sub>\" [90,60] 89) where "\\[X]\<^sub>\ \ Abs ((Rep \)[X]\<^sub>\)" lemma af_letter_lifted_semantics: "\afletter \ (Abs \) = Abs (af_letter \ \)" by (metis Rep_Abs_eq af_letter_congruent Abs_eq) lemma af_lifted_semantics: "\af (Abs \) w = Abs (af \ w)" by (induction w rule: rev_induct) (auto simp: Abs_eq, insert Rep_Abs_eq af_letter_congruent eq_sym, blast) lemma af_lifted_range: "range (\af (Abs \)) \ {Abs \ | \. nested_prop_atoms \ \ nested_prop_atoms \}" using af_lifted_semantics af_nested_prop_atoms by blast definition af_letter\<^sub>F_lifted :: "'a ltln \ 'a set \ 'ltlq \ 'ltlq" ("\afletter\<^sub>F") where "\afletter\<^sub>F \ \ \ \ Abs (af_letter\<^sub>F \ (Rep \) \)" definition af_letter\<^sub>G_lifted :: "'a ltln \ 'a set \ 'ltlq \ 'ltlq" ("\afletter\<^sub>G") where "\afletter\<^sub>G \ \ \ \ Abs (af_letter\<^sub>G \ (Rep \) \)" lemma af_letter\<^sub>F_lifted_semantics: "\afletter\<^sub>F \ \ (Abs \) = Abs (af_letter\<^sub>F \ \ \)" by (metis af_letter\<^sub>F_lifted_def Rep_inverse af_letter\<^sub>F_def af_letter_congruent Abs_eq) lemma af_letter\<^sub>G_lifted_semantics: "\afletter\<^sub>G \ \ (Abs \) = Abs (af_letter\<^sub>G \ \ \)" by (metis af_letter\<^sub>G_lifted_def Rep_inverse af_letter\<^sub>G_def af_letter_congruent Abs_eq) abbreviation af\<^sub>F_lifted :: "'a ltln \ 'ltlq \ 'a set list \ 'ltlq" ("\af\<^sub>F") where "\af\<^sub>F \ \ w \ fold (\afletter\<^sub>F \) w \" abbreviation af\<^sub>G_lifted :: "'a ltln \ 'ltlq \ 'a set list \ 'ltlq" ("\af\<^sub>G") where "\af\<^sub>G \ \ w \ fold (\afletter\<^sub>G \) w \" lemma af\<^sub>F_lifted_semantics: "\af\<^sub>F \ (Abs \) w = Abs (af\<^sub>F \ \ w)" by (induction w rule: rev_induct) (auto simp: af_letter\<^sub>F_lifted_semantics) lemma af\<^sub>G_lifted_semantics: "\af\<^sub>G \ (Abs \) w = Abs (af\<^sub>G \ \ w)" by (induction w rule: rev_induct) (auto simp: af_letter\<^sub>G_lifted_semantics) lemma af\<^sub>F_lifted_range: "nested_prop_atoms \ \ nested_prop_atoms (F\<^sub>n \) \ range (\af\<^sub>F \ (Abs \)) \ {Abs \ | \. nested_prop_atoms \ \ nested_prop_atoms (F\<^sub>n \)}" using af\<^sub>F_lifted_semantics af\<^sub>F_nested_prop_atoms by blast lemma af\<^sub>G_lifted_range: "nested_prop_atoms \ \ nested_prop_atoms (G\<^sub>n \) \ range (\af\<^sub>G \ (Abs \)) \ {Abs \ | \. nested_prop_atoms \ \ nested_prop_atoms (G\<^sub>n \)}" using af\<^sub>G_lifted_semantics af\<^sub>G_nested_prop_atoms by blast definition af_letter\<^sub>\_lifted :: "'a ltln set \ 'a set \ 'ltlq \ 'ltlq \ 'ltlq \ 'ltlq" ("\afletter\<^sub>\") where "\afletter\<^sub>\ X \ p \ (Abs (fst (af_letter\<^sub>\ X (Rep (fst p), Rep (snd p)) \)), Abs (snd (af_letter\<^sub>\ X (Rep (fst p), Rep (snd p)) \)))" abbreviation af\<^sub>\_lifted :: "'a ltln set \ 'ltlq \ 'ltlq \ 'a set list \ 'ltlq \ 'ltlq" ("\af\<^sub>\") where "\af\<^sub>\ X p w \ fold (\afletter\<^sub>\ X) w p" lemma af_letter\<^sub>\_lifted_semantics: "\afletter\<^sub>\ X \ (Abs x, Abs y) = (Abs (fst (af_letter\<^sub>\ X (x, y) \)), Abs (snd (af_letter\<^sub>\ X (x, y) \)))" by (simp add: af_letter\<^sub>\_def af_letter\<^sub>\_lifted_def) (insert GF_advice_congruent Rep_Abs_eq Rep_inverse af_letter_lifted_semantics eq_trans Abs_eq, blast) lemma af\<^sub>\_lifted_semantics: "\af\<^sub>\ X (Abs \, Abs \) w = (Abs (fst (af\<^sub>\ X (\, \) w)), Abs (snd (af\<^sub>\ X (\, \) w)))" apply (induction w rule: rev_induct) apply (auto simp: af_letter\<^sub>\_lifted_def af_letter\<^sub>\_lifted_semantics af_letter_lifted_semantics) by (metis (no_types, hide_lams) af_letter\<^sub>\_lifted_def af\<^sub>\_fst af_letter\<^sub>\_lifted_semantics eq_fst_iff prod.sel(2)) subsection \Büchi automata for basic languages\ definition \\<^sub>\ :: "'a ltln \ ('a set, 'ltlq) dba" where "\\<^sub>\ \ = dba UNIV (Abs \) \afletter (\\. \ = \true\<^sub>n)" definition \\<^sub>\_GF :: "'a ltln \ ('a set, 'ltlq) dba" where "\\<^sub>\_GF \ = dba UNIV (Abs (F\<^sub>n \)) (\afletter\<^sub>F \) (\\. \ = \true\<^sub>n)" definition \\<^sub>\ :: "'a ltln \ ('a set, 'ltlq) dca" where "\\<^sub>\ \ = dca UNIV (Abs \) \afletter (\\. \ = \false\<^sub>n)" definition \\<^sub>\_FG :: "'a ltln \ ('a set, 'ltlq) dca" where "\\<^sub>\_FG \ = dca UNIV (Abs (G\<^sub>n \)) (\afletter\<^sub>G \) (\\. \ = \false\<^sub>n)" lemma dba_run: "DBA.run (dba UNIV p \ \) (to_stream w) p" unfolding DBA.run_def by (rule transition_system.snth_run) fastforce lemma dca_run: "DCA.run (dca UNIV p \ \) (to_stream w) p" unfolding DCA.run_def by (rule transition_system.snth_run) fastforce lemma \\<^sub>\_language: "\ \ \LTL \ to_stream w \ DBA.language (\\<^sub>\ \) \ w \\<^sub>n \" proof - assume "\ \ \LTL" then have "w \\<^sub>n \ \ (\n. \k\n. af \ (w[0 \ k]) \ true\<^sub>n)" by (meson af_\LTL af_prefix_true le_cases) also have "\ \ (\n. \k\n. af \ (w[0 \ Suc k]) \ true\<^sub>n)" by (meson af_prefix_true le_SucI order_refl) also have "\ \ infs (\\. \ = \true\<^sub>n) (DBA.trace (\\<^sub>\ \) (to_stream w) (Abs \))" by (simp add: infs_snth \\<^sub>\_def DBA.succ_def af_lifted_semantics Abs_eq[symmetric] af_letter_lifted_semantics) also have "\ \ to_stream w \ DBA.language (\\<^sub>\ \)" unfolding \\<^sub>\_def dba.initial_def dba.accepting_def by (metis dba_run DBA.language DBA.language_elim dba.sel(2) dba.sel(4)) finally show ?thesis by simp qed lemma \\<^sub>\_GF_language: "\ \ \LTL \ to_stream w \ DBA.language (\\<^sub>\_GF \) \ w \\<^sub>n G\<^sub>n (F\<^sub>n \)" proof - assume "\ \ \LTL" then have "w \\<^sub>n G\<^sub>n (F\<^sub>n \) \ (\n. \k. af (F\<^sub>n \) (w[n \ k]) \\<^sub>L true\<^sub>n)" using ltl_lang_equivalence.af_\LTL_GF by blast also have "\ \ (\n. \k>n. af\<^sub>F \ (F\<^sub>n \) (w[0 \ k]) \ true\<^sub>n)" using af\<^sub>F_semantics_ltr af\<^sub>F_semantics_rtl using \\ \ \LTL\ af_\LTL_GF calculation by blast also have "\ \ (\n. \k\n. af\<^sub>F \ (F\<^sub>n \) (w[0 \ Suc k]) \ true\<^sub>n)" by (metis less_Suc_eq_le less_imp_Suc_add) also have "\ \ infs (\\. \ = \true\<^sub>n) (DBA.trace (\\<^sub>\_GF \) (to_stream w) (Abs (F\<^sub>n \)))" by (simp add: infs_snth \\<^sub>\_GF_def DBA.succ_def af\<^sub>F_lifted_semantics Abs_eq[symmetric] af_letter\<^sub>F_lifted_semantics) also have "\ \ to_stream w \ DBA.language (\\<^sub>\_GF \)" unfolding \\<^sub>\_GF_def dba.initial_def dba.accepting_def by (metis dba_run DBA.language DBA.language_elim dba.sel(2) dba.sel(4)) finally show ?thesis by simp qed lemma \\<^sub>\_language: "\ \ \LTL \ to_stream w \ DCA.language (\\<^sub>\ \) \ w \\<^sub>n \" proof - assume "\ \ \LTL" then have "w \\<^sub>n \ \ (\n. \k\n. \ af \ (w[0 \ k]) \ false\<^sub>n)" by (meson af_\LTL af_prefix_false le_cases order_refl) also have "\ \ (\n. \k\n. \ af \ (w[0 \ Suc k]) \ false\<^sub>n)" by (meson af_prefix_false le_SucI order_refl) also have "\ \ \ infs (\\. \ = \false\<^sub>n) (DCA.trace (\\<^sub>\ \) (to_stream w) (Abs \))" by (simp add: infs_snth \\<^sub>\_def DBA.succ_def af_lifted_semantics Abs_eq[symmetric] af_letter_lifted_semantics) also have "\ \ to_stream w \ DCA.language (\\<^sub>\ \)" unfolding \\<^sub>\_def dca.initial_def dca.rejecting_def by (metis dca_run DCA.language DCA.language_elim dca.sel(2) dca.sel(4)) finally show ?thesis by simp qed lemma \\<^sub>\_FG_language: "\ \ \LTL \ to_stream w \ DCA.language (\\<^sub>\_FG \) \ w \\<^sub>n F\<^sub>n (G\<^sub>n \)" proof - assume "\ \ \LTL" then have "w \\<^sub>n F\<^sub>n (G\<^sub>n \) \ (\k. \j. \ af (G\<^sub>n \) (w[k \ j]) \\<^sub>L false\<^sub>n)" using ltl_lang_equivalence.af_\LTL_FG by blast also have "\ \ (\n. \k>n. \ af\<^sub>G \ (G\<^sub>n \) (w[0 \ k]) \ false\<^sub>n)" using af\<^sub>G_semantics_ltr af\<^sub>G_semantics_rtl using \\ \ \LTL\ af_\LTL_FG calculation by blast also have "\ \ (\n. \k\n. \ af\<^sub>G \ (G\<^sub>n \) (w[0 \ Suc k]) \ false\<^sub>n)" by (metis less_Suc_eq_le less_imp_Suc_add) also have "\ \ \ infs (\\. \ = \false\<^sub>n) (DCA.trace (\\<^sub>\_FG \) (to_stream w) (Abs (G\<^sub>n \)))" by (simp add: infs_snth \\<^sub>\_FG_def DBA.succ_def af\<^sub>G_lifted_semantics Abs_eq[symmetric] af_letter\<^sub>G_lifted_semantics) also have "\ \ to_stream w \ DCA.language (\\<^sub>\_FG \)" unfolding \\<^sub>\_FG_def dca.initial_def dca.rejecting_def by (metis dca_run DCA.language DCA.language_elim dca.sel(2) dca.sel(4)) finally show ?thesis by simp qed lemma \\<^sub>\_nodes: "DBA.nodes (\\<^sub>\ \) \ {Abs \ | \. nested_prop_atoms \ \ nested_prop_atoms \}" unfolding \\<^sub>\_def transition_system_initial.nodes_alt_def using af_lifted_semantics af_nested_prop_atoms by fastforce lemma \\<^sub>\_GF_nodes: "DBA.nodes (\\<^sub>\_GF \) \ {Abs \ | \. nested_prop_atoms \ \ nested_prop_atoms (F\<^sub>n \)}" unfolding \\<^sub>\_GF_def DBA.nodes_def transition_system_initial.nodes_alt_def transition_system.reachable_alt_def using af\<^sub>F_nested_prop_atoms[of "F\<^sub>n \"] by (auto simp: af\<^sub>F_lifted_semantics) lemma \\<^sub>\_nodes: "DCA.nodes (\\<^sub>\ \) \ {Abs \ | \. nested_prop_atoms \ \ nested_prop_atoms \}" unfolding \\<^sub>\_def transition_system_initial.nodes_alt_def using af_lifted_semantics af_nested_prop_atoms by fastforce lemma \\<^sub>\_FG_nodes: "DCA.nodes (\\<^sub>\_FG \) \ {Abs \ | \. nested_prop_atoms \ \ nested_prop_atoms (G\<^sub>n \)}" unfolding \\<^sub>\_FG_def DCA.nodes_def transition_system_initial.nodes_alt_def transition_system.reachable_alt_def using af\<^sub>G_nested_prop_atoms[of "G\<^sub>n \"] by (auto simp: af\<^sub>G_lifted_semantics) subsection \A DCA checking the GF-advice Function\ definition \ :: "'a ltln \ 'a ltln set \ ('a set, 'ltlq \ 'ltlq) dca" where "\ \ X = dca UNIV (Abs \, Abs (\[X]\<^sub>\)) (\afletter\<^sub>\ X) (\p. snd p = \false\<^sub>n)" lemma \_language: "to_stream w \ DCA.language (\ \ X) \ (\i. suffix i w \\<^sub>n af \ (prefix i w)[X]\<^sub>\)" proof - have "(\i. suffix i w \\<^sub>n af \ (prefix i w)[X]\<^sub>\) \ (\m. \k\m. \ snd (af\<^sub>\ X (\, \[X]\<^sub>\) (prefix (Suc k) w)) \ false\<^sub>n)" using af\<^sub>\_semantics_ltr af\<^sub>\_semantics_rtl by blast also have "\ \ \ infs (\p. snd p = \false\<^sub>n) (DCA.trace (\ \ X) (to_stream w) (Abs \, Abs (\[X]\<^sub>\)))" by(simp add: infs_snth \_def DCA.succ_def af\<^sub>\_lifted_semantics af_letter\<^sub>\_lifted_semantics Abs_eq) also have "\ \ to_stream w \ DCA.language (\ \ X)" by (simp add: \_def dca.initial_def dca.rejecting_def DCA.language_def dca_run) finally show ?thesis by blast qed lemma \_nodes: "DCA.nodes (\ \ X) \ {Abs \ | \. nested_prop_atoms \ \ nested_prop_atoms \} \ {Abs \ | \. nested_prop_atoms \ \ nested_prop_atoms\<^sub>\ \ X}" unfolding \_def DCA.nodes_def transition_system_initial.nodes_alt_def transition_system.reachable_alt_def apply (auto simp add: af\<^sub>\_lifted_semantics af_letter\<^sub>\_lifted_semantics) using af\<^sub>\_fst_nested_prop_atoms apply force using GF_advice_nested_prop_atoms\<^sub>\ af\<^sub>\_snd_nested_prop_atoms dra_construction_axioms by fastforce subsection \A DRA for each combination of sets X and Y\ lemma dba_language: "(\w. to_stream w \ DBA.language \ \ w \\<^sub>n \) \ DBA.language \ = {w. to_omega w \\<^sub>n \}" by (metis (mono_tags, lifting) Collect_cong DBA.language_def mem_Collect_eq to_stream_to_omega) lemma dca_language: "(\w. to_stream w \ DCA.language \ \ w \\<^sub>n \) \ DCA.language \ = {w. to_omega w \\<^sub>n \}" by (metis (mono_tags, lifting) Collect_cong DCA.language_def mem_Collect_eq to_stream_to_omega) definition \\<^sub>1 :: "'a ltln \ 'a ltln list \ ('a set, 'ltlq \ 'ltlq) dca" where "\\<^sub>1 \ xs = \ \ (set xs)" lemma \\<^sub>1_language: "to_omega ` DCA.language (\\<^sub>1 \ xs) = L\<^sub>1 \ (set xs)" by (simp add: \\<^sub>1_def L\<^sub>1_def set_eq_iff \_language) lemma \\<^sub>1_alphabet: "DCA.alphabet (\\<^sub>1 \ xs) = UNIV" unfolding \\<^sub>1_def \_def by simp definition \\<^sub>2 :: "'a ltln list \ 'a ltln list \ ('a set, 'ltlq list degen) dba" where "\\<^sub>2 xs ys = dbail (map (\\. \\<^sub>\_GF (\[set ys]\<^sub>\)) xs)" lemma \\<^sub>2_language: "to_omega ` DBA.language (\\<^sub>2 xs ys) = L\<^sub>2 (set xs) (set ys)" by (simp add: \\<^sub>2_def L\<^sub>2_def set_eq_iff dba_language[OF \\<^sub>\_GF_language[OF FG_advice_\LTL(1)]]) lemma \\<^sub>2_alphabet: "DBA.alphabet (\\<^sub>2 xs ys) = UNIV" - by (simp add: \\<^sub>2_def \\<^sub>\_GF_def dbail_def dbgail_def DGBA.degen_def) + by (simp add: \\<^sub>2_def \\<^sub>\_GF_def dbail_def dbgail_def) definition \\<^sub>3 :: "'a ltln list \ 'a ltln list \ ('a set, 'ltlq list) dca" where "\\<^sub>3 xs ys = dcail (map (\\. \\<^sub>\_FG (\[set xs]\<^sub>\)) ys)" lemma \\<^sub>3_language: "to_omega ` DCA.language (\\<^sub>3 xs ys) = L\<^sub>3 (set xs) (set ys)" by (simp add: \\<^sub>3_def L\<^sub>3_def set_eq_iff dca_language[OF \\<^sub>\_FG_language[OF GF_advice_\LTL(1)]]) lemma \\<^sub>3_alphabet: "DCA.alphabet (\\<^sub>3 xs ys) = UNIV" by (simp add: \\<^sub>3_def \\<^sub>\_FG_def dcail_def) definition "\' \ xs ys = dbcrai (\\<^sub>2 xs ys) (dcai (\\<^sub>1 \ xs) (\\<^sub>3 xs ys))" lemma \'_language: "to_omega ` DRA.language (\' \ xs ys) = (L\<^sub>1 \ (set xs) \ L\<^sub>2 (set xs) (set ys) \ L\<^sub>3 (set xs) (set ys))" by (simp add: \'_def \\<^sub>1_language \\<^sub>2_language \\<^sub>3_language) fastforce lemma \'_alphabet: "DRA.alphabet (\' \ xs ys) = UNIV" by (simp add: \'_def dbcrai_def dcai_def \\<^sub>1_alphabet \\<^sub>2_alphabet \\<^sub>3_alphabet) subsection \A DRA for @{term "L(\)"}\ definition "ltl_to_dra \ = draul (map (\(xs, ys). \' \ xs ys) (advice_sets \))" lemma ltl_to_dra_language: "to_omega ` DRA.language (ltl_to_dra \) = language_ltln \" proof - have 1: "INTER (set (map (\(x, y). \' \ x y) (advice_sets \))) dra.alphabet = UNION (set (map (\(x, y). \' \ x y) (advice_sets \))) dra.alphabet" by (induction "advice_sets \") (metis advice_sets_not_empty, simp add: \'_alphabet split_def advice_sets_not_empty) have "language_ltln \ = \ {(L\<^sub>1 \ X \ L\<^sub>2 X Y \ L\<^sub>3 X Y) | X Y. X \ subformulas\<^sub>\ \ \ Y \ subformulas\<^sub>\ \}" unfolding master_theorem_language by auto also have "\ = \ {L\<^sub>1 \ (set xs) \ L\<^sub>2 (set xs) (set ys) \ L\<^sub>3 (set xs) (set ys) | xs ys. (xs, ys) \ set (advice_sets \)}" unfolding advice_sets_subformulas by (metis (no_types, lifting)) also have "\ = \ {to_omega ` DRA.language (\' \ xs ys) | xs ys. (xs, ys) \ set (advice_sets \)}" by (simp add: \'_language) finally show ?thesis unfolding ltl_to_dra_def draul_language[OF 1] by auto qed lemma ltl_to_dra_alphabet: "alphabet (ltl_to_dra \) = UNIV" by (auto simp: ltl_to_dra_def draul_def \'_alphabet split: prod.split) (insert advice_sets_subformulas, blast) subsection \Setting the Alphabet of a DRA\ definition dra_set_alphabet :: "('a set, 'b) dra \ 'a set set \ ('a set, 'b) dra" where "dra_set_alphabet \ \ = dra \ (initial \) (succ \) (accepting \)" lemma dra_set_alphabet_language: "\ \ alphabet \ \ language (dra_set_alphabet \ \) = language \ \ {s. sset s \ \}" by (auto simp add: dra_set_alphabet_def language_def set_eq_iff DRA.run_alt_def) lemma dra_set_alphabet_alphabet[simp]: "alphabet (dra_set_alphabet \ \) = \" unfolding dra_set_alphabet_def by simp lemma dra_set_alphabet_nodes: "\ \ alphabet \ \ DRA.nodes (dra_set_alphabet \ \) \ DRA.nodes \" unfolding dra_set_alphabet_def DRA.nodes_def transition_system_initial.nodes_alt_def transition_system.reachable_alt_def by auto (metis DRA.path_alt_def DRA.path_def dra.sel(1) dra.sel(3) subset_trans) subsection \A DRA for @{term "L(\)"} with a finite alphabet\ definition "ltl_to_dra_alphabet \ Ap = dra_set_alphabet (ltl_to_dra \) (Pow Ap)" lemma ltl_to_dra_alphabet_language: assumes "atoms_ltln \ \ Ap" shows "to_omega ` language (ltl_to_dra_alphabet \ Ap) = language_ltln \ \ {w. range w \ Pow Ap}" proof - have 1: "Pow Ap \ alphabet (ltl_to_dra \)" unfolding ltl_to_dra_alphabet by simp show ?thesis unfolding ltl_to_dra_alphabet_def dra_set_alphabet_language[OF 1] by (simp add: ltl_to_dra_language sset_range) force qed lemma ltl_to_dra_alphabet_alphabet[simp]: "alphabet (ltl_to_dra_alphabet \ Ap) = Pow Ap" unfolding ltl_to_dra_alphabet_def by simp lemma ltl_to_dra_alphabet_nodes: "DRA.nodes (ltl_to_dra_alphabet \ Ap) \ DRA.nodes (ltl_to_dra \)" unfolding ltl_to_dra_alphabet_def by (rule dra_set_alphabet_nodes) (simp add: ltl_to_dra_alphabet) end end diff --git a/thys/Transition_Systems_and_Automata/Automata/DBA/DBA_Combine.thy b/thys/Transition_Systems_and_Automata/Automata/DBA/DBA_Combine.thy --- a/thys/Transition_Systems_and_Automata/Automata/DBA/DBA_Combine.thy +++ b/thys/Transition_Systems_and_Automata/Automata/DBA/DBA_Combine.thy @@ -1,303 +1,303 @@ section \Deterministic Büchi Automata Combinations\ theory DBA_Combine imports "DBA" "DGBA" begin definition dbgail :: "('label, 'state) dba list \ ('label, 'state list) dgba" where "dbgail AA \ dgba (INTER (set AA) dba.alphabet) (map dba.initial AA) (\ a pp. map2 (\ A p. dba.succ A a p) AA pp) (map (\ k pp. dba.accepting (AA ! k) (pp ! k)) [0 ..< length AA])" lemma dbgail_trace_smap: assumes "length pp = length AA" "k < length AA" shows "smap (\ pp. pp ! k) (dgba.trace (dbgail AA) w pp) = dba.trace (AA ! k) w (pp ! k)" using assms unfolding dbgail_def by (coinduction arbitrary: w pp) (force) lemma dbgail_nodes_length: assumes "pp \ DGBA.nodes (dbgail AA)" shows "length pp = length AA" using assms unfolding dbgail_def by induct auto lemma dbgail_nodes[intro]: assumes "pp \ DGBA.nodes (dbgail AA)" "k < length pp" shows "pp ! k \ DBA.nodes (AA ! k)" using assms unfolding dbgail_def by induct auto lemma dbgail_nodes_finite[intro]: assumes "list_all (finite \ DBA.nodes) AA" shows "finite (DGBA.nodes (dbgail AA))" proof (rule finite_subset) show "DGBA.nodes (dbgail AA) \ listset (map DBA.nodes AA)" by (force simp: listset_member list_all2_conv_all_nth dbgail_nodes_length) have "finite (listset (map DBA.nodes AA)) \ list_all finite (map DBA.nodes AA)" by (rule listset_finite) (auto simp: list_all_iff) then show "finite (listset (map DBA.nodes AA))" using assms by (simp add: list.pred_map) qed lemma dbgail_nodes_card: assumes "list_all (finite \ DBA.nodes) AA" shows "card (DGBA.nodes (dbgail AA)) \ prod_list (map (card \ DBA.nodes) AA)" proof - have "card (DGBA.nodes (dbgail AA)) \ card (listset (map DBA.nodes AA))" proof (rule card_mono) have "finite (listset (map DBA.nodes AA)) \ list_all finite (map DBA.nodes AA)" by (rule listset_finite) (auto simp: list_all_iff) then show "finite (listset (map DBA.nodes AA))" using assms by (simp add: list.pred_map) show "DGBA.nodes (dbgail AA) \ listset (map DBA.nodes AA)" by (force simp: listset_member list_all2_conv_all_nth dbgail_nodes_length) qed also have "\ = prod_list (map (card \ DBA.nodes) AA)" by simp finally show ?thesis by this qed lemma dbgail_language[simp]: "DGBA.language (dbgail AA) = INTER (set AA) DBA.language" proof safe fix w A assume 1: "w \ DGBA.language (dbgail AA)" "A \ set AA" obtain 2: "dgba.run (dbgail AA) w (dgba.initial (dbgail AA))" "gen infs (dgba.accepting (dbgail AA)) (dgba.trace (dbgail AA) w (dgba.initial (dbgail AA)))" using 1(1) by rule obtain k where 3: "A = AA ! k" "k < length AA" using 1(2) unfolding in_set_conv_nth by auto have 4: "(\ pp. dba.accepting A (pp ! k)) \ set (dgba.accepting (dbgail AA))" using 3 unfolding dbgail_def by auto show "w \ DBA.language A" proof show "dba.run A w (dba.initial A)" using 1(2) 2(1) unfolding DBA.run_alt_def DGBA.run_alt_def dbgail_def by auto have "True \ infs (\ pp. dba.accepting A (pp ! k)) (dgba.trace (dbgail AA) w (map dba.initial AA))" using 2(2) 4 unfolding dbgail_def by auto also have "\ \ infs (dba.accepting A) (smap (\ pp. pp ! k) (dgba.trace (dbgail AA) w (map dba.initial AA)))" by (simp add: comp_def) also have "smap (\ pp. pp ! k) (dgba.trace (dbgail AA) w (map dba.initial AA)) = dba.trace (AA ! k) w (map dba.initial AA ! k)" using 3(2) by (fastforce intro: dbgail_trace_smap) also have "\ = dba.trace A w (dba.initial A)" using 3 by auto finally show "infs (dba.accepting A) (dba.trace A w (dba.initial A))" by simp qed next fix w assume 1: "w \ INTER (set AA) DBA.language" have 2: "dba.run A w (dba.initial A)" "infs (dba.accepting A) (dba.trace A w (dba.initial A))" if "A \ set AA" for A using 1 that by auto show "w \ DGBA.language (dbgail AA)" proof (intro DGBA.language ballI gen) show "dgba.run (dbgail AA) w (dgba.initial (dbgail AA))" using 2(1) unfolding DBA.run_alt_def DGBA.run_alt_def dbgail_def by auto next fix P assume 3: "P \ set (dgba.accepting (dbgail AA))" obtain k where 4: "P = (\ pp. dba.accepting (AA ! k) (pp ! k))" "k < length AA" using 3 unfolding dbgail_def by auto have "True \ infs (dba.accepting (AA ! k)) (dba.trace (AA ! k) w (map dba.initial AA ! k))" using 2(2) 4(2) by auto also have "dba.trace (AA ! k) w (map dba.initial AA ! k) = smap (\ pp. pp ! k) (dgba.trace (dbgail AA) w (map dba.initial AA))" using 4(2) by (fastforce intro: dbgail_trace_smap[symmetric]) also have "infs (dba.accepting (AA ! k)) \ \ infs P (dgba.trace (dbgail AA) w (map dba.initial AA))" unfolding 4(1) by (simp add: comp_def) also have "map dba.initial AA = dgba.initial (dbgail AA)" unfolding dbgail_def by simp finally show "infs P (dgba.trace (dbgail AA) w (dgba.initial (dbgail AA)))" by simp qed qed definition dbail :: "('label, 'state) dba list \ ('label, 'state list degen) dba" where - "dbail = degen \ dbgail" + "dbail = dgbad \ dbgail" lemma dbail_nodes_finite[intro]: assumes "list_all (finite \ DBA.nodes) AA" shows "finite (DBA.nodes (dbail AA))" using dbgail_nodes_finite assms unfolding dbail_def by auto lemma dbail_nodes_card: assumes"list_all (finite \ DBA.nodes) AA" shows "card (DBA.nodes (dbail AA)) \ max 1 (length AA) * prod_list (map (card \ DBA.nodes) AA)" proof - have "card (DBA.nodes (dbail AA)) \ max 1 (length (dgba.accepting (dbgail AA))) * card (DGBA.nodes (dbgail AA))" - unfolding dbail_def using degen_nodes_card by simp + unfolding dbail_def using dgbad_nodes_card by simp also have "length (dgba.accepting (dbgail AA)) = length AA" unfolding dbgail_def by simp also have "card (DGBA.nodes (dbgail AA)) \ prod_list (map (card \ DBA.nodes) AA)" using dbgail_nodes_card assms by this finally show ?thesis by simp qed lemma dbail_language[simp]: "DBA.language (dbail AA) = INTER (set AA) DBA.language" - unfolding dbail_def using degen_language dbgail_language by auto + unfolding dbail_def using dgbad_language dbgail_language by auto definition dbau :: "('label, 'state\<^sub>1) dba \ ('label, 'state\<^sub>2) dba \ ('label, 'state\<^sub>1 \ 'state\<^sub>2) dba" where "dbau A B \ dba (dba.alphabet A \ dba.alphabet B) (dba.initial A, dba.initial B) (\ a (p, q). (dba.succ A a p, dba.succ B a q)) (\ (p, q). dba.accepting A p \ dba.accepting B q)" (* TODO: can these be extracted as more general theorems about sscan? *) lemma dbau_fst[iff]: "infs (P \ fst) (dba.trace (dbau A B) w (p, q)) \ infs P (dba.trace A w p)" proof - let ?t = "dba.trace (dbau A B) w (p, q)" have "infs (P \ fst) ?t \ infs P (smap fst ?t)" by (simp add: comp_def) also have "smap fst ?t = dba.trace A w p" unfolding dbau_def by (coinduction arbitrary: w p q) (auto) finally show ?thesis by this qed lemma dbau_snd[iff]: "infs (P \ snd) (dba.trace (dbau A B) w (p, q)) \ infs P (dba.trace B w q)" proof - let ?t = "dba.trace (dbau A B) w (p, q)" have "infs (P \ snd) ?t \ infs P (smap snd ?t)" by (simp add: comp_def) also have "smap snd ?t = dba.trace B w q" unfolding dbau_def by (coinduction arbitrary: w p q) (auto) finally show ?thesis by this qed lemma dbau_nodes_fst[intro]: assumes "dba.alphabet A = dba.alphabet B" shows "fst ` DBA.nodes (dbau A B) \ DBA.nodes A" proof (rule subsetI, erule imageE) fix pq p assume "pq \ DBA.nodes (dbau A B)" "p = fst pq" then show "p \ DBA.nodes A" using assms unfolding dbau_def by (induct arbitrary: p) (auto) qed lemma dbau_nodes_snd[intro]: assumes "dba.alphabet A = dba.alphabet B" shows "snd ` DBA.nodes (dbau A B) \ DBA.nodes B" proof (rule subsetI, erule imageE) fix pq q assume "pq \ DBA.nodes (dbau A B)" "q = snd pq" then show "q \ DBA.nodes B" using assms unfolding dbau_def by (induct arbitrary: q) (auto) qed lemma dbau_nodes_finite[intro]: assumes "dba.alphabet A = dba.alphabet B" assumes "finite (DBA.nodes A)" "finite (DBA.nodes B)" shows "finite (DBA.nodes (dbau A B))" proof (rule finite_subset) show "DBA.nodes (dbau A B) \ DBA.nodes A \ DBA.nodes B" using dbau_nodes_fst[OF assms(1)] dbau_nodes_snd[OF assms(1)] unfolding image_subset_iff by force show "finite (DBA.nodes A \ DBA.nodes B)" using assms(2, 3) by simp qed lemma dbau_nodes_card[intro]: assumes "dba.alphabet A = dba.alphabet B" assumes "finite (DBA.nodes A)" "finite (DBA.nodes B)" shows "card (DBA.nodes (dbau A B)) \ card (DBA.nodes A) * card (DBA.nodes B)" proof - have "card (DBA.nodes (dbau A B)) \ card (DBA.nodes A \ DBA.nodes B)" proof (rule card_mono) show "finite (DBA.nodes A \ DBA.nodes B)" using assms(2, 3) by simp show "DBA.nodes (dbau A B) \ DBA.nodes A \ DBA.nodes B" using dbau_nodes_fst[OF assms(1)] dbau_nodes_snd[OF assms(1)] unfolding image_subset_iff by force qed also have "\ = card (DBA.nodes A) * card (DBA.nodes B)" using card_cartesian_product by this finally show ?thesis by this qed lemma dbau_language[simp]: assumes "dba.alphabet A = dba.alphabet B" shows "DBA.language (dbau A B) = DBA.language A \ DBA.language B" proof - have 1: "dba.alphabet (dbau A B) = dba.alphabet A \ dba.alphabet B" unfolding dbau_def by simp have 2: "dba.initial (dbau A B) = (dba.initial A, dba.initial B)" unfolding dbau_def by simp have 3: "dba.accepting (dbau A B) = (\ pq. (dba.accepting A \ fst) pq \ (dba.accepting B \ snd) pq)" unfolding dbau_def by auto have 4: "infs (dba.accepting (dbau A B)) (DBA.trace (dbau A B) w (p, q)) \ infs (dba.accepting A) (DBA.trace A w p) \ infs (dba.accepting B) (DBA.trace B w q)" for w p q unfolding 3 by blast show ?thesis using assms unfolding DBA.language_def DBA.run_alt_def 1 2 4 by auto qed definition dbaul :: "('label, 'state) dba list \ ('label, 'state list) dba" where "dbaul AA \ dba (UNION (set AA) dba.alphabet) (map dba.initial AA) (\ a pp. map2 (\ A p. dba.succ A a p) AA pp) (\ pp. \ k < length AA. dba.accepting (AA ! k) (pp ! k))" lemma dbaul_trace_smap: assumes "length pp = length AA" "k < length AA" shows "smap (\ pp. pp ! k) (dba.trace (dbaul AA) w pp) = dba.trace (AA ! k) w (pp ! k)" using assms unfolding dbaul_def by (coinduction arbitrary: w pp) (force) lemma dbaul_nodes_length: assumes "pp \ DBA.nodes (dbaul AA)" shows "length pp = length AA" using assms unfolding dbaul_def by induct auto lemma dbaul_nodes[intro]: assumes "INTER (set AA) dba.alphabet = UNION (set AA) dba.alphabet" assumes "pp \ DBA.nodes (dbaul AA)" "k < length pp" shows "pp ! k \ DBA.nodes (AA ! k)" using assms(2, 3, 1) unfolding dbaul_def by induct force+ lemma dbaul_nodes_finite[intro]: assumes "INTER (set AA) dba.alphabet = UNION (set AA) dba.alphabet" assumes "list_all (finite \ DBA.nodes) AA" shows "finite (DBA.nodes (dbaul AA))" proof (rule finite_subset) show "DBA.nodes (dbaul AA) \ listset (map DBA.nodes AA)" using assms(1) by (force simp: listset_member list_all2_conv_all_nth dbaul_nodes_length) have "finite (listset (map DBA.nodes AA)) \ list_all finite (map DBA.nodes AA)" by (rule listset_finite) (auto simp: list_all_iff) then show "finite (listset (map DBA.nodes AA))" using assms(2) by (simp add: list.pred_map) qed lemma dbaul_nodes_card: assumes "INTER (set AA) dba.alphabet = UNION (set AA) dba.alphabet" assumes "list_all (finite \ DBA.nodes) AA" shows "card (DBA.nodes (dbaul AA)) \ prod_list (map (card \ DBA.nodes) AA)" proof - have "card (DBA.nodes (dbaul AA)) \ card (listset (map DBA.nodes AA))" proof (rule card_mono) have "finite (listset (map DBA.nodes AA)) \ list_all finite (map DBA.nodes AA)" by (rule listset_finite) (auto simp: list_all_iff) then show "finite (listset (map DBA.nodes AA))" using assms(2) by (simp add: list.pred_map) show "DBA.nodes (dbaul AA) \ listset (map DBA.nodes AA)" using assms(1) by (force simp: listset_member list_all2_conv_all_nth dbaul_nodes_length) qed also have "\ = prod_list (map (card \ DBA.nodes) AA)" by simp finally show ?thesis by this qed lemma dbaul_language[simp]: assumes "INTER (set AA) dba.alphabet = UNION (set AA) dba.alphabet" shows "DBA.language (dbaul AA) = UNION (set AA) DBA.language" proof safe fix w assume 1: "w \ DBA.language (dbaul AA)" obtain 2: "dba.run (dbaul AA) w (dba.initial (dbaul AA))" "infs (dba.accepting (dbaul AA)) (dba.trace (dbaul AA) w (dba.initial (dbaul AA)))" using 1 by rule obtain k where 3: "k < length AA" "infs (\ pp. dba.accepting (AA ! k) (pp ! k)) (dba.trace (dbaul AA) w (map dba.initial AA))" using 2(2) unfolding dbaul_def by auto show "w \ UNION (set AA) DBA.language" proof (intro UN_I DBA.language) show "AA ! k \ set AA" using 3(1) by simp show "dba.run (AA ! k) w (dba.initial (AA ! k))" using assms 2(1) 3(1) unfolding DBA.run_alt_def DGBA.run_alt_def dbaul_def by force have "True \ infs (\ pp. dba.accepting (AA ! k) (pp ! k)) (dba.trace (dbaul AA) w (map dba.initial AA))" using 3(2) by auto also have "\ \ infs (dba.accepting (AA ! k)) (smap (\ pp. pp ! k) (dba.trace (dbaul AA) w (map dba.initial AA)))" by (simp add: comp_def) also have "smap (\ pp. pp ! k) (dba.trace (dbaul AA) w (map dba.initial AA)) = dba.trace (AA ! k) w (map dba.initial AA ! k)" using 3(1) by (fastforce intro: dbaul_trace_smap) also have "\ = dba.trace (AA ! k) w (dba.initial (AA ! k))" using 3 by auto finally show "infs (dba.accepting (AA ! k)) (dba.trace (AA ! k) w (dba.initial (AA ! k)))" by simp qed next fix A w assume 1: "A \ set AA" "w \ DBA.language A" obtain 2: "dba.run A w (dba.initial A)" "infs (dba.accepting A) (dba.trace A w (dba.initial A))" using 1(2) by rule obtain k where 3: "A = AA ! k" "k < length AA" using 1(1) unfolding in_set_conv_nth by auto show "w \ DBA.language (dbaul AA)" proof show "dba.run (dbaul AA) w (dba.initial (dbaul AA))" using 1(1) 2(1) unfolding DBA.run_alt_def DGBA.run_alt_def dbaul_def by auto have "True \ infs (dba.accepting (AA ! k)) (dba.trace (AA ! k) w (map dba.initial AA ! k))" using 2(2) 3 by auto also have "dba.trace (AA ! k) w (map dba.initial AA ! k) = smap (\ pp. pp ! k) (dba.trace (dbaul AA) w (map dba.initial AA))" using 3(2) by (fastforce intro: dbaul_trace_smap[symmetric]) also have "infs (dba.accepting (AA ! k)) \ \ infs (\ pp. dba.accepting (AA ! k) (pp ! k)) (dba.trace (dbaul AA) w (map dba.initial AA))" by (simp add: comp_def) finally show "infs (dba.accepting (dbaul AA)) (dba.trace (dbaul AA) w (dba.initial (dbaul AA)))" using 3(2) unfolding dbaul_def by auto qed qed end \ No newline at end of file diff --git a/thys/Transition_Systems_and_Automata/Automata/DBA/DGBA.thy b/thys/Transition_Systems_and_Automata/Automata/DBA/DGBA.thy --- a/thys/Transition_Systems_and_Automata/Automata/DBA/DGBA.thy +++ b/thys/Transition_Systems_and_Automata/Automata/DBA/DGBA.thy @@ -1,90 +1,146 @@ section \Deterministic Generalized Büchi Automata\ theory DGBA imports "DBA" - "../../Transition_Systems/Transition_System_Degeneralization" + "../../Basic/Degeneralization" begin datatype ('label, 'state) dgba = dgba (alphabet: "'label set") (initial: "'state") (succ: "'label \ 'state \ 'state") (accepting: "'state pred gen") - global_interpretation dgba: transition_system_initial_generalized - "succ A" "\ a p. a \ alphabet A" "\ p. p = initial A" "accepting A" + global_interpretation dgba: transition_system_initial + "succ A" "\ a p. a \ alphabet A" "\ p. p = initial A" for A defines path = dgba.path and run = dgba.run and reachable = dgba.reachable and nodes = dgba.nodes and - enableds = dgba.enableds and paths = dgba.paths and runs = dgba.runs and - dexecute = dgba.dexecute and denabled = dgba.denabled and dinitial = dgba.dinitial and - daccepting = dgba.dcondition + enableds = dgba.enableds and paths = dgba.paths and runs = dgba.runs by this abbreviation target where "target \ dgba.target" abbreviation states where "states \ dgba.states" abbreviation trace where "trace \ dgba.trace" abbreviation successors :: "('label, 'state) dgba \ 'state \ 'state set" where "successors \ dgba.successors TYPE('label)" lemma path_alt_def: "path A w p \ set w \ alphabet A" unfolding lists_iff_set[symmetric] proof show "w \ lists (alphabet A)" if "path A w p" using that by (induct arbitrary: p) (auto) show "path A w p" if "w \ lists (alphabet A)" using that by (induct arbitrary: p) (auto) qed lemma run_alt_def: "run A w p \ sset w \ alphabet A" unfolding streams_iff_sset[symmetric] proof show "w \ streams (alphabet A)" if "run A w p" using that by (coinduction arbitrary: w p) (force elim: dgba.run.cases) show "run A w p" if "w \ streams (alphabet A)" using that by (coinduction arbitrary: w p) (force elim: streams.cases) qed definition language :: "('label, 'state) dgba \ 'label stream set" where "language A \ {w. run A w (initial A) \ gen infs (accepting A) (trace A w (initial A))}" lemma language[intro]: assumes "run A w (initial A)" "gen infs (accepting A) (trace A w (initial A))" shows "w \ language A" using assms unfolding language_def by auto lemma language_elim[elim]: assumes "w \ language A" obtains "run A w (initial A)" "gen infs (accepting A) (trace A w (initial A))" using assms unfolding language_def by auto lemma language_alphabet: "language A \ streams (alphabet A)" unfolding language_def run_alt_def using sset_streams by auto - definition degen :: "('label, 'state) dgba \ ('label, 'state degen) dba" where - "degen A \ dba (alphabet A) (The (dinitial A)) (dexecute A) (daccepting A)" - - lemma degen_simps[simp]: - "dba.alphabet (degen A) = alphabet A" - "dba.initial (degen A) = (initial A, 0)" - "dba.succ (degen A) = dexecute A" - "dba.accepting (degen A) = daccepting A" - unfolding degen_def dgba.dinitial_def by auto + definition dgbad :: "('label, 'state) dgba \ ('label, 'state degen) dba" where + "dgbad A \ dba + (alphabet A) + (initial A, 0) + (\ a (p, k). (succ A a p, count (accepting A) p k)) + (degen (accepting A))" - lemma degen_trace[simp]: "dba.trace (degen A) = dgba.degen.trace A" unfolding degen_simps by rule - lemma degen_run[simp]: "dba.run (degen A) = dgba.degen.run A" - unfolding DBA.run_def degen_simps dgba.denabled_def case_prod_beta' by rule - lemma degen_nodes[simp]: "DBA.nodes (degen A) = dgba.degen.nodes TYPE('label) A" - unfolding DBA.nodes_def degen_simps - unfolding dgba.denabled_def dgba.dinitial_def - unfolding prod_eq_iff case_prod_beta' prod.sel - by rule + lemma dgbad_simps[simp]: + "dba.alphabet (dgbad A) = alphabet A" + "dba.initial (dgbad A) = (initial A, 0)" + "dba.succ (dgbad A) a (p, k) = (succ A a p, count (accepting A) p k)" + "dba.accepting (dgbad A) = degen (accepting A)" + unfolding dgbad_def by auto - lemma degen_nodes_finite[iff]: "finite (DBA.nodes (degen A)) \ finite (DGBA.nodes A)" by simp - lemma degen_nodes_card: "card (DBA.nodes (degen A)) \ max 1 (length (accepting A)) * card (DGBA.nodes A)" - using dgba.degen_nodes_card by simp + lemma dgbad_target[simp]: "dba.target (dgbad A) w (p, k) = + (dgba.target A w p, fold (count (accepting A)) (butlast (p # dgba.states A w p)) k)" + by (induct w arbitrary: p k) (auto) + lemma dgbad_states[simp]: "dba.states (dgbad A) w (p, k) = + dgba.states A w p || scan (count (accepting A)) (p # dgba.states A w p) k" + by (induct w arbitrary: p k) (auto) + lemma dgbad_trace[simp]: "dba.trace (dgbad A) w (p, k) = + dgba.trace A w p ||| sscan (count (accepting A)) (p ## dgba.trace A w p) k" + by (coinduction arbitrary: w p k) (auto) + lemma dgbad_path[iff]: "dba.path (dgbad A) w (p, k) \ dgba.path A w p" + unfolding DBA.path_alt_def DGBA.path_alt_def by simp + lemma dgbad_run[iff]: "dba.run (dgbad A) w (p, k) \ dgba.run A w p" + unfolding DBA.run_alt_def DGBA.run_alt_def by simp - lemma degen_language[simp]: "DBA.language (degen A) = DGBA.language A" - unfolding DBA.language_def DGBA.language_def degen_simps - unfolding degen_trace degen_run - unfolding dgba.degen_run dgba.degen_infs gen_def - by rule + (* TODO: revise *) + lemma dgbad_nodes_fst[simp]: "fst ` DBA.nodes (dgbad A) = DGBA.nodes A" + unfolding dba.nodes_alt_def dba.reachable_alt_def + unfolding dgba.nodes_alt_def dgba.reachable_alt_def + unfolding image_def by simp + lemma dgbad_nodes_snd_empty: + assumes "accepting A = []" + shows "snd ` DBA.nodes (dgbad A) \ {0}" + proof - + have 2: "snd (dba.succ (dgbad A) a (p, k)) = 0" for a p k using assms by auto + show ?thesis using 2 by (auto elim: dba.nodes.cases) + qed + lemma dgbad_nodes_snd_nonempty: + assumes "accepting A \ []" + shows "snd ` DBA.nodes (dgbad A) \ {0 ..< length (accepting A)}" + proof - + have 1: "snd (dba.initial (dgbad A)) < length (accepting A)" + using assms by simp + have 2: "snd (dba.succ (dgbad A) a (p, k)) < length (accepting A)" for a p k + using assms by auto + show ?thesis using 1 2 by (auto elim: dba.nodes.cases) + qed + lemma dgbad_nodes_empty: + assumes "accepting A = []" + shows "DBA.nodes (dgbad A) = DGBA.nodes A \ {0}" + proof - + have "(p, k) \ DBA.nodes (dgbad A) \ p \ fst ` DBA.nodes (dgbad A) \ k = 0" for p k + using dgbad_nodes_snd_empty[OF assms] by (force simp del: dgbad_nodes_fst) + then show ?thesis by auto + qed + lemma dgbad_nodes_nonempty: + assumes "accepting A \ []" + shows "DBA.nodes (dgbad A) \ DGBA.nodes A \ {0 ..< length (accepting A)}" + using subset_fst_snd dgbad_nodes_fst[of A] dgbad_nodes_snd_nonempty[OF assms] by blast + lemma dgbad_nodes: "DBA.nodes (dgbad A) \ DGBA.nodes A \ {0 ..< max 1 (length (accepting A))}" + using dgbad_nodes_empty dgbad_nodes_nonempty by force + + lemma dgbad_language[simp]: "DBA.language (dgbad A) = DGBA.language A" by force + + lemma dgbad_nodes_finite[iff]: "finite (DBA.nodes (dgbad A)) \ finite (DGBA.nodes A)" + proof + show "finite (DGBA.nodes A)" if "finite (DBA.nodes (dgbad A))" + using that by (auto simp flip: dgbad_nodes_fst) + show "finite (DBA.nodes (dgbad A))" if "finite (DGBA.nodes A)" + using dgbad_nodes that finite_subset by fastforce + qed + lemma dgbad_nodes_card: "card (DBA.nodes (dgbad A)) \ max 1 (length (accepting A)) * card (DGBA.nodes A)" + proof (cases "finite (DGBA.nodes A)") + case True + have "card (DBA.nodes (dgbad A)) \ card (DGBA.nodes A \ {0 ..< max 1 (length (accepting A))})" + using dgbad_nodes True by (blast intro: card_mono) + also have "\ = max 1 (length (accepting A)) * card (DGBA.nodes A)" unfolding card_cartesian_product by simp + finally show ?thesis by this + next + case False + then have "card (DGBA.nodes A) = 0" "card (DBA.nodes (dgbad A)) = 0" by auto + then show ?thesis by simp + qed end \ No newline at end of file diff --git a/thys/Transition_Systems_and_Automata/Automata/DCA/DCA_Combine.thy b/thys/Transition_Systems_and_Automata/Automata/DCA/DCA_Combine.thy --- a/thys/Transition_Systems_and_Automata/Automata/DCA/DCA_Combine.thy +++ b/thys/Transition_Systems_and_Automata/Automata/DCA/DCA_Combine.thy @@ -1,298 +1,298 @@ section \Deterministic Co-Büchi Automata Combinations\ theory DCA_Combine imports "DCA" "DGCA" begin definition dcai :: "('label, 'state\<^sub>1) dca \ ('label, 'state\<^sub>2) dca \ ('label, 'state\<^sub>1 \ 'state\<^sub>2) dca" where "dcai A B \ dca (dca.alphabet A \ dca.alphabet B) (dca.initial A, dca.initial B) (\ a (p, q). (dca.succ A a p, dca.succ B a q)) (\ (p, q). dca.rejecting A p \ dca.rejecting B q)" lemma dcai_fst[iff]: "infs (P \ fst) (dca.trace (dcai A B) w (p, q)) \ infs P (dca.trace A w p)" proof - let ?t = "dca.trace (dcai A B) w (p, q)" have "infs (P \ fst) ?t \ infs P (smap fst ?t)" by (simp add: comp_def) also have "smap fst ?t = dca.trace A w p" unfolding dcai_def by (coinduction arbitrary: w p q) (auto) finally show ?thesis by this qed lemma dcai_snd[iff]: "infs (P \ snd) (dca.trace (dcai A B) w (p, q)) \ infs P (dca.trace B w q)" proof - let ?t = "dca.trace (dcai A B) w (p, q)" have "infs (P \ snd) ?t \ infs P (smap snd ?t)" by (simp add: comp_def) also have "smap snd ?t = dca.trace B w q" unfolding dcai_def by (coinduction arbitrary: w p q) (auto) finally show ?thesis by this qed lemma dcai_nodes_fst[intro]: "fst ` DCA.nodes (dcai A B) \ DCA.nodes A" proof (rule subsetI, erule imageE) fix pq p assume "pq \ DCA.nodes (dcai A B)" "p = fst pq" then show "p \ DCA.nodes A" unfolding dcai_def by (induct arbitrary: p) (auto) qed lemma dcai_nodes_snd[intro]: "snd ` DCA.nodes (dcai A B) \ DCA.nodes B" proof (rule subsetI, erule imageE) fix pq q assume "pq \ DCA.nodes (dcai A B)" "q = snd pq" then show "q \ DCA.nodes B" unfolding dcai_def by (induct arbitrary: q) (auto) qed lemma dcai_nodes_finite[intro]: assumes "finite (DCA.nodes A)" "finite (DCA.nodes B)" shows "finite (DCA.nodes (dcai A B))" proof (rule finite_subset) show "DCA.nodes (dcai A B) \ DCA.nodes A \ DCA.nodes B" using dcai_nodes_fst dcai_nodes_snd unfolding image_subset_iff by force show "finite (DCA.nodes A \ DCA.nodes B)" using assms by simp qed lemma dcai_nodes_card[intro]: assumes "finite (DCA.nodes A)" "finite (DCA.nodes B)" shows "card (DCA.nodes (dcai A B)) \ card (DCA.nodes A) * card (DCA.nodes B)" proof - have "card (DCA.nodes (dcai A B)) \ card (DCA.nodes A \ DCA.nodes B)" proof (rule card_mono) show "finite (DCA.nodes A \ DCA.nodes B)" using assms by simp show "DCA.nodes (dcai A B) \ DCA.nodes A \ DCA.nodes B" using dcai_nodes_fst dcai_nodes_snd unfolding image_subset_iff by force qed also have "\ = card (DCA.nodes A) * card (DCA.nodes B)" using card_cartesian_product by this finally show ?thesis by this qed lemma dcai_language[simp]: "DCA.language (dcai A B) = DCA.language A \ DCA.language B" proof - have 1: "dca.alphabet (dcai A B) = dca.alphabet A \ dca.alphabet B" unfolding dcai_def by simp have 2: "dca.initial (dcai A B) = (dca.initial A, dca.initial B)" unfolding dcai_def by simp have 3: "dca.rejecting (dcai A B) = (\ pq. (dca.rejecting A \ fst) pq \ (dca.rejecting B \ snd) pq)" unfolding dcai_def by auto have 4: "infs (dca.rejecting (dcai A B)) (DCA.trace (dcai A B) w (p, q)) \ infs (dca.rejecting A) (DCA.trace A w p) \ infs (dca.rejecting B) (DCA.trace B w q)" for w p q unfolding 3 by blast show ?thesis unfolding DCA.language_def DCA.run_alt_def 1 2 4 by auto qed definition dcail :: "('label, 'state) dca list \ ('label, 'state list) dca" where "dcail AA \ dca (INTER (set AA) dca.alphabet) (map dca.initial AA) (\ a pp. map2 (\ A p. dca.succ A a p) AA pp) (\ pp. \ k < length AA. dca.rejecting (AA ! k) (pp ! k))" lemma dcail_trace_smap: assumes "length pp = length AA" "k < length AA" shows "smap (\ pp. pp ! k) (dca.trace (dcail AA) w pp) = dca.trace (AA ! k) w (pp ! k)" using assms unfolding dcail_def by (coinduction arbitrary: w pp) (force) lemma dcail_nodes_length: assumes "pp \ DCA.nodes (dcail AA)" shows "length pp = length AA" using assms unfolding dcail_def by induct auto lemma dcail_nodes[intro]: assumes "pp \ DCA.nodes (dcail AA)" "k < length pp" shows "pp ! k \ DCA.nodes (AA ! k)" using assms unfolding dcail_def by induct auto lemma dcail_finite[intro]: assumes "list_all (finite \ DCA.nodes) AA" shows "finite (DCA.nodes (dcail AA))" proof (rule finite_subset) show "DCA.nodes (dcail AA) \ listset (map DCA.nodes AA)" by (force simp: listset_member list_all2_conv_all_nth dcail_nodes_length) have "finite (listset (map DCA.nodes AA)) \ list_all finite (map DCA.nodes AA)" by (rule listset_finite) (auto simp: list_all_iff) then show "finite (listset (map DCA.nodes AA))" using assms by (simp add: list.pred_map) qed lemma dcail_nodes_card: assumes "list_all (finite \ DCA.nodes) AA" shows "card (DCA.nodes (dcail AA)) \ prod_list (map (card \ DCA.nodes) AA)" proof - have "card (DCA.nodes (dcail AA)) \ card (listset (map DCA.nodes AA))" proof (rule card_mono) have "finite (listset (map DCA.nodes AA)) \ list_all finite (map DCA.nodes AA)" by (rule listset_finite) (auto simp: list_all_iff) then show "finite (listset (map DCA.nodes AA))" using assms by (simp add: list.pred_map) show "DCA.nodes (dcail AA) \ listset (map DCA.nodes AA)" by (force simp: listset_member list_all2_conv_all_nth dcail_nodes_length) qed also have "\ = prod_list (map (card \ DCA.nodes) AA)" by simp finally show ?thesis by this qed lemma dcail_language[simp]: "DCA.language (dcail AA) = INTER (set AA) DCA.language" proof safe fix A w assume 1: "w \ DCA.language (dcail AA)" "A \ set AA" obtain 2: "dca.run (dcail AA) w (dca.initial (dcail AA))" "\ infs (dca.rejecting (dcail AA)) (dca.trace (dcail AA) w (dca.initial (dcail AA)))" using 1(1) by rule obtain k where 3: "A = AA ! k" "k < length AA" using 1(2) unfolding in_set_conv_nth by auto have 4: "\ infs (\ pp. dca.rejecting A (pp ! k)) (dca.trace (dcail AA) w (map dca.initial AA))" using 2(2) 3 unfolding dcail_def by auto show "w \ DCA.language A" proof show "dca.run A w (dca.initial A)" using 1(2) 2(1) unfolding DCA.run_alt_def dcail_def by auto have "True \ \ infs (\ pp. dca.rejecting A (pp ! k)) (dca.trace (dcail AA) w (map dca.initial AA))" using 4 by simp also have "\ \ \ infs (dca.rejecting A) (smap (\ pp. pp ! k) (dca.trace (dcail AA) w (map dca.initial AA)))" by (simp add: comp_def) also have "smap (\ pp. pp ! k) (dca.trace (dcail AA) w (map dca.initial AA)) = dca.trace (AA ! k) w (map dca.initial AA ! k)" using 3(2) by (fastforce intro: dcail_trace_smap) also have "\ = dca.trace A w (dca.initial A)" using 3 by auto finally show "\ infs (dca.rejecting A) (DCA.trace A w (dca.initial A))" by simp qed next fix w assume 1: "w \ INTER (set AA) DCA.language" have 2: "dca.run A w (dca.initial A)" "\ infs (dca.rejecting A) (dca.trace A w (dca.initial A))" if "A \ set AA" for A using 1 that by auto have 3: "\ infs (\ pp. dca.rejecting (AA ! k) (pp ! k)) (dca.trace (dcail AA) w (map dca.initial AA))" if "k < length AA" for k proof - have "True \ \ infs (dca.rejecting (AA ! k)) (dca.trace (AA ! k) w (map dca.initial AA ! k))" using 2(2) that by auto also have "dca.trace (AA ! k) w (map dca.initial AA ! k) = smap (\ pp. pp ! k) (dca.trace (dcail AA) w (map dca.initial AA))" using that by (fastforce intro: dcail_trace_smap[symmetric]) also have "infs (dca.rejecting (AA ! k)) \ \ infs (\ pp. dca.rejecting (AA ! k) (pp ! k)) (dca.trace (dcail AA) w (map dca.initial AA))" by (simp add: comp_def) finally show ?thesis by simp qed show "w \ DCA.language (dcail AA)" proof show "dca.run (dcail AA) w (dca.initial (dcail AA))" using 2(1) unfolding DCA.run_alt_def dcail_def by auto show "\ infs (dca.rejecting (dcail AA)) (dca.trace (dcail AA) w (dca.initial (dcail AA)))" using 3 unfolding dcail_def by auto qed qed definition dcgaul :: "('label, 'state) dca list \ ('label, 'state list) dgca" where "dcgaul AA \ dgca (UNION (set AA) dca.alphabet) (map dca.initial AA) (\ a pp. map2 (\ A p. dca.succ A a p) AA pp) (map (\ k pp. dca.rejecting (AA ! k) (pp ! k)) [0 ..< length AA])" lemma dcgaul_trace_smap: assumes "length pp = length AA" "k < length AA" shows "smap (\ pp. pp ! k) (dgca.trace (dcgaul AA) w pp) = dca.trace (AA ! k) w (pp ! k)" using assms unfolding dcgaul_def by (coinduction arbitrary: w pp) (force) lemma dcgaul_nodes_length: assumes "pp \ DGCA.nodes (dcgaul AA)" shows "length pp = length AA" using assms unfolding dcgaul_def by induct auto lemma dcgaul_nodes[intro]: assumes "INTER (set AA) dca.alphabet = UNION (set AA) dca.alphabet" assumes "pp \ DGCA.nodes (dcgaul AA)" "k < length pp" shows "pp ! k \ DCA.nodes (AA ! k)" using assms(2, 3, 1) unfolding dcgaul_def by induct force+ lemma dcgaul_nodes_finite[intro]: assumes "INTER (set AA) dca.alphabet = UNION (set AA) dca.alphabet" assumes "list_all (finite \ DCA.nodes) AA" shows "finite (DGCA.nodes (dcgaul AA))" proof (rule finite_subset) show "DGCA.nodes (dcgaul AA) \ listset (map DCA.nodes AA)" using assms(1) by (force simp: listset_member list_all2_conv_all_nth dcgaul_nodes_length) have "finite (listset (map DCA.nodes AA)) \ list_all finite (map DCA.nodes AA)" by (rule listset_finite) (auto simp: list_all_iff) then show "finite (listset (map DCA.nodes AA))" using assms(2) by (simp add: list.pred_map) qed lemma dcgaul_nodes_card: assumes "INTER (set AA) dca.alphabet = UNION (set AA) dca.alphabet" assumes "list_all (finite \ DCA.nodes) AA" shows "card (DGCA.nodes (dcgaul AA)) \ prod_list (map (card \ DCA.nodes) AA)" proof - have "card (DGCA.nodes (dcgaul AA)) \ card (listset (map DCA.nodes AA))" proof (rule card_mono) have "finite (listset (map DCA.nodes AA)) \ list_all finite (map DCA.nodes AA)" by (rule listset_finite) (auto simp: list_all_iff) then show "finite (listset (map DCA.nodes AA))" using assms(2) by (simp add: list.pred_map) show "DGCA.nodes (dcgaul AA) \ listset (map DCA.nodes AA)" using assms(1) by (force simp: listset_member list_all2_conv_all_nth dcgaul_nodes_length) qed also have "\ = prod_list (map (card \ DCA.nodes) AA)" by simp finally show ?thesis by this qed lemma dcgaul_language[simp]: assumes "INTER (set AA) dca.alphabet = UNION (set AA) dca.alphabet" shows "DGCA.language (dcgaul AA) = UNION (set AA) DCA.language" proof safe fix w assume 1: "w \ DGCA.language (dcgaul AA)" obtain k where 2: "dgca.run (dcgaul AA) w (dgca.initial (dcgaul AA))" "k < length AA" "\ infs (\ pp. dca.rejecting (AA ! k) (pp ! k)) (dgca.trace (dcgaul AA) w (dgca.initial (dcgaul AA)))" using 1 unfolding dcgaul_def by force show "w \ UNION (set AA) DCA.language" proof (intro UN_I DCA.language) show "AA ! k \ set AA" using 2(2) by simp show "dca.run (AA ! k) w (dca.initial (AA ! k))" using assms 2(1, 2) unfolding DCA.run_alt_def DGCA.run_alt_def dcgaul_def by force have "True \ \ infs (\ pp. dca.rejecting (AA ! k) (pp ! k)) (dgca.trace (dcgaul AA) w (map dca.initial AA))" using 2(3) unfolding dcgaul_def by auto also have "\ \ \ infs (dca.rejecting (AA ! k)) (smap (\ pp. pp ! k) (dgca.trace (dcgaul AA) w (map dca.initial AA)))" by (simp add: comp_def) also have "smap (\ pp. pp ! k) (dgca.trace (dcgaul AA) w (map dca.initial AA)) = dca.trace (AA ! k) w (map dca.initial AA ! k)" using 2(2) by (fastforce intro: dcgaul_trace_smap) also have "\ = dca.trace (AA ! k) w (dca.initial (AA ! k))" using 2(2) by auto finally show "\ infs (dca.rejecting (AA ! k)) (dca.trace (AA ! k) w (dca.initial (AA ! k)))" by simp qed next fix A w assume 1: "A \ set AA" "w \ DCA.language A" obtain 2: "dca.run A w (dca.initial A)" "\ infs (dca.rejecting A) (dca.trace A w (dca.initial A))" using 1(2) by rule obtain k where 3: "A = AA ! k" "k < length AA" using 1(1) unfolding in_set_conv_nth by auto show "w \ DGCA.language (dcgaul AA)" proof (intro DGCA.language bexI cogen) show "dgca.run (dcgaul AA) w (dgca.initial (dcgaul AA))" using 1(1) 2(1) unfolding DCA.run_alt_def DGCA.run_alt_def dcgaul_def by auto have "True \ \ infs (dca.rejecting (AA ! k)) (dca.trace (AA ! k) w (map dca.initial AA ! k))" using 2(2) 3 by auto also have "dca.trace (AA ! k) w (map dca.initial AA ! k) = smap (\ pp. pp ! k) (dgca.trace (dcgaul AA) w (map dca.initial AA))" using 3(2) by (fastforce intro: dcgaul_trace_smap[symmetric]) also have "\ infs (dca.rejecting (AA ! k)) \ \ \ infs (\ pp. dca.rejecting (AA ! k) (pp ! k)) (dgca.trace (dcgaul AA) w (map dca.initial AA))" by (simp add: comp_def) also have "map dca.initial AA = dgca.initial (dcgaul AA)" unfolding dcgaul_def by simp finally show "\ infs (\ pp. dca.rejecting (AA ! k) (pp ! k)) (dgca.trace (dcgaul AA) w (dgca.initial (dcgaul AA)))" by simp show "(\ pp. dca.rejecting (AA ! k) (pp ! k)) \ set (dgca.rejecting (dcgaul AA))" unfolding dcgaul_def using 3(2) by simp qed qed definition dcaul :: "('label, 'state) dca list \ ('label, 'state list degen) dca" where - "dcaul = degen \ dcgaul" + "dcaul = dgcad \ dcgaul" lemma dcaul_nodes_finite[intro]: assumes "INTER (set AA) dca.alphabet = UNION (set AA) dca.alphabet" assumes "list_all (finite \ DCA.nodes) AA" shows "finite (DCA.nodes (dcaul AA))" using dcgaul_nodes_finite assms unfolding dcaul_def by auto lemma dcaul_nodes_card: assumes "INTER (set AA) dca.alphabet = UNION (set AA) dca.alphabet" assumes "list_all (finite \ DCA.nodes) AA" shows "card (DCA.nodes (dcaul AA)) \ max 1 (length AA) * prod_list (map (card \ DCA.nodes) AA)" proof - have "card (DCA.nodes (dcaul AA)) \ max 1 (length (dgca.rejecting (dcgaul AA))) * card (DGCA.nodes (dcgaul AA))" - unfolding dcaul_def using degen_nodes_card by simp + unfolding dcaul_def using dgcad_nodes_card by simp also have "length (dgca.rejecting (dcgaul AA)) = length AA" unfolding dcgaul_def by simp also have "card (DGCA.nodes (dcgaul AA)) \ prod_list (map (card \ DCA.nodes) AA)" using dcgaul_nodes_card assms by this finally show ?thesis by simp qed lemma dcaul_language[simp]: assumes "INTER (set AA) dca.alphabet = UNION (set AA) dca.alphabet" shows "DCA.language (dcaul AA) = UNION (set AA) DCA.language" - unfolding dcaul_def using degen_language dcgaul_language[OF assms] by auto + unfolding dcaul_def using dgcad_language dcgaul_language[OF assms] by auto end \ No newline at end of file diff --git a/thys/Transition_Systems_and_Automata/Automata/DCA/DGCA.thy b/thys/Transition_Systems_and_Automata/Automata/DCA/DGCA.thy --- a/thys/Transition_Systems_and_Automata/Automata/DCA/DGCA.thy +++ b/thys/Transition_Systems_and_Automata/Automata/DCA/DGCA.thy @@ -1,91 +1,146 @@ section \Deterministic Co-Generalized Co-Büchi Automata\ theory DGCA imports "DCA" - "../../Transition_Systems/Transition_System_Degeneralization" + "../../Basic/Degeneralization" begin datatype ('label, 'state) dgca = dgca (alphabet: "'label set") (initial: "'state") (succ: "'label \ 'state \ 'state") (rejecting: "'state pred gen") - global_interpretation dgca: transition_system_initial_generalized - "succ A" "\ a p. a \ alphabet A" "\ p. p = initial A" "rejecting A" + global_interpretation dgca: transition_system_initial + "succ A" "\ a p. a \ alphabet A" "\ p. p = initial A" for A defines path = dgca.path and run = dgca.run and reachable = dgca.reachable and nodes = dgca.nodes and - enableds = dgca.enableds and paths = dgca.paths and runs = dgca.runs and - dexecute = dgca.dexecute and denabled = dgca.denabled and dinitial = dgca.dinitial and - drejecting = dgca.dcondition + enableds = dgca.enableds and paths = dgca.paths and runs = dgca.runs by this abbreviation target where "target \ dgca.target" abbreviation states where "states \ dgca.states" abbreviation trace where "trace \ dgca.trace" abbreviation successors :: "('label, 'state) dgca \ 'state \ 'state set" where "successors \ dgca.successors TYPE('label)" lemma path_alt_def: "path A w p \ set w \ alphabet A" unfolding lists_iff_set[symmetric] proof show "w \ lists (alphabet A)" if "path A w p" using that by (induct arbitrary: p) (auto) show "path A w p" if "w \ lists (alphabet A)" using that by (induct arbitrary: p) (auto) qed lemma run_alt_def: "run A w p \ sset w \ alphabet A" unfolding streams_iff_sset[symmetric] proof show "w \ streams (alphabet A)" if "run A w p" using that by (coinduction arbitrary: w p) (force elim: dgca.run.cases) show "run A w p" if "w \ streams (alphabet A)" using that by (coinduction arbitrary: w p) (force elim: streams.cases) qed definition language :: "('label, 'state) dgca \ 'label stream set" where "language A \ {w. run A w (initial A) \ cogen fins (rejecting A) (trace A w (initial A))}" lemma language[intro]: assumes "run A w (initial A)" "cogen fins (rejecting A) (trace A w (initial A))" shows "w \ language A" using assms unfolding language_def by auto lemma language_elim[elim]: assumes "w \ language A" obtains "run A w (initial A)" "cogen fins (rejecting A) (trace A w (initial A))" using assms unfolding language_def by auto lemma language_alphabet: "language A \ streams (alphabet A)" unfolding language_def run_alt_def using sset_streams by auto - definition degen :: "('label, 'state) dgca \ ('label, 'state degen) dca" where - "degen A \ dca (alphabet A) (The (dinitial A)) (dexecute A) (drejecting A)" - - lemma degen_simps[simp]: - "dca.alphabet (degen A) = alphabet A" - "dca.initial (degen A) = (initial A, 0)" - "dca.succ (degen A) = dexecute A" - "dca.rejecting (degen A) = drejecting A" - unfolding degen_def dgca.dinitial_def by auto + definition dgcad :: "('label, 'state) dgca \ ('label, 'state degen) dca" where + "dgcad A \ dca + (alphabet A) + (initial A, 0) + (\ a (p, k). (succ A a p, count (rejecting A) p k)) + (degen (rejecting A))" - lemma degen_trace[simp]: "dca.trace (degen A) = dgca.degen.trace A" unfolding degen_simps by rule - lemma degen_run[simp]: "dca.run (degen A) = dgca.degen.run A" - unfolding DCA.run_def degen_simps dgca.denabled_def case_prod_beta' by rule - lemma degen_nodes[simp]: "DCA.nodes (degen A) = dgca.degen.nodes TYPE('label) A" - unfolding DCA.nodes_def degen_simps - unfolding dgca.denabled_def dgca.dinitial_def - unfolding prod_eq_iff case_prod_beta' prod.sel - by rule + lemma dgcad_simps[simp]: + "dca.alphabet (dgcad A) = alphabet A" + "dca.initial (dgcad A) = (initial A, 0)" + "dca.succ (dgcad A) a (p, k) = (succ A a p, count (rejecting A) p k)" + "dca.rejecting (dgcad A) = degen (rejecting A)" + unfolding dgcad_def by auto - lemma degen_nodes_finite[iff]: "finite (DCA.nodes (degen A)) \ finite (DGCA.nodes A)" by simp - lemma degen_nodes_card: "card (DCA.nodes (degen A)) \ max 1 (length (rejecting A)) * card (DGCA.nodes A)" - using dgca.degen_nodes_card by simp + lemma dgcad_target[simp]: "dca.target (dgcad A) w (p, k) = + (dgca.target A w p, fold (count (rejecting A)) (butlast (p # dgca.states A w p)) k)" + by (induct w arbitrary: p k) (auto) + lemma dgcad_states[simp]: "dca.states (dgcad A) w (p, k) = + dgca.states A w p || scan (count (rejecting A)) (p # dgca.states A w p) k" + by (induct w arbitrary: p k) (auto) + lemma dgcad_trace[simp]: "dca.trace (dgcad A) w (p, k) = + dgca.trace A w p ||| sscan (count (rejecting A)) (p ## dgca.trace A w p) k" + by (coinduction arbitrary: w p k) (auto) + lemma dgcad_path[iff]: "dca.path (dgcad A) w (p, k) \ dgca.path A w p" + unfolding DCA.path_alt_def DGCA.path_alt_def by simp + lemma dgcad_run[iff]: "dca.run (dgcad A) w (p, k) \ dgca.run A w p" + unfolding DCA.run_alt_def DGCA.run_alt_def by simp - lemma degen_language[simp]: "DCA.language (degen A) = DGCA.language A" - unfolding DCA.language_def DGCA.language_def degen_simps - unfolding degen_trace degen_run - unfolding dgca.degen_run dgca.degen_infs cogen_def - unfolding ball_simps(10) - by rule + (* TODO: revise *) + lemma dgcad_nodes_fst[simp]: "fst ` DCA.nodes (dgcad A) = DGCA.nodes A" + unfolding dca.nodes_alt_def dca.reachable_alt_def + unfolding dgca.nodes_alt_def dgca.reachable_alt_def + unfolding image_def by simp + lemma dgcad_nodes_snd_empty: + assumes "rejecting A = []" + shows "snd ` DCA.nodes (dgcad A) \ {0}" + proof - + have 2: "snd (dca.succ (dgcad A) a (p, k)) = 0" for a p k using assms by auto + show ?thesis using 2 by (auto elim: dca.nodes.cases) + qed + lemma dgcad_nodes_snd_nonempty: + assumes "rejecting A \ []" + shows "snd ` DCA.nodes (dgcad A) \ {0 ..< length (rejecting A)}" + proof - + have 1: "snd (dca.initial (dgcad A)) < length (rejecting A)" + using assms by simp + have 2: "snd (dca.succ (dgcad A) a (p, k)) < length (rejecting A)" for a p k + using assms by auto + show ?thesis using 1 2 by (auto elim: dca.nodes.cases) + qed + lemma dgcad_nodes_empty: + assumes "rejecting A = []" + shows "DCA.nodes (dgcad A) = DGCA.nodes A \ {0}" + proof - + have "(p, k) \ DCA.nodes (dgcad A) \ p \ fst ` DCA.nodes (dgcad A) \ k = 0" for p k + using dgcad_nodes_snd_empty[OF assms] by (force simp del: dgcad_nodes_fst) + then show ?thesis by auto + qed + lemma dgcad_nodes_nonempty: + assumes "rejecting A \ []" + shows "DCA.nodes (dgcad A) \ DGCA.nodes A \ {0 ..< length (rejecting A)}" + using subset_fst_snd dgcad_nodes_fst[of A] dgcad_nodes_snd_nonempty[OF assms] by blast + lemma dgcad_nodes: "DCA.nodes (dgcad A) \ DGCA.nodes A \ {0 ..< max 1 (length (rejecting A))}" + using dgcad_nodes_empty dgcad_nodes_nonempty by force + + lemma dgcad_language[simp]: "DCA.language (dgcad A) = DGCA.language A" by force + + lemma dgcad_nodes_finite[iff]: "finite (DCA.nodes (dgcad A)) \ finite (DGCA.nodes A)" + proof + show "finite (DGCA.nodes A)" if "finite (DCA.nodes (dgcad A))" + using that by (auto simp flip: dgcad_nodes_fst) + show "finite (DCA.nodes (dgcad A))" if "finite (DGCA.nodes A)" + using dgcad_nodes that finite_subset by fastforce + qed + lemma dgcad_nodes_card: "card (DCA.nodes (dgcad A)) \ max 1 (length (rejecting A)) * card (DGCA.nodes A)" + proof (cases "finite (DGCA.nodes A)") + case True + have "card (DCA.nodes (dgcad A)) \ card (DGCA.nodes A \ {0 ..< max 1 (length (rejecting A))})" + using dgcad_nodes True by (blast intro: card_mono) + also have "\ = max 1 (length (rejecting A)) * card (DGCA.nodes A)" unfolding card_cartesian_product by simp + finally show ?thesis by this + next + case False + then have "card (DGCA.nodes A) = 0" "card (DCA.nodes (dgcad A)) = 0" by auto + then show ?thesis by simp + qed end \ No newline at end of file diff --git a/thys/Transition_Systems_and_Automata/Basic/Acceptance.thy b/thys/Transition_Systems_and_Automata/Basic/Acceptance.thy --- a/thys/Transition_Systems_and_Automata/Basic/Acceptance.thy +++ b/thys/Transition_Systems_and_Automata/Basic/Acceptance.thy @@ -1,51 +1,49 @@ theory Acceptance imports Sequence_LTL begin type_synonym 'a pred = "'a \ bool" type_synonym 'a rabin = "'a pred \ 'a pred" type_synonym 'a gen = "'a list" - (* TODO: move to degeneralization theory *) - type_synonym 'a degen = "'a \ nat" definition rabin :: "'a rabin \ 'a stream pred" where "rabin \ \ (I, F) w. infs I w \ fins F w" lemma rabin[intro]: assumes "IF = (I, F)" "infs I w" "fins F w" shows "rabin IF w" using assms unfolding rabin_def by auto lemma rabin_elim[elim]: assumes "rabin IF w" obtains I F where "IF = (I, F)" "infs I w" "fins F w" using assms unfolding rabin_def by auto definition gen :: "('a \ 'b pred) \ ('a gen \ 'b pred)" where "gen P cs w \ \ c \ set cs. P c w" lemma gen[intro]: assumes "\ c. c \ set cs \ P c w" shows "gen P cs w" using assms unfolding gen_def by auto lemma gen_elim[elim]: assumes "gen P cs w" obtains "\ c. c \ set cs \ P c w" using assms unfolding gen_def by auto definition cogen :: "('a \ 'b pred) \ ('a gen \ 'b pred)" where "cogen P cs w \ \ c \ set cs. P c w" lemma cogen[intro]: assumes "c \ set cs" "P c w" shows "cogen P cs w" using assms unfolding cogen_def by auto lemma cogen_elim[elim]: assumes "cogen P cs w" obtains c where "c \ set cs" "P c w" using assms unfolding cogen_def by auto lemma cogen_alt_def: "cogen P cs w \ \ gen (\ c w. Not (P c w)) cs w" by auto end \ No newline at end of file diff --git a/thys/Transition_Systems_and_Automata/Basic/Degeneralization.thy b/thys/Transition_Systems_and_Automata/Basic/Degeneralization.thy new file mode 100644 --- /dev/null +++ b/thys/Transition_Systems_and_Automata/Basic/Degeneralization.thy @@ -0,0 +1,224 @@ +theory Degeneralization +imports + Acceptance + Sequence_Zip +begin + + type_synonym 'a degen = "'a \ nat" + + definition degen :: "'a pred gen \ 'a degen pred" where + "degen cs \ \ (a, k). k \ length cs \ (cs ! k) a" + + lemma degen_simps[iff]: "degen cs (a, k) \ k \ length cs \ (cs ! k) a" unfolding degen_def by simp + + definition count :: "'a pred gen \ 'a \ nat \ nat" where + "count cs a k \ if k < length cs then if (cs ! k) a then Suc k mod length cs else k else 0" + + lemma count_empty[simp]: "count [] a k = 0" unfolding count_def by simp + lemma count_nonempty[simp]: + assumes "cs \ []" + shows "count cs a k < length cs" + using assms unfolding count_def by simp + lemma count_constant_1: + assumes "k < length cs" + assumes "\ a. a \ set w \ \ (cs ! k) a" + shows "fold (count cs) w k = k" + using assms unfolding count_def by (induct w) (auto) + lemma count_constant_2: + assumes "k < length cs" + assumes "\ a. a \ set (w || k # scan (count cs) w k) \ \ degen cs a" + shows "fold (count cs) w k = k" + using assms unfolding count_def by (induct w) (auto) + + lemma degen_skip_condition: + assumes "k < length cs" + assumes "infs (degen cs) (w ||| k ## sscan (count cs) w k)" + obtains u a v + where "w = u @- a ## v" "fold (count cs) u k = k" "(cs ! k) a" + proof - + have 1: "Collect (degen cs) \ sset (w ||| k ## sscan (count cs) w k) \ {}" + using infs_any assms(2) by auto + obtain ys x zs where 2: + "w ||| k ## sscan (count cs) w k = ys @- x ## zs" + "Collect (degen cs) \ set ys = {}" + "x \ Collect (degen cs)" + using split_stream_first 1 by this + define u where "u \ stake (length ys) w" + define a where "a \ w !! length ys" + define v where "v \ sdrop (Suc (length ys)) w" + have "ys = stake (length ys) (w ||| k ## sscan (count cs) w k)" using shift_eq 2(1) by auto + also have "\ = stake (length ys) w || stake (length ys) (k ## sscan (count cs) w k)" by simp + also have "\ = take (length ys) u || take (length ys) (k # scan (count cs) u k)" + unfolding u_def + using append_eq_conv_conj length_stake length_zip stream.sel + using sscan_stake stake.simps(2) stake_Suc stake_szip take_stake + by metis + also have "\ = take (length ys) (u || k # scan (count cs) u k)" using take_zip by rule + also have "\ = u || k # scan (count cs) u k" unfolding u_def by simp + finally have 3: "ys = u || k # scan (count cs) u k" by this + have "x = (w ||| k ## sscan (count cs) w k) !! length ys" unfolding 2(1) by simp + also have "\ = (w !! length ys, (k ## sscan (count cs) w k) !! length ys)" by simp + also have "\ = (a, fold (count cs) u k)" unfolding u_def a_def by simp + finally have 4: "x = (a, fold (count cs) u k)" by this + have 5: "fold (count cs) u k = k" using count_constant_2 assms(1) 2(2) unfolding 3 by blast + show ?thesis + proof + show "w = u @- a ## v" unfolding u_def a_def v_def using id_stake_snth_sdrop by this + show "fold (count cs) u k = k" using 5 by this + show "(cs ! k) a" using assms(1) 2(3) unfolding 4 5 by simp + qed + qed + lemma degen_skip_arbitrary: + assumes "k < length cs" "l < length cs" + assumes "infs (degen cs) (w ||| k ## sscan (count cs) w k)" + obtains u v + where "w = u @- v" "fold (count cs) u k = l" + using assms + proof (induct "nat ((int l - int k) mod length cs)" arbitrary: l thesis) + case (0) + have 1: "length cs > 0" using assms(1) by auto + have 2: "(int l - int k) mod length cs = 0" using 0(1) 1 by (auto intro: antisym) + have 3: "int l mod length cs = int k mod length cs" using mod_eq_dvd_iff 2 by force + have 4: "k = l" using 0(3, 4) 3 by simp + show ?case + proof (rule 0(2)) + show "w = [] @- w" by simp + show "fold (count cs) [] k = l" using 4 by simp + qed + next + case (Suc n) + have 1: "length cs > 0" using assms(1) by auto + define l' where "l' = nat ((int l - 1) mod length cs)" + obtain u v where 2: "w = u @- v" "fold (count cs) u k = l'" + proof (rule Suc(1)) + have 2: "Suc n < length cs" using nat_less_iff Suc(2) 1 by simp + have "n = nat (int n)" by simp + also have "int n = (int (Suc n) - 1) mod length cs" using 2 by simp + also have "\ = (int l - int k - 1) mod length cs" using Suc(2) by (simp add: mod_simps) + also have "\ = (int l - 1 - int k) mod length cs" by (simp add: algebra_simps) + also have "\ = (int l' - int k) mod length cs" using l'_def 1 by (simp add: mod_simps) + finally show "n = nat ((int l' - int k) mod length cs)" by this + show "k < length cs" using Suc(4) by this + show "l' < length cs" using nat_less_iff l'_def 1 by simp + show "infs (degen cs) (w ||| k ## sscan (count cs) w k)" using Suc(6) by this + qed + have 3: "l' < length cs" using nat_less_iff l'_def 1 by simp + have 4: "v ||| l' ## sscan (count cs) v l' = sdrop (length u) (w ||| k ## sscan (count cs) w k)" + using 2 eq_scons eq_shift + by (metis sdrop.simps(2) sdrop_simps sdrop_szip sscan_scons_snth sscan_sdrop stream.sel(2)) + have 5: "infs (degen cs) (v ||| l' ## sscan (count cs) v l')" using Suc(6) unfolding 4 by blast + obtain vu a vv where 6: "v = vu @- a ## vv" "fold (count cs) vu l' = l'" "(cs ! l') a" + using degen_skip_condition 3 5 by this + have "l = nat (int l)" by simp + also have "int l = int l mod length cs" using Suc(5) by simp + also have "\ = int (Suc l') mod length cs" using l'_def 1 by (simp add: mod_simps) + finally have 7: "l = Suc l' mod length cs" using nat_mod_as_int by metis + show ?case + proof (rule Suc(3)) + show "w = (u @ vu @ [a]) @- vv" unfolding 2(1) 6(1) by simp + show "fold (count cs) (u @ vu @ [a]) k = l" using 2(2) 3 6(2, 3) 7 unfolding count_def by simp + qed + qed + lemma degen_skip_arbitrary_condition: + assumes "l < length cs" + assumes "infs (degen cs) (w ||| k ## sscan (count cs) w k)" + obtains u a v + where "w = u @- a ## v" "fold (count cs) u k = l" "(cs ! l) a" + proof - + have 1: "count cs (shd w) k < length cs" using mod_Suc assms(1) unfolding count_def by auto + have 2: "infs (degen cs) (stl w ||| count cs (shd w) k ## sscan (count cs) (stl w) (count cs (shd w) k))" + using assms(2) by (metis alw.cases sscan.code stream.sel(2) szip.simps(2)) + obtain u v where 3: "stl w = u @- v" "fold (count cs) u (count cs (shd w) k) = l" + using degen_skip_arbitrary 1 assms(1) 2 by this + have 4: "v ||| l ## sscan (count cs) v l = + sdrop (length u) (stl w ||| count cs (shd w) k ## sscan (count cs) (stl w) (count cs (shd w) k))" + using 3 eq_scons eq_shift + by (metis sdrop.simps(2) sdrop_simps sdrop_szip sscan_scons_snth sscan_sdrop stream.sel(2)) + have 5: "infs (degen cs) (v ||| l ## sscan (count cs) v l)" using 2 unfolding 4 by blast + obtain vu a vv where 6: "v = vu @- a ## vv" "fold (count cs) vu l = l" "(cs ! l) a" + using degen_skip_condition assms(1) 5 by this + show ?thesis + proof + show "w = (shd w # u @ vu) @- a ## vv" using 3(1) 6(1) by (simp add: eq_scons) + show "fold (count cs) (shd w # u @ vu) k = l" using 3(2) 6(2) by simp + show "(cs ! l) a" using 6(3) by this + qed + qed + lemma gen_degen_step: + assumes "gen infs cs w" + obtains u a v + where "w = u @- a ## v" "degen cs (a, fold (count cs) u k)" + proof (cases "k < length cs") + case True + have 1: "infs (cs ! k) w" using assms True by auto + have 2: "{a. (cs ! k) a} \ sset w \ {}" using infs_any 1 by auto + obtain u a v where 3: "w = u @- a ## v" "{a. (cs ! k) a} \ set u = {}" "a \ {a. (cs ! k) a}" + using split_stream_first 2 by this + have 4: "fold (count cs) u k = k" using count_constant_1 True 3(2) by auto + show ?thesis using 3(1, 3) 4 that by simp + next + case False + show ?thesis + proof + show "w = [] @- shd w ## stl w" by simp + show "degen cs (shd w, fold (count cs) [] k)" using False by simp + qed + qed + + lemma degen_infs[iff]: "infs (degen cs) (w ||| k ## sscan (count cs) w k) \ gen infs cs w" + proof + show "gen infs cs w" if "infs (degen cs) (w ||| k ## sscan (count cs) w k)" + proof + fix c + assume 1: "c \ set cs" + obtain l where 2: "c = cs ! l" "l < length cs" using in_set_conv_nth 1 by metis + show "infs c w" + using that unfolding 2(1) + proof (coinduction arbitrary: w k rule: infs_set_coinduct) + case (infs_set w k) + obtain u a v where 3: "w = u @- a ## v" "(cs ! l) a" + using degen_skip_arbitrary_condition 2(2) infs_set by this + let ?k = "fold (count cs) u k" + let ?l = "fold (count cs) (u @ [a]) k" + have 4: "a ## v ||| ?k ## sscan (count cs) (a ## v) ?k = + sdrop (length u) (w ||| k ## sscan (count cs) w k)" + using 3(1) eq_shift scons_eq + by (metis sdrop_simps(1) sdrop_stl sdrop_szip sscan_scons_snth sscan_sdrop stream.sel(2)) + have 5: "infs (degen cs) (a ## v ||| ?k ## sscan (count cs) (a ## v) ?k)" + using infs_set unfolding 4 by blast + show ?case + proof (intro exI conjI bexI) + show "w = (u @ [a]) @- v" "(cs ! l) a" "a \ set (u @ [a])" "v = v" using 3 by auto + show "infs (degen cs) (v ||| ?l ## sscan (count cs) v ?l)" using 5 by simp + qed + qed + qed + show "infs (degen cs) (w ||| k ## sscan (count cs) w k)" if "gen infs cs w" + using that + proof (coinduction arbitrary: w k rule: infs_set_coinduct) + case (infs_set w k) + obtain u a v where 1: "w = u @- a ## v" "degen cs (a, fold (count cs) u k)" + using gen_degen_step infs_set by this + let ?u = "u @ [a] || k # scan (count cs) u k" + let ?l = "fold (count cs) (u @ [a]) k" + show ?case + proof (intro exI conjI bexI) + have "w ||| k ## sscan (count cs) w k = + (u @ [a]) @- v ||| k ## scan (count cs) u k @- ?l ## sscan (count cs) v ?l" + unfolding 1(1) by simp + also have "\ = ?u @- (v ||| ?l ## sscan (count cs) v ?l)" + by (metis length_Cons length_append_singleton scan_length shift.simps(2) szip_shift) + finally show "w ||| k ## sscan (count cs) w k = ?u @- (v ||| ?l ## sscan (count cs) v ?l)" by this + show "degen cs (a, fold (count cs) u k)" using 1(2) by this + have "(a, fold (count cs) u k) = (last (u @ [a]), last (k # scan (count cs) u k))" + unfolding scan_last by simp + also have "\ = last ?u" by (simp add: zip_eq_Nil_iff) + also have "\ \ set ?u" by (fastforce intro: last_in_set simp: zip_eq_Nil_iff) + finally show "(a, fold (count cs) u k) \ set ?u" by this + show "v ||| ?l ## sscan (count cs) v ?l = v ||| ?l ## sscan (count cs) v ?l" by rule + show "gen infs cs v" using infs_set unfolding 1(1) by auto + qed + qed + qed + +end \ No newline at end of file diff --git a/thys/Transition_Systems_and_Automata/Transition_Systems/Transition_System_Degeneralization.thy b/thys/Transition_Systems_and_Automata/Transition_Systems/Transition_System_Degeneralization.thy deleted file mode 100644 --- a/thys/Transition_Systems_and_Automata/Transition_Systems/Transition_System_Degeneralization.thy +++ /dev/null @@ -1,350 +0,0 @@ -theory Transition_System_Degeneralization -imports - "../Basic/Acceptance" - "Transition_System_Extra" -begin - - locale transition_system_initial_generalized = - transition_system_initial execute enabled initial - for execute :: "'transition \ 'state \ 'state" - and enabled :: "'transition \ 'state \ bool" - and initial :: "'state \ bool" - + - (* TODO: why is this a list and not a set? *) - fixes condition :: "'state pred gen" - begin - - (* TODO: make this a definition, prove useful (automation) things about, use opaquely *) - abbreviation "count p k \ - if k < length condition - then if (condition ! k) p then Suc k mod length condition else k - else 0" - - definition dexecute :: "'transition \ 'state degen \ 'state degen" where - "dexecute a \ \ (p, k). (execute a p, count p k)" - definition denabled :: "'transition \ 'state degen \ bool" where - "denabled a \ \ (p, k). enabled a p" - definition dinitial :: "'state degen \ bool" where - "dinitial \ \ (p, k). initial p \ k = 0" - - sublocale degen: transition_system_initial dexecute denabled dinitial by this - - lemma degen_run[iff]: "degen.run r (p, k) \ run r p" - proof - show "run r p" if "degen.run r (p, k)" - using that by (coinduction arbitrary: r p k) (auto simp: dexecute_def denabled_def) - show "degen.run r (p, k)" if "run r p" - using that by (coinduction arbitrary: r p k) (auto simp: dexecute_def denabled_def) - qed - - lemma degen_target_fst: "fst (degen.target w (p, k)) = target w p" - by (induct w arbitrary: p k) (auto simp: dexecute_def) - lemma degen_target_snd: - assumes "k < length condition" - assumes "\ q. q \ set (butlast (p # states w p)) \ \ (condition ! k) q" - shows "snd (degen.target w (p, k)) = k" - using assms by (induct w arbitrary: p) (auto simp: dexecute_def) - lemma degen_target_snd': - assumes "k < length condition" - assumes "\ q l. (q, l) \ set (butlast ((p, k) # degen.states w (p, k))) \ \ (condition ! l) q" - shows "snd (degen.target w (p, k)) = k" - using assms - proof (induct w arbitrary: p k) - case (Nil) - show ?case by simp - next - case (Cons a w) - have "snd (degen.target (a # w) (p, k)) = snd (degen.target w (dexecute a (p, k)))" by simp - also obtain q where 1: "dexecute a (p, k) = (q, k)" unfolding dexecute_def using Cons(2, 3) by auto - also have "snd (degen.target w \) = k" using Cons 1 by auto - finally show ?case by this - qed - lemma degen_nodes_fst[simp]: "fst ` degen.nodes = nodes" - proof (intro equalityI subsetI) - show "p \ fst ` degen.nodes" if "p \ nodes" for p - using that - proof induct - case (initial p) - have 1: "dinitial (p, 0)" using initial unfolding dinitial_def by simp - show ?case using 1 by (auto intro: rev_image_eqI) - next - case (execute p a) - obtain k where 1: "(p, k) \ degen.nodes" using execute(2) by auto - have 2: "denabled a (p, k)" unfolding denabled_def using execute(3) by simp - have 3: "execute a p = fst (dexecute a (p, k))" unfolding dexecute_def by simp - show ?case using 1 2 3 by auto - qed - show "p \ nodes" if "p \ fst ` degen.nodes" for p - using that - proof - fix pk - assume "pk \ degen.nodes" "p = fst pk" - then show "p \ nodes" - by (induct arbitrary: p) (auto simp: dexecute_def denabled_def dinitial_def) - qed - qed - lemma degen_nodes_snd_empty: - assumes "condition = []" - shows "snd ` degen.nodes \ {0}" - proof - - have 1: "dinitial (p, k) \ k = 0" for p k unfolding dinitial_def by simp - have 2: "snd (dexecute a (p, k)) = 0" for a p k using assms unfolding dexecute_def by simp - show ?thesis using 1 2 by (auto elim: degen.nodes.cases) - qed - lemma degen_nodes_snd_nonempty: - assumes "condition \ []" - shows "snd ` degen.nodes \ {0 ..< length condition}" - proof - - have 1: "dinitial (p, k) \ k < length condition" for p k using assms unfolding dinitial_def by simp - have 2: "snd (dexecute a (p, k)) < length condition" for a p k using assms unfolding dexecute_def by simp - show ?thesis using 1 2 by (auto elim: degen.nodes.cases) - qed - lemma degen_nodes_empty: - assumes "condition = []" - shows "degen.nodes = nodes \ {0}" - proof - - have "(p, k) \ degen.nodes \ p \ fst ` degen.nodes \ k = 0" for p k - using degen_nodes_snd_empty assms by (force simp del: degen_nodes_fst) - then show ?thesis by auto - qed - lemma degen_nodes_nonempty: - assumes "condition \ []" - shows "degen.nodes \ nodes \ {0 ..< length condition}" - using subset_fst_snd degen_nodes_fst degen_nodes_snd_nonempty[OF assms] by blast - lemma degen_nodes: "degen.nodes \ nodes \ {0 ..< max 1 (length condition)}" - using degen_nodes_empty degen_nodes_nonempty by force - - lemma degen_nodes_finite[iff]: "finite degen.nodes \ finite nodes" - proof - show "finite nodes" if "finite degen.nodes" using that by (auto simp flip: degen_nodes_fst) - show "finite degen.nodes" if "finite nodes" using degen_nodes that by (auto intro: finite_subset) - qed - lemma degen_nodes_card: "card degen.nodes \ max 1 (length condition) * card nodes" - proof (cases "finite nodes") - case True - have "card degen.nodes \ card (nodes \ {0 ..< max 1 (length condition)})" - using degen_nodes True by (blast intro: card_mono) - also have "\ = max 1 (length condition) * card nodes" unfolding card_cartesian_product by simp - finally show ?thesis by this - next - case False - then have "card nodes = 0" "card degen.nodes = 0" by auto - then show ?thesis by simp - qed - - definition dcondition :: "'state degen pred" where - "dcondition \ \ (p, k). k \ length condition \ (condition ! k) p" - - lemma degen_skip_condition: - assumes "k < length condition" - assumes "infs dcondition (degen.trace r (p, k))" - obtains s t q - where "r = s @- t" "degen.target s (p, k) = (q, k)" "dcondition (q, k)" - proof - - have 1: "Collect dcondition \ sset ((p, k) ## degen.trace r (p, k)) \ {}" - using infs_any assms(2) by auto - obtain u q l v where 2: - "(p, k) ## degen.trace r (p, k) = u @- (q, l) ## v" - "Collect dcondition \ set u = {}" - "(q, l) \ Collect dcondition" - using 1 by (force elim!: split_stream_first) - let ?w = "(p, k) # degen.states (stake (length u) r) (p, k)" - have "?w = stake (Suc (length u)) ((p, k) ## degen.trace r (p, k))" by simp - also have "\ = stake (Suc (length u)) (u @- (q, l) ## v)" unfolding 2(1) by rule - also have "\ = u @ [(q, l)]" unfolding stake_Suc using eq_shift by auto - finally have 3: "(p, k) # degen.states (stake (length u) r) (p, k) = u @ [(q, l)]" by this - have 4: "degen.target (stake (length u) r) (p, k) = (q, l)" unfolding degen.target_alt_def 3 by simp - have 5: "Collect dcondition \ set (butlast ?w) = {}" using 2(2) 3 by simp - have "l = snd (q, l)" by simp - also have "\ = snd (degen.target (stake (length u) r) (p, k))" using 4 by simp - also have "\ = k" using degen_target_snd' assms(1) 5 unfolding dcondition_def by blast - finally have 6: "k = l" by rule - show ?thesis - proof - show "r = stake (length u) r @- sdrop (length u) r" by simp - show "degen.target (stake (length u) r) (p, k) = (q, k)" using 4 6 by simp - show "dcondition (q, k)" using 2(3) 6 by auto - qed - qed - lemma degen_skip_increment: - assumes "k < length condition" - assumes "infs dcondition (degen.trace w (p, k))" - obtains u v q - where "w = u @- v" "u \ []" "degen.target u (p, k) = (q, Suc k mod length condition)" - proof - - obtain u v q where 1: "w = u @- v" "degen.target u (p, k) = (q, k)" "dcondition (q, k)" - using degen_skip_condition assms by this - show ?thesis - proof - show "w = (u @ [shd v]) @- stl v" using 1(1) by simp - show "u @ [shd v] \ []" by simp - show "degen.target (u @ [shd v]) (p, k) = (execute (shd v) q, Suc k mod length condition)" - using assms(1) 1(2, 3) by (simp add: dexecute_def dcondition_def) - qed - qed - lemma degen_skip_arbitrary: - assumes "k < length condition" "l < length condition" - assumes "infs dcondition (degen.trace w (p, k))" - obtains u v q - where "w = u @- v" "degen.target u (p, k) = (q, l)" - using assms - proof (induct "nat ((int l - int k) mod length condition)" arbitrary: thesis l) - case (0) - have 1: "length condition > 0" using assms(1) by auto - have 2: "(int l - int k) mod length condition = 0" using 0(1) 1 by (auto intro: antisym) - have 3: "int l mod length condition = int k mod length condition" using mod_eq_dvd_iff 2 by force - have 4: "k = l" using 0(3, 4) 3 by simp - show ?case - proof (rule 0(2)) - show "w = [] @- w" by simp - show "degen.target [] (p, k) = (p, l)" using 4 by simp - qed - next - case (Suc n) - have 1: "length condition > 0" using assms(1) by auto - define l' where "l' = nat ((int l - 1) mod length condition)" - obtain u v q where 2: "w = u @- v" "degen.target u (p, k) = (q, l')" - proof (rule Suc(1)) - have 2: "Suc n < length condition" using nat_less_iff Suc(2) 1 by simp - have "n = nat (int n)" by simp - also have "int n = (int (Suc n) - 1) mod length condition" using 2 by simp - also have "\ = (int l - int k - 1) mod length condition" using Suc(2) by (simp add: mod_simps) - also have "\ = (int l - 1 - int k) mod length condition" by (simp add: algebra_simps) - also have "\ = (int l' - int k) mod length condition" using l'_def 1 by (simp add: mod_simps) - finally show "n = nat ((int l' - int k) mod length condition)" by this - show "k < length condition" using Suc(4) by this - show "l' < length condition" using nat_less_iff l'_def 1 by simp - show "infs dcondition (degen.trace w (p, k))" using Suc(6) by this - qed - obtain vu vv t where 3: "v = vu @- vv" "degen.target vu (q, l') = (t, Suc l' mod length condition)" - proof (rule degen_skip_increment) - show "l' < length condition" using nat_less_iff l'_def 1 by simp - show "infs dcondition (degen.trace v (q, l'))" using Suc(6) 2 by simp - qed - show ?case - proof (rule Suc(3)) - have "l = nat (int l)" by simp - also have "int l = int l mod length condition" using Suc(5) by simp - also have "\ = int (Suc l') mod length condition" using l'_def 1 by (simp add: mod_simps) - finally have 4: "l = Suc l' mod length condition" using nat_mod_as_int by metis - show "w = (u @ vu) @- vv" unfolding 2(1) 3(1) by simp - show "degen.target (u @ vu) (p, k) = (t, l)" using 2(2) 3(2) 4 by simp - qed - qed - lemma degen_skip_arbitrary_condition: - assumes "l < length condition" - assumes "infs dcondition (degen.trace w (p, k))" - obtains u v q - where "w = u @- v" "degen.target u (p, k) = (q, l)" "dcondition (q, l)" - proof - - obtain x y where 10: "dexecute (shd w) (p, k) = (x, y)" by force - have 11: "y < length condition" using mod_Suc assms(1) 10 unfolding dexecute_def by auto - have 12: "infs dcondition (degen.trace (stl w) (x, y))" - using 10 by (metis alw_ev_stl assms(2) sscan.simps(2)) - obtain u v q where 1: "stl w = u @- v" "degen.target u (x, y) = (q, l)" - using degen_skip_arbitrary 11 assms(1) 12 by this - have 2: "infs dcondition (degen.trace v (q, l))" using 12 1(2) unfolding 1(1) by simp - obtain vu vv t where 3: "v = vu @- vv" "degen.target vu (q, l) = (t, l)" "dcondition (t, l)" - using degen_skip_condition assms(1) 2 by this - show ?thesis - proof - show "w = (shd w # u @ vu) @- vv" using 1(1) 3(1) - by (simp add: "1"(1) "3"(1) stream.expand) - show "degen.target (shd w # u @ vu) (p, k) = (t, l)" using 1(2) 3(2) 10 by simp - show "dcondition (t, l)" using 3(3) by this - qed - qed - - lemma degen_infs_1: - assumes "infs dcondition (degen.trace w (p, k))" - assumes "P \ set condition" - shows "infs P (trace w p)" - using assms - proof (coinduction arbitrary: w p k rule: infs_trace_coinduct) - case (infs_trace w p k) - obtain l where 1: "P = condition ! l" "l < length condition" - using infs_trace(2) in_set_conv_nth by metis - obtain u v q where 2: "w = u @- v" "degen.target u (p, k) = (q, l)" "dcondition (q, l)" - using degen_skip_arbitrary_condition 1(2) infs_trace(1) by this - have 3: "q = target u p" using 2(2) degen_target_fst by (metis fst_conv) - obtain p' k' where 4: "dexecute (shd w) (p, k) = (p', k')" by force - have 5: "infs dcondition (degen.trace (shd w ## stl w) (p, k))" using infs_trace(1) by simp - show ?case - proof (intro exI conjI) - show "w = u @- v" using 2(1) by this - show "P (target u p)" using 1(2) 2(3) unfolding dcondition_def 1(1) 3 by simp - show "w = [shd w] @- stl w" "[shd w] \ []" "stl w = stl w" by auto - show "target [shd w] p = p'" using 4 by (simp add: dexecute_def) - show "infs dcondition (degen.trace (stl w) (p', k'))" using 4 5 unfolding sscan_scons by simp - show "P \ set condition" using infs_trace(2) by this - qed - qed - lemma degen_infs_2: - assumes "\ P. P \ set condition \ infs P (trace w p)" - shows "infs dcondition (degen.trace w (p, k))" - using assms - proof (coinduction arbitrary: w p k rule: degen.infs_trace_coinduct) - case (infs_trace w p k) - show ?case - proof (cases "k < length condition") - case True - have 1: "infs (condition ! k) (trace w p)" using infs_trace True by simp - have 2: "{q. (condition ! k) q} \ sset (p ## trace w p) \ {}" using infs_any 1 by auto - obtain ys x zs where 3: - "p ## trace w p = ys @- x ## zs" - "{q. (condition ! k) q} \ set ys = {}" - "x \ {q. (condition ! k) q}" - using split_stream_first 2 by this - define u where "u = stake (length ys) w" - define v where "v = sdrop (length ys) w" - obtain q l where 4: "degen.target u (p, k) = (q, l)" by force - have "p # states u p = stake (length (ys @ [x])) (p ## trace w p)" unfolding u_def by simp - also have "p ## trace w p = (ys @ [x]) @- zs" using 3(1) by simp - also have "stake (length (ys @ [x])) \ = ys @ [x]" unfolding stake_shift by simp - finally have 5: "p # states u p = ys @ [x]" by this - have 6: "butlast (p # states u p) = ys" using 5 by auto - have "l = snd (degen.target u (p, k))" unfolding 4 by simp - also have "\ = k" using degen_target_snd 3(2) 6 True by fast - finally have 7: "k = l" by rule - have "q = fst (degen.target u (p, k))" unfolding 4 by simp - also have "\ = target u p" using degen_target_fst by this - also have "\ = last (p # states u p)" unfolding scan_last by rule - also have "\ = x" unfolding 5 by simp - finally have 8: "q = x" by this - have 9: "(condition ! l) q" using 3(3) unfolding 7 8 by simp - obtain x y where 10: "dexecute (shd w) (p, k) = (x, y)" by force - have 11: "\ P \ set condition. infs P (trace (shd w ## stl w) p)" using infs_trace by simp - have 12: "execute (shd w) p = x" using infs_trace(1) 10 unfolding dexecute_def by auto - show ?thesis - proof (intro exI conjI) - show "w = u @- v" unfolding u_def v_def by simp - show "dcondition (degen.target u (p, k))" using 4 9 by (auto simp: dcondition_def) - show "w = [shd w] @- stl w" "[shd w] \ []" "stl w = stl w" by auto - show "degen.target [shd w] (p, k) = (x, y)" using 10 by simp - show "\ P. P \ set condition \ infs P (trace (stl w) x)" - using 11 12 unfolding sscan_scons by simp - qed - next - case False - obtain x y where 10: "dexecute (shd w) (p, k) = (x, y)" by force - have 11: "\ P \ set condition. infs P (trace (shd w ## stl w) p)" using infs_trace by simp - have 12: "execute (shd w) p = x" using infs_trace(1) 10 unfolding dexecute_def by auto - show ?thesis - proof (intro exI conjI) - show "w = [] @- w" by simp - show "dcondition (degen.target [] (p, k))" unfolding dcondition_def using False by simp - show "w = [shd w] @- stl w" "[shd w] \ []" "stl w = stl w" by auto - show "degen.target [shd w] (p, k) = (x, y)" using 10 by simp - show "\ P. P \ set condition \ infs P (trace (stl w) x)" - using 11 12 unfolding sscan_scons by simp - qed - qed - qed - - lemma degen_infs: "infs dcondition (degen.trace w (p, k)) \ - (\ P \ set condition. infs P (trace w p))" - using degen_infs_1 degen_infs_2 by auto - - end - -end \ No newline at end of file