src/HOL/IMP/Big_Step.thy
author nipkow
Wed, 01 Jun 2011 21:35:34 +0200
changeset 43982 11fce8564415
child 43999 686fa0a0696e
permissions -rw-r--r--
Replacing old IMP with new Semantics material
     1 (* Author: Gerwin Klein, Tobias Nipkow *)
     2 
     3 theory Big_Step imports Com begin
     4 
     5 subsection "Big-Step Semantics of Commands"
     6 
     7 inductive
     8   big_step :: "com \<times> state \<Rightarrow> state \<Rightarrow> bool" (infix "\<Rightarrow>" 55)
     9 where
    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" |
    14 
    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" |
    19 
    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"
    23 
    24 schematic_lemma ex: "(''x'' ::= N 5; ''y'' ::= V ''x'', s) \<Rightarrow> ?t"
    25 apply(rule Semi)
    26 apply(rule Assign)
    27 apply simp
    28 apply(rule Assign)
    29 done
    30 
    31 thm ex[simplified]
    32 
    33 text{* We want to execute the big-step rules: *}
    34 
    35 code_pred big_step .
    36 
    37 text{* For inductive definitions we need command
    38        \texttt{values} instead of \texttt{value}. *}
    39 
    40 values "{t. (SKIP, lookup[]) \<Rightarrow> t}"
    41 
    42 text{* We need to translate the result state into a list
    43 to display it. *}
    44 
    45 values "{map t [''x''] |t. (SKIP, lookup [(''x'',42)]) \<Rightarrow> t}"
    46 
    47 values "{map t [''x''] |t. (''x'' ::= N 2, lookup [(''x'',42)]) \<Rightarrow> t}"
    48 
    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}"
    52 
    53 
    54 text{* Proof automation: *}
    55 
    56 declare big_step.intros [intro]
    57 
    58 text{* The standard induction rule 
    59 @{thm [display] big_step.induct [no_vars]} *}
    60 
    61 thm big_step.induct
    62 
    63 text{* A customized induction rule for (c,s) pairs: *}
    64 
    65 lemmas big_step_induct = big_step.induct[split_format(complete)]
    66 thm big_step_induct
    67 text {*
    68 @{thm [display] big_step_induct [no_vars]}
    69 *}
    70 
    71 
    72 subsection "Rule inversion"
    73 
    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: *}
    76 
    77 inductive_cases skipE[elim!]: "(SKIP,s) \<Rightarrow> t"
    78 thm skipE
    79 
    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.
    83 
    84 Similarly for the other commands: *}
    85 
    86 inductive_cases AssignE[elim!]: "(x ::= a,s) \<Rightarrow> t"
    87 thm AssignE
    88 inductive_cases SemiE[elim!]: "(c1;c2,s1) \<Rightarrow> s3"
    89 thm SemiE
    90 inductive_cases IfE[elim!]: "(IF b THEN c1 ELSE c2,s) \<Rightarrow> t"
    91 thm IfE
    92 
    93 inductive_cases WhileE[elim]: "(WHILE b DO c,s) \<Rightarrow> t"
    94 thm WhileE
    95 text{* Only [elim]: [elim!] would not terminate. *}
    96 
    97 text{* An automatic example: *}
    98 
    99 lemma "(IF b THEN SKIP ELSE SKIP, s) \<Rightarrow> t \<Longrightarrow> t = s"
   100 by blast
   101 
   102 text{* Rule inversion by hand via the ``cases'' method: *}
   103 
   104 lemma assumes "(IF b THEN SKIP ELSE SKIP, s) \<Rightarrow> t"
   105 shows "t = s"
   106 proof-
   107   from assms show ?thesis
   108   proof cases  --"inverting assms"
   109     case IfTrue thm IfTrue
   110     thus ?thesis by blast
   111   next
   112     case IfFalse thus ?thesis by blast
   113   qed
   114 qed
   115 
   116 
   117 subsection "Command Equivalence"
   118 
   119 text {*
   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:
   124 *}
   125 abbreviation
   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)"
   128 
   129 text {*
   130 Warning: @{text"\<sim>"} is the symbol written \verb!\ < s i m >! (without spaces).
   131 
   132   As an example, we show that loop unfolding is an equivalence
   133   transformation on programs:
   134 *}
   135 lemma unfold_while:
   136   "(WHILE b DO c) \<sim> (IF b THEN c; WHILE b DO c ELSE SKIP)" (is "?w \<sim> ?iw")
   137 proof -
   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
   146     }
   147     moreover
   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"} *}
   150     { assume "bval b s"
   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)
   158     }
   159     ultimately
   160     -- "both cases together give us what we want:"
   161     have "(?iw, s) \<Rightarrow> t" by blast
   162   }
   163   moreover
   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
   171     }
   172     moreover
   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 *}
   175     { assume "bval b s"
   176       with `(?iw, s) \<Rightarrow> t` have "(c; ?w, s) \<Rightarrow> t" by auto
   177       -- "and for this, only the Semi-rule is applicable:"
   178       then obtain s' where
   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}"
   181       with `bval b s`
   182       have "(?w, s) \<Rightarrow> t" by (rule WhileTrue)
   183     }
   184     ultimately
   185     -- "both cases together again give us what we want:"
   186     have "(?w, s) \<Rightarrow> t" by blast
   187   }
   188   ultimately
   189   show ?thesis by blast
   190 qed
   191 
   192 text {* Luckily, such lengthy proofs are seldom necessary.  Isabelle can
   193 prove many such facts automatically.  *}
   194 
   195 lemma 
   196   "(WHILE b DO c) \<sim> (IF b THEN c; WHILE b DO c ELSE SKIP)"
   197 by blast
   198 
   199 lemma triv_if:
   200   "(IF b THEN c ELSE c) \<sim> c"
   201 by blast
   202 
   203 lemma commute_if:
   204   "(IF b1 THEN (IF b2 THEN c11 ELSE c12) ELSE c2) 
   205    \<sim> 
   206    (IF b2 THEN (IF b1 THEN c11 ELSE c2) ELSE (IF b1 THEN c12 ELSE c2))"
   207 by blast
   208 
   209 
   210 subsection "Execution is deterministic"
   211 
   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)
   215 apply blast+
   216 done
   217 
   218 text {*
   219   This is the proof as you might present it in a lecture. The remaining
   220   cases are simple enough to be proved automatically:
   221 *}
   222 theorem
   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}:"
   226   fix b c s s1 t t'
   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'"
   237     by auto
   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"
   241 
   242 
   243 end