(*
* Copyright 2016 , Data61 , CSIRO
*
* This software may be distributed and modified according to the terms of
* the BSD 2 - Clause license . Note that NO WARRANTY is provided .
* See " LICENSE_BSD2 . txt " for details .
*
* @ TAG ( DATA61_BSD )
*)
section ‹ COMPLX small-step semantics›
theory SmallStep
imports Language
begin
text ‹ The procedure environment›
type_synonym ('s,'p,'f) body = "'p ==> ('s,'p,'f) com option"
text ‹ State types›
datatype ('s,'f) xstate = Normal 's | Fault 'f | Stuck
lemma rtrancl_mono_proof[mono]:
"(∧ a b. x a b ⟶ y a b) ==> rtranclp x a b ⟶ rtranclp y a b"
apply (rule impI, rotate_tac, induct rule: rtranclp.induct)
apply simp_all
apply (metis rtranclp.intros )
done
primrec redex:: "('s,'p,'f)com ==> ('s,'p,'f)com"
where
"redex Skip = Skip" |
"redex (Basic f) = (Basic f)" |
"redex (Spec r) = (Spec r)" |
"redex (Seq c1 c2 ) = redex c1 " |
"redex (Cond b c1 c2 ) = (Cond b c1 c2 )" |
"redex (While b c) = (While b c)" |
"redex (Call p) = (Call p)" |
"redex (DynCom d) = (DynCom d)" |
"redex (Guard f b c) = (Guard f b c)" |
"redex (Throw) = Throw" |
"redex (Catch c1 c2 ) = redex c1 " |
"redex (Await b c) = Await b c" |
"redex (Parallel cs) = Parallel cs"
subsection ‹ Small-Step Computation: ‹ Γ ⊨ (c, s) → (c', s')› ›
text ‹ The final configuration is either of the form ‹ (Skip,_)› for normal
, or @{term "(Throw,Normal s)"} in case the program was started in
@{term "Normal"} state and terminated abruptly. Explicit abrupt states are removed
the language definition and thus do not need to be propogated. ›
type_synonym ('s,'p,'f) config = "('s,'p,'f)com × ('s,'f) xstate"
definition final:: "('s,'p,'f) config ==> bool" where
"final cfg = (fst cfg=Skip ∨ (fst cfg=Throw ∧ (∃ s. snd cfg=Normal s)))"
primrec atom_com :: "🍋 ‹ ('s,'p,'f) body ==> › ('s, 'p, 'f) com ==> bool" where
"atom_com Skip = True" |
"atom_com (Basic f) = True" |
"atom_com (Spec r) = True" |
"atom_com (Seq c1 c2 ) = (atom_com c1 ∧ atom_com c2 )" |
"atom_com (Cond b c1 c2 ) = (atom_com c1 ∧ atom_com c2 )" |
"atom_com (While b c) = atom_com c" |
(* Change to atom_com (Call p) = atom_com (\<Theta> p)
Butow do we pass function body from step? *)
"atom_com (Call p) = False" |
"atom_com (DynCom f) = (∀ s::'s. atom_com (f s))" |
"atom_com (Guard f g c) = atom_com c" |
"atom_com Throw = True" |
"atom_com (Catch c1 c2 ) = (atom_com c1 ∧ atom_com c2 )" |
"atom_com (Parallel cs) = False" |
"atom_com (Await b c) = False"
inductive
"step" ::"[('s,'p,'f) body, ('s,'p,'f) config,('s,'p,'f) config] ==> bool"
(‹ _⊨ (_ → / _)› [81 ,81 ,81 ] 100 )
and "step_rtrancl" :: "[('s,'p,'f) body, ('s,'p,'f) config,('s,'p,'f) config] ==> bool"
(‹ _ ⊨ (_ → * / _)› [81 ,81 ,81 ] 100 )
for Γ::"('s,'p,'f) body"
where
"Γ ⊨ a → * b ≡ (step Γ)* * a b"
| Basic: "Γ ⊨ (Basic f,Normal s) → (Skip,Normal (f s))"
| Spec: "(s,t) ∈ r ==> Γ ⊨ (Spec r,Normal s) → (Skip,Normal t)"
| SpecStuck: "∀ t. (s,t) ∉ r ==> Γ ⊨ (Spec r,Normal s) → (Skip,Stuck)"
| Guard: "s∈ g ==> Γ ⊨ (Guard f g c,Normal s) → (c,Normal s)"
| GuardFault: "s∉ g ==> Γ ⊨ (Guard f g c,Normal s) → (Skip,Fault f)"
| Seq: "Γ ⊨ (c1 ,s) → (c1 ',s')
==>
Γ ⊨ (Seq c1 c2 ,s) → (Seq c1 ' c2 , s')"
| SeqSkip: "Γ ⊨ (Seq Skip c2 ,s) → (c2 , s)"
| SeqThrow: "Γ ⊨ (Seq Throw c2 ,Normal s) → (Throw, Normal s)"
| CondTrue: "s∈ b ==> Γ ⊨ (Cond b c1 c2 ,Normal s) → (c1 ,Normal s)"
| CondFalse: "s∉ b ==> Γ ⊨ (Cond b c1 c2 ,Normal s) → (c2 ,Normal s)"
| WhileTrue: "[ s∈ b]
==>
Γ ⊨ (While b c,Normal s) → (Seq c (While b c),Normal s)"
| WhileFalse: "[ s∉ b]
==>
Γ ⊨ (While b c,Normal s) → (Skip,Normal s)"
| Call: "Γ p=Some b ==>
Γ ⊨ (Call p,Normal s) → (b,Normal s)"
| CallUndefined: "Γ p=None ==>
Γ ⊨ (Call p,Normal s) → (Skip,Stuck)"
| DynCom: "Γ ⊨ (DynCom c,Normal s) → (c s,Normal s)"
| Catch: "[ Γ ⊨ (c1 ,s) → (c1 ',s')]
==>
Γ ⊨ (Catch c1 c2 ,s) → (Catch c1 ' c2 ,s')"
| CatchSkip: "Γ ⊨ (Catch Skip c2 ,s) → (Skip,s)"
| CatchThrow: "Γ ⊨ (Catch Throw c2 ,Normal s) → (c2 ,Normal s)"
| FaultProp: "[ c≠ Skip; redex c = c] ==> Γ ⊨ (c,Fault f) → (Skip,Fault f)"
| StuckProp: "[ c≠ Skip; redex c = c] ==> Γ ⊨ (c,Stuck) → (Skip,Stuck)"
| Parallel: "[ i < length cs; Γ ⊨ (cs!i, s) → (c', s') ]
==> Γ ⊨ (Parallel cs, s) → (Parallel (cs[i := c']), s')"
| ParSkip: "[ ∀ c ∈ set cs. c = Skip ] ==> Γ ⊨ (Parallel cs, s) → (Skip, s)"
(* If exception is thrown, the parallel execution may either abort
immediately (rule ParThrow) or keep executing (rule Parallel) *)
| ParThrow: "[ Throw ∈ set cs ] ==> Γ ⊨ (Parallel cs, s) → (Throw, s)"
| Await: "[ s ∈ b; Γ ⊨ (c, Normal s) → * (c', Normal s');
atom_com c; c' = Skip ∨ c' = Throw ]
==> Γ ⊨ (Await b c, Normal s) → (c', Normal s')"
| AwaitStuck:
"[ s ∈ b; Γ ⊨ (c, Normal s) → * (c', Stuck) ;
atom_com c]
==> Γ ⊨ (Await b c, Normal s) → (Skip, Stuck)"
| AwaitFault:
"[ s ∈ b; Γ ⊨ (c, Normal s) → * (c', Fault f) ;
atom_com c]
==> Γ ⊨ (Await b c, Normal s) → (Skip, Fault f)"
| AwaitNonAtom:
" ¬ atom_com c
==> Γ ⊨ (Await b c, Normal s) → (Skip, Stuck)"
lemmas step_induct = step.induct [of _ "(c,s)" "(c',s')" , split_format (complete), case_names
Basic Spec SpecStuck Guard GuardFault Seq SeqSkip SeqThrow CondTrue CondFalse
WhileTrue WhileFalse Call CallUndefined DynCom Catch CatchThrow CatchSkip
FaultProp StuckProp Parallel ParSkip Await, induct set]
text ‹ The execution of a command is blocked if it cannot make progress, but is not in a final
. It is the intention that ‹ ∃ cfg. Γ ⊨ (c, s) → cfg) ∨ final (c, s) ∨ blocked Γ c s› , but
do not prove this. ›
function (sequential) blocked :: "('s,'p,'f) body ==> ('s,'p,'f) com ==> ('s,'f)xstate ==> bool" where
"blocked Γ (Seq (Await b c1 ) c2 ) (Normal s) = (s ∉ b)"
| "blocked Γ (Catch (Await b c1 ) c2 ) (Normal s) = (s ∉ b)"
| "blocked Γ (Await b c) (Normal s) = (s ∉ b ∨ (∀ c' s'. Γ ⊨ (c, Normal s) → * (c', Normal s') ⟶ ¬ final (c', Normal s')))"
| "blocked Γ (Parallel cs) (Normal s) = (∀ t ∈ set cs. blocked Γ t (Normal s) ∨ final (t, Normal s))"
| "blocked Γ _ _ = False"
by (pat_completeness, auto)
inductive_cases step_elim_cases [cases set]:
"Γ ⊨ (Skip,s) → u"
"Γ ⊨ (Guard f g c,s) → u"
"Γ ⊨ (Basic f,s) → u"
"Γ ⊨ (Spec r,s) → u"
"Γ ⊨ (Seq c1 c2,s) → u"
"Γ ⊨ (Cond b c1 c2,s) → u"
"Γ ⊨ (While b c,s) → u"
"Γ ⊨ (Call p,s) → u"
"Γ ⊨ (DynCom c,s) → u"
"Γ ⊨ (Throw,s) → u"
"Γ ⊨ (Catch c1 c2,s) → u"
"Γ ⊨ (Parallel cs,s) → u"
"Γ ⊨ (Await b e,s) → u"
inductive_cases step_Normal_elim_cases [cases set]:
"Γ ⊨ (Skip,Normal s) → u"
"Γ ⊨ (Guard f g c,Normal s) → u"
"Γ ⊨ (Basic f,Normal s) → u"
"Γ ⊨ (Spec r,Normal s) → u"
"Γ ⊨ (Seq c1 c2,Normal s) → u"
"Γ ⊨ (Cond b c1 c2,Normal s) → u"
"Γ ⊨ (While b c,Normal s) → u"
"Γ ⊨ (Call p,Normal s) → u"
"Γ ⊨ (DynCom c,Normal s) → u"
"Γ ⊨ (Throw,Normal s) → u"
"Γ ⊨ (Catch c1 c2,Normal s) → u"
"Γ ⊨ (Parallel cs,Normal s) → u"
"Γ ⊨ (Await b e,Normal s) → u"
abbreviation
"step_trancl" :: "[('s,'p,'f) body, ('s,'p,'f) config,('s,'p,'f) config] ==> bool"
(‹ _⊨ (_ → + / _)› [81 ,81 ,81 ] 100 )
where
"Γ ⊨ cf0 → + cf1 ≡ (CONST step Γ)+ + cf0 cf1"
abbreviation
"step_n_trancl" :: "[('s,'p,'f) body, ('s,'p,'f) config,nat,('s,'p,'f) config] ==> bool"
(‹ _⊨ (_ → n_ / _)› [81 ,81 ,81 ,81 ] 100 )
where
"Γ ⊨ cf0 → nn cf1 ≡ (CONST step Γ ^^ n) cf0 cf1"
lemma no_step_final:
assumes step: "Γ ⊨ (c,s) → (c',s')"
shows "final (c,s) ==> P"
using step
by induct (auto simp add: final_def)
lemma no_step_final':
assumes step: "Γ ⊨ cfg → cfg'"
shows "final cfg ==> P"
using step
by (cases cfg, cases cfg') (auto intro: no_step_final)
lemma no_steps_final:
"Γ ⊨ v → * w ==> final v ==> w = v"
apply (cases v)
apply simp
apply (erule converse_rtranclpE)
apply simp
apply (erule (1 ) no_step_final')
done
lemma step_Fault:
assumes step: "Γ ⊨ (c, s) → (c', s')"
shows "∧ f. s=Fault f ==> s'=Fault f"
using step
by (induct) auto
lemma step_Stuck:
assumes step: "Γ ⊨ (c, s) → (c', s')"
shows "∧ f. s=Stuck ==> s'=Stuck"
using step
by (induct) auto
lemma SeqSteps:
assumes steps: "Γ ⊨ cfg1 → * cfg2 "
shows "∧ c1 s c1 ' s'. [ cfg1 = (c1 ,s);cfg2 =(c1 ',s')]
==> Γ ⊨ (Seq c1 c2 ,s) → * (Seq c1 ' c2 , s')"
using steps
proof (induct rule: converse_rtranclp_induct [case_names Refl Trans])
case Refl
thus ?case
by simp
next
case (Trans cfg1 cfg'')
have step: "Γ ⊨ cfg1 → cfg''" by fact
have steps: "Γ ⊨ cfg'' → * cfg2 " by fact
have cfg1 : "cfg1 = (c1 , s)" and cfg2 : "cfg2 = (c1 ', s')" by fact+
obtain c1 '' s'' where cfg'': "cfg''=(c1 '',s'')"
by (cases cfg'') auto
from step cfg1 cfg''
have "Γ ⊨ (c1 ,s) → (c1 '',s'')"
by simp
hence "Γ ⊨ (Seq c1 c2 ,s) → (Seq c1 '' c2 ,s'')"
by (rule step.Seq)
also from Trans.hyps (3 ) [OF cfg'' cfg2 ]
have "Γ ⊨ (Seq c1 '' c2 , s'') → * (Seq c1 ' c2 , s')" .
finally show ?case .
qed
lemma CatchSteps:
assumes steps: "Γ ⊨ cfg1 → * cfg2 "
shows "∧ c1 s c1 ' s'. [ cfg1 = (c1 ,s); cfg2 =(c1 ',s')]
==> Γ ⊨ (Catch c1 c2 ,s) → * (Catch c1 ' c2 , s')"
using steps
proof (induct rule: converse_rtranclp_induct [case_names Refl Trans])
case Refl
thus ?case
by simp
next
case (Trans cfg1 cfg'')
have step: "Γ ⊨ cfg1 → cfg''" by fact
have steps: "Γ ⊨ cfg'' → * cfg2 " by fact
have cfg1 : "cfg1 = (c1 , s)" and cfg2 : "cfg2 = (c1 ', s')" by fact+
obtain c1 '' s'' where cfg'': "cfg''=(c1 '',s'')"
by (cases cfg'') auto
from step cfg1 cfg''
have s: "Γ ⊨ (c1 ,s) → (c1 '',s'')"
by simp
hence "Γ ⊨ (Catch c1 c2 ,s) → (Catch c1 '' c2 ,s'')"
by (rule step.Catch)
also from Trans.hyps (3 ) [OF cfg'' cfg2 ]
have "Γ ⊨ (Catch c1 '' c2 , s'') → * (Catch c1 ' c2 , s')" .
finally show ?case .
qed
lemma steps_Fault: "Γ ⊨ (c, Fault f) → * (Skip, Fault f)"
proof (induct c)
case (Seq c1 c2 )
have steps_c1 : "Γ ⊨ (c1 , Fault f) → * (Skip, Fault f)" by fact
have steps_c2 : "Γ ⊨ (c2 , Fault f) → * (Skip, Fault f)" by fact
from SeqSteps [OF steps_c1 refl refl]
have "Γ ⊨ (Seq c1 c2 , Fault f) → * (Seq Skip c2 , Fault f)" .
also
have "Γ ⊨ (Seq Skip c2 , Fault f) → (c2 , Fault f)" by (rule SeqSkip)
also note steps_c2
finally show ?case by simp
next
case (Catch c1 c2 )
have steps_c1 : "Γ ⊨ (c1 , Fault f) → * (Skip, Fault f)" by fact
from CatchSteps [OF steps_c1 refl refl]
have "Γ ⊨ (Catch c1 c2 , Fault f) → * (Catch Skip c2 , Fault f)" .
also
have "Γ ⊨ (Catch Skip c2 , Fault f) → (Skip, Fault f)" by (rule CatchSkip)
finally show ?case by simp
qed (fastforce intro: step.intros )+
lemma steps_Stuck: "Γ ⊨ (c, Stuck) → * (Skip, Stuck)"
proof (induct c)
case (Seq c1 c2 )
have steps_c1 : "Γ ⊨ (c1 , Stuck) → * (Skip, Stuck)" by fact
have steps_c2 : "Γ ⊨ (c2 , Stuck) → * (Skip, Stuck)" by fact
from SeqSteps [OF steps_c1 refl refl]
have "Γ ⊨ (Seq c1 c2 , Stuck) → * (Seq Skip c2 , Stuck)" .
also
have "Γ ⊨ (Seq Skip c2 , Stuck) → (c2 , Stuck)" by (rule SeqSkip)
also note steps_c2
finally show ?case by simp
next
case (Catch c1 c2 )
have steps_c1 : "Γ ⊨ (c1 , Stuck) → * (Skip, Stuck)" by fact
from CatchSteps [OF steps_c1 refl refl]
have "Γ ⊨ (Catch c1 c2 , Stuck) → * (Catch Skip c2 , Stuck)" .
also
have "Γ ⊨ (Catch Skip c2 , Stuck) → (Skip, Stuck)" by (rule CatchSkip)
finally show ?case by simp
qed (fastforce intro: step.intros )+
lemma step_Fault_prop:
assumes step: "Γ ⊨ (c, s) → (c', s')"
shows "∧ f. s=Fault f ==> s'=Fault f"
using step
by (induct) auto
lemma step_Stuck_prop:
assumes step: "Γ ⊨ (c, s) → (c', s')"
shows "s=Stuck ==> s'=Stuck"
using step
by (induct) auto
lemma steps_Fault_prop:
assumes step: "Γ ⊨ (c, s) → * (c', s')"
shows "s=Fault f ==> s'=Fault f"
using step
proof (induct rule: converse_rtranclp_induct2 [case_names Refl Trans])
case Refl thus ?case by simp
next
case (Trans c s c'' s'')
thus ?case
by (auto intro: step_Fault_prop)
qed
lemma steps_Stuck_prop:
assumes step: "Γ ⊨ (c, s) → * (c', s')"
shows "s=Stuck ==> s'=Stuck"
using step
proof (induct rule: converse_rtranclp_induct2 [case_names Refl Trans])
case Refl thus ?case by simp
next
case (Trans c s c'' s'')
thus ?case
by (auto intro: step_Stuck_prop)
qed
end
Messung V0.5 in Prozent C=89 H=99 G=94
¤ Dauer der Verarbeitung: 0.11 Sekunden
¤
*© Formatika GbR, Deutschland
Wurzel
Suchen
NIST Cobol Testsuite
Haftungshinweis
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.