src/HOL/IMP/Compiler.thy
author nipkow
Mon, 30 Apr 2001 19:26:04 +0200
changeset 11275 71498de45241
parent 10425 cab4acf9276d
child 11701 3d51fbf81c17
permissions -rw-r--r--
new proof
     1 (*  Title:      HOL/IMP/Compiler.thy
     2     ID:         $Id$
     3     Author:     Tobias Nipkow, TUM
     4     Copyright   1996 TUM
     5 
     6 A simple compiler for a simplistic machine.
     7 *)
     8 
     9 theory Compiler = Natural:
    10 
    11 datatype instr = ASIN loc aexp | JMPF bexp nat | JMPB nat
    12 
    13 consts  stepa1 :: "instr list => ((state*nat) * (state*nat))set"
    14 
    15 syntax
    16         "@stepa1" :: "[instr list,state,nat,state,nat] => bool"
    17                      ("_ |- <_,_>/ -1-> <_,_>" [50,0,0,0,0] 50)
    18         "@stepa" :: "[instr list,state,nat,state,nat] => bool"
    19                      ("_ |-/ <_,_>/ -*-> <_,_>" [50,0,0,0,0] 50)
    20 
    21 translations  "P |- <s,m> -1-> <t,n>" == "((s,m),t,n) : stepa1 P"
    22               "P |- <s,m> -*-> <t,n>" == "((s,m),t,n) : ((stepa1 P)^*)"
    23 
    24 
    25 inductive "stepa1 P"
    26 intros
    27 ASIN:
    28        "\<lbrakk> n<size P; P!n = ASIN x a \<rbrakk> \<Longrightarrow> P |- <s,n> -1-> <s[x::= a s],Suc n>"
    29 JMPFT:
    30        "\<lbrakk> n<size P; P!n = JMPF b i;  b s \<rbrakk> \<Longrightarrow> P |- <s,n> -1-> <s,Suc n>"
    31 JMPFF:
    32        "\<lbrakk> n<size P; P!n = JMPF b i; ~b s; m=n+i \<rbrakk> \<Longrightarrow> P |- <s,n> -1-> <s,m>"
    33 JMPB:
    34       "\<lbrakk> n<size P; P!n = JMPB i; i <= n \<rbrakk> \<Longrightarrow> P |- <s,n> -1-> <s,n-i>"
    35 
    36 consts compile :: "com => instr list"
    37 primrec
    38 "compile SKIP = []"
    39 "compile (x:==a) = [ASIN x a]"
    40 "compile (c1;c2) = compile c1 @ compile c2"
    41 "compile (IF b THEN c1 ELSE c2) =
    42  [JMPF b (length(compile c1)+2)] @ compile c1 @
    43  [JMPF (%x. False) (length(compile c2)+1)] @ compile c2"
    44 "compile (WHILE b DO c) = [JMPF b (length(compile c)+2)] @ compile c @
    45  [JMPB (length(compile c)+1)]"
    46 
    47 declare nth_append[simp];
    48 
    49 (* Lemmas for lifting an execution into a prefix and suffix
    50    of instructions; only needed for the first proof *)
    51 
    52 lemma app_right_1:
    53   "is1 |- <s1,i1> -1-> <s2,i2> \<Longrightarrow> is1 @ is2 |- <s1,i1> -1-> <s2,i2>"
    54 apply(erule stepa1.induct);
    55    apply (simp add:ASIN)
    56   apply (force intro!:JMPFT)
    57  apply (force intro!:JMPFF)
    58 apply (simp add: JMPB)
    59 done      
    60       
    61 lemma app_left_1:
    62   "is2 |- <s1,i1> -1-> <s2,i2> \<Longrightarrow>
    63    is1 @ is2 |- <s1,size is1+i1> -1-> <s2,size is1+i2>"
    64 apply(erule stepa1.induct);
    65    apply (simp add:ASIN)
    66   apply (fastsimp intro!:JMPFT)
    67  apply (fastsimp intro!:JMPFF)
    68 apply (simp add: JMPB)
    69 done
    70 
    71 lemma app_right:
    72   "is1 |- <s1,i1> -*-> <s2,i2> \<Longrightarrow> is1 @ is2 |- <s1,i1> -*-> <s2,i2>"
    73 apply(erule rtrancl_induct2);
    74  apply simp
    75 apply(blast intro:app_right_1 rtrancl_trans)
    76 done
    77 
    78 lemma app_left:
    79   "is2 |- <s1,i1> -*-> <s2,i2> \<Longrightarrow>
    80    is1 @ is2 |- <s1,size is1+i1> -*-> <s2,size is1+i2>"
    81 apply(erule rtrancl_induct2);
    82  apply simp
    83 apply(blast intro:app_left_1 rtrancl_trans)
    84 done
    85 
    86 lemma app_left2:
    87   "\<lbrakk> is2 |- <s1,i1> -*-> <s2,i2>; j1 = size is1+i1; j2 = size is1+i2 \<rbrakk> \<Longrightarrow>
    88    is1 @ is2 |- <s1,j1> -*-> <s2,j2>"
    89 by (simp add:app_left)
    90 
    91 lemma app1_left:
    92   "is |- <s1,i1> -*-> <s2,i2> \<Longrightarrow>
    93    instr # is |- <s1,Suc i1> -*-> <s2,Suc i2>"
    94 by(erule app_left[of _ _ _ _ _ "[instr]",simplified])
    95 
    96 
    97 (* The first proof; statement very intuitive,
    98    but application of induction hypothesis requires the above lifting lemmas
    99 *)
   100 theorem "<c,s> -c-> t ==> compile c |- <s,0> -*-> <t,length(compile c)>"
   101 apply(erule evalc.induct);
   102       apply simp;
   103      apply(force intro!: ASIN);
   104     apply simp
   105     apply(rule rtrancl_trans)
   106     apply(erule app_right)
   107     apply(erule app_left[of _ 0,simplified])
   108 (* IF b THEN c0 ELSE c1; case b is true *)
   109    apply(simp);
   110    (* execute JMPF: *)
   111    apply (rule rtrancl_into_rtrancl2)
   112     apply(force intro!: JMPFT);
   113    (* execute compile c0: *)
   114    apply(rule app1_left)
   115    apply(rule rtrancl_into_rtrancl);
   116     apply(erule app_right)
   117    (* execute JMPF: *)
   118    apply(force intro!: JMPFF);
   119 (* end of case b is true *)
   120   apply simp
   121   apply (rule rtrancl_into_rtrancl2)
   122    apply(force intro!: JMPFF)
   123   apply(force intro!: app_left2 app1_left)
   124 (* WHILE False *)
   125  apply(force intro: JMPFF);
   126 (* WHILE True *)
   127 apply(simp)
   128 apply(rule rtrancl_into_rtrancl2);
   129  apply(force intro!: JMPFT);
   130 apply(rule rtrancl_trans);
   131  apply(rule app1_left)
   132  apply(erule app_right)
   133 apply(rule rtrancl_into_rtrancl2);
   134  apply(force intro!: JMPB)
   135 apply(simp)
   136 done
   137 
   138 (* Second proof; statement is generalized to cater for prefixes and suffixes;
   139    needs none of the lifting lemmas, but instantiations of pre/suffix.
   140 *)
   141 theorem "<c,s> -c-> t ==> 
   142  !a z. a@compile c@z |- <s,length a> -*-> <t,length a + length(compile c)>";
   143 apply(erule evalc.induct);
   144       apply simp;
   145      apply(force intro!: ASIN);
   146     apply(intro strip);
   147     apply(erule_tac x = a in allE);
   148     apply(erule_tac x = "a@compile c0" in allE);
   149     apply(erule_tac x = "compile c1@z" in allE);
   150     apply(erule_tac x = z in allE);
   151     apply(simp add:add_assoc[THEN sym]);
   152     apply(blast intro:rtrancl_trans);
   153 (* IF b THEN c0 ELSE c1; case b is true *)
   154    apply(intro strip);
   155    (* instantiate assumption sufficiently for later: *)
   156    apply(erule_tac x = "a@[?I]" in allE);
   157    apply(simp);
   158    (* execute JMPF: *)
   159    apply(rule rtrancl_into_rtrancl2);
   160     apply(force intro!: JMPFT);
   161    (* execute compile c0: *)
   162    apply(rule rtrancl_trans);
   163     apply(erule allE);
   164     apply assumption;
   165    (* execute JMPF: *)
   166    apply(rule r_into_rtrancl);
   167    apply(force intro!: JMPFF);
   168 (* end of case b is true *)
   169   apply(intro strip);
   170   apply(erule_tac x = "a@[?I]@compile c0@[?J]" in allE);
   171   apply(simp add:add_assoc);
   172   apply(rule rtrancl_into_rtrancl2);
   173    apply(force intro!: JMPFF);
   174   apply(blast);
   175  apply(force intro: JMPFF);
   176 apply(intro strip);
   177 apply(erule_tac x = "a@[?I]" in allE);
   178 apply(erule_tac x = a in allE);
   179 apply(simp);
   180 apply(rule rtrancl_into_rtrancl2);
   181  apply(force intro!: JMPFT);
   182 apply(rule rtrancl_trans);
   183  apply(erule allE);
   184  apply assumption;
   185 apply(rule rtrancl_into_rtrancl2);
   186  apply(force intro!: JMPB);
   187 apply(simp);
   188 done
   189 
   190 (* Missing: the other direction! *)
   191 
   192 end