lemma impl_not_or: "φ impl ψ = (not φ) or ψ" by blast
lemma not_or: "not (φ or ψ) = (not φ) aand (not ψ)" by blast
lemma not_aand: "not (φ aand ψ) = (not φ) or (not ψ)" by blast
lemma non_not[simp]: "not (not φ) = φ"by simp
text‹Temporal (LTL) connectives:›
fun holds where"holds P xs ⟷ P (shd xs)" fun nxt where"nxt φ xs = φ (stl xs)"
definition"HLD s = holds (λx. x ∈ s)"
abbreviation HLD_nxt (infixr‹⋅› 65) where "s ⋅ P ≡ HLD s aand nxt P"
context notes [[inductive_internals]] begin
inductive ev for φ where
base: "φ xs ==> ev φ xs"
|
step: "ev φ (stl xs) ==> ev φ xs"
coinductive alw for φ where
alw: "[φ xs; alw φ (stl xs)]==> alw φ xs"
🍋‹weak until:› coinductive UNTIL (infix‹until› 60) for φ ψ where
base: "ψ xs ==> (φ until ψ) xs"
|
step: "[φ xs; (φ until ψ) (stl xs)]==> (φ until ψ) xs"
end
lemma holds_mono: assumes holds: "holds P xs"and 0: "∧ x. P x ==> Q x" shows"holds Q xs" using assms by auto
lemma holds_aand: "(holds P aand holds Q) steps ⟷ holds (λ step. P step ∧ Q step) steps"by auto
lemma HLD_iff: "HLD s ψ ⟷ shd ψ ∈ s" by (simp add: HLD_def)
lemma HLD_Stream[simp]: "HLD X (x ## ψ) ⟷ x ∈ X" by (simp add: HLD_iff)
lemma nxt_mono: assumes nxt: "nxt φ xs"and 0: "∧ xs. φ xs ==> ψ xs" shows"nxt ψ xs" using assms by auto
declare ev.intros[intro] declare alw.cases[elim]
lemma ev_induct_strong[consumes 1, case_names base step]: "ev φ x ==> (∧xs. φ xs ==> P xs) ==> (∧xs. ev φ (stl xs) ==>¬ φ xs ==> P (stl xs) ==> P xs) ==> P x" by (induct rule: ev.induct) auto
lemma alw_coinduct[consumes 1, case_names alw stl]: "X x ==> (∧x. X x ==> φ x) ==> (∧x. X x ==>¬ alw φ (stl x) ==> X (stl x)) ==> alw φ x" using alw.coinduct[of X x φ] by auto
lemma ev_mono: assumes ev: "ev φ xs"and 0: "∧ xs. φ xs ==> ψ xs" shows"ev ψ xs" using ev by induct (auto simp: 0)
lemma ev_or: "ev (φ or ψ) = ev φ or ev ψ"
proof-
{fix xs assume"(ev φ or ev ψ) xs"hence"ev (φ or ψ) xs" by (auto elim: ev_mono)
} moreover
{fix xs assume"ev (φ or ψ) xs"hence"(ev φ or ev ψ) xs" by induct auto
} ultimatelyshow ?thesis by blast qed
lemma ev_alw_aand: assumes φ: "ev (alw φ) xs"and ψ: "ev (alw ψ) xs" shows"ev (alw (φ aand ψ)) xs"
proof- obtain xl xs1 where xs1: "xs = xl @- xs1"and φφ: "alw φ xs1" using φ by (metis ev_imp_shift) moreoverobtain yl ys1 where xs2: "xs = yl @- ys1"and ψψ: "alw ψ ys1" using ψ by (metis ev_imp_shift) ultimatelyhave 0: "xl @- xs1 = yl @- ys1"by auto hence"prefix xl yl ∨ prefix yl xl"using shift_prefix_cases by auto thus ?thesis proof assume"prefix xl yl" thenobtain yl1 where yl: "yl = xl @ yl1"by (elim prefixE) have xs1': "xs1 = yl1 @- ys1"using 0 unfolding yl by simp have"alw φ ys1"using φφ unfolding xs1' by (metis alw_shift) hence"alw (φ aand ψ) ys1"using ψψ unfolding alw_aand by auto thus ?thesis unfolding xs2 by (auto intro: alw_ev_shift) next assume"prefix yl xl" thenobtain xl1 where xl: "xl = yl @ xl1"by (elim prefixE) have ys1': "ys1 = xl1 @- xs1"using 0 unfolding xl by simp have"alw ψ xs1"using ψψ unfolding ys1' by (metis alw_shift) hence"alw (φ aand ψ) xs1"using φφ unfolding alw_aand by auto thus ?thesis unfolding xs1 by (auto intro: alw_ev_shift) qed qed
lemma ev_alw_alw_impl: assumes"ev (alw φ) xs"and"alw (alw φ impl ev ψ) xs" shows"ev ψ xs" using assms by induct auto
lemma ev_alw_stl[simp]: "ev (alw φ) (stl x) ⟷ ev (alw φ) x" by (metis (full_types) alw_nxt ev_nxt nxt.simps)
lemma alw_alw_impl_ev: "alw (alw φ impl ev ψ) = (ev (alw φ) impl alw (ev ψ))" (is"?A = ?B")
proof-
{fix xs assume"?A xs ∧ ev (alw φ) xs"hence"alw (ev ψ) xs" by coinduct (auto elim: ev_alw_alw_impl)
} moreover
{fix xs assume"?B xs"hence"?A xs" by coinduct auto
} ultimatelyshow ?thesis by blast qed
lemma ev_alw_impl: assumes"ev φ xs"and"alw (φ impl ψ) xs"shows"ev ψ xs" using assms by induct auto
lemma ev_alw_impl_ev: assumes"ev φ xs"and"alw (φ impl ev ψ) xs"shows"ev ψ xs" using ev_alw_impl[OF assms] by simp
lemma alw_mp: assumes"alw φ xs"and"alw (φ impl ψ) xs" shows"alw ψ xs"
proof-
{assume"alw φ xs ∧ alw (φ impl ψ) xs"hence ?thesis by coinduct auto
} thus ?thesis using assms by auto qed
lemma all_imp_alw: assumes"∧ xs. φ xs"shows"alw φ xs"
proof-
{assume"∀ xs. φ xs" hence ?thesis by coinduct auto
} thus ?thesis using assms by auto qed
lemma alw_impl_ev_alw: assumes"alw (φ impl ev ψ) xs" shows"alw (ev φ impl ev ψ) xs" using assms by coinduct (auto dest: ev_alw_impl)
lemma ev_holds_sset: "ev (holds P) xs ⟷ (∃ x ∈ sset xs. P x)" (is"?L ⟷ ?R") proof safe assume ?L thus ?R by induct (metis holds.simps stream.set_sel(1), metis stl_sset) next fix x assume"x ∈ sset xs""P x" thus ?L by (induct rule: sset_induct) (simp_all add: ev.base ev.step) qed
text‹LTL as a program logic:› lemma alw_invar: assumes"φ xs"and"alw (φ impl nxt φ) xs" shows"alw φ xs"
proof-
{assume"φ xs ∧ alw (φ impl nxt φ) xs"hence ?thesis by coinduct auto
} thus ?thesis using assms by auto qed
lemma variance: assumes 1: "φ xs"and 2: "alw (φ impl (ψ or nxt φ)) xs" shows"(alw φ or ev ψ) xs"
proof-
{assume"¬ ev ψ xs"hence"alw (not ψ) xs"unfolding not_ev[symmetric] . moreoverhave"alw (not ψ impl (φ impl nxt φ)) xs" using 2 by coinduct auto ultimatelyhave"alw (φ impl nxt φ) xs"by(auto dest: alw_mp) with 1 have"alw φ xs"by(rule alw_invar)
} thus ?thesis by blast qed
lemma ev_alw_imp_nxt: assumes e: "ev φ xs"and a: "alw (φ impl (nxt φ)) xs" shows"ev (alw φ) xs"
proof- obtain xl xs1 where xs: "xs = xl @- xs1"and φ: "φ xs1" using e by (metis ev_imp_shift) have"φ xs1 ∧ alw (φ impl (nxt φ)) xs1"using a φ unfolding xs by (metis alw_shift) hence"alw φ xs1"by(coinduct xs1 rule: alw.coinduct) auto thus ?thesis unfolding xs by (auto intro: alw_ev_shift) qed
inductive ev_at :: "('a stream ==> bool) ==> nat ==> 'a stream ==> bool"for P :: "'a stream ==> bool"where
base: "P ψ ==> ev_at P 0 ψ"
| step:"¬ P ψ ==> ev_at P n (stl ψ) ==> ev_at P (Suc n) ψ"
inductive_simps ev_at_0[simp]: "ev_at P 0 ψ"
inductive_simps ev_at_Suc[simp]: "ev_at P (Suc n) ψ"
lemma ev_at_imp_snth: "ev_at P n ψ ==> P (sdrop n ψ)" by (induction n arbitrary: ψ) auto
lemma ev_at_HLD_imp_snth: "ev_at (HLD X) n ψ ==> ψ !! n ∈ X" by (auto dest!: ev_at_imp_snth simp: HLD_iff)
lemma ev_at_HLD_single_imp_snth: "ev_at (HLD {x}) n ψ ==> ψ !! n = x" by (drule ev_at_HLD_imp_snth) simp
lemma ev_at_unique: "ev_at P n ψ ==> ev_at P m ψ ==> n = m" proof (induction arbitrary: m rule: ev_at.induct) case (base ψ) thenshow ?case by (simp add: ev_at.simps[of _ _ ψ]) next case (step ψ n) from step.prems step.hyps step.IH[of "m - 1"] show ?case by (auto simp add: ev_at.simps[of _ _ ψ]) qed
lemma ev_iff_ev_at: "ev P ψ ⟷ (∃n. ev_at P n ψ)" proof assume"ev P ψ"thenshow"∃n. ev_at P n ψ" by (induction rule: ev_induct_strong) (auto intro: ev_at.intros) next assume"∃n. ev_at P n ψ" thenobtain n where"ev_at P n ψ" by auto thenshow"ev P ψ" byinduction auto qed
lemma ev_at_shift: "ev_at (HLD X) i (stake (Suc i) ψ @- ψ' :: 's stream) ⟷ ev_at (HLD X) i ψ" by (induction i arbitrary: ψ) (auto simp: HLD_iff)
lemma ev_iff_ev_at_unique: "ev P ψ ⟷ (∃!n. ev_at P n ψ)" by (auto intro: ev_at_unique simp: ev_iff_ev_at)
lemma alw_HLD_iff_streams: "alw (HLD X) ψ ⟷ ψ ∈ streams X" proof assume"alw (HLD X) ψ"thenshow"ψ ∈ streams X" proof (coinduction arbitrary: ψ) case (streams ψ) thenshow ?caseby (cases ψ) auto qed next assume"ψ ∈ streams X"thenshow"alw (HLD X) ψ" proof (coinduction arbitrary: ψ) case (alw ψ) thenshow ?caseby (cases ψ) auto qed qed
lemma not_alw_iff: "¬ (alw P ψ) ⟷ ev (not P) ψ" using not_alw[of P] by (simp add: fun_eq_iff)
lemma not_ev_iff: "¬ (ev P ψ) ⟷ alw (not P) ψ" using not_alw_iff[of "not P" ψ, symmetric] by simp
lemma ev_Stream: "ev P (x ## s) ⟷ P (x ## s) ∨ ev P s" by (auto elim: ev.cases)
lemma alw_ev_imp_ev_alw: assumes"alw (ev P) ψ"shows"ev (P aand alw (ev P)) ψ" proof - have"ev P ψ"using assms by auto from this assms show ?thesis by induct auto qed
lemma ev_False: "ev (λx. False) ψ ⟷ False" proof assume"ev (λx. False) ψ"thenshow False by induct auto qed auto
lemma alw_False: "alw (λx. False) ψ ⟷ False" by auto
lemma ev_iff_sdrop: "ev P ψ ⟷ (∃m. P (sdrop m ψ))" proof safe assume"ev P ψ"thenshow"∃m. P (sdrop m ψ)" by (induct rule: ev_induct_strong) (auto intro: exI[of _ 0] exI[of _ "Suc n"for n]) next fix m assume"P (sdrop m ψ)"thenshow"ev P ψ" by (induct m arbitrary: ψ) auto qed
lemma alw_iff_sdrop: "alw P ψ ⟷ (∀m. P (sdrop m ψ))" proof safe fix m assume"alw P ψ"thenshow"P (sdrop m ψ)" by (induct m arbitrary: ψ) auto next assume"∀m. P (sdrop m ψ)"thenshow"alw P ψ" by (coinduction arbitrary: ψ) (auto elim: allE[of _ 0] allE[of _ "Suc n"for n]) qed
lemma infinite_iff_alw_ev: "infinite {m. P (sdrop m ψ)} ⟷ alw (ev P) ψ" unfolding infinite_nat_iff_unbounded_le alw_iff_sdrop ev_iff_sdrop by simp (metis le_Suc_ex le_add1)
lemma alw_inv: assumes stl: "∧s. f (stl s) = stl (f s)" shows"alw P (f s) ⟷ alw (λx. P (f x)) s" proof assume"alw P (f s)"thenshow"alw (λx. P (f x)) s" by (coinduction arbitrary: s rule: alw_coinduct)
(auto simp: stl) next assume"alw (λx. P (f x)) s"thenshow"alw P (f s)" by (coinduction arbitrary: s rule: alw_coinduct) (auto simp flip: stl) qed
lemma ev_inv: assumes stl: "∧s. f (stl s) = stl (f s)" shows"ev P (f s) ⟷ ev (λx. P (f x)) s" proof assume"ev P (f s)"thenshow"ev (λx. P (f x)) s" by (induction"f s" arbitrary: s) (auto simp: stl) next assume"ev (λx. P (f x)) s"thenshow"ev P (f s)" byinduction (auto simp flip: stl) qed
lemma alw_smap: "alw P (smap f s) ⟷ alw (λx. P (smap f x)) s" by (rule alw_inv) simp
lemma ev_smap: "ev P (smap f s) ⟷ ev (λx. P (smap f x)) s" by (rule ev_inv) simp
lemma alw_cong: assumes P: "alw P ψ"and eq: "∧ψ. P ψ ==> Q1 ψ ⟷ Q2 ψ" shows"alw Q1 ψ ⟷ alw Q2 ψ" proof - from eq have"(alw P aand Q1) = (alw P aand Q2)"by auto thenhave"alw (alw P aand Q1) ψ = alw (alw P aand Q2) ψ"by auto with P show"alw Q1 ψ ⟷ alw Q2 ψ" by (simp add: alw_aand) qed
lemma ev_cong: assumes P: "alw P ψ"and eq: "∧ψ. P ψ ==> Q1 ψ ⟷ Q2 ψ" shows"ev Q1 ψ ⟷ ev Q2 ψ" proof - from P have"alw (λxs. Q1 xs ⟶ Q2 xs) ψ"by (rule alw_mono) (simp add: eq) moreoverfrom P have"alw (λxs. Q2 xs ⟶ Q1 xs) ψ"by (rule alw_mono) (simp add: eq) moreovernote ev_alw_impl[of Q1 ψ Q2] ev_alw_impl[of Q2 ψ Q1] ultimatelyshow"ev Q1 ψ ⟷ ev Q2 ψ" by auto qed
lemma alwD: "alw P x ==> P x" by auto
lemma alw_alwD: "alw P ψ ==> alw (alw P) ψ" by simp
lemma suntil_smap: "(P suntil Q) (smap f s) ⟷ ((λx. P (smap f x)) suntil (λx. Q (smap f x))) s" by (rule suntil_inv) simp
lemma hld_smap: "HLD x (smap f s) = holds (λy. f y ∈ x) s" by (simp add: HLD_def)
lemma suntil_mono: assumes eq: "∧ψ. P ψ ==> Q1 ψ ==> Q2 ψ""∧ψ. P ψ ==> R1 ψ ==> R2 ψ" assumes *: "(Q1 suntil R1) ψ""alw P ψ"shows"(Q2 suntil R2) ψ" using * by induct (auto intro: eq suntil.intros)
lemma suntil_cong: "alw P ψ ==> (∧ψ. P ψ ==> Q1 ψ ⟷ Q2 ψ) ==> (∧ψ. P ψ ==> R1 ψ ⟷ R2 ψ) ==> (Q1 suntil R1) ψ ⟷ (Q2 suntil R2) ψ" using suntil_mono[of P Q1 Q2 R1 R2 ψ] suntil_mono[of P Q2 Q1 R2 R1 ψ] by auto
lemma ev_suntil_iff: "ev (P suntil Q) ψ ⟷ ev Q ψ" proof assume"ev (P suntil Q) ψ"thenshow"ev Q ψ" by induct (auto dest: ev_suntil) next assume"ev Q ψ"thenshow"ev (P suntil Q) ψ" by induct (auto intro: suntil.intros) qed
lemma true_suntil: "((λ_. True) suntil P) = ev P" by (simp add: suntil_def ev_def)
lemma suntil_lfp: "(φ suntil ψ) = lfp (λP s. ψ s ∨ (φ s ∧ P (stl s)))" by (simp add: suntil_def)
lemma sfilter_P[simp]: "P (shd s) ==> sfilter P s = shd s ## sfilter P (stl s)" using sfilter_Stream[of P "shd s""stl s"] by simp
lemma sfilter_not_P[simp]: "¬ P (shd s) ==> sfilter P s = sfilter P (stl s)" using sfilter_Stream[of P "shd s""stl s"] by simp
lemma sfilter_eq: assumes"ev (holds P) s" shows"sfilter P s = x ## s' ⟷ P x ∧ (not (holds P) suntil (HLD {x} aand nxt (λs. sfilter P s = s'))) s" using assms by (induct rule: ev_induct_strong)
(auto simp add: HLD_iff intro: suntil.intros elim: suntil.cases)
lemma sfilter_streams: "alw (ev (holds P)) ψ ==> ψ ∈ streams A ==> sfilter P ψ ∈ streams {x∈A. P x}" proof (coinduction arbitrary: ψ) case (streams ψ) thenhave"ev (holds P) ψ"by blast from this streams show ?case by (induct rule: ev_induct_strong) (auto elim: streamsE) qed
lemma alw_sfilter: assumes *: "alw (ev (holds P)) s" shows"alw Q (sfilter P s) ⟷ alw (λx. Q (sfilter P x)) s" proof assume"alw Q (sfilter P s)"with * show"alw (λx. Q (sfilter P x)) s" proof (coinduction arbitrary: s rule: alw_coinduct) case (stl s) thenhave"ev (holds P) s" by blast from this stl show ?case by (induct rule: ev_induct_strong) auto qed auto next assume"alw (λx. Q (sfilter P x)) s"with * show"alw Q (sfilter P s)" proof (coinduction arbitrary: s rule: alw_coinduct) case (stl s) thenhave"ev (holds P) s" by blast from this stl show ?case by (induct rule: ev_induct_strong) auto qed auto qed
lemma ev_sfilter: assumes *: "alw (ev (holds P)) s" shows"ev Q (sfilter P s) ⟷ ev (λx. Q (sfilter P x)) s" proof assume"ev Q (sfilter P s)"from this * show"ev (λx. Q (sfilter P x)) s" proof (induction"sfilter P s" arbitrary: s rule: ev_induct_strong) case (step s) thenhave"ev (holds P) s" by blast from this step show ?case by (induct rule: ev_induct_strong) auto qed auto next assume"ev (λx. Q (sfilter P x)) s"thenshow"ev Q (sfilter P s)" proof (induction rule: ev_induct_strong) case (step s) thenshow ?case by (cases "P (shd s)") auto qed auto qed
lemma holds_sfilter: assumes"ev (holds Q) s"shows"holds P (sfilter Q s) ⟷ (not (holds Q) suntil (holds (Q aand P))) s" proof assume"holds P (sfilter Q s)"with assms show"(not (holds Q) suntil (holds (Q aand P))) s" by (induct rule: ev_induct_strong) (auto intro: suntil.intros) next assume"(not (holds Q) suntil (holds (Q aand P))) s"thenshow"holds P (sfilter Q s)" by induct auto qed
lemma alw_sconst: "alw P (sconst x) ⟷ P (sconst x)" proof assume"P (sconst x)"thenshow"alw P (sconst x)" by coinduction auto qed auto
lemma ev_sconst: "ev P (sconst x) ⟷ P (sconst x)" proof assume"ev P (sconst x)"thenshow"P (sconst x)" by (induction"sconst x") auto qed auto
lemma suntil_sconst: "(φ suntil ψ) (sconst x) ⟷ ψ (sconst x)" proof assume"(φ suntil ψ) (sconst x)"thenshow"ψ (sconst x)" by (induction"sconst x") auto qed (auto intro: suntil.intros)
lemma hld_smap': "HLD x (smap f s) = HLD (f -` x) s" by (simp add: HLD_def)
lemma pigeonhole_stream: assumes"alw (HLD s) ψ" assumes"finite s" shows"∃x∈s. alw (ev (HLD {x})) ψ" proof - have"∀i∈UNIV. ∃x∈s. ψ !! i = x" using‹alw (HLD s) ψ›by (simp add: alw_iff_sdrop HLD_iff) from pigeonhole_infinite_rel[OF infinite_UNIV_nat ‹finite s› this] show ?thesis by (simp add: HLD_iff flip: infinite_iff_alw_ev) qed
lemma ev_eq_suntil: "ev P ψ ⟷ (not P suntil P) ψ" proof assume"ev P ψ"thenshow"((λxs. ¬ P xs) suntil P) ψ" by (induction rule: ev_induct_strong) (auto intro: suntil.intros) qed (auto simp: ev_suntil)
section‹Weak vs. strong until (contributed by Michael Foster, University of Sheffield)›
lemma suntil_implies_until: "(φ suntil ψ) ψ ==> (φ until ψ) ψ" by (induct rule: suntil_induct_strong) (auto intro: UNTIL.intros)
lemma alw_implies_until: "alw φ ψ ==> (φ until ψ) ψ" unfolding until_false[symmetric] by (auto elim: until_mono)
lemma until_ev_suntil: "(φ until ψ) ψ ==> ev ψ ψ ==> (φ suntil ψ) ψ" proof (rotate_tac, induction rule: ev.induct) case (base xs) thenshow ?case by (simp add: suntil.base) next case (step xs) thenshow ?case by (metis UNTIL.cases suntil.base suntil.step) qed
lemma suntil_as_until: "(φ suntil ψ) ψ = ((φ until ψ) ψ ∧ ev ψ ψ)" using ev_suntil suntil_implies_until until_ev_suntil by blast
lemma until_not_relesased_now: "(φ until ψ) ψ ==>¬ ψ ψ ==> φ ψ" using UNTIL.cases by auto
lemma until_must_release_ev: "(φ until ψ) ψ ==> ev (not φ) ψ ==> ev ψ ψ" proof (rotate_tac, induction rule: ev.induct) case (base xs) thenshow ?case using until_not_relesased_now by blast next case (step xs) thenshow ?case using UNTIL.cases by blast qed
lemma until_as_suntil: "(φ until ψ) ψ = ((φ suntil ψ) or (alw φ)) ψ" using alw_implies_until not_alw_iff suntil_implies_until until_ev_suntil until_must_release_ev by blast
lemma alw_holds: "alw (holds P) (h##t) = (P h ∧ alw (holds P) t)" by (metis alw.simps holds_Stream stream.sel(2))
lemma alw_eq_sconst: "(alw (HLD {h}) t) = (t = sconst h)" unfolding sconst_alt alw_HLD_iff_streams streams_iff_sset using stream.set_sel(1) by force
lemma sdrop_if_suntil: "(p suntil q) ψ ==>∃j. q (sdrop j ψ) ∧ (∀k < j. p (sdrop k ψ))" proof(induction rule: suntil.induct) case (base ψ) thenshow ?case by force next case (step ψ) thenobtain j where"q (sdrop j (stl ψ))""∀kby blast with step(1,2) show ?case using ev_at_imp_snth less_Suc_eq_0_disj by (auto intro!: exI[where x="j+1"]) qed
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.