1 (* Author: Gerwin Klein, Tobias Nipkow *)
3 theory Big_Step imports Com begin
5 subsection "Big-Step Semantics of Commands"
8 big_step :: "com \<times> state \<Rightarrow> state \<Rightarrow> bool" (infix "\<Rightarrow>" 55)
10 Skip: "(SKIP,s) \<Rightarrow> s" |
11 Assign: "(x ::= a,s) \<Rightarrow> s(x := aval a s)" |
12 Semi: "\<lbrakk> (c\<^isub>1,s\<^isub>1) \<Rightarrow> s\<^isub>2; (c\<^isub>2,s\<^isub>2) \<Rightarrow> s\<^isub>3 \<rbrakk> \<Longrightarrow>
13 (c\<^isub>1;c\<^isub>2, s\<^isub>1) \<Rightarrow> s\<^isub>3" |
15 IfTrue: "\<lbrakk> bval b s; (c\<^isub>1,s) \<Rightarrow> t \<rbrakk> \<Longrightarrow>
16 (IF b THEN c\<^isub>1 ELSE c\<^isub>2, s) \<Rightarrow> t" |
17 IfFalse: "\<lbrakk> \<not>bval b s; (c\<^isub>2,s) \<Rightarrow> t \<rbrakk> \<Longrightarrow>
18 (IF b THEN c\<^isub>1 ELSE c\<^isub>2, s) \<Rightarrow> t" |
20 WhileFalse: "\<not>bval b s \<Longrightarrow> (WHILE b DO c,s) \<Rightarrow> s" |
21 WhileTrue: "\<lbrakk> bval b s\<^isub>1; (c,s\<^isub>1) \<Rightarrow> s\<^isub>2; (WHILE b DO c, s\<^isub>2) \<Rightarrow> s\<^isub>3 \<rbrakk> \<Longrightarrow>
22 (WHILE b DO c, s\<^isub>1) \<Rightarrow> s\<^isub>3"
24 schematic_lemma ex: "(''x'' ::= N 5; ''y'' ::= V ''x'', s) \<Rightarrow> ?t"
33 text{* We want to execute the big-step rules: *}
37 text{* For inductive definitions we need command
38 \texttt{values} instead of \texttt{value}. *}
40 values "{t. (SKIP, lookup[]) \<Rightarrow> t}"
42 text{* We need to translate the result state into a list
45 values "{map t [''x''] |t. (SKIP, lookup [(''x'',42)]) \<Rightarrow> t}"
47 values "{map t [''x''] |t. (''x'' ::= N 2, lookup [(''x'',42)]) \<Rightarrow> t}"
49 values "{map t [''x'',''y''] |t.
50 (WHILE Less (V ''x'') (V ''y'') DO (''x'' ::= Plus (V ''x'') (N 5)),
51 lookup [(''x'',0),(''y'',13)]) \<Rightarrow> t}"
54 text{* Proof automation: *}
56 declare big_step.intros [intro]
58 text{* The standard induction rule
59 @{thm [display] big_step.induct [no_vars]} *}
63 text{* A customized induction rule for (c,s) pairs: *}
65 lemmas big_step_induct = big_step.induct[split_format(complete)]
68 @{thm [display] big_step_induct [no_vars]}
72 subsection "Rule inversion"
74 text{* What can we deduce from @{prop "(SKIP,s) \<Rightarrow> t"} ?
75 That @{prop "s = t"}. This is how we can automatically prove it: *}
77 inductive_cases skipE[elim!]: "(SKIP,s) \<Rightarrow> t"
80 text{* This is an \emph{elimination rule}. The [elim] attribute tells auto,
81 blast and friends (but not simp!) to use it automatically; [elim!] means that
82 it is applied eagerly.
84 Similarly for the other commands: *}
86 inductive_cases AssignE[elim!]: "(x ::= a,s) \<Rightarrow> t"
88 inductive_cases SemiE[elim!]: "(c1;c2,s1) \<Rightarrow> s3"
90 inductive_cases IfE[elim!]: "(IF b THEN c1 ELSE c2,s) \<Rightarrow> t"
93 inductive_cases WhileE[elim]: "(WHILE b DO c,s) \<Rightarrow> t"
95 text{* Only [elim]: [elim!] would not terminate. *}
97 text{* An automatic example: *}
99 lemma "(IF b THEN SKIP ELSE SKIP, s) \<Rightarrow> t \<Longrightarrow> t = s"
102 text{* Rule inversion by hand via the ``cases'' method: *}
104 lemma assumes "(IF b THEN SKIP ELSE SKIP, s) \<Rightarrow> t"
107 from assms show ?thesis
108 proof cases --"inverting assms"
109 case IfTrue thm IfTrue
110 thus ?thesis by blast
112 case IfFalse thus ?thesis by blast
117 subsection "Command Equivalence"
120 We call two statements @{text c} and @{text c'} equivalent wrt.\ the
121 big-step semantics when \emph{@{text c} started in @{text s} terminates
122 in @{text s'} iff @{text c'} started in the same @{text s} also terminates
123 in the same @{text s'}}. Formally:
126 equiv_c :: "com \<Rightarrow> com \<Rightarrow> bool" (infix "\<sim>" 50) where
127 "c \<sim> c' == (\<forall>s t. (c,s) \<Rightarrow> t = (c',s) \<Rightarrow> t)"
130 Warning: @{text"\<sim>"} is the symbol written \verb!\ < s i m >! (without spaces).
132 As an example, we show that loop unfolding is an equivalence
133 transformation on programs:
136 "(WHILE b DO c) \<sim> (IF b THEN c; WHILE b DO c ELSE SKIP)" (is "?w \<sim> ?iw")
138 -- "to show the equivalence, we look at the derivation tree for"
139 -- "each side and from that construct a derivation tree for the other side"
140 { fix s t assume "(?w, s) \<Rightarrow> t"
141 -- "as a first thing we note that, if @{text b} is @{text False} in state @{text s},"
142 -- "then both statements do nothing:"
143 { assume "\<not>bval b s"
144 hence "t = s" using `(?w,s) \<Rightarrow> t` by blast
145 hence "(?iw, s) \<Rightarrow> t" using `\<not>bval b s` by blast
148 -- "on the other hand, if @{text b} is @{text True} in state @{text s},"
149 -- {* then only the @{text WhileTrue} rule can have been used to derive @{text "(?w, s) \<Rightarrow> t"} *}
151 with `(?w, s) \<Rightarrow> t` obtain s' where
152 "(c, s) \<Rightarrow> s'" and "(?w, s') \<Rightarrow> t" by auto
153 -- "now we can build a derivation tree for the @{text IF}"
154 -- "first, the body of the True-branch:"
155 hence "(c; ?w, s) \<Rightarrow> t" by (rule Semi)
156 -- "then the whole @{text IF}"
157 with `bval b s` have "(?iw, s) \<Rightarrow> t" by (rule IfTrue)
160 -- "both cases together give us what we want:"
161 have "(?iw, s) \<Rightarrow> t" by blast
164 -- "now the other direction:"
165 { fix s t assume "(?iw, s) \<Rightarrow> t"
166 -- "again, if @{text b} is @{text False} in state @{text s}, then the False-branch"
167 -- "of the @{text IF} is executed, and both statements do nothing:"
168 { assume "\<not>bval b s"
169 hence "s = t" using `(?iw, s) \<Rightarrow> t` by blast
170 hence "(?w, s) \<Rightarrow> t" using `\<not>bval b s` by blast
173 -- "on the other hand, if @{text b} is @{text True} in state @{text s},"
174 -- {* then this time only the @{text IfTrue} rule can have be used *}
176 with `(?iw, s) \<Rightarrow> t` have "(c; ?w, s) \<Rightarrow> t" by auto
177 -- "and for this, only the Semi-rule is applicable:"
179 "(c, s) \<Rightarrow> s'" and "(?w, s') \<Rightarrow> t" by auto
180 -- "with this information, we can build a derivation tree for the @{text WHILE}"
182 have "(?w, s) \<Rightarrow> t" by (rule WhileTrue)
185 -- "both cases together again give us what we want:"
186 have "(?w, s) \<Rightarrow> t" by blast
189 show ?thesis by blast
192 text {* Luckily, such lengthy proofs are seldom necessary. Isabelle can
193 prove many such facts automatically. *}
196 "(WHILE b DO c) \<sim> (IF b THEN c; WHILE b DO c ELSE SKIP)"
200 "(IF b THEN c ELSE c) \<sim> c"
204 "(IF b1 THEN (IF b2 THEN c11 ELSE c12) ELSE c2)
206 (IF b2 THEN (IF b1 THEN c11 ELSE c2) ELSE (IF b1 THEN c12 ELSE c2))"
210 subsection "Execution is deterministic"
212 text {* This proof is automatic. *}
213 theorem big_step_determ: "\<lbrakk> (c,s) \<Rightarrow> t; (c,s) \<Rightarrow> u \<rbrakk> \<Longrightarrow> u = t"
214 apply (induct arbitrary: u rule: big_step.induct)
219 This is the proof as you might present it in a lecture. The remaining
220 cases are simple enough to be proved automatically:
223 "(c,s) \<Rightarrow> t \<Longrightarrow> (c,s) \<Rightarrow> t' \<Longrightarrow> t' = t"
224 proof (induct arbitrary: t' rule: big_step.induct)
225 -- "the only interesting case, @{text WhileTrue}:"
227 -- "The assumptions of the rule:"
228 assume "bval b s" and "(c,s) \<Rightarrow> s1" and "(WHILE b DO c,s1) \<Rightarrow> t"
229 -- {* Ind.Hyp; note the @{text"\<And>"} because of arbitrary: *}
230 assume IHc: "\<And>t'. (c,s) \<Rightarrow> t' \<Longrightarrow> t' = s1"
231 assume IHw: "\<And>t'. (WHILE b DO c,s1) \<Rightarrow> t' \<Longrightarrow> t' = t"
232 -- "Premise of implication:"
233 assume "(WHILE b DO c,s) \<Rightarrow> t'"
234 with `bval b s` obtain s1' where
235 c: "(c,s) \<Rightarrow> s1'" and
236 w: "(WHILE b DO c,s1') \<Rightarrow> t'"
238 from c IHc have "s1' = s1" by blast
239 with w IHw show "t' = t" by blast
240 qed blast+ -- "prove the rest automatically"