Theory Temporal_Logics
theory Temporal_Logics
imports Timed_Automata.CTL LTL.LTL LTL_Master_Theorem.Omega_Words_Fun_Stream
begin
lemmas [simp] = holds.simps
lemma suffix_stl:
"suffix (Suc 0) (snth xs) = snth (stl xs)"
unfolding suffix_def by auto
lemma suntil_iff_sdrop:
"(φ suntil ψ) xs ⟷ (∃i. ψ (sdrop i xs) ∧ (∀j<i. φ (sdrop j xs)))"
proof safe
show "∃i. ψ (sdrop i xs) ∧ (∀j<i. φ (sdrop j xs))" if "(φ suntil ψ) xs"
using that
proof (induction rule: suntil.induct)
case (base ω)
then show ?case
by force
next
case (step ω)
then obtain i where "ψ (sdrop i (stl ω))" "∀j<i. φ (sdrop j (stl ω))"
by safe
with ‹φ ω› have "φ (sdrop j ω)" if "j<i + 1" for j
using that by (cases j) auto
with ‹ψ (sdrop i (stl ω))› show ?case
by (inst_existentials "i + 1") auto
qed
show "(φ suntil ψ) xs" if "ψ (sdrop i xs)" "∀j<i. φ (sdrop j xs)" for i
using that by (induction i arbitrary: xs; fastforce intro: suntil.intros)
qed
lemma to_stream_suffix_Suc:
"to_stream (suffix (Suc k) xs) = stl (to_stream (suffix k xs))"
by (metis add.right_neutral add_Suc_right suffix_stl suffix_suffix
to_omega_def to_omega_to_stream to_stream_to_omega)
lemma to_stream_stake:
"sdrop k (to_stream w) = to_stream (suffix k w)"
by (induction k arbitrary: w) (auto simp: sdrop_stl to_stream_suffix_Suc)
lemma to_omega_suffix[simp]:
"suffix k (to_omega s) = to_omega (sdrop k s)"
by auto
primrec semantics_ltlc' :: "['a word, ('a ⇒ bool) ltlc] ⇒ bool" ("_ ⊨⇩c'' _" [80,80] 80)
where
"ξ ⊨⇩c' true⇩c = True"
| "ξ ⊨⇩c' false⇩c = False"
| "ξ ⊨⇩c' prop⇩c(q) = (q (ξ 0))"
| "ξ ⊨⇩c' not⇩c φ = (¬ ξ ⊨⇩c' φ)"
| "ξ ⊨⇩c' φ and⇩c ψ = (ξ ⊨⇩c' φ ∧ ξ ⊨⇩c' ψ)"
| "ξ ⊨⇩c' φ or⇩c ψ = (ξ ⊨⇩c' φ ∨ ξ ⊨⇩c' ψ)"
| "ξ ⊨⇩c' φ implies⇩c ψ = (ξ ⊨⇩c' φ ⟶ ξ ⊨⇩c' ψ)"
| "ξ ⊨⇩c' X⇩c φ = (suffix 1 ξ ⊨⇩c' φ)"
| "ξ ⊨⇩c' F⇩c φ = (∃i. suffix i ξ ⊨⇩c' φ)"
| "ξ ⊨⇩c' G⇩c φ = (∀i. suffix i ξ ⊨⇩c' φ)"
| "ξ ⊨⇩c' φ U⇩c ψ = (∃i. suffix i ξ ⊨⇩c' ψ ∧ (∀j<i. suffix j ξ ⊨⇩c' φ))"
| "ξ ⊨⇩c' φ R⇩c ψ = (∀i. suffix i ξ ⊨⇩c' ψ ∨ (∃j<i. suffix j ξ ⊨⇩c' φ))"
| "ξ ⊨⇩c' φ W⇩c ψ = (∀i. suffix i ξ ⊨⇩c' φ ∨ (∃j≤i. suffix j ξ ⊨⇩c' ψ))"
| "ξ ⊨⇩c' φ M⇩c ψ = (∃i. suffix i ξ ⊨⇩c' φ ∧ (∀j≤i. suffix j ξ ⊨⇩c' ψ))"
lemma semantics_ltlc'_sugar [simp]:
"ξ ⊨⇩c' φ iff⇩c ψ = (ξ ⊨⇩c' φ ⟷ ξ ⊨⇩c' ψ)"
"ξ ⊨⇩c' F⇩c φ = ξ ⊨⇩c' (true⇩c U⇩c φ)"
"ξ ⊨⇩c' G⇩c φ = ξ ⊨⇩c' (false⇩c R⇩c φ)"
by (auto simp add: Iff_ltlc_def)
definition "language_ltlc' φ ≡ {ξ. ξ ⊨⇩c' φ}"
fun ltlc_to_pltl :: "('a ⇒ bool) ltlc ⇒ 'a pltl"
where
"ltlc_to_pltl true⇩c = true⇩p"
| "ltlc_to_pltl false⇩c = false⇩p"
| "ltlc_to_pltl (prop⇩c(q)) = atom⇩p(q)"
| "ltlc_to_pltl (not⇩c φ) = not⇩p (ltlc_to_pltl φ)"
| "ltlc_to_pltl (φ and⇩c ψ) = (ltlc_to_pltl φ) and⇩p (ltlc_to_pltl ψ)"
| "ltlc_to_pltl (φ or⇩c ψ) = (ltlc_to_pltl φ) or⇩p (ltlc_to_pltl ψ)"
| "ltlc_to_pltl (φ implies⇩c ψ) = (ltlc_to_pltl φ) implies⇩p (ltlc_to_pltl ψ)"
| "ltlc_to_pltl (X⇩c φ) = X⇩p (ltlc_to_pltl φ)"
| "ltlc_to_pltl (F⇩c φ) = F⇩p (ltlc_to_pltl φ)"
| "ltlc_to_pltl (G⇩c φ) = G⇩p (ltlc_to_pltl φ)"
| "ltlc_to_pltl (φ U⇩c ψ) = (ltlc_to_pltl φ) U⇩p (ltlc_to_pltl ψ)"
| "ltlc_to_pltl (φ R⇩c ψ) = (ltlc_to_pltl φ) R⇩p (ltlc_to_pltl ψ)"
| "ltlc_to_pltl (φ W⇩c ψ) = (ltlc_to_pltl φ) W⇩p (ltlc_to_pltl ψ)"
| "ltlc_to_pltl (φ M⇩c ψ) = (ltlc_to_pltl φ) M⇩p (ltlc_to_pltl ψ)"
lemma ltlc_to_pltl_semantics [simp]:
"w ⊨⇩p ltlc_to_pltl φ ⟷ w ⊨⇩c' φ"
by (induction φ arbitrary: w) simp_all
lemma semantics_ltlc'_semantics_ltlc_atoms_iff:
"w ⊨⇩c' φ ⟷ (λi. {a ∈ atoms_ltlc φ. a (w i)}) ⊨⇩c φ"
proof -
have *:
"(λi. {a. (a ∈ atoms_ltlc φ1 ∨ a ∈ atoms_ltlc φ2) ∧ a (w i)}) ⊨⇩c φ1
⟷ ((λi. {a ∈ atoms_ltlc φ1. a (w i)}) ⊨⇩c φ1)" for w :: "nat ⇒ 'a" and φ1 φ2
by (rule ltlc_eq_on) (auto simp: pw_eq_on_def)
have **:
"(λi. {a. (a ∈ atoms_ltlc φ1 ∨ a ∈ atoms_ltlc φ2) ∧ a (w i)}) ⊨⇩c φ2
⟷ ((λi. {a ∈ atoms_ltlc φ2. a (w i)}) ⊨⇩c φ2)" for w :: "nat ⇒ 'a" and φ1 φ2
by (rule ltlc_eq_on) (auto simp: pw_eq_on_def)
show ?thesis
by (induction φ arbitrary: w) (simp_all add: suffix_def * **)
qed
lemma semantics_ltlc'_semantics_ltlc_atoms_iff':
"w ⊨⇩c' φ ⟷ ((λx. {a ∈ atoms_ltlc φ. a x}) o w) ⊨⇩c φ"
unfolding comp_def by (rule semantics_ltlc'_semantics_ltlc_atoms_iff)
lemma map_semantics_ltlc_inj:
assumes "inj f"
shows "w ⊨⇩c φ ⟷ (image f o w) ⊨⇩c map_ltlc f φ"
using assms unfolding comp_def by (intro map_semantics_ltlc_aux) auto
lemma semantics_ltlc'_abstract:
assumes "inj abstr" "⋀x. label x = abstr ` {a ∈ atoms_ltlc φ. a x}"
shows "w ⊨⇩c' φ ⟷ (label o w) ⊨⇩c map_ltlc abstr φ"
by (subst semantics_ltlc'_semantics_ltlc_atoms_iff')
(simp add: comp_def assms(2) map_semantics_ltlc_inj[OF ‹inj abstr›])
context
includes lifting_syntax
begin
lemma holds_transfer:
"((R ===> (=)) ===> stream_all2 R ===> (=)) holds holds"
apply (intro rel_funI)
subgoal for φ ψ xs ys
by (cases xs; cases ys) (auto dest: rel_funD)
done
lemma alw_mono1:
"alw φ xs" if "(stream_all2 R ===> (=)) φ ψ" "stream_all2 R xs ys" "alw ψ ys"
using that(2,3)
by (coinduction arbitrary: xs ys) (use that(1) stream.rel_sel in ‹auto dest!: rel_funD›)
lemma alw_mono2:
"alw ψ ys" if "(stream_all2 R ===> (=)) φ ψ" "stream_all2 R xs ys" "alw φ xs"
using that(2,3)
by (coinduction arbitrary: xs ys) (use that(1) stream.rel_sel in ‹auto dest!: rel_funD›)
lemma alw_transfer':
"alw x xs = alw y ys" if "(stream_all2 R ===> (=)) x y" "stream_all2 R xs ys"
using alw_mono1 alw_mono2 that by blast
lemma alw_transfer:
"((stream_all2 R ===> (=)) ===> stream_all2 R ===> (=)) alw alw"
by (intro rel_funI) (rule alw_transfer')
lemma nxt_transfer:
"((stream_all2 R ===> (=)) ===> stream_all2 R ===> (=)) nxt nxt"
by (intro rel_funI) (simp, meson rel_funD stream.rel_sel)
lemma suntil_mono1:
"(φ suntil ψ) xs"
if "(stream_all2 R ===> (=)) φ φ'" "(stream_all2 R ===> (=)) ψ ψ'" "stream_all2 R xs ys"
"(φ' suntil ψ') ys"
using that(4,3)
proof (induction arbitrary: xs)
case (base ω)
then show ?case
using that(1,2) by (auto dest!: rel_funD intro: suntil.base)
next
case (step ω)
from ‹stream_all2 R xs ω› have "stream_all2 R (stl xs) (stl ω)"
using stream.rel_sel by auto
from ‹φ' ω› ‹stream_all2 R xs ω› have "φ xs"
using that(1,2) by (auto dest!: rel_funD)
moreover from step.IH ‹stream_all2 R xs ω› have "(φ suntil ψ) (stl xs)"
using stream.rel_sel by auto
ultimately show ?case ..
qed
lemma suntil_mono2:
"(φ' suntil ψ') ys"
if "(stream_all2 R ===> (=)) φ φ'" "(stream_all2 R ===> (=)) ψ ψ'" "stream_all2 R xs ys"
"(φ suntil ψ) xs"
using that(4,3)
proof (induction arbitrary: ys)
case (base ω)
then show ?case
using that(1,2) by (auto dest!: rel_funD intro: suntil.base)
next
case (step xs ω)
from ‹stream_all2 R xs ω› have "stream_all2 R (stl xs) (stl ω)"
using stream.rel_sel by auto
from ‹φ xs› ‹stream_all2 R xs ω› have "φ' ω"
using that(1,2) by (auto dest!: rel_funD)
moreover from step.IH ‹stream_all2 R xs ω› have "(φ' suntil ψ') (stl ω)"
using stream.rel_sel by auto
ultimately show ?case ..
qed
lemma suntil_transfer':
"(φ suntil ψ) xs = (φ' suntil ψ') ys"
if "(stream_all2 R ===> (=)) φ φ'" "(stream_all2 R ===> (=)) ψ ψ'" "stream_all2 R xs ys"
using suntil_mono1 suntil_mono2 that by metis
lemma suntil_transfer:
"((stream_all2 R ===> (=)) ===> (stream_all2 R ===> (=)) ===> stream_all2 R ===> (=))
Linear_Temporal_Logic_on_Streams.suntil Linear_Temporal_Logic_on_Streams.suntil"
by (intro rel_funI) (rule suntil_transfer')
lemma ev_mono1:
"ev φ xs" if "(stream_all2 R ===> (=)) φ ψ" "stream_all2 R xs ys" "ev ψ ys"
using that(3,2) by (induction arbitrary: xs; use that(1) stream.rel_sel in ‹blast dest: rel_funD›)
lemma ev_mono2:
"ev ψ ys" if "(stream_all2 R ===> (=)) φ ψ" "stream_all2 R xs ys" "ev φ xs"
using that(3,2) by (induction arbitrary: ys; use that(1) stream.rel_sel in ‹blast dest: rel_funD›)
lemma ev_transfer':
"ev x xs = ev y ys" if "(stream_all2 R ===> (=)) x y" "stream_all2 R xs ys"
using ev_mono1 ev_mono2 that by blast
lemma ev_transfer:
"((stream_all2 R ===> (=)) ===> (stream_all2 R ===> (=))) ev ev"
by (intro rel_funI) (rule ev_transfer')
end