theory Rewriting imports
LTL "HOL-Library.Extended_Nat" begin
text‹This theory provides rewrite rules for the simplification of LTL formulas. It supports: \begin{itemize} \item Constants Removal \item @{const Next_ltln}-Normalisation \item Modal Simplification (based on pure eventual, pure universal, or suspendable formulas) \item Syntactic Implication Checking \end{itemize}
It reuses parts of LTL\_Rewrite.thy (CAVA, LTL\_TO\_GBA). Furthermore, some rules were taken from cite‹"DBLP:conf/cav/SomenziB00"› and cite‹"DBLP:conf/tacas/BabiakKRS12"›. All functions are defined for @{type ltln}.›
subsection‹Constant Eliminating Constructors›
definition mk_and where "mk_and x y ≡ case x of falsen==> falsen | truen==> y | _ ==> (case y of falsen==> falsen | truen==> x | _ ==> x andn y)"
definition mk_or where "mk_or x y ≡ case x of falsen==> y | truen==> truen | _ ==> (case y of truen==> truen | falsen==> x | _ ==> x orn y)"
fun remove_strong_ops where "remove_strong_ops (x Un y) = remove_strong_ops y"
| "remove_strong_ops (x Mn y) = x andn y"
| "remove_strong_ops (x orn y) = remove_strong_ops x orn remove_strong_ops y"
| "remove_strong_ops x = x"
fun remove_weak_ops where "remove_weak_ops (x Rn y) = remove_weak_ops y"
| "remove_weak_ops (x Wn y) = x orn y"
| "remove_weak_ops (x andn y) = remove_weak_ops x andn remove_weak_ops y"
| "remove_weak_ops x = x"
definition mk_finally where "mk_finally x ≡ case x of truen==> truen | falsen==> falsen | _ ==> Fn (remove_strong_ops x)"
definition mk_globally where "mk_globally x ≡ case x of truen==> truen | falsen==> falsen | _ ==> Gn (remove_weak_ops x)"
definition mk_until where "mk_until x y ≡ case x of falsen==> y | truen==> mk_finally y | _ ==> (case y of truen==> truen | falsen==> falsen | _ ==> x Un y)"
definition mk_release where "mk_release x y ≡ case x of truen==> y | falsen==> mk_globally y | _ ==> (case y of truen==> truen | falsen==> falsen | _ ==> x Rn y)"
definition mk_weak_until where "mk_weak_until x y ≡ case y of truen==> truen | falsen==> mk_globally x | _ ==> (case x of truen==> truen | falsen==> y | _ ==> x Wn y)"
definition mk_strong_release where "mk_strong_release x y ≡ case y of falsen==> falsen | truen==> mk_finally x | _ ==> (case x of truen==> y | falsen==> falsen | _ ==> x Mn y)"
definition mk_next where "mk_next x ≡ case x of truen==> truen | falsen==> falsen | _ ==> Xn x"
definition mk_next_pow (‹Xn''›) where "mk_next_pow n x ≡ case x of truen==> truen | falsen==> falsen | _ ==> (Next_ltln ^^ n) x"
lemma mk_and_semantics [simp]: "w ⊨n mk_and x y ⟷ w ⊨n x andn y" unfolding mk_and_def by (cases x; cases y; simp)
lemma mk_or_semantics [simp]: "w ⊨n mk_or x y ⟷ w ⊨n x orn y" unfolding mk_or_def by (cases x; cases y; simp)
lemma remove_strong_ops_sound [simp]: "w ⊨n Fn (remove_strong_ops y) ⟷ w ⊨n Fn y" by (induction y arbitrary: w) (auto; force)+
lemma remove_weak_ops_sound [simp]: "w ⊨n Gn (remove_weak_ops y) ⟷ w ⊨n Gn y" by (induction y arbitrary: w) (auto; force)+
lemma mk_finally_semantics [simp]: "w ⊨n mk_finally x ⟷ w ⊨n Fn x" by (simp add: mk_finally_def del: semantics_ltln.simps(8,9) remove_strong_ops.simps split: ltln.splits)
lemma mk_globally_semantics [simp]: "w ⊨n mk_globally x ⟷ w ⊨n Gn x" by (simp add: mk_globally_def del: semantics_ltln.simps(8,9) remove_weak_ops.simps split: ltln.splits)
lemma mk_until_semantics [simp]: "w ⊨n mk_until x y ⟷ w ⊨n x Un y" proof (cases x) case (True_ltln) show ?thesis unfolding True_ltln mk_until_def by (cases y) auto next case (False_ltln) thus ?thesis by (force simp: mk_until_def) qed (cases y; force simp: mk_until_def)+
lemma mk_release_semantics [simp]: "w ⊨n mk_release x y ⟷ w ⊨n x Rn y" proof (cases x) case (False_ltln) thus ?thesis unfolding False_ltln mk_release_def by (cases y) auto next case (True_ltln) thus ?thesis by (force simp: mk_release_def) qed (cases y; force simp: mk_release_def)+
lemma mk_weak_until_semantics [simp]: "w ⊨n mk_weak_until x y ⟷ w ⊨n x Wn y" proof (cases y) case (False_ltln) thus ?thesis unfolding False_ltln mk_weak_until_def by (cases x) auto next case (True_ltln) thus ?thesis by (force simp: mk_weak_until_def) qed (cases x; force simp: mk_weak_until_def)+
lemma mk_strong_release_semantics [simp]: "w ⊨n mk_strong_release x y ⟷ w ⊨n x Mn y" proof (cases y) case (True_ltln) show ?thesis unfolding True_ltln mk_strong_release_def by (cases x) auto next case (False_ltln) thus ?thesis by (force simp: mk_strong_release_def) qed (cases x; force simp: mk_strong_release_def)+
lemma mk_next_semantics [simp]: "w ⊨n mk_next x ⟷ w ⊨n Xn x" unfolding mk_next_def by (cases x; auto)
lemma mk_next_pow_semantics [simp]: "w ⊨n mk_next_pow i x ⟷ suffix i w ⊨n x" by (induction i arbitrary: w; cases x)
(auto simp: mk_next_pow_def)
lemma mk_next_pow_simp [simp, code_unfold]: "mk_next_pow 0 x = x" "mk_next_pow 1 x = mk_next x" by (cases x; simp add: mk_next_pow_def mk_next_def)+
lemma is_constant_constructorsI: "is_constant x ==> is_constant y ==> is_constant (mk_and x y)" "¬is_constant x ==>¬is_constant y ==>¬is_constant (mk_and x y)" "is_constant x ==> is_constant y ==> is_constant (mk_or x y)" "¬is_constant x ==>¬is_constant y ==>¬is_constant (mk_or x y)" "is_constant x ==> is_constant (mk_finally x)" "¬is_constant x ==>¬is_constant (mk_finally x)" "is_constant x ==> is_constant (mk_globally x)" "¬is_constant x ==>¬is_constant (mk_globally x)" "is_constant x ==> is_constant (mk_until y x)" "¬is_constant x ==>¬is_constant (mk_until y x)" "is_constant x ==> is_constant (mk_release y x)" "¬is_constant x ==>¬is_constant (mk_release y x)" "is_constant x ==> is_constant y ==> is_constant (mk_weak_until x y)" "¬is_constant x ==>¬is_constant y ==>¬is_constant (mk_weak_until x y)" "is_constant x ==> is_constant y ==> is_constant (mk_strong_release x y)" "¬is_constant x ==>¬is_constant y ==>¬is_constant (mk_strong_release x y)" "is_constant x ==> is_constant (mk_next x)" "¬is_constant x ==>¬is_constant (mk_next x)" "is_constant x ==> is_constant (mk_next_pow n x)" by (cases x; cases y; simp add: mk_and_def mk_or_def mk_finally_def mk_globally_def mk_until_def mk_release_def mk_weak_until_def mk_strong_release_def mk_next_def mk_next_pow_def)+
lemma is_constant_constructors_simps: "mk_next_pow n x = falsen⟷ x = falsen" "mk_next_pow n x = truen⟷ x = truen" "is_constant (mk_next_pow n x) ⟷ is_constant x" by (induction n) (cases x; simp add: mk_next_pow_def)+
lemma is_constant_constructors_simps2: "is_constant (mk_and x y) ⟷ (x = truen∧ y = truen∨ x = falsen∨ y = falsen)" "is_constant (mk_or x y) ⟷ (x = falsen∧ y = falsen∨ x = truen∨ y = truen)" "is_constant (mk_finally x) ⟷ is_constant x" "is_constant (mk_globally x) ⟷ is_constant x" "is_constant (mk_until y x) ⟷ is_constant x" "is_constant (mk_release y x) ⟷ is_constant x" "is_constant (mk_next x) ⟷ is_constant x" by ((cases x; cases y; simp add: mk_and_def),
(cases x; cases y; simp add: mk_or_def),
(meson is_constant_constructorsI)+)
lemma is_constant_constructors_simps3: "is_constant (mk_weak_until x y) ⟷ (x = falsen∧ y = falsen∨ x = truen∨ y = truen)" "is_constant (mk_strong_release x y) ⟷ (x = truen∧ y = truen∨ x = falsen∨ y = falsen)" by (cases x; cases y; simp add: mk_weak_until_def mk_strong_release_def is_constant_constructors_simps2)+
lemma is_constant_semantics: "is_constant φ ==> ((∀w. w ⊨n φ) ∨¬(∃w. w ⊨n φ))" by (cases φ) auto
lemma until_constant_simp: "is_constant ψ ==> w ⊨n φ Un ψ ⟷ w ⊨n ψ" by (cases ψ) auto
lemma release_constant_simp: "is_constant ψ ==> w ⊨n φ Rn ψ ⟷ w ⊨n ψ" by (cases ψ) auto
lemma mk_next_pow_dist: "mk_next_pow (i + j) φ = mk_next_pow i (mk_next_pow j φ)" by (cases j; simp) (cases φ; simp add: mk_next_pow_def funpow_add; simp add: funpow_swap1)
lemma mk_next_pow_until: "suffix (min i j) w ⊨n (mk_next_pow (i - j) φ) Un (mk_next_pow (j - i) ψ) ⟷ w ⊨n (mk_next_pow i φ) Un (mk_next_pow j ψ)" by (simp add: mk_next_pow_dist min_def add.commute)
lemma mk_next_pow_release: "suffix (min i j) w ⊨n (mk_next_pow (i - j) φ) Rn (mk_next_pow (j - i) ψ) ⟷ w ⊨n (mk_next_pow i φ) Rn (mk_next_pow j ψ)" by (simp add: mk_next_pow_dist min_def add.commute)
subsection‹X-Normalisation›
text‹The following rewrite functions pulls the X-operator up in the syntax tree. This preprocessing
step enables the removal of X-operators in front of suspendable formulas. Furthermore constants are
removed as far as possible.›
fun the_enat_0 :: "enat ==> nat" where "the_enat_0 i = i"
| "the_enat_0 ∞ = 0"
(* TODO this proof is a bit slow and could be optimized *) lemma combine_weak_until_strong_release_semantics: assumes"i = ∞⟷ is_constant φ" assumes"j = ∞⟷ is_constant ψ" shows"w ⊨n to_ltln (combine mk_weak_until (φ, i) (ψ, j)) ⟷ w ⊨n to_ltln (φ, i) Wn to_ltln (ψ, j)" and"w ⊨n to_ltln (combine mk_strong_release (φ, i) (ψ, j)) ⟷ w ⊨n to_ltln (φ, i) Mn to_ltln (ψ, j)" by ((cases i; cases j; simp add: min_def is_constant_constructors_simps is_constant_constructors_simps3 del: semantics_ltln.simps),
(cases φ; simp add: assms),
(cases ψ; insert assms; auto simp: add.commute))+
lemma rewrite_X_enat_infinity_invariant: "snd (rewrite_X_enat φ) = ∞⟷ is_constant (fst (rewrite_X_enat φ))" proof (induction φ) case (And_ltln φ ψ) thus ?case by (simp add: combine_infinity_invariant[OF And_ltln(1,2), unfolded prod.collapse]) next case (Or_ltln φ ψ) thus ?case by (simp add: combine_infinity_invariant[OF Or_ltln(1,2), unfolded prod.collapse]) next case (Until_ltln φ ψ) thus ?case by (simp add: combine_infinity_invariant[OF Until_ltln(1,2), unfolded prod.collapse]) next case (Release_ltln φ ψ) thus ?case by (simp add: combine_infinity_invariant[OF Release_ltln(1,2), unfolded prod.collapse]) next case (WeakUntil_ltln φ ψ) thus ?case by (simp add: combine_infinity_invariant[OF WeakUntil_ltln(1,2), unfolded prod.collapse]) next case (StrongRelease_ltln φ ψ) thus ?case by (simp add: combine_infinity_invariant[OF StrongRelease_ltln(1,2), unfolded prod.collapse]) next case (Next_ltln φ) thus ?case by (simp add: split_def) (metis eSuc_infinity eSuc_inject) qed auto
lemma rewrite_X_enat_correct: "w ⊨n φ ⟷ w ⊨n to_ltln (rewrite_X_enat φ)" proof (induction φ arbitrary: w) case (And_ltln φ ψ) thus ?case using combine_and_or_semantics[OF rewrite_X_enat_infinity_invariant rewrite_X_enat_infinity_invariant] by fastforce next case (Or_ltln φ ψ) thus ?case using combine_and_or_semantics[OF rewrite_X_enat_infinity_invariant rewrite_X_enat_infinity_invariant] by fastforce next case (Until_ltln φ ψ) thus ?case unfolding rewrite_X_enat.simps combine_until_release_semantics[OF rewrite_X_enat_infinity_invariant rewrite_X_enat_infinity_invariant, unfolded prod.collapse] by fastforce next case (Release_ltln φ ψ) thus ?case unfolding rewrite_X_enat.simps combine_until_release_semantics[OF rewrite_X_enat_infinity_invariant rewrite_X_enat_infinity_invariant, unfolded prod.collapse] by fastforce next case (WeakUntil_ltln φ ψ) thus ?case unfolding rewrite_X_enat.simps combine_weak_until_strong_release_semantics[OF rewrite_X_enat_infinity_invariant rewrite_X_enat_infinity_invariant, unfolded prod.collapse] by fastforce next case (StrongRelease_ltln φ ψ) thus ?case unfolding rewrite_X_enat.simps combine_weak_until_strong_release_semantics[OF rewrite_X_enat_infinity_invariant rewrite_X_enat_infinity_invariant, unfolded prod.collapse] by fastforce next case (Next_ltln φ) moreover have" w ⊨n to_ltln (rewrite_X_enat (Xn φ)) ⟷ suffix 1 w ⊨n to_ltln (rewrite_X_enat φ)" by (simp add: split_def; cases "snd (rewrite_X_enat φ) ≠∞")
(auto simp: eSuc_def, auto simp: rewrite_X_enat_infinity_invariant eSuc_def dest: is_constant_semantics) ultimately show ?case using semantics_ltln.simps(7) by blast qed auto
lemma rewrite_X_sound [simp]: "w ⊨n rewrite_X φ ⟷ w ⊨n φ" using rewrite_X_enat_correct unfolding rewrite_X_def Let_def by auto
subsection‹Pure Eventual, Pure Universal, and Suspendable Formulas›
lemma pure_eventual_left_append: "pure_eventual μ ==> w ⊨n μ ==> (u ⌢ w) ⊨n μ" proof (induction μ arbitrary: u w) case (Until_ltln μ μ') moreover thenobtain i where"suffix i w ⊨n μ'" by auto hence"μ = truen==> ?case" by simp (metis suffix_conc_length suffix_suffix) moreover have"pure_eventual μ' ==> (u ⌢ w) ⊨n μ'" by (metis ‹suffix i w ⊨n μ'› Until_ltln(2) prefix_suffix) hence"pure_eventual μ' ==> ?case" by force ultimately show ?case by fastforce next case (Release_ltln μ μ') thus ?case by (cases "∀i. suffix i w ⊨n μ'"; simp_all)
(metis linear suffix_conc_snd gr0I not_less0 prefix_suffix suffix_0)+ next case (WeakUntil_ltln μ μ') thus ?case by (cases "∀i. suffix i w ⊨n μ'"; simp_all)
(metis zero_le le0 nat_le_linear prefix_suffix suffix_0 suffix_conc_length suffix_conc_snd suffix_subseq_join)+ next case (StrongRelease_ltln μ μ') moreover thenobtain i where"suffix i w ⊨n μ andn μ'" by auto hence"μ' = truen==> ?case" by simp (metis suffix_conc_length suffix_suffix) moreover have"pure_eventual μ ==> pure_eventual μ' ==> (u ⌢ w) ⊨n μ andn μ'" by (metis ‹suffix i w ⊨n μ andn μ'› calculation(1) calculation(2) prefix_suffix semantics_ltln.simps(5)) hence"pure_eventual μ ==> pure_eventual μ' ==> ?case" by force ultimately show ?case by fastforce qed (auto, metis diff_zero le_0_eq not_less_eq_eq suffix_conc_length suffix_conc_snd word_split)
lemma pure_universal_suffix_closed: "pure_universal ν ==> (u ⌢ w) ⊨n ν ==> w ⊨n ν" proof (induction ν arbitrary: u w) case (Until_ltln ν ν') hence"∃i. suffix i (u ⌢ w) ⊨n ν' ∧ (∀j<i. suffix j (u ⌢ w) ⊨n ν)" using semantics_ltln.simps(8) by blast thus ?case by simp (metis Until_ltln(1-3) le_0_eq le_eq_less_or_eq le_less_linear prefix_suffix pure_universal.simps(5) suffix_conc_fst suffix_conc_snd) next case (Release_ltln ν ν') moreover hence"∀i. suffix i (u ⌢ w) ⊨n ν' ∨ (∃j<i. suffix j (u ⌢ w) ⊨n ν)" by simp ultimately show ?case by simp (metis semantics_ltln.simps(2) not_less0 prefix_suffix suffix_0 suffix_conc_length suffix_suffix) next case (WeakUntil_ltln ν ν') moreover hence"∀i. suffix i (u ⌢ w) ⊨n ν ∨ (∃j≤i. suffix j (u ⌢ w) ⊨n ν')" by simp ultimately show ?case by simp (metis (full_types) le_antisym prefix_suffix semantics_ltln.simps(2) suffix_0 suffix_conc_length suffix_suffix zero_le) next case (StrongRelease_ltln ν ν') hence"∃i. suffix i (u ⌢ w) ⊨n ν ∧ (∀j≤i. suffix j (u ⌢ w) ⊨n ν')" using semantics_ltln.simps(11) by blast thus ?case by simp (metis StrongRelease_ltln(1-3) diff_is_0_eq nat_le_linear prefix_conc_length prefix_suffix pure_universal.simps(8) subsequence_length suffix_conc_snd suffix_subseq_join) next case (Next_ltln μ) thus ?case by (metis prefix_suffix pure_universal.simps(9) semantics_ltln.simps(7) semiring_normalization_rules(24) suffix_conc_length suffix_suffix) qed auto
lemma suspendable_prefix_invariant: "suspendable ξ ==> (u ⌢ w) ⊨n ξ ⟷ w ⊨n ξ" proof (induction ξ arbitrary: u w) case (Until_ltln ξ ξ') show ?case proof (cases "suspendable ξ'") case False hence"ξ = truen"and"pure_universal ξ'" using Until_ltln by simp+ thus ?thesis by (simp; metis (no_types) linear pure_universal_suffix_closed suffix_conc_fst suffix_conc_length suffix_conc_snd suffix_suffix) qed (simp; metis Until_ltln(2) not_less0 prefix_suffix) next case (Release_ltln ξ ξ') show ?case proof (cases "suspendable ξ'") case False hence"ξ = falsen"and"pure_eventual ξ'" using Release_ltln by simp+ thus ?thesis by (simp; metis (no_types) le_iff_add add_diff_cancel_left' linear pure_eventual_left_append suffix_0 suffix_conc_fst suffix_conc_snd) qed (simp; metis Release_ltln(2) not_less0 prefix_suffix) next case (WeakUntil_ltln ξ ξ') show ?case proof (cases "suspendable ξ ∧ suspendable ξ'") case False hence"ξ' = falsen"and"pure_eventual ξ" using WeakUntil_ltln by simp+ thus ?thesis by (simp; metis (no_types) le_iff_add add_diff_cancel_left' linear pure_eventual_left_append suffix_0 suffix_conc_fst suffix_conc_snd) qed (simp; metis (full_types) WeakUntil_ltln.IH prefix_suffix) next case (StrongRelease_ltln ξ ξ') show ?case proof (cases "suspendable ξ ∧ suspendable ξ'") case False hence"ξ' = truen"and"pure_universal ξ" using StrongRelease_ltln by simp+ thus ?thesis by (simp; metis (no_types) linear pure_universal_suffix_closed suffix_conc_fst suffix_conc_length suffix_conc_snd suffix_suffix) qed (simp; metis (full_types) StrongRelease_ltln.IH(1) StrongRelease_ltln.IH(2) prefix_suffix) qed (simp_all, metis prefix_suffix)
theorem pure_eventual_until_simp: assumes"pure_eventual μ" shows"w ⊨n φ Un μ ⟷ w ⊨n μ" proof - have"∧i. suffix i w ⊨n μ ==> w ⊨n μ" using pure_eventual_left_append[OF assms] prefix_suffix by metis thus ?thesis by force qed
theorem pure_universal_release_simp: assumes"pure_universal ν" shows"w ⊨n φ Rn ν ⟷ w ⊨n ν" proof - have"∧i. w ⊨n ν ==> suffix i w ⊨n ν" using pure_universal_suffix_closed[OF assms] prefix_suffix by metis thus ?thesis by force qed
theorem pure_universal_weak_until_simp: assumes"pure_universal φ"and"pure_universal ψ" shows"w ⊨n φ Wn ψ ⟷ w ⊨n φ orn ψ" proof - have"∧i. w ⊨n φ ==> suffix i w ⊨n φ"and"∧i. w ⊨n ψ ==> suffix i w ⊨n ψ" using assms pure_universal_suffix_closed prefix_suffix by metis+ thus ?thesis by force qed
theorem pure_eventual_strong_release_simp: assumes"pure_eventual φ"and"pure_eventual ψ" shows"w ⊨n φ Mn ψ ⟷ w ⊨n φ andn ψ" proof - have"∧i. suffix i w ⊨n φ ==> w ⊨n φ"and"∧i. suffix i w ⊨n ψ ==> w ⊨n ψ" using assms pure_eventual_left_append prefix_suffix by metis+ thus ?thesis by force qed
theorem suspendable_formula_simp: assumes"suspendable ξ" shows"w ⊨n Xn ξ ⟷ w ⊨n ξ" (is ?t1) and"w ⊨n φ Un ξ ⟷ w ⊨n ξ" (is ?t2) and"w ⊨n φ Rn ξ ⟷ w ⊨n ξ" (is ?t3) proof - have"∧i. suffix i w ⊨n ξ ⟷ w ⊨n ξ" using suspendable_prefix_invariant[OF assms] prefix_suffix by metis thus ?t1 ?t2 ?t3 by force+ qed
theorem suspendable_formula_simp2: assumes"suspendable φ"and"suspendable ψ" shows"w ⊨n φ Wn ψ ⟷ w ⊨n φ orn ψ" (is ?t1) and"w ⊨n φ Mn ψ ⟷ w ⊨n φ andn ψ" (is ?t2) proof - have"∧i. suffix i w ⊨n φ ⟷ w ⊨n φ"and"∧i. suffix i w ⊨n ψ ⟷ w ⊨n ψ" using assms suspendable_prefix_invariant prefix_suffix by metis+ thus ?t1 ?t2 by force+ qed
lemma syntactical_implies_correct: "φ ⊨s ψ ==> w ⊨n φ ==> w ⊨n ψ" by (induction arbitrary: w rule: syntactical_implies.induct; auto; force)
fun rewrite_syn_imp where "rewrite_syn_imp (φ andn ψ) = ( if φ ⊨s ψ then rewrite_syn_imp φ else if ψ ⊨s φ then rewrite_syn_imp ψ else if φ ⊨s (notn ψ) ∨ ψ ⊨s (notn φ) then falsen else mk_and (rewrite_syn_imp φ) (rewrite_syn_imp ψ))"
| "rewrite_syn_imp (φ orn ψ) = ( if φ ⊨s ψ then rewrite_syn_imp ψ else if ψ ⊨s φ then rewrite_syn_imp φ else if (notn φ) ⊨s ψ ∨ (notn ψ) ⊨s φ then truen else mk_or (rewrite_syn_imp φ) (rewrite_syn_imp ψ))"
| "rewrite_syn_imp (φ Un ψ) = ( if φ ⊨s ψ then rewrite_syn_imp ψ else if (notn φ) ⊨s ψ then mk_finally (rewrite_syn_imp ψ) else mk_until (rewrite_syn_imp φ) (rewrite_syn_imp ψ))"
| "rewrite_syn_imp (φ Rn ψ) = ( if ψ ⊨s φ then rewrite_syn_imp ψ else if ψ ⊨s (notn φ) then mk_globally (rewrite_syn_imp ψ) else mk_release (rewrite_syn_imp φ) (rewrite_syn_imp ψ))"
| "rewrite_syn_imp (Xn φ) = mk_next (rewrite_syn_imp φ)"
| "rewrite_syn_imp φ = φ"
lemma rewrite_syn_imp_sound: "w ⊨n rewrite_syn_imp φ ⟷ w ⊨n φ" proof (induction φ arbitrary: w) case And_ltln thus ?case by (simp add: Let_def; metis syntactical_implies_correct notn_semantics) next case (Or_ltln φ ψ) moreover have"(notn φ) ⊨s ψ ==>∀w. w ⊨n φ orn ψ" by (auto intro: syntactical_implies_correct[of "notn φ"]) moreover have"(notn ψ) ⊨s φ ==>∀w. w ⊨n φ orn ψ" by (auto intro: syntactical_implies_correct[of "notn ψ"]) ultimately show ?case by (auto intro: syntactical_implies_correct) next case (Until_ltln φ ψ) moreover have"φ ⊨s ψ ==> ?case" by (force simp add: Until_ltln dest: syntactical_implies_correct) moreover
{ assume A: "(notn φ) ⊨s ψ"and B: "¬ φ ⊨s ψ" hence [simp]: "rewrite_syn_imp (φ Un ψ) = mk_finally (rewrite_syn_imp ψ)" by simp
{ assume"∃i. suffix i w ⊨n ψ" moreover
define i where"i ≡ LEAST i. suffix i w ⊨n ψ" ultimately have"∀j < i. ¬suffix j w ⊨n ψ"and"suffix i w ⊨n ψ" by (blast dest: not_less_Least , metis LeastI ‹∃i. suffix i w ⊨n ψ› i_def) hence"∀j < i. suffix j w ⊨n φ"and"suffix i w ⊨n ψ" using syntactical_implies_correct[OF A] by auto
} hence ?case by (simp del: rewrite_syn_imp.simps; unfold Until_ltln(2)) blast
} ultimately show ?case by fastforce next case (Release_ltln φ ψ) moreover have"ψ ⊨s φ ==> ?case" by (force simp add: Release_ltln dest: syntactical_implies_correct) moreover
{ assume A: "ψ ⊨s (notn φ)"and B: "¬ ψ ⊨s φ" hence [simp]: "rewrite_syn_imp (φ Rn ψ) = mk_globally (rewrite_syn_imp ψ)" by simp
{ assume"∃i. ¬suffix i w ⊨n ψ" moreover
define i where"i ≡ LEAST i. ¬suffix i w ⊨n ψ" ultimately have"∀j < i. suffix j w ⊨n ψ"and"¬ suffix i w ⊨n ψ" by (blast dest: not_less_Least , metis LeastI ‹∃i. ¬suffix i w ⊨n ψ› i_def) hence"∀j < i. ¬suffix j w ⊨n φ"and"¬ suffix i w ⊨n ψ" using syntactical_implies_correct[OF A] by auto
} hence ?case by (simp del: rewrite_syn_imp.simps; unfold Release_ltln(2)) blast
} ultimately show ?case by fastforce qed auto
subsection‹Iterated Rewriting›
fun iterate where "iterate f x 0 = x"
| "iterate f x (Suc n) = (let x' = f x in if x = x' then x else iterate f x' n)"
definition "rewrite_iter_slow φ ≡ iterate (rewrite_syn_imp o rewrite_modal o rewrite_X) φ (size φ)"
text‹The rewriting functions defined in the previous subsections can be used as-is. However, in the
most cases one wants to iterate these rules until the formula cannot be simplified further.
@{const rewrite_iter_fast} pulls X operators up in the syntax tree and the uses the
"modal" simplification rules. @{const rewrite_iter_slow} additionally tries to simplify the
formula using syntactic implication checking.›
lemma iterate_sound: assumes"∧φ. w ⊨n f φ ⟷ w ⊨n φ" shows"w ⊨n iterate f φ n ⟷ w ⊨n φ" by (induction n arbitrary: φ; simp add: assms Let_def)
theorem rewrite_iter_fast_sound [simp]: "w ⊨n rewrite_iter_fast φ ⟷ w ⊨n φ" using iterate_sound[of _ "rewrite_modal o rewrite_X"] unfolding comp_def rewrite_modal_sound rewrite_X_sound rewrite_iter_fast_def by blast
theorem rewrite_iter_slow_sound [simp]: "w ⊨n rewrite_iter_slow φ ⟷ w ⊨n φ" using iterate_sound[of _ "rewrite_syn_imp o rewrite_modal o rewrite_X"] unfolding comp_def rewrite_modal_sound rewrite_X_sound rewrite_syn_imp_sound rewrite_iter_slow_def by blast
subsection‹Preservation of atoms›
lemma iterate_atoms: assumes "∧φ. atoms_ltln (f φ) ⊆ atoms_ltln φ" shows "atoms_ltln (iterate f φ n) ⊆ atoms_ltln φ" by (induction n arbitrary: φ) (auto, metis (mono_tags, lifting) assms in_mono)
lemma rewrite_modal_atoms: "atoms_ltln (rewrite_modal φ) ⊆ atoms_ltln φ" by (induction φ) auto
lemma rewrite_syn_imp_atoms: "atoms_ltln (rewrite_syn_imp φ) ⊆ atoms_ltln φ" proof (induction φ) case (And_ltln φ1 φ2) thenshow ?case using mk_and_atoms by simp fast next case (Or_ltln φ1 φ2) thenshow ?case using mk_or_atoms by simp fast next case (Next_ltln φ) thenshow ?case using mk_next_atoms by simp fast next case (Until_ltln φ1 φ2) thenshow ?case using mk_finally_atoms mk_until_atoms by simp fast next case (Release_ltln φ1 φ2) thenshow ?case using mk_globally_atoms mk_release_atoms by simp fast qed simp_all
lemma rewrite_iter_fast_atoms: "atoms_ltln (rewrite_iter_fast φ) ⊆ atoms_ltln φ" proof - have1: "∧φ. atoms_ltln (rewrite_modal (rewrite_X φ)) ⊆ atoms_ltln φ" using rewrite_modal_atoms rewrite_X_atoms by force
show ?thesis by (simp add: rewrite_iter_fast_def 1 iterate_atoms) qed
lemma rewrite_iter_slow_atoms: "atoms_ltln (rewrite_iter_slow φ) ⊆ atoms_ltln φ" proof - have1: "∧φ. atoms_ltln (rewrite_syn_imp (rewrite_modal (rewrite_X φ))) ⊆ atoms_ltln φ" using rewrite_syn_imp_atoms rewrite_modal_atoms rewrite_X_atoms by force
show ?thesis by (simp add: rewrite_iter_slow_def 1 iterate_atoms) qed
subsection‹Simplifier›
text‹We now define a convenience wrapper for the rewriting engine›
datatype mode = Nop | Fast | Slow
fun simplify :: "mode ==> 'a ltln ==> 'a ltln" where "simplify Nop = id"
| "simplify Fast = rewrite_iter_fast"
| "simplify Slow = rewrite_iter_slow"
theorem simplify_correct: "w ⊨n simplify m φ ⟷ w ⊨n φ" by (cases m) simp+
lemma simplify_atoms: "atoms_ltln (simplify m φ) ⊆ atoms_ltln φ" by (cases m) (insert rewrite_iter_fast_atoms rewrite_iter_slow_atoms, fastforce+)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.