Theory Labeled_Transition_Systems
section ‹Labeled Transition Systems›
theory Labeled_Transition_Systems
imports Main
begin
subsection ‹Base LTS›
text ‹
The locale ‹LTS› represents a labeled transition system consisting of a set of states $\mathcal{P}$, a set of actions $\Sigma$, and a transition relation $\mapsto \subseteq \mathcal{P}\times\Sigma\times\mathcal{P}$.
We formalize the sets of states and actions by the type variables ‹'s› and ‹'a›. An LTS is then determined by the transition relation ‹step›.
›
locale lts =
fixes step :: ‹'s ⇒ 'a ⇒ 's ⇒ bool› (‹_ ↦ _ _› [70,70,70] 80)
begin
text ‹One may lift \<^term>‹step› to sets of states, written as ‹P ↦S α Q›.›
abbreviation step_setp (‹_ ↦S _ _› [70,70,70] 80) where
‹P ↦S α Q ≡ (∀q ∈ Q. ∃p ∈ P. p ↦ α q) ∧ (∀p ∈ P. ∀q. p ↦ α q ⟶ q ∈ Q)›
text ‹The set of ‹α›-derivatives for a set of states ‹P›.›
definition step_set :: ‹'s set ⇒ 'a ⇒ 's set› where
‹step_set P α ≡ { q . ∃p ∈ P. p ↦ α q }›
text ‹The set of possible ‹α›-steps for a set of states ‹P› is an instance of \<^term>‹step› lifted to sets of steps.›
lemma step_set_is_step_set: ‹P ↦S α (step_set P α)›
using step_set_def by force
text ‹The lifted \<^term>‹step_setp› (‹P ↦S α Q›) is therefore this set ‹Q›.›
lemma step_set_eq:
assumes ‹P ↦S α Q›
shows ‹Q = step_set P α›
using assms step_set_is_step_set by fastforce
end
subsection ‹Labeled Transition Systems with Silent Steps›
text ‹
We formalize labeled transition systems with silent steps as an extension of ordinary labeled transition systems with a fixed internal action ‹τ›.
›
locale lts_tau =
lts step
for step :: ‹'s ⇒ 'a ⇒ 's ⇒ bool› (‹_ ↦ _ _› [70,70,70] 80) +
fixes τ :: 'a
begin
text ‹
The paper \<^cite>‹bj2023silentStepSpectroscopyArxiv› introduces a transition $p \xrightarrow{(\alpha)}p'$ if $p \xrightarrow{\alpha} p'$, or if $\alpha = \tau$ and $p = p'$.
We define \<^term>‹soft_step› analogously and provide the notation ‹p ↦a α p'›.
›
abbreviation soft_step (‹_ ↦a _ _› [70,70,70] 80) where
‹p ↦a α q ≡ p ↦α q ∨ (α = τ ∧ p = q)›
inductive silent_reachable :: ‹'s ⇒ 's ⇒ bool› (infix ‹↠› 80)
where
refl: ‹p ↠ p› |
step: ‹p ↠ p''› if ‹p ↦ τ p'› and ‹p' ↠ p''›
text ‹If ‹p'› is silent-reachable from ‹p› and there is a ‹τ›-transition from ‹p'› to ‹p''› then ‹p''› is silent reachable from ‹p›.›
lemma silent_reachable_append_τ: ‹p ↠ p' ⟹ p' ↦ τ p'' ⟹ p ↠ p''›
proof (induct rule: silent_reachable.induct)
case (refl p)
then show ?case using silent_reachable.intros by blast
next
case (step p p' p'')
then show ?case using silent_reachable.intros by blast
qed
text ‹The relation \<^term>‹silent_reachable› is transitive.›
lemma silent_reachable_trans:
assumes
‹p ↠ p'›
‹p' ↠ p''›
shows
‹p ↠ p''›
using assms silent_reachable.intros(2)
by (induct, blast+)
text ‹The relation ‹silent_reachable_loopless› is a variation of \<^term>‹silent_reachable› that does not use self-loops.›
inductive silent_reachable_loopless :: ‹'s ⇒ 's ⇒ bool› (infix ‹↠L› 80)
where
‹p ↠L p› |
‹p ↠L p''› if ‹p ↦ τ p'› and ‹p' ↠L p''› and ‹p ≠ p'›
text ‹If a state ‹p'› is \<^term>‹silent_reachable› from ‹p› it is also \<^term>‹silent_reachable_loopless›.›
lemma silent_reachable_impl_loopless:
assumes ‹p ↠ p'›
shows ‹p ↠L p'›
using assms
proof(induct rule: silent_reachable.induct)
case (refl p)
thus ?case by (rule silent_reachable_loopless.intros(1))
next
case (step p p' p'')
thus ?case proof(cases ‹p = p'›)
case True
thus ?thesis using step.hyps(3) by auto
next
case False
thus ?thesis using step.hyps silent_reachable_loopless.intros(2) by blast
qed
qed
lemma tau_chain_reachabilty:
assumes ‹∀i < length pp - 1. pp!i ↦ τ pp!(Suc i)›
shows ‹∀j < length pp. ∀i ≤ j. pp!i ↠ pp!j›
proof safe
fix j i
assume ‹j < length pp› ‹i ≤ j›
thus ‹pp!i ↠ pp!j›
proof (induct j)
case 0
then show ?case
using silent_reachable.refl by blast
next
case (Suc j)
then show ?case
proof (induct i)
case 0
then show ?case using assms silent_reachable_append_τ
by (metis Suc_lessD Suc_lessE bot_nat_0.extremum diff_Suc_1)
next
case (Suc i)
then show ?case using silent_reachable.refl assms silent_reachable_append_τ
by (metis Suc_lessD Suc_lessE diff_Suc_1 le_SucE)
qed
qed
qed
text ‹A state ‹p› can reach ‹p'› weakly by performing an ‹α›-transition, possibly proceeded and followed by any number of ‹τ›-transitions.›
definition weak_step (‹_ ↠↦↠ _ _› [70, 70, 70] 80) where
‹p ↠↦↠ α p' ≡ if α = τ
then p ↠ p'
else ∃p1 p2. p ↠ p1 ∧ p1 ↦ α p2 ∧ p2 ↠ p'›
lemma silent_prepend_weak_step: ‹p ↠ p' ⟹ p' ↠↦↠ α p'' ⟹ p ↠↦↠ α p''›
unfolding weak_step_def using silent_reachable_trans[of p p'] by fastforce
text ‹A sequence of \<^term>‹weak_step›s from one state ‹p› to another ‹p'›.›
inductive weak_step_sequence :: ‹'s ⇒ 'a list ⇒ 's ⇒ bool› (‹_ ↠↦↠$ _ _› [70,70,70] 80) where
‹p ↠↦↠$ [] p'› if ‹p ↠ p'› |
‹p ↠↦↠$ (α#rt) p''› if ‹p ↠↦↠ α p'› ‹p' ↠↦↠$ rt p''›
lemma weak_step_sequence_trans:
assumes ‹p ↠↦↠$ tr_1 p'› and ‹p' ↠↦↠$ tr_2 p''›
shows ‹p ↠↦↠$ (tr_1 @ tr_2) p''›
using assms weak_step_sequence.intros(2)
proof induct
case (1 p p')
then show ?case
by (metis weak_step_sequence.simps append_Nil silent_prepend_weak_step silent_reachable_trans)
next
case (2 p α p' rt p'')
then show ?case by fastforce
qed
text ‹The weak traces of a state are all possible sequences of weak transitions that can be performed.›
abbreviation weak_traces :: ‹'s ⇒ 'a list set›
where ‹weak_traces p ≡ {tr. ∃p'. p ↠↦↠$ tr p'}›
text ‹The empty trace is in \<^term>‹weak_traces› for all states.›
lemma empty_trace_allways_weak_trace:
shows ‹[] ∈ weak_traces p›
using silent_reachable.intros(1) weak_step_sequence.intros(1) by fastforce
text ‹‹τ› can be prepended to any weak trace.›
lemma prepend_τ_weak_trace:
assumes ‹tr ∈ weak_traces p›
shows ‹(τ # tr) ∈ weak_traces p›
using assms silent_reachable.intros(1) mem_Collect_eq
weak_step_sequence.intros(2) weak_step_def by fastforce
lemma silent_prepend_weak_traces:
assumes
‹p ↠ p'›
‹tr ∈ weak_traces p'›
shows
‹tr ∈ weak_traces p›
using assms
proof -
assume ‹p ↠ p'›
and ‹tr ∈ weak_traces p'›
hence ‹∃p''. p' ↠↦↠$ tr p''› by auto
then obtain p'' where ‹p' ↠↦↠$ tr p''› by auto
from ‹p' ↠↦↠$ tr p''›
and ‹p ↠ p'›
have ‹p ↠↦↠$ tr p''›
by (metis append_self_conv2 weak_step_sequence.intros(1) weak_step_sequence_trans)
hence ‹∃p''. p ↠↦↠$ tr p''› by auto
then show ‹tr ∈ weak_traces p›
by blast
qed
text ‹If there is an ‹α›-transition from ‹p› to ‹p'›, and ‹p'› has a weak trace ‹tr›, then the sequence ‹(α # tr)› is a valid (weak) trace of ‹p›.›
lemma step_prepend_weak_traces:
assumes
‹p ↦ α p'›
‹tr ∈ weak_traces p'›
shows
‹(α # tr) ∈ weak_traces p›
using assms
proof -
from ‹tr ∈ weak_traces p'›
have ‹∃p''. p' ↠↦↠$ tr p''› by auto
then obtain p'' where ‹p' ↠↦↠$ tr p''› by auto
with ‹p ↦ α p'›
have ‹p ↠↦↠$ (α # tr) p''›
by (metis lts_tau.silent_reachable.intros(1) lts_tau.silent_reachable_append_τ
lts_tau.weak_step_def lts_tau.weak_step_sequence.intros(2))
then have ‹∃p''. p ↠↦↠$ (α # tr) p''› by auto
then show ‹(α # tr) ∈ weak_traces p› by auto
qed
text ‹A state is weakly trace pre-ordered to another other, ‹weakly_trace_preordered›
denoted by ‹≲WT› if all its traces can also be observed from the second process.›
definition weakly_trace_preordered (infix ‹≲WT› 60) where
‹p ≲WT q ≡ weak_traces p ⊆ weak_traces q›
definition weakly_trace_equivalent (infix ‹≃WT› 60) where
‹p ≃WT q ≡ p ≲WT q ∧ q ≲WT p›
text ‹Just like \<^term>‹step_setp›, one can lift \<^term>‹silent_reachable› to sets of states.›
abbreviation silent_reachable_setp (infix ‹↠S› 80) where
‹P ↠S P' ≡ ((∀p' ∈ P'. ∃p ∈ P. p ↠ p') ∧ (∀p ∈ P. ∀p'. p ↠ p' ⟶ p' ∈ P'))›
definition silent_reachable_set :: ‹'s set ⇒ 's set› where
‹silent_reachable_set P ≡ { q . ∃p ∈ P. p ↠ q }›
lemma sreachable_set_is_sreachable: ‹P ↠S (silent_reachable_set P)›
using silent_reachable_set_def by auto
lemma sreachable_set_eq:
assumes ‹P ↠S Q›
shows ‹Q = silent_reachable_set P›
using sreachable_set_is_sreachable assms by fastforce
text ‹We likewise lift \<^term>‹soft_step› to sets of states.›
abbreviation soft_step_setp (‹_ ↦aS _ _› [70,70,70] 80) where
‹P ↦aS α Q ≡ (∀q ∈ Q. ∃p ∈ P. p ↦a α q) ∧ (∀p ∈ P. ∀q. p ↦a α q ⟶ q ∈ Q)›
definition soft_step_set :: ‹'s set ⇒ 'a ⇒ 's set› where
‹soft_step_set P α ≡ { q . ∃p ∈ P. p ↦a α q }›
lemma soft_step_set_is_soft_step_set:
‹P ↦aS α (soft_step_set P α)›
using soft_step_set_def by auto
lemma exactly_one_soft_step_set:
‹∃!Q. P ↦aS α Q›
proof -
from soft_step_set_is_soft_step_set
have ‹P ↦aS α (soft_step_set P α)›
and ‹⋀Q. P ↦aS α Q ⟹ Q = (soft_step_set P α)›
by fastforce+
show ‹∃!Q. P ↦aS α Q›
proof
from ‹P ↦aS α (soft_step_set P α)›
show ‹P ↦aS α (soft_step_set P α)› .
next
from ‹⋀Q. P ↦aS α Q ⟹ Q = (soft_step_set P α)›
show ‹⋀Q. P ↦aS α Q ⟹ Q = (soft_step_set P α)› .
qed
qed
lemma soft_step_set_eq:
assumes ‹P ↦aS α Q›
shows ‹Q = soft_step_set P α›
using exactly_one_soft_step_set soft_step_set_is_soft_step_set assms
by fastforce
text ‹A state is stable if it cannot make any further internal steps.›
abbreviation ‹stable_state p ≡ ∀p'. ¬(p ↦ τ p')›
lemma stable_state_stable:
assumes ‹stable_state p› ‹p ↠ p'›
shows ‹p = p'›
using assms(2,1) by (cases, blast+)
definition stability_respecting :: ‹('s ⇒ 's ⇒ bool) ⇒ bool› where
‹stability_respecting R ≡ ∀ p q. R p q ∧ stable_state p ⟶
(∃q'. q ↠ q' ∧ R p q' ∧ stable_state q')›
end
end