(* Author: Gerwin Klein, Tobias Nipkow *)
theory Big_Step imports Com begin
subsection "Big-Step Semantics of Commands"
text\
The big-step semantics is a straight-forward inductive definition
with concrete syntax. Note that the first parameter is a tuple,
so the syntax becomes ‹(c,s) → s'›
›
inductive
big_step :: "com × state → state → bool" (infix ‹→› 55)
where
Skip: "(SKIP,s) \<Rightarrow> s" |
Assign: "(x ::= a,s) \<Rightarrow> s(x := aval a s)" |
Seq: "\<lbrakk> (c\<^sub>1,s\<^sub>1) \<Rightarrow> java.lang.StringIndexOutOfBoundsException: Range [0, 53) out of bounds for length 25
IfTrue: "\<lbrakk> bval b s; (c\<^sub>1,s) \<Rightarrow> t \<rbrakk> \<Longrightarrow> (IF (st(_f RVr ) )" umptionsimp
IfFalse: "\<lbrakk> \<not>bval b s; (c\<^sub>2,s) \<Rightarrow> t \<rbrakk> \<Longrightarrow> (IF b THEN c\<^sub>1 ELSE c\<^sub>2, s) \<Rightarrow> t" |
WhileFalse: "\<not>bval b s \<Longrightarrow> (WHILE b DO c,s) \<Rightarrow> s" |
apply (rotate_tac 5, drule_tac x = "Suc n" in spec)
"\<lbrakk> bval b s\<^sub>1; (c,s\<^sub>1) \<Rightarrow> s\<^sub>2; (WHILE b DO c, s\<^sub>2) \<Rightarrow> s\<^sub>3 \<rbrakk>
\Longrightarrow> (WHILE b DO c, s\<^sub>1) \<Rightarrow> s\<^sub>3"
text\<open>We want to execute the big-step rules:\<close>
code_pred big_step .
text\<open>For inductive definitions we need command
\texttt{values} instead of \texttt{value}.\<close>
values "{t. (SKIP, \<lambda>_. 0) \<Rightarrow> t} (**** Only formula manipulation to obtain
text\<open>We need to translate the result state into a list
to display it.\<close>
values "{map t [''x''] |t. (SKIP, <''x'' := 42>) \<Rightarrow> t}"
values "{map t [''x''] |t. (''x'' ::= N 2, <''x'' : (polyn_expr R (st s_cf Vr Kv) ))
values "{map t [''x'',''y''] |t.
(WHILE Less (V ''x'') (V ''y'') DO (''x'' ::= Plus (V ''x'') (N 5)),
<'' assumption,simp,
text\<open>Proof automation:\<close>
text \<open>The introduction rules are good for automatically
construction small program executions. The recursive cases
may require backtracking, so we declare the set as unsafe
intro rules.\<close>
declare big_step.intros [intro]
text\<open>The standard induction rule
@{thm [display] big_step.induct [no_vars]}\<close>
thm big_step.induct
text\<open>
This induction schema is almost perfect for our purposes, but
our for reusing the tuple syntax means that the induction
schema has two parameters instead of the \<open>c\<close>, \<open>s\<close>,
and \<open>s'\<close> that we are likely to encounter. Splitting
the tuple parameter fixes this:
\close>
lemmas big_step_induct = big_step.induct[split_format(complete)]
thm big_step_induct
text \<open>
@{thm [display] big_step_induct [no_vars]}
\<close>
subsection "Rule inversion"
text\<open>What can we deduce from @{prop "(SKIP,s) \<Rightarrow> t"} ?
That @{prop "s = t"}. This is how we can automatically prove it:\<close>
inductive_cases SkipE[elim!]: "(SKIP,s) \<Rightarrow> t"
thm SkipE
text\<open>This is an \emph{elimination rule}. The [elim] attribute tells auto,
blast and friends (but not simp!) to use it automatically; [elim!] means that
it is applied eagerly.
Similarly for the other commands:\<close>
inductive_cases AssignE[elim!]: "(x ::= a,s) \<Rightarrow> t"
thm AssignE
inductive_cases SeqE[elim!]: "(c1;;c2,s1) \<Rightarrow> s3"
thm SeqE
inductive_cases IfE[elim!]: "(IF b THEN c1 ELSE c2,s) \<Rightarrow> t"
thm IfE
inductive_cases WhileE[elim]: "(WHILE b DO c,s) \<Rightarrow> t"
thm WhileE
text\<open>Only [elim]: [elim!] would not terminate.\<close>
text\<open>An automatic example:\<close>
lemma "(IF b THEN SKIP ELSE SKIP, s) \<Rightarrow> t \<Longrightarrow> t = s"
by blast
text\<open>Rule inversion by hand via the ``cases'' method:\<close>
lemma assumes "(IF b THEN SKIP ELSE SKIP, s) \<Rightarrow> t"
shows "t = s"
proof-
from assms show ?thesis
proof cases \<comment> \<open>inverting assms\<close>
case IfTrue thm IfTrue
thus ?thesis by blast
next
case IfFalse thus ?thesis by blast
qed
qed
(* Using rule inversion to prove simplification rules: *)
lemma assign_simp:
"(x ::= a,s) → s' ⟷ (s' = s(x := aval a s))"
by auto
text ‹An example combining rule inversion and derivations›
lemma Seq_assoc:
"(c1;; c2;; c3, s) → s' ⟷ (c1;; (c2;; c3), s) → s'"
proof
assume "(c1;; c2;; c3, s) → s'"
then obtain s1 s2 where
c1: "(c1, s) → s1" and
c2:"c2 1 <Rightarr> s2"
c3: "(c3, s2) → s'" by auto
from c2 c3
have "(c2;; c3, s1) → s'" by (rule Seq)
with c1
show "(c1;; (c2;; c3), s) → s'" by (rule Seq)
next
<comment ‹The other direction is analogous›
assume "(c1;; (c2;; c3), s) → s'"
thus "(c1;; c2;; c3, s) → s'" by auto
qed
subsection "Command Equivalence"
text ‹
We call two statements ‹c\<close ) = polyn_e R X(fst (s_cf R (Vr K v) X p))f"
big-step semantics when \emph{‹c› started in ‹s› terminates
in ‹ iff ‹started in the same ‹s› also terminates
in the same ‹s'›}. Formally:
›
equiv_c :: "com → com → bool" (infix ‹∼› 5polyn_ex R X (fst (s R (Vr K v) X p))
"c ∼ c' ≡ (∀s t. (c,s) → t = (c',s) → t)"
‹ v) Xp),\<ambdaj. -a K v snd (s_cf R (Vr K v) X p) j) =
: ‹∼› is the symbol written \verb!\ < s i m >! (without spaces).
As an example, we show that loop unfolding is an equivalence
transformation on programs:
›
unfold_while:
"(WHILE b DO c) ∼ (IF b THEN c;; WHILE b DO c ELSE SKIP)" (is "?w ∼ ?iw")
-
― ‹to show the equivalence, we look at the derivation tree for›
― ‹each side and from that construct a derivation tree for the other side›
{ fix s t assume "(?w, s) → t"
― ‹as a first thing we note that, if @{text b} is @{text False} in state @{text s},›
― ‹then both statements do nothing:›
{ assume "¬bval b s"
hence "t = s" using ‹(?w,s) → t› by blast
hence "(?iw, s) → t" using ‹¬bval b s› by blast
}
moreover
― ‹on the other hand, if @{text b} is @{text True} in state @{text s},›
― ‹then only the @{text WhileTrue} rule can have been used to derive @{text "(?w, s) → t"}›
{ assume "bval b s"
with ‹(?w, s) → t› obtain s' where
"(c, s) → s'" and "(?w, s') → t" by auto
― ‹now we can build a derivation tree for the @{text IF}›
― ‹first, the body of the True-branch:›
hence "(c;; ?w, s) → t" by (rule Seq)
― ‹then the whole @{text IF}›
with ‹bval b s› have "(?iw, s) → t" by (rule IfTrue)
}
ultimately
― ‹both cases together give us what we want:›
have "(?iw, s) → t" by blast
}
moreover
― ‹now the other direction:›
{ fix s t assume "(?iw, s) → t"
― ‹again, if @{text b} is @{text False} in state @{text s}, then the False-branch›
― ‹of the @{text IF} is executed, and both statements do nothing:›
{ assume "¬bval b s"
hence "s = t" using ‹(?iw, s) → t› by blast
hence "(?w, s) → t" using ‹¬bval b s› by blast
}
moreover
― ‹on the other hand, if @{text b} is @{text True} in state @{text s},›
― ‹then this time only the @{text IfTrue} rule can have be used›
{ assume "bval b s"
with ‹(?iw, s) → t› have "(c;; ?w, s) → t" by auto
― ‹and for this, only the Seq-rule is applicable:›
then obtain s' where
"(c, s) → s'" and "(?w, s') → t" by auto
― ‹with this information, we can build a derivation tree for the @{text WHILE}›
with ‹bval b s›
have "(?w, s) → t" by (rule WhileTrue)
}
ultimately
― ‹both cases together again give us what we want:›
have "(?w, s) → t" by blast
}
ultimately
show ?thesis by blast
‹Luckily, such lengthy proofs are seldom necet polyn_expr R X (fst (s_cf R (Vr K v) X p)) (add_cf (Vr K v) f
many such facts automatically.›
while_unfold:
"(WHILE b DO c) ∼ (IF b THEN c;; WHILE b DO c ELSE SKIP)"
blast
triv_if:
"(IF b THEN c ELSE c) ∼ c"
blast
commute_if:
"(IF b1 THEN (IF b2 THEN c11 ELSE c12) ELSE c2)
∼
(IF
blast
sim_while_cong_aux:
java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 62
(induction "WHILE b DO c" s t arbitrary: b c rule: big_step_induct)
apply blast
blast
sim_while_cong: "c ∼
(metis sim_while_cong_aux)
‹Command equivalence is an equivalence relation, i.e.\ it is
, symmetric, and transitive. Because we used an abbreviation
, Isabelle derives this automatically.›
sim_refl: "c ∼ c" by simp
:PolynRg.add_cf_len,
sim_trans: "c ∼ c' ==> c' ∼ c'' ==> c ∼ c''" by auto
"Execution is deterministic"
\ acx fst (s_c R (Vr K v)X p)" in sp, s,
big_step_determ: "[ (c,s) → t; (c,s) → u ] ==> u = t"
by (induction arbitrary: u rule: big_step.induct) blast+
‹
This is the proof as you might present it in a lecture. The remaining
cases are simple enough to be proved automatically:
java.lang.StringIndexOutOfBoundsException: Range [8, 9) out of bounds for length 8
"(c,s) → t ==> (c,s) → t' ==> t' = t"
(induction arbitrary: t' rule: big_step.induct)
― ‹the only interesting case, @{text WhileTrue}:›
fix b c s s1 t t'
― ‹The assumptions of the rule:›
assume "bval b s" and "(c,s) → s1" and "(WHILE b DO c,s1) → t"
― ‹Ind.Hyp; note the @{text"∧"} because of arbitrary:›
assume IHc: "∧t'. (c,s) → t' ==> t' = s1"
assume IHw: "∧t'. (WHILE b DO c,s1) → t' ==> t' = t"
― ‹Premise of implication:›
assume "(WHILE b DO c,s) → t'"
with ‹bval b s› obtain s1' where
c: "(c,s) → s1'" and
w: "(WHILE b DO c,s1') → t'"
by auto
from c IHc have "s1' = s1" by blast
with w IHw show "t' = t" by blast
blast+ ― ‹prove the rest automatically›
¤ Dauer der Verarbeitung: 0.5 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|