(* Title: A Definitional Encoding of TLA in Isabelle/HOL Authors:GudmundGrov<ggrovatinf.ed.ac.uk> StephanMerz<Stephan.Merzatloria.fr> Year:2011 Maintainer:GudmundGrov<ggrovatinf.ed.ac.uk>
*)
section‹Semantics›
theory Semantics imports Sequence Intensional begin
text‹
This theory mechanises a \emph{shallow} embedding of \tlastar{} using the ‹Sequence› and ‹Intensional› theories. A shallow embedding
represents \tlastar{} using Isabelle/HOL predicates, while a \emph{deep}
embedding would represent \tlastar{} formulas and pre-formulas as mutually
inductive datatypes\footnote{See e.g. cite‹"Wildmoser04"› for a discussion
about deep vs. shallow embeddings in Isabelle/HOL.}.
The choice of a shallow over a deep embedding is motivated by the following
factors: a shallow embedding is usually less involved, and existing Isabelle
theories and tools can be applied more directly to enhance automation; due to
the lifting in the ‹Intensional› theory, a shallow embedding can reuse
standard logical operators, whilst a deep embedding requires a different
set of operators for both formulas and pre-formulas. Finally, since our
target is system verification rather than proving meta-properties of \tlastar{},
which requires a deep embedding, a shallow embedding is more fit for purpose. ›
subsection"Types of Formulas"
text‹
To mechanise the \tlastar{} semantics, the following
type abbreviations are used: ›
type_synonym ('a,'b) formfun = "'a seq ==> 'b" type_synonym 'a formula = "('a,bool) formfun" type_synonym ('a,'b) stfun = "'a ==> 'b" type_synonym 'a stpred = "('a,bool) stfun"
instance "fun" :: (type,type) world ..
instance "prod" :: (type,type) world ..
text‹
Pair and function are instantiated to be of type class world.
This allows use of the lifted intensional logic for formulas, and
standard logical connectives can therefore be used. ›
subsection"Semantics of TLA*"
text‹The semantics of \tlastar{} is defined.›
definition always :: "('a::world) formula ==> 'a formula" where"always F ≡ λ s. ∀ n. (s |s n) ⊨ F"
definition nexts :: "('a::world) formula ==> 'a formula" where"nexts F ≡ λ s. (tail s) ⊨ F"
definition before :: "('a::world,'b) stfun ==> ('a,'b) formfun" where"before f ≡ λ s. (first s) ⊨ f"
definition after :: "('a::world,'b) stfun ==> ('a,'b) formfun" where"after f ≡ λ s. (second s) ⊨ f"
definition unch :: "('a::world,'b) stfun ==> 'a formula" where"unch v ≡ λ s. s ⊨ (after v) = (before v)"
definition action :: "('a::world) formula ==> ('a,'b) stfun ==> 'a formula" where"action P v ≡ λ s. ∀ i. ((s |s i) ⊨ P) ∨ ((s |s i) ⊨ unch v)"
subsubsection"Concrete Syntax"
text‹This is the concrete syntax for the (abstract) operators above.›
lemma linalw: assumes h1: "a ≤ b"and h2: "(w |s a) ⊨◻A" shows"(w |s b) ⊨◻A" proof (clarsimp simp: always_def) fix n from h1 obtain k where g1: "b = a + k"by (auto simp: le_iff_add) with h2 show"(w |s b |s n) ⊨ A"by (auto simp: always_def suffix_plus ac_simps) qed
subsection"Invariance Under Stuttering"
text‹
A key feature of \tlastar{} is that specification at different abstraction
levels can be compared. The soundness of this relies on the stuttering invariance
of formulas. Since the embedding is shallow, it cannot be shown that a generic \tlastar{} formula is stuttering invariant. However, this section will show that
each operator is stuttering invariant or preserves stuttering invariance in an
appropriate sense, which can be used to show stuttering invariance
for given specifications.
Formula ‹F› is stuttering invariant if for any two similar behaviours
(i.e., sequences of states), ‹F› holds in one iff it holds in the other.
The definition is generalised to arbitrary expressions, and not just predicates. ›
text‹
The requirement for stuttering invariance is too strong for pre-formulas.
For example, an action formula specifies a relation between the first two states
of a behaviour, and will rarely be satisfied by a stuttering step. This is why
pre-formulas are ``protected'' by (square or angle) brackets in \tlastar{}:
the only place a pre-formula ‹P› can be used is inside an action: ‹◻[P]_v›.
To show that ‹◻[P]_v› is stuttering invariant, is must be shown that a
slightly weaker predicate holds for @{term P}. For example, if @{term P} contains
a term of the form ‹◯◯Q›, then it is not a well-formed pre-formula, thus ‹◻[P]_v› is not stuttering invariant. This weaker version of
stuttering invariance has been named \emph{near stuttering invariance}. ›
text‹
Predicate @{term "stutinv F"} formalises stuttering invariance for
formula @{term F}. That is if two sequences are similar @{term "s ≈ t"} (equal up
to stuttering) then the validity of @{term F} under both @{term s} and @{term t}
are equivalent. Predicate @{term "nstutinv P"} should be read as \emph{nearly
stuttering invariant} -- and is required for some stuttering invariance proofs. ›
lemma stutinv_strictly_stronger: assumes h: "STUTINV F"shows"NSTUTINV F" unfolding nstutinv_def proof (clarify) fix s t :: "nat ==> 'a" assume a1: "first s = first t"and a2: "(tail s) ≈ (tail t)" have"s ≈ t" proof - have tg1: "(first s) ## (tail s) = s"by (rule seq_app_first_tail) have tg2: "(first t) ## (tail t) = t"by (rule seq_app_first_tail) with a1 have tg2': "(first s) ## (tail t) = t"by simp from a2 have"(first s) ## (tail s) ≈ (first s) ## (tail t)"by (rule app_seqsimilar) with tg1 tg2' show ?thesis by simp qed with h show"(s ⊨ F) = (t ⊨ F)"by (simp add: stutinv_def) qed
subsubsection"Properties of @{term stutinv}"
text‹
This subsection proves stuttering invariance, preservation of stuttering invariance
and introduction of stuttering invariance for different formulas.
First, state predicates are stuttering invariant. ›
theorem stut_always: assumes H:"STUTINV F"shows"STUTINV ◻F" proof (clarsimp simp: stutinv_def) fix s t :: "'a seq" assume a2: "s ≈ t" show"(s ⊨ (◻ F)) = (t ⊨ (◻ F))" proof assume a1: "t ⊨◻ F" show"s ⊨◻ F" proof (clarsimp simp: always_def) fix n from a2[THEN sim_step] obtain m where m: "s |s n ≈ t |s m"by blast from a1 have"(t |s m) ⊨ F"by (simp add: always_def) with H m show"(s |s n) ⊨ F"by (simp add: stutinv_def) qed next assume a1: "s ⊨ (◻ F)" show"t ⊨ (◻ F)" proof (clarsimp simp: always_def) fix n from a2[THEN seqsim_sym, THEN sim_step] obtain m where m: "t |s n ≈ s |s m"by blast from a1 have"(s |s m) ⊨ F"by (simp add: always_def) with H m show"(t |s n) ⊨ F"by (simp add: stutinv_def) qed qed qed
text‹
Assuming that formula @{term P} is nearly suttering invariant
then ‹◻[P]_v› will be stuttering invariant. ›
lemma stut_action_lemma: assumes H: "NSTUTINV P"and st: "s ≈ t"and P: "t ⊨◻[P]_v" shows"s ⊨◻[P]_v" proof (clarsimp simp: action_def) fix n assume"¬ ((s |s n) ⊨ Unchanged v)" hence v: "v (s (Suc n)) ≠ v (s n)" by (simp add: unch_defs first_def second_def suffix_def) from st[THEN sim_step] obtain m where
a2': "s |s n ≈ t |s m ∧ (s |s Suc n ≈ t |s Suc m ∨ s |s Suc n ≈ t |s m)" .. hence g1: "(s |s n ≈ t |s m)"by simp hence g1'': "first (s |s n) = first (t |s m)"by (simp add: sim_first) hence g1': "s n = t m"by (simp add: suffix_def first_def) from a2' have g2: "s |s Suc n ≈ t |s Suc m ∨ s |s Suc n ≈ t |s m"by simp from P have a1': "((t |s m) ⊨ P) ∨ ((t |s m) ⊨ Unchanged v)"by (simp add: action_def) from g2 show"(s |s n) ⊨ P" proof assume"s |s Suc n ≈ t |s m" hence"first (s |s Suc n) = first (t |s m)"by (simp add: sim_first) hence"s (Suc n) = t m"by (simp add: suffix_def first_def) with g1' v show ?thesis by simp ― ‹by contradiction› next assume a3: "s |s Suc n ≈ t |s Suc m" hence"first (s |s Suc n) = first (t |s Suc m)"by (simp add: sim_first) hence a3': "s (Suc n) = t (Suc m)"by (simp add: suffix_def first_def) from a1' show ?thesis proof assume"(t |s m) ⊨ Unchanged v" hence"v (t (Suc m)) = v (t m)" by (simp add: unch_defs first_def second_def suffix_def) with g1' a3' v show ?thesis by simp ― ‹again, by contradiction› next assume a4: "(t |s m) ⊨ P" from a3 have"tail (s |s n) ≈ tail (t |s m)"by (simp add: tail_def suffix_plus) with H g1'' a4 show ?thesis by (auto simp: nstutinv_def) qed qed qed
theorem stut_action: assumes H: "NSTUTINV P"shows"STUTINV ◻[P]_v" proof (clarsimp simp: stutinv_def) fix s t :: "'a seq" assume st: "s ≈ t" show"(s ⊨◻[P]_v) = (t ⊨◻[P]_v)" proof assume"t ⊨◻[P]_v" with H st show"s ⊨◻[P]_v"by (rule stut_action_lemma) next assume"s ⊨◻[P]_v" with H st[THEN seqsim_sym] show"t ⊨◻[P]_v"by (rule stut_action_lemma) qed qed
text‹
The lemmas below shows that propositional and predicate operators
preserve stuttering invariance. ›
lemma nstut_unch: "NSTUTINV (Unchanged v)" proof (unfold unch_def) have g1: "NSTUTINV v$"by (rule nstut_after) have"NSTUTINV $v"by (rule stut_before[THEN stutinv_strictly_stronger]) with g1 show"NSTUTINV (v$ = $v)"by (rule nstut_eq) qed
text‹
Formulas ‹[P]_v› are not \tlastar{} formulas by themselves,
but we need to reason about them when they appear wrapped
inside ‹◻[-]_v›. We only require that it preserves nearly
stuttering invariance. Observe that ‹[P]_v› trivially holds for
a stuttering step, so it cannot be stuttering invariant. ›
lemma nstut_actrans: "NSTUTINV P ==> NSTUTINV [P]_v" by (simp add: actrans_def nstut_unch nstut_or)
lemma stut_eventually: "STUTINV F ==> STUTINV ♢F" by (simp add: eventually_def stut_not stut_always)
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.