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