Theory Diagram
section ‹Predicate Transformers Semantics of Invariant Diagrams›
theory Diagram
imports Hoare
begin
text ‹
This theory introduces the concept of a transition diagram and proves
a number of Hoare total corectness rules for these diagrams. As before
the diagrams are introduced using their predicate transformer semantics.
A transition diagram $D$ is a function from pairs of indexes to predicate
transformers: $D:I\times I \to (\mathit{State}\ \mathit{set}\to \mathit{State}\ \mathit{set})$, or more
general $D:I\times I \to \mathit{Ptran}$, where $\mathit{Ptran}$ is a complete lattice. The elements
of $I$ are called situations and intuitively a diagram is executed starting
in a situation $i\in I$ by choosing a transition $D (i,j)$ which is enabled
and continuing similarly from $j$ if there are enabled trasitions. The
execution of a diagram stops when there are no more transitions enabled or
when it fails.
The semantics of a transition diagram is an indexed predicate transformer
($I\to \mathit{State}\ \mathit{set}$).
If $Q:I\to \mathit{State}\ \mathit{set}$ is an indexed predicate, then $p = \mathit{pt}\ D\ Q\ i$ is a
weakest predicate such that if the executution of $D$ starts in a state
$s\in p$ from situation $i$, then it terminates, and if it terminates
in situation $j$ and state $s'$, then $s'\in Q \ j$.
We introduce first the indexed predicate transformer $\mathit{step}\ D$ of executing
one step of diagram $D$. The predicate $step\ D\ Q\ i$ is true for those
states $s$ from which the execution of one step of $D$ starting in situation
$i$ ends in one of the situations $j$ such that $Q \, j$ is true.
›
definition
"step D Q i = (INF j . D (i, j) (Q j) :: _ :: complete_lattice)"
definition
"dmono D = (∀ ij . mono (D ij))"
lemma dmono_mono [simp]: "dmono D ⟹ mono (D ij)"
by (simp add: dmono_def)
theorem mono_step [simp]:
"dmono D ⟹ mono (step D)"
apply (simp add: dmono_def mono_def le_fun_def step_def Inf_fun_def)
apply auto
apply (rule INF_greatest)
apply auto
apply (rule_tac y = "D(xa, j) (x j)" in order_trans)
apply auto
apply (rule INF_lower)
by auto
text ‹
The indexed predicate transformer of a transition diagram is defined as the least
fixpoint of the unfolding of the execution of the diagram. The indexed predicate
transformer $dgr\ D\ U$ is the choice between executing one step of $D$ follwed by
$U$ ($(\mathit{step}\ D)\circ U$) or skip if no transion of $D$ is enabled
($\mathit{assume}\ \neg \mathit{grd} (\mathit{step}\ D)$).
›
definition
"dgr D U = ((step D) o U) ⊓ [.-(grd (step D)).]"
theorem mono_mono_dgr [simp]: "dmono D ⟹ mono_mono (dgr D)"
apply (simp add: mono_mono_def mono_def)
apply safe
apply (simp_all add: dgr_def)
apply (simp_all add: le_fun_def inf_fun_def)
apply safe
apply (rule_tac y = "(step D (x xa) xb)" in order_trans)
apply simp_all
apply (case_tac "mono (step D)")
apply (simp add: mono_def)
apply (simp add: le_fun_def)
apply simp
apply (rule_tac y = "(step D (f x) xa)" in order_trans)
apply simp_all
apply (case_tac "mono (step D)")
apply (simp add: mono_def)
apply (simp_all add: le_fun_def)
apply (rule_tac y = "(assume (- grd (step D)) x xa)" in order_trans)
apply simp_all
apply (case_tac "mono (assume (- grd (step D)))")
apply (simp add: mono_def le_fun_def)
by simp
definition
"pt D = lfp (dgr D)"
text ‹
If $U$ is an indexed predicate transformer and if $P, Q:I\to \mathit{State} \ \mathit{set}$
are indexed predicates, then the meaning of the Hoare triple defined earlier,
$\models P \{ | U | \} Q$, is that if
we start $U$ in a state $s$ from a situation $i$ such that $s\in P\, i$,
then U terminates, and if it terminates in $s'$ and situation $j$, then
$s'\in Q\ j$ is true.
Next theorem shows that in a diagram all transitions are correct
if and only if $\mathit{step}\ D$ is correct.
›
theorem hoare_step:
"(∀ i j . ⊨ (P i) {| D(i,j) |} (Q j) ) = (⊨ P {| step D |} Q)"
apply safe
apply (simp add: le_fun_def Hoare_def step_def)
apply safe
apply (rule INF_greatest)
apply auto
apply (simp add: le_fun_def Hoare_def step_def)
apply (erule_tac x = i in allE)
apply (rule_tac y = "INF j. D(i, j) (Q j)" in order_trans)
apply auto
apply (rule INF_lower)
by auto
text ‹
Next theorem provides the first proof rule for total correctnes of transition
diagrams. If all transitions are correct and if a global variant decreases
on every transition then the diagram is correct and it terminates. The variant
must decrease according to a well founded and transitive relation.
›
theorem hoare_diagram:
"dmono D ⟹ (∀ w i j . ⊨ X w i {| D(i,j) |} Sup_less X w j) ⟹
⊨ (Sup (range X)) {| pt D |} (Sup(range X) ⊓ -(grd (step D)))"
apply (simp add: hoare_step pt_def)
apply (rule hoare_fixpoint)
apply auto
apply (simp add: dgr_def)
apply (simp add: hoare_choice)
apply safe
apply (simp add: hoare_sequential)
apply auto
apply (simp add: hoare_assume)
apply (rule le_infI1)
by (rule SUP_upper, auto)
text‹
This theorem is a more general form of the more familiar form with a variant $t$
which must decrease. If we take $X\ w\ i = (Y \ i \land t\ i = w)$, then the
second hypothesis of the theorem above becomes
$\models Y \ i \land t\ i = w \{| D(i,j) |\} Y \ i \land t \ i < w$. However,
the more general form of the theorem is needed, because
in data refinements, the form $Y\ i \land t\ i = w$ cannot be preserved.
›
text ‹
The drawback of this theorem is that the variant must be decreased on every
transitions which may be too cumbersome for practical applications. A similar
situation occur when introducing proof rules for mutually recursive procedures.
There the straightforward generalization of the proof rule of a recursive procedure
to mutually recursive procedures suffers of a similar problem. We would need
to prove that the variant decreases before every recursive call. Nipkow
\<^cite>‹"nipkow:2002"› has introduced a rule for mutually recursive procedures
in which the variant is required to decrease only in a sequence of recursive
calls before calling again a procedure in this sequence. We introduce a
similar proof rule in which the variant depends also on the situation
indexes.
›
locale DiagramTermination =
fixes pair:: "'a ⇒ 'b ⇒ ('c::well_founded_transitive)"
begin
definition
"SUP_L_P X u i = (SUP v∈{v. pair v i < u}. X v i :: _ :: complete_lattice)"
definition
"SUP_LE_P X u i = (SUP v∈{v. pair v i ≤ u}. X v i :: _ :: complete_lattice)"
lemma SUP_L_P_upper:
"pair v i < u ⟹ P v i ≤ SUP_L_P P u i"
by (auto simp add: SUP_L_P_def intro: SUP_upper)
lemma SUP_L_P_least:
"(!! v . pair v i < u ⟹ P v i ≤ Q) ⟹ SUP_L_P P u i ≤ Q"
by (simp add: SUP_L_P_def, rule SUP_least, auto)
lemma SUP_LE_P_upper:
"pair v i ≤ u ⟹ P v i ≤ SUP_LE_P P u i"
by (auto simp add: SUP_LE_P_def intro: SUP_upper)
lemma SUP_LE_P_least:
"(!! v . pair v i ≤ u ⟹ P v i ≤ Q) ⟹ SUP_LE_P P u i ≤ Q"
by (simp add: SUP_LE_P_def, rule SUP_least, auto)
lemma SUP_SUP_L [simp]: "Sup (range (SUP_LE_P X)) = Sup (range X)"
apply (simp add: fun_eq_iff Sup_fun_def image_comp, clarify)
apply (rule antisym)
apply (rule SUP_least)
apply (rule SUP_LE_P_least)
apply (rule SUP_upper, simp)
apply (rule SUP_least)
apply (rule_tac y = "SUP_LE_P X (pair xa x) x" in order_trans)
apply (rule SUP_LE_P_upper, simp)
by (rule SUP_upper, simp)
lemma SUP_L_SUP_LE_P [simp]: "Sup_less (SUP_LE_P X) = SUP_L_P X"
apply (rule antisym)
apply (subst le_fun_def, safe)
apply (rule Sup_less_least)
apply (subst le_fun_def, safe)
apply (rule SUP_LE_P_least)
apply (rule SUP_L_P_upper, simp)
apply (simp add: le_fun_def, safe)
apply (rule SUP_L_P_least)
apply (rule_tac y = "SUP_LE_P X (pair v xa) xa" in order_trans)
apply (rule SUP_LE_P_upper, simp)
apply (cut_tac P = "SUP_LE_P X" in Sup_less_upper)
by (simp, simp add: le_fun_def)
end
theorem (in DiagramTermination) hoare_diagram2:
"dmono D ⟹ (∀ u i j . ⊨ X u i {| D(i, j) |} SUP_L_P X (pair u i) j) ⟹
⊨ (Sup (range X)) {| pt D |} ((Sup (range X)) ⊓ (-(grd (step D))))"
apply (frule_tac X = "SUP_LE_P X" in hoare_diagram)
apply auto
apply (simp add: SUP_LE_P_def)
apply (unfold hoare_Sup [THEN sym])
apply auto
apply (rule_tac Q = "SUP_L_P X (pair p i) j" in hoare_mono)
apply auto
apply (rule SUP_L_P_least)
apply (rule SUP_L_P_upper)
apply (rule order_trans3)
by auto
lemma mono_pt [simp]: "dmono D ⟹ mono (pt D)"
apply (drule mono_mono_dgr)
by (simp add: pt_def)
theorem (in DiagramTermination) hoare_diagram3:
"dmono D ⟹
(∀ u i j . ⊨ X u i {| D(i, j) |} SUP_L_P X (pair u i) j) ⟹
P ≤ Sup (range X) ⟹ ((Sup (range X)) ⊓ (-(grd (step D)))) ≤ Q ⟹
⊨ P {| pt D |} Q"
apply (rule hoare_mono)
apply auto
apply (rule hoare_pre)
apply auto
apply (rule hoare_diagram2)
by auto
text‹
The following definition introduces the concept of correct Hoare triples for diagrams.
›
definition (in DiagramTermination)
Hoare_dgr :: "('b ⇒ ('u::{complete_distrib_lattice, boolean_algebra})) ⇒ ('b × 'b ⇒ 'u ⇒ 'u) ⇒ ('b ⇒ 'u) ⇒ bool" ("⊢ (_){| _ |}(_) "
[0,0,900] 900) where
"⊢ P {| D |} Q ≡ (∃ X . (∀ u i j . ⊨ X u i {| D(i, j) |} SUP_L_P X (pair u i) j) ∧
P = Sup (range X) ∧ Q = ((Sup (range X)) ⊓ (-(grd (step D)))))"
definition (in DiagramTermination)
Hoare_dgr1 :: "('b ⇒ ('u::{complete_distrib_lattice, boolean_algebra})) ⇒ ('b × 'b ⇒ 'u ⇒ 'u) ⇒ ('b ⇒ 'u) ⇒ bool" ("⊢1 (_){| _ |}(_) "
[0,0,900] 900) where
"⊢1 P {| D |} Q ≡ (∃ X . (∀ u i j . ⊨ X u i {| D(i, j) |} SUP_L_P X (pair u i) j) ∧
P ≤ Sup (range X) ∧ ((Sup (range X)) ⊓ (-(grd (step D)))) ≤ Q)"
theorem (in DiagramTermination) hoare_dgr_correctness:
"dmono D ⟹ (⊢ P {| D |} Q) ⟹ (⊨ P {| pt D |} Q)"
apply (simp add: Hoare_dgr_def)
apply safe
apply (rule hoare_diagram3)
by auto
theorem (in DiagramTermination) hoare_dgr_correctness1:
"dmono D ⟹ (⊢1 P {| D |} Q) ⟹ (⊨ P {| pt D |} Q)"
apply (simp add: Hoare_dgr1_def)
apply safe
apply (rule hoare_diagram3)
by auto
definition
"dgr_demonic Q ij = [:Q ij:]"
theorem dgr_demonic_mono[simp]:
"dmono (dgr_demonic Q)"
by (simp add: dmono_def dgr_demonic_def)
definition
"dangelic R Q i = angelic (R i) (Q i)"
lemma grd_dgr:
"((grd (step D) i)::('a::complete_boolean_algebra)) = ⨆ {P . ∃ j . P = grd (D(i,j))}"
apply (simp add: grd_def step_def)
apply (unfold step_def uminus_Inf)
apply (case_tac "(uminus ` range (λj::'b. D (i, j) ⊥)) = {P::'a. ∃j::'b. P = - D (i, j) ⊥}")
apply (auto cong del: SUP_cong_simp)
done
lemma grd_dgr_set:
"((grd (step D) i)::('a set)) = Union {P . ∃ j . P = grd (D(i,j))}"
by (simp add: grd_dgr)
lemma not_grd_dgr [simp]: "(a ∈ (- grd (step D) i)) = (∀ j . a ∉ grd (D(i,j)))"
apply (simp add: grd_dgr)
by auto
lemma not_grd_dgr2 [simp]: "a ∉ (grd (step D) i) = (∀ j . a ∉ grd (D(i,j)))"
apply (subst not_grd_dgr [THEN sym])
by simp
end