| 1 | (* *********************************************************************) |
|---|
| 2 | (* *) |
|---|
| 3 | (* The Compcert verified compiler *) |
|---|
| 4 | (* *) |
|---|
| 5 | (* Xavier Leroy, INRIA Paris-Rocquencourt *) |
|---|
| 6 | (* *) |
|---|
| 7 | (* Copyright Institut National de Recherche en Informatique et en *) |
|---|
| 8 | (* Automatique. All rights reserved. This file is distributed *) |
|---|
| 9 | (* under the terms of the GNU General Public License as published by *) |
|---|
| 10 | (* the Free Software Foundation, either version 2 of the License, or *) |
|---|
| 11 | (* (at your option) any later version. This file is also distributed *) |
|---|
| 12 | (* under the terms of the INRIA Non-Commercial License Agreement. *) |
|---|
| 13 | (* *) |
|---|
| 14 | (* *********************************************************************) |
|---|
| 15 | |
|---|
| 16 | (* * Dynamic semantics for the Clight language *) |
|---|
| 17 | |
|---|
| 18 | (*include "Coqlib.ma".*) |
|---|
| 19 | (*include "Errors.ma".*) |
|---|
| 20 | (*include "Integers.ma".*) |
|---|
| 21 | (*include "Floats.ma".*) |
|---|
| 22 | (*include "Values.ma".*) |
|---|
| 23 | (*include "AST.ma".*) |
|---|
| 24 | (*include "Mem.ma".*) |
|---|
| 25 | include "Globalenvs.ma". |
|---|
| 26 | include "Csyntax.ma". |
|---|
| 27 | include "Maps.ma". |
|---|
| 28 | (*include "Events.ma".*) |
|---|
| 29 | include "Smallstep.ma". |
|---|
| 30 | |
|---|
| 31 | (* * * Semantics of type-dependent operations *) |
|---|
| 32 | |
|---|
| 33 | (* * Interpretation of values as truth values. |
|---|
| 34 | Non-zero integers, non-zero floats and non-null pointers are |
|---|
| 35 | considered as true. The integer zero (which also represents |
|---|
| 36 | the null pointer) and the float 0.0 are false. *) |
|---|
| 37 | |
|---|
| 38 | inductive is_false: val → type → Prop ≝ |
|---|
| 39 | | is_false_int: ∀sz,sg. |
|---|
| 40 | is_false (Vint zero) (Tint sz sg) |
|---|
| 41 | | is_false_pointer: ∀r,r',t. |
|---|
| 42 | is_false (Vnull r) (Tpointer r' t) |
|---|
| 43 | | is_false_float: ∀sz. |
|---|
| 44 | is_false (Vfloat Fzero) (Tfloat sz). |
|---|
| 45 | |
|---|
| 46 | inductive is_true: val → type → Prop ≝ |
|---|
| 47 | | is_true_int_int: ∀n,sz,sg. |
|---|
| 48 | n ≠ zero → |
|---|
| 49 | is_true (Vint n) (Tint sz sg) |
|---|
| 50 | | is_true_pointer_pointer: ∀r,b,pc,ofs,s,t. |
|---|
| 51 | is_true (Vptr r b pc ofs) (Tpointer s t) |
|---|
| 52 | | is_true_float: ∀f,sz. |
|---|
| 53 | f ≠ Fzero → |
|---|
| 54 | is_true (Vfloat f) (Tfloat sz). |
|---|
| 55 | |
|---|
| 56 | inductive bool_of_val : val → type → val → Prop ≝ |
|---|
| 57 | | bool_of_val_true: ∀v,ty. |
|---|
| 58 | is_true v ty → |
|---|
| 59 | bool_of_val v ty Vtrue |
|---|
| 60 | | bool_of_val_false: ∀v,ty. |
|---|
| 61 | is_false v ty → |
|---|
| 62 | bool_of_val v ty Vfalse. |
|---|
| 63 | |
|---|
| 64 | (* * The following [sem_] functions compute the result of an operator |
|---|
| 65 | application. Since operators are overloaded, the result depends |
|---|
| 66 | both on the static types of the arguments and on their run-time values. |
|---|
| 67 | Unlike in C, automatic conversions between integers and floats |
|---|
| 68 | are not performed. For instance, [e1 + e2] is undefined if [e1] |
|---|
| 69 | is a float and [e2] an integer. The Clight producer must have explicitly |
|---|
| 70 | promoted [e2] to a float. *) |
|---|
| 71 | |
|---|
| 72 | let rec sem_neg (v: val) (ty: type) : option val ≝ |
|---|
| 73 | match ty with |
|---|
| 74 | [ Tint _ _ ⇒ |
|---|
| 75 | match v with |
|---|
| 76 | [ Vint n ⇒ Some ? (Vint (neg n)) |
|---|
| 77 | | _ => None ? |
|---|
| 78 | ] |
|---|
| 79 | | Tfloat _ ⇒ |
|---|
| 80 | match v with |
|---|
| 81 | [ Vfloat f ⇒ Some ? (Vfloat (Fneg f)) |
|---|
| 82 | | _ ⇒ None ? |
|---|
| 83 | ] |
|---|
| 84 | | _ ⇒ None ? |
|---|
| 85 | ]. |
|---|
| 86 | |
|---|
| 87 | let rec sem_notint (v: val) : option val ≝ |
|---|
| 88 | match v with |
|---|
| 89 | [ Vint n ⇒ Some ? (Vint (xor n mone)) |
|---|
| 90 | | _ ⇒ None ? |
|---|
| 91 | ]. |
|---|
| 92 | |
|---|
| 93 | let rec sem_notbool (v: val) (ty: type) : option val ≝ |
|---|
| 94 | match ty with |
|---|
| 95 | [ Tint _ _ ⇒ |
|---|
| 96 | match v with |
|---|
| 97 | [ Vint n ⇒ Some ? (of_bool (eq n zero)) |
|---|
| 98 | | Vptr _ _ _ _ ⇒ Some ? Vfalse |
|---|
| 99 | | _ ⇒ None ? |
|---|
| 100 | ] |
|---|
| 101 | | Tpointer _ _ ⇒ |
|---|
| 102 | match v with |
|---|
| 103 | [ Vint n ⇒ Some ? (of_bool (eq n zero)) |
|---|
| 104 | | Vptr _ _ _ _ ⇒ Some ? Vfalse |
|---|
| 105 | | _ ⇒ None ? |
|---|
| 106 | ] |
|---|
| 107 | | Tfloat _ ⇒ |
|---|
| 108 | match v with |
|---|
| 109 | [ Vfloat f ⇒ Some ? (of_bool (Fcmp Ceq f Fzero)) |
|---|
| 110 | | _ ⇒ None ? |
|---|
| 111 | ] |
|---|
| 112 | | _ ⇒ None ? |
|---|
| 113 | ]. |
|---|
| 114 | |
|---|
| 115 | let rec sem_add (v1:val) (t1:type) (v2: val) (t2:type) : option val ≝ |
|---|
| 116 | match classify_add t1 t2 with |
|---|
| 117 | [ add_case_ii ⇒ (**r integer addition *) |
|---|
| 118 | match v1 with |
|---|
| 119 | [ Vint n1 ⇒ match v2 with |
|---|
| 120 | [ Vint n2 ⇒ Some ? (Vint (add n1 n2)) |
|---|
| 121 | | _ ⇒ None ? ] |
|---|
| 122 | | _ ⇒ None ? ] |
|---|
| 123 | | add_case_ff ⇒ (**r float addition *) |
|---|
| 124 | match v1 with |
|---|
| 125 | [ Vfloat n1 ⇒ match v2 with |
|---|
| 126 | [ Vfloat n2 ⇒ Some ? (Vfloat (Fadd n1 n2)) |
|---|
| 127 | | _ ⇒ None ? ] |
|---|
| 128 | | _ ⇒ None ? ] |
|---|
| 129 | | add_case_pi ty ⇒ (**r pointer plus integer *) |
|---|
| 130 | match v1 with |
|---|
| 131 | [ Vptr r1 b1 p1 ofs1 ⇒ match v2 with |
|---|
| 132 | [ Vint n2 ⇒ Some ? (Vptr r1 b1 p1 (add ofs1 (mul (repr (sizeof ty)) n2))) |
|---|
| 133 | | _ ⇒ None ? ] |
|---|
| 134 | | Vnull r ⇒ match v2 with |
|---|
| 135 | [ Vint n2 ⇒ if eq n2 zero then Some ? (Vnull r) else None ? |
|---|
| 136 | | _ ⇒ None ? ] |
|---|
| 137 | | _ ⇒ None ? ] |
|---|
| 138 | | add_case_ip ty ⇒ (**r integer plus pointer *) |
|---|
| 139 | match v1 with |
|---|
| 140 | [ Vint n1 ⇒ match v2 with |
|---|
| 141 | [ Vptr r2 b2 p2 ofs2 ⇒ Some ? (Vptr r2 b2 p2 (add ofs2 (mul (repr (sizeof ty)) n1))) |
|---|
| 142 | | _ ⇒ None ? ] |
|---|
| 143 | | _ ⇒ None ? ] |
|---|
| 144 | | add_default ⇒ None ? |
|---|
| 145 | ]. |
|---|
| 146 | |
|---|
| 147 | let rec sem_sub (v1:val) (t1:type) (v2: val) (t2:type) : option val ≝ |
|---|
| 148 | match classify_sub t1 t2 with |
|---|
| 149 | [ sub_case_ii ⇒ (**r integer subtraction *) |
|---|
| 150 | match v1 with |
|---|
| 151 | [ Vint n1 ⇒ match v2 with |
|---|
| 152 | [ Vint n2 ⇒ Some ? (Vint (sub n1 n2)) |
|---|
| 153 | | _ ⇒ None ? ] |
|---|
| 154 | | _ ⇒ None ? ] |
|---|
| 155 | | sub_case_ff ⇒ (**r float subtraction *) |
|---|
| 156 | match v1 with |
|---|
| 157 | [ Vfloat f1 ⇒ match v2 with |
|---|
| 158 | [ Vfloat f2 ⇒ Some ? (Vfloat (Fsub f1 f2)) |
|---|
| 159 | | _ ⇒ None ? ] |
|---|
| 160 | | _ ⇒ None ? ] |
|---|
| 161 | | sub_case_pi ty ⇒ (**r pointer minus integer *) |
|---|
| 162 | match v1 with |
|---|
| 163 | [ Vptr r1 b1 p1 ofs1 ⇒ match v2 with |
|---|
| 164 | [ Vint n2 ⇒ Some ? (Vptr r1 b1 p1 (sub ofs1 (mul (repr (sizeof ty)) n2))) |
|---|
| 165 | | _ ⇒ None ? ] |
|---|
| 166 | | _ ⇒ None ? ] |
|---|
| 167 | | sub_case_pp ty ⇒ (**r pointer minus pointer *) |
|---|
| 168 | match v1 with |
|---|
| 169 | [ Vptr r1 b1 p1 ofs1 ⇒ match v2 with |
|---|
| 170 | [ Vptr r2 b2 p2 ofs2 ⇒ |
|---|
| 171 | if eq_block b1 b2 then |
|---|
| 172 | if eq (repr (sizeof ty)) zero then None ? |
|---|
| 173 | else Some ? (Vint (divu (sub ofs1 ofs2) (repr (sizeof ty)))) |
|---|
| 174 | else None ? |
|---|
| 175 | | _ ⇒ None ? ] |
|---|
| 176 | | Vnull r ⇒ match v2 with [ Vnull r' ⇒ Some ? (Vint zero) | _ ⇒ None ? ] |
|---|
| 177 | | _ ⇒ None ? ] |
|---|
| 178 | | sub_default ⇒ None ? |
|---|
| 179 | ]. |
|---|
| 180 | |
|---|
| 181 | let rec sem_mul (v1:val) (t1:type) (v2: val) (t2:type) : option val ≝ |
|---|
| 182 | match classify_mul t1 t2 with |
|---|
| 183 | [ mul_case_ii ⇒ |
|---|
| 184 | match v1 with |
|---|
| 185 | [ Vint n1 ⇒ match v2 with |
|---|
| 186 | [ Vint n2 ⇒ Some ? (Vint (mul n1 n2)) |
|---|
| 187 | | _ ⇒ None ? ] |
|---|
| 188 | | _ ⇒ None ? ] |
|---|
| 189 | | mul_case_ff ⇒ |
|---|
| 190 | match v1 with |
|---|
| 191 | [ Vfloat f1 ⇒ match v2 with |
|---|
| 192 | [ Vfloat f2 ⇒ Some ? (Vfloat (Fmul f1 f2)) |
|---|
| 193 | | _ ⇒ None ? ] |
|---|
| 194 | | _ ⇒ None ? ] |
|---|
| 195 | | mul_default ⇒ |
|---|
| 196 | None ? |
|---|
| 197 | ]. |
|---|
| 198 | |
|---|
| 199 | let rec sem_div (v1:val) (t1:type) (v2: val) (t2:type) : option val ≝ |
|---|
| 200 | match classify_div t1 t2 with |
|---|
| 201 | [ div_case_I32unsi ⇒ |
|---|
| 202 | match v1 with |
|---|
| 203 | [ Vint n1 ⇒ match v2 with |
|---|
| 204 | [ Vint n2 ⇒ if eq n2 zero then None ? else Some ? (Vint (divu n1 n2)) |
|---|
| 205 | | _ ⇒ None ? ] |
|---|
| 206 | | _ ⇒ None ? ] |
|---|
| 207 | | div_case_ii ⇒ |
|---|
| 208 | match v1 with |
|---|
| 209 | [ Vint n1 ⇒ match v2 with |
|---|
| 210 | [ Vint n2 ⇒ if eq n2 zero then None ? else Some ? (Vint(divs n1 n2)) |
|---|
| 211 | | _ ⇒ None ? ] |
|---|
| 212 | | _ ⇒ None ? ] |
|---|
| 213 | | div_case_ff ⇒ |
|---|
| 214 | match v1 with |
|---|
| 215 | [ Vfloat f1 ⇒ match v2 with |
|---|
| 216 | [ Vfloat f2 ⇒ Some ? (Vfloat(Fdiv f1 f2)) |
|---|
| 217 | | _ ⇒ None ? ] |
|---|
| 218 | | _ ⇒ None ? ] |
|---|
| 219 | | div_default ⇒ |
|---|
| 220 | None ? |
|---|
| 221 | ]. |
|---|
| 222 | |
|---|
| 223 | let rec sem_mod (v1:val) (t1:type) (v2: val) (t2:type) : option val ≝ |
|---|
| 224 | match classify_mod t1 t2 with |
|---|
| 225 | [ mod_case_I32unsi ⇒ |
|---|
| 226 | match v1 with |
|---|
| 227 | [ Vint n1 ⇒ match v2 with |
|---|
| 228 | [ Vint n2 ⇒ if eq n2 zero then None ? else Some ? (Vint (modu n1 n2)) |
|---|
| 229 | | _ ⇒ None ? ] |
|---|
| 230 | | _ ⇒ None ? ] |
|---|
| 231 | | mod_case_ii ⇒ |
|---|
| 232 | match v1 with |
|---|
| 233 | [ Vint n1 ⇒ match v2 with |
|---|
| 234 | [ Vint n2 ⇒ if eq n2 zero then None ? else Some ? (Vint (mods n1 n2)) |
|---|
| 235 | | _ ⇒ None ? ] |
|---|
| 236 | | _ ⇒ None ? ] |
|---|
| 237 | | mod_default ⇒ |
|---|
| 238 | None ? |
|---|
| 239 | ]. |
|---|
| 240 | |
|---|
| 241 | let rec sem_and (v1,v2: val) : option val ≝ |
|---|
| 242 | match v1 with |
|---|
| 243 | [ Vint n1 ⇒ match v2 with |
|---|
| 244 | [ Vint n2 ⇒ Some ? (Vint(i_and n1 n2)) |
|---|
| 245 | | _ ⇒ None ? ] |
|---|
| 246 | | _ ⇒ None ? |
|---|
| 247 | ]. |
|---|
| 248 | |
|---|
| 249 | let rec sem_or (v1,v2: val) : option val ≝ |
|---|
| 250 | match v1 with |
|---|
| 251 | [ Vint n1 ⇒ match v2 with |
|---|
| 252 | [ Vint n2 ⇒ Some ? (Vint(or n1 n2)) |
|---|
| 253 | | _ ⇒ None ? ] |
|---|
| 254 | | _ ⇒ None ? |
|---|
| 255 | ]. |
|---|
| 256 | |
|---|
| 257 | let rec sem_xor (v1,v2: val) : option val ≝ |
|---|
| 258 | match v1 with |
|---|
| 259 | [ Vint n1 ⇒ match v2 with |
|---|
| 260 | [ Vint n2 ⇒ Some ? (Vint(xor n1 n2)) |
|---|
| 261 | | _ ⇒ None ? ] |
|---|
| 262 | | _ ⇒ None ? |
|---|
| 263 | ]. |
|---|
| 264 | |
|---|
| 265 | let rec sem_shl (v1,v2: val): option val ≝ |
|---|
| 266 | match v1 with |
|---|
| 267 | [ Vint n1 ⇒ match v2 with |
|---|
| 268 | [ Vint n2 ⇒ |
|---|
| 269 | if ltu n2 iwordsize then Some ? (Vint(shl n1 n2)) else None ? |
|---|
| 270 | | _ ⇒ None ? ] |
|---|
| 271 | | _ ⇒ None ? ]. |
|---|
| 272 | |
|---|
| 273 | let rec sem_shr (v1: val) (t1: type) (v2: val) (t2: type): option val ≝ |
|---|
| 274 | match classify_shr t1 t2 with |
|---|
| 275 | [ shr_case_I32unsi ⇒ |
|---|
| 276 | match v1 with |
|---|
| 277 | [ Vint n1 ⇒ match v2 with |
|---|
| 278 | [ Vint n2 ⇒ |
|---|
| 279 | if ltu n2 iwordsize then Some ? (Vint (shru n1 n2)) else None ? |
|---|
| 280 | | _ ⇒ None ? ] |
|---|
| 281 | | _ ⇒ None ? ] |
|---|
| 282 | | shr_case_ii => |
|---|
| 283 | match v1 with |
|---|
| 284 | [ Vint n1 ⇒ match v2 with |
|---|
| 285 | [ Vint n2 ⇒ |
|---|
| 286 | if ltu n2 iwordsize then Some ? (Vint (shr n1 n2)) else None ? |
|---|
| 287 | | _ ⇒ None ? ] |
|---|
| 288 | | _ ⇒ None ? ] |
|---|
| 289 | | shr_default ⇒ |
|---|
| 290 | None ? |
|---|
| 291 | ]. |
|---|
| 292 | |
|---|
| 293 | let rec sem_cmp_mismatch (c: comparison): option val ≝ |
|---|
| 294 | match c with |
|---|
| 295 | [ Ceq => Some ? Vfalse |
|---|
| 296 | | Cne => Some ? Vtrue |
|---|
| 297 | | _ => None ? |
|---|
| 298 | ]. |
|---|
| 299 | |
|---|
| 300 | let rec sem_cmp_match (c: comparison): option val ≝ |
|---|
| 301 | match c with |
|---|
| 302 | [ Ceq => Some ? Vtrue |
|---|
| 303 | | Cne => Some ? Vfalse |
|---|
| 304 | | _ => None ? |
|---|
| 305 | ]. |
|---|
| 306 | |
|---|
| 307 | let rec sem_cmp (c:comparison) |
|---|
| 308 | (v1: val) (t1: type) (v2: val) (t2: type) |
|---|
| 309 | (m: mem): option val ≝ |
|---|
| 310 | match classify_cmp t1 t2 with |
|---|
| 311 | [ cmp_case_I32unsi ⇒ |
|---|
| 312 | match v1 with |
|---|
| 313 | [ Vint n1 ⇒ match v2 with |
|---|
| 314 | [ Vint n2 ⇒ Some ? (of_bool (cmpu c n1 n2)) |
|---|
| 315 | | _ ⇒ None ? ] |
|---|
| 316 | | _ ⇒ None ? ] |
|---|
| 317 | | cmp_case_ipip ⇒ |
|---|
| 318 | match v1 with |
|---|
| 319 | [ Vint n1 ⇒ match v2 with |
|---|
| 320 | [ Vint n2 ⇒ Some ? (of_bool (cmp c n1 n2)) |
|---|
| 321 | | _ ⇒ None ? |
|---|
| 322 | ] |
|---|
| 323 | | Vptr r1 b1 p1 ofs1 ⇒ |
|---|
| 324 | match v2 with |
|---|
| 325 | [ Vptr r2 b2 p2 ofs2 ⇒ |
|---|
| 326 | if valid_pointer m r1 b1 (signed ofs1) |
|---|
| 327 | ∧ valid_pointer m r2 b2 (signed ofs2) then |
|---|
| 328 | if eq_block b1 b2 |
|---|
| 329 | then Some ? (of_bool (cmp c ofs1 ofs2)) |
|---|
| 330 | else sem_cmp_mismatch c |
|---|
| 331 | else None ? |
|---|
| 332 | | Vnull r2 ⇒ sem_cmp_mismatch c |
|---|
| 333 | | _ ⇒ None ? ] |
|---|
| 334 | | Vnull r1 ⇒ |
|---|
| 335 | match v2 with |
|---|
| 336 | [ Vptr r2 b2 p2 ofs2 ⇒ sem_cmp_mismatch c |
|---|
| 337 | | Vnull r2 ⇒ sem_cmp_match c |
|---|
| 338 | | _ ⇒ None ? |
|---|
| 339 | ] |
|---|
| 340 | | _ ⇒ None ? ] |
|---|
| 341 | | cmp_case_ff ⇒ |
|---|
| 342 | match v1 with |
|---|
| 343 | [ Vfloat f1 ⇒ |
|---|
| 344 | match v2 with |
|---|
| 345 | [ Vfloat f2 ⇒ Some ? (of_bool (Fcmp c f1 f2)) |
|---|
| 346 | | _ ⇒ None ? ] |
|---|
| 347 | | _ ⇒ None ? ] |
|---|
| 348 | | cmp_default ⇒ None ? |
|---|
| 349 | ]. |
|---|
| 350 | |
|---|
| 351 | definition sem_unary_operation |
|---|
| 352 | : unary_operation → val → type → option val ≝ |
|---|
| 353 | λop,v,ty. |
|---|
| 354 | match op with |
|---|
| 355 | [ Onotbool => sem_notbool v ty |
|---|
| 356 | | Onotint => sem_notint v |
|---|
| 357 | | Oneg => sem_neg v ty |
|---|
| 358 | ]. |
|---|
| 359 | |
|---|
| 360 | let rec sem_binary_operation |
|---|
| 361 | (op: binary_operation) |
|---|
| 362 | (v1: val) (t1: type) (v2: val) (t2:type) |
|---|
| 363 | (m: mem): option val ≝ |
|---|
| 364 | match op with |
|---|
| 365 | [ Oadd ⇒ sem_add v1 t1 v2 t2 |
|---|
| 366 | | Osub ⇒ sem_sub v1 t1 v2 t2 |
|---|
| 367 | | Omul ⇒ sem_mul v1 t1 v2 t2 |
|---|
| 368 | | Omod ⇒ sem_mod v1 t1 v2 t2 |
|---|
| 369 | | Odiv ⇒ sem_div v1 t1 v2 t2 |
|---|
| 370 | | Oand ⇒ sem_and v1 v2 |
|---|
| 371 | | Oor ⇒ sem_or v1 v2 |
|---|
| 372 | | Oxor ⇒ sem_xor v1 v2 |
|---|
| 373 | | Oshl ⇒ sem_shl v1 v2 |
|---|
| 374 | | Oshr ⇒ sem_shr v1 t1 v2 t2 |
|---|
| 375 | | Oeq ⇒ sem_cmp Ceq v1 t1 v2 t2 m |
|---|
| 376 | | One ⇒ sem_cmp Cne v1 t1 v2 t2 m |
|---|
| 377 | | Olt ⇒ sem_cmp Clt v1 t1 v2 t2 m |
|---|
| 378 | | Ogt ⇒ sem_cmp Cgt v1 t1 v2 t2 m |
|---|
| 379 | | Ole ⇒ sem_cmp Cle v1 t1 v2 t2 m |
|---|
| 380 | | Oge ⇒ sem_cmp Cge v1 t1 v2 t2 m |
|---|
| 381 | ]. |
|---|
| 382 | |
|---|
| 383 | (* * Semantic of casts. [cast v1 t1 t2 v2] holds if value [v1], |
|---|
| 384 | viewed with static type [t1], can be cast to type [t2], |
|---|
| 385 | resulting in value [v2]. *) |
|---|
| 386 | |
|---|
| 387 | let rec cast_int_int (sz: intsize) (sg: signedness) (i: int) : int ≝ |
|---|
| 388 | match sz with |
|---|
| 389 | [ I8 ⇒ match sg with [ Signed ⇒ sign_ext 8 i | Unsigned ⇒ zero_ext 8 i ] |
|---|
| 390 | | I16 ⇒ match sg with [ Signed => sign_ext 16 i | Unsigned ⇒ zero_ext 16 i ] |
|---|
| 391 | | I32 ⇒ i |
|---|
| 392 | ]. |
|---|
| 393 | |
|---|
| 394 | let rec cast_int_float (si : signedness) (i: int) : float ≝ |
|---|
| 395 | match si with |
|---|
| 396 | [ Signed ⇒ floatofint i |
|---|
| 397 | | Unsigned ⇒ floatofintu i |
|---|
| 398 | ]. |
|---|
| 399 | |
|---|
| 400 | let rec cast_float_int (si : signedness) (f: float) : int ≝ |
|---|
| 401 | match si with |
|---|
| 402 | [ Signed ⇒ intoffloat f |
|---|
| 403 | | Unsigned ⇒ intuoffloat f |
|---|
| 404 | ]. |
|---|
| 405 | |
|---|
| 406 | let rec cast_float_float (sz: floatsize) (f: float) : float ≝ |
|---|
| 407 | match sz with |
|---|
| 408 | [ F32 ⇒ singleoffloat f |
|---|
| 409 | | F64 ⇒ f |
|---|
| 410 | ]. |
|---|
| 411 | |
|---|
| 412 | inductive type_region : type → region → Prop ≝ |
|---|
| 413 | | type_rgn_pointer : ∀s,t. type_region (Tpointer s t) s |
|---|
| 414 | | type_rgn_array : ∀s,t,n. type_region (Tarray s t n) s |
|---|
| 415 | (* XXX Is the following necessary? *) |
|---|
| 416 | | type_rgn_code : ∀tys,ty. type_region (Tfunction tys ty) Code. |
|---|
| 417 | |
|---|
| 418 | inductive cast : mem → val → type → type → val → Prop ≝ |
|---|
| 419 | | cast_ii: ∀m,i,sz2,sz1,si1,si2. (**r int to int *) |
|---|
| 420 | cast m (Vint i) (Tint sz1 si1) (Tint sz2 si2) |
|---|
| 421 | (Vint (cast_int_int sz2 si2 i)) |
|---|
| 422 | | cast_fi: ∀m,f,sz1,sz2,si2. (**r float to int *) |
|---|
| 423 | cast m (Vfloat f) (Tfloat sz1) (Tint sz2 si2) |
|---|
| 424 | (Vint (cast_int_int sz2 si2 (cast_float_int si2 f))) |
|---|
| 425 | | cast_if: ∀m,i,sz1,sz2,si1. (**r int to float *) |
|---|
| 426 | cast m (Vint i) (Tint sz1 si1) (Tfloat sz2) |
|---|
| 427 | (Vfloat (cast_float_float sz2 (cast_int_float si1 i))) |
|---|
| 428 | | cast_ff: ∀m,f,sz1,sz2. (**r float to float *) |
|---|
| 429 | cast m (Vfloat f) (Tfloat sz1) (Tfloat sz2) |
|---|
| 430 | (Vfloat (cast_float_float sz2 f)) |
|---|
| 431 | | cast_pp: ∀m,r,r',ty,ty',b,pc,ofs. |
|---|
| 432 | type_region ty r → |
|---|
| 433 | type_region ty' r' → |
|---|
| 434 | ∀pc':pointer_compat b r'. |
|---|
| 435 | cast m (Vptr r b pc ofs) ty ty' (Vptr r' b pc' ofs) |
|---|
| 436 | | cast_ip_z: ∀m,sz,sg,ty',r. |
|---|
| 437 | type_region ty' r → |
|---|
| 438 | cast m (Vint zero) (Tint sz sg) ty' (Vnull r) |
|---|
| 439 | | cast_pp_z: ∀m,ty,ty',r,r'. |
|---|
| 440 | type_region ty r → |
|---|
| 441 | type_region ty' r' → |
|---|
| 442 | cast m (Vnull r) ty ty' (Vnull r'). |
|---|
| 443 | |
|---|
| 444 | (* * * Operational semantics *) |
|---|
| 445 | |
|---|
| 446 | (* * The semantics uses two environments. The global environment |
|---|
| 447 | maps names of functions and global variables to memory block references, |
|---|
| 448 | and function pointers to their definitions. (See module [Globalenvs].) *) |
|---|
| 449 | |
|---|
| 450 | definition genv ≝ (genv_t Genv) fundef. |
|---|
| 451 | |
|---|
| 452 | (* * The local environment maps local variables to block references. |
|---|
| 453 | The current value of the variable is stored in the associated memory |
|---|
| 454 | block. *) |
|---|
| 455 | |
|---|
| 456 | definition env ≝ (tree_t ? PTree) block. (* map variable -> location *) |
|---|
| 457 | |
|---|
| 458 | definition empty_env: env ≝ (empty …). |
|---|
| 459 | |
|---|
| 460 | (* * [load_value_of_type ty m b ofs] computes the value of a datum |
|---|
| 461 | of type [ty] residing in memory [m] at block [b], offset [ofs]. |
|---|
| 462 | If the type [ty] indicates an access by value, the corresponding |
|---|
| 463 | memory load is performed. If the type [ty] indicates an access by |
|---|
| 464 | reference, the pointer [Vptr b ofs] is returned. *) |
|---|
| 465 | |
|---|
| 466 | let rec load_value_of_type (ty: type) (m: mem) (b: block) (ofs: int) : option val ≝ |
|---|
| 467 | match access_mode ty with |
|---|
| 468 | [ By_value chunk ⇒ loadv chunk m (Vptr Any b ? ofs) |
|---|
| 469 | | By_reference r ⇒ |
|---|
| 470 | match pointer_compat_dec b r with |
|---|
| 471 | [ inl p ⇒ Some ? (Vptr r b p ofs) |
|---|
| 472 | | inr _ ⇒ None ? |
|---|
| 473 | ] |
|---|
| 474 | | By_nothing ⇒ None ? |
|---|
| 475 | ]. |
|---|
| 476 | cases b // |
|---|
| 477 | qed. |
|---|
| 478 | |
|---|
| 479 | (* * Symmetrically, [store_value_of_type ty m b ofs v] returns the |
|---|
| 480 | memory state after storing the value [v] in the datum |
|---|
| 481 | of type [ty] residing in memory [m] at block [b], offset [ofs]. |
|---|
| 482 | This is allowed only if [ty] indicates an access by value. *) |
|---|
| 483 | |
|---|
| 484 | let rec store_value_of_type (ty_dest: type) (m: mem) (loc: block) (ofs: int) (v: val) : option mem ≝ |
|---|
| 485 | match access_mode ty_dest with |
|---|
| 486 | [ By_value chunk ⇒ storev chunk m (Vptr Any loc ? ofs) v |
|---|
| 487 | | By_reference _ ⇒ None ? |
|---|
| 488 | | By_nothing ⇒ None ? |
|---|
| 489 | ]. |
|---|
| 490 | cases loc // |
|---|
| 491 | qed. |
|---|
| 492 | |
|---|
| 493 | (* * Allocation of function-local variables. |
|---|
| 494 | [alloc_variables e1 m1 vars e2 m2] allocates one memory block |
|---|
| 495 | for each variable declared in [vars], and associates the variable |
|---|
| 496 | name with this block. [e1] and [m1] are the initial local environment |
|---|
| 497 | and memory state. [e2] and [m2] are the final local environment |
|---|
| 498 | and memory state. *) |
|---|
| 499 | |
|---|
| 500 | inductive alloc_variables: env → mem → |
|---|
| 501 | list (ident × type) → |
|---|
| 502 | env → mem → Prop ≝ |
|---|
| 503 | | alloc_variables_nil: |
|---|
| 504 | ∀e,m. |
|---|
| 505 | alloc_variables e m (nil ?) e m |
|---|
| 506 | | alloc_variables_cons: |
|---|
| 507 | ∀e,m,id,ty,vars,m1,b1,m2,e2. |
|---|
| 508 | alloc m 0 (sizeof ty) Any = 〈m1, b1〉 → |
|---|
| 509 | alloc_variables (set … id b1 e) m1 vars e2 m2 → |
|---|
| 510 | alloc_variables e m (〈id, ty〉 :: vars) e2 m2. |
|---|
| 511 | |
|---|
| 512 | (* * Initialization of local variables that are parameters to a function. |
|---|
| 513 | [bind_parameters e m1 params args m2] stores the values [args] |
|---|
| 514 | in the memory blocks corresponding to the variables [params]. |
|---|
| 515 | [m1] is the initial memory state and [m2] the final memory state. *) |
|---|
| 516 | |
|---|
| 517 | inductive bind_parameters: env → |
|---|
| 518 | mem → list (ident × type) → list val → |
|---|
| 519 | mem → Prop ≝ |
|---|
| 520 | | bind_parameters_nil: |
|---|
| 521 | ∀e,m. |
|---|
| 522 | bind_parameters e m (nil ?) (nil ?) m |
|---|
| 523 | | bind_parameters_cons: |
|---|
| 524 | ∀e,m,id,ty,params,v1,vl,b,m1,m2. |
|---|
| 525 | get ??? id e = Some ? b → |
|---|
| 526 | store_value_of_type ty m b zero v1 = Some ? m1 → |
|---|
| 527 | bind_parameters e m1 params vl m2 → |
|---|
| 528 | bind_parameters e m (〈id, ty〉 :: params) (v1 :: vl) m2. |
|---|
| 529 | |
|---|
| 530 | (* * Return the list of blocks in the codomain of [e]. *) |
|---|
| 531 | |
|---|
| 532 | definition blocks_of_env : env → list block ≝ λe. |
|---|
| 533 | map ?? (λx. snd ?? x) (elements ??? e). |
|---|
| 534 | |
|---|
| 535 | (* * Selection of the appropriate case of a [switch], given the value [n] |
|---|
| 536 | of the selector expression. *) |
|---|
| 537 | |
|---|
| 538 | let rec select_switch (n: int) (sl: labeled_statements) |
|---|
| 539 | on sl : labeled_statements ≝ |
|---|
| 540 | match sl with |
|---|
| 541 | [ LSdefault _ ⇒ sl |
|---|
| 542 | | LScase c s sl' ⇒ if eq c n then sl else select_switch n sl' |
|---|
| 543 | ]. |
|---|
| 544 | |
|---|
| 545 | (* * Turn a labeled statement into a sequence *) |
|---|
| 546 | |
|---|
| 547 | let rec seq_of_labeled_statement (sl: labeled_statements) : statement ≝ |
|---|
| 548 | match sl with |
|---|
| 549 | [ LSdefault s ⇒ s |
|---|
| 550 | | LScase c s sl' ⇒ Ssequence s (seq_of_labeled_statement sl') |
|---|
| 551 | ]. |
|---|
| 552 | |
|---|
| 553 | (* |
|---|
| 554 | Section SEMANTICS. |
|---|
| 555 | |
|---|
| 556 | Variable ge: genv. |
|---|
| 557 | |
|---|
| 558 | (** ** Evaluation of expressions *) |
|---|
| 559 | |
|---|
| 560 | Section EXPR. |
|---|
| 561 | |
|---|
| 562 | Variable e: env. |
|---|
| 563 | Variable m: mem. |
|---|
| 564 | *) |
|---|
| 565 | (* * [eval_expr ge e m a v] defines the evaluation of expression [a] |
|---|
| 566 | in r-value position. [v] is the value of the expression. |
|---|
| 567 | [e] is the current environment and [m] is the current memory state. *) |
|---|
| 568 | |
|---|
| 569 | inductive eval_expr (ge:genv) (e:env) (m:mem) : expr → val → trace → Prop ≝ |
|---|
| 570 | | eval_Econst_int: ∀i,ty. |
|---|
| 571 | eval_expr ge e m (Expr (Econst_int i) ty) (Vint i) E0 |
|---|
| 572 | | eval_Econst_float: ∀f,ty. |
|---|
| 573 | eval_expr ge e m (Expr (Econst_float f) ty) (Vfloat f) E0 |
|---|
| 574 | | eval_Elvalue: ∀a,ty,loc,ofs,v,tr. |
|---|
| 575 | eval_lvalue ge e m (Expr a ty) loc ofs tr → |
|---|
| 576 | load_value_of_type ty m loc ofs = Some ? v → |
|---|
| 577 | eval_expr ge e m (Expr a ty) v tr |
|---|
| 578 | | eval_Eaddrof: ∀a,ty,r,loc,ofs,tr. |
|---|
| 579 | eval_lvalue ge e m a loc ofs tr → |
|---|
| 580 | ∀pc:pointer_compat loc r. |
|---|
| 581 | eval_expr ge e m (Expr (Eaddrof a) (Tpointer r ty)) (Vptr r loc pc ofs) tr |
|---|
| 582 | | eval_Esizeof: ∀ty',ty. |
|---|
| 583 | eval_expr ge e m (Expr (Esizeof ty') ty) (Vint (repr (sizeof ty'))) E0 |
|---|
| 584 | | eval_Eunop: ∀op,a,ty,v1,v,tr. |
|---|
| 585 | eval_expr ge e m a v1 tr → |
|---|
| 586 | sem_unary_operation op v1 (typeof a) = Some ? v → |
|---|
| 587 | eval_expr ge e m (Expr (Eunop op a) ty) v tr |
|---|
| 588 | | eval_Ebinop: ∀op,a1,a2,ty,v1,v2,v,tr1,tr2. |
|---|
| 589 | eval_expr ge e m a1 v1 tr1 → |
|---|
| 590 | eval_expr ge e m a2 v2 tr2 → |
|---|
| 591 | sem_binary_operation op v1 (typeof a1) v2 (typeof a2) m = Some ? v → |
|---|
| 592 | eval_expr ge e m (Expr (Ebinop op a1 a2) ty) v (tr1⧺tr2) |
|---|
| 593 | | eval_Econdition_true: ∀a1,a2,a3,ty,v1,v2,tr1,tr2. |
|---|
| 594 | eval_expr ge e m a1 v1 tr1 → |
|---|
| 595 | is_true v1 (typeof a1) → |
|---|
| 596 | eval_expr ge e m a2 v2 tr2 → |
|---|
| 597 | eval_expr ge e m (Expr (Econdition a1 a2 a3) ty) v2 (tr1⧺tr2) |
|---|
| 598 | | eval_Econdition_false: ∀a1,a2,a3,ty,v1,v3,tr1,tr2. |
|---|
| 599 | eval_expr ge e m a1 v1 tr1 → |
|---|
| 600 | is_false v1 (typeof a1) → |
|---|
| 601 | eval_expr ge e m a3 v3 tr2 → |
|---|
| 602 | eval_expr ge e m (Expr (Econdition a1 a2 a3) ty) v3 (tr1⧺tr2) |
|---|
| 603 | | eval_Eorbool_1: ∀a1,a2,ty,v1,tr. |
|---|
| 604 | eval_expr ge e m a1 v1 tr → |
|---|
| 605 | is_true v1 (typeof a1) → |
|---|
| 606 | eval_expr ge e m (Expr (Eorbool a1 a2) ty) Vtrue tr |
|---|
| 607 | | eval_Eorbool_2: ∀a1,a2,ty,v1,v2,v,tr1,tr2. |
|---|
| 608 | eval_expr ge e m a1 v1 tr1 → |
|---|
| 609 | is_false v1 (typeof a1) → |
|---|
| 610 | eval_expr ge e m a2 v2 tr2 → |
|---|
| 611 | bool_of_val v2 (typeof a2) v → |
|---|
| 612 | eval_expr ge e m (Expr (Eorbool a1 a2) ty) v (tr1⧺tr2) |
|---|
| 613 | | eval_Eandbool_1: ∀a1,a2,ty,v1,tr. |
|---|
| 614 | eval_expr ge e m a1 v1 tr → |
|---|
| 615 | is_false v1 (typeof a1) → |
|---|
| 616 | eval_expr ge e m (Expr (Eandbool a1 a2) ty) Vfalse tr |
|---|
| 617 | | eval_Eandbool_2: ∀a1,a2,ty,v1,v2,v,tr1,tr2. |
|---|
| 618 | eval_expr ge e m a1 v1 tr1 → |
|---|
| 619 | is_true v1 (typeof a1) → |
|---|
| 620 | eval_expr ge e m a2 v2 tr2 → |
|---|
| 621 | bool_of_val v2 (typeof a2) v → |
|---|
| 622 | eval_expr ge e m (Expr (Eandbool a1 a2) ty) v (tr1⧺tr2) |
|---|
| 623 | | eval_Ecast: ∀a,ty,ty',v1,v,tr. |
|---|
| 624 | eval_expr ge e m a v1 tr → |
|---|
| 625 | cast m v1 (typeof a) ty v → |
|---|
| 626 | eval_expr ge e m (Expr (Ecast ty a) ty') v tr |
|---|
| 627 | | eval_Ecost: ∀a,ty,v,l,tr. |
|---|
| 628 | eval_expr ge e m a v tr → |
|---|
| 629 | eval_expr ge e m (Expr (Ecost l a) ty) v (tr⧺Echarge l) |
|---|
| 630 | |
|---|
| 631 | (* * [eval_lvalue ge e m a r b ofs] defines the evaluation of expression [a] |
|---|
| 632 | in l-value position. The result is the memory location [b, ofs] |
|---|
| 633 | that contains the value of the expression [a]. The memory location should |
|---|
| 634 | be representable in a pointer of region r. *) |
|---|
| 635 | |
|---|
| 636 | with eval_lvalue (*(ge:genv) (e:env) (m:mem)*) : expr → block → int → trace → Prop ≝ |
|---|
| 637 | | eval_Evar_local: ∀id,l,ty. |
|---|
| 638 | (* XXX notation? e!id*) get ??? id e = Some ? l → |
|---|
| 639 | eval_lvalue ge e m (Expr (Evar id) ty) l zero E0 |
|---|
| 640 | | eval_Evar_global: ∀id,l,ty. |
|---|
| 641 | (* XXX e!id *) get ??? id e = None ? → |
|---|
| 642 | find_symbol ?? ge id = Some ? l → |
|---|
| 643 | eval_lvalue ge e m (Expr (Evar id) ty) l zero E0 |
|---|
| 644 | | eval_Ederef: ∀a,ty,r,l,p,ofs,tr. |
|---|
| 645 | eval_expr ge e m a (Vptr r l p ofs) tr → |
|---|
| 646 | eval_lvalue ge e m (Expr (Ederef a) ty) l ofs tr |
|---|
| 647 | (* Aside: note that each block of memory is entirely contained within one |
|---|
| 648 | memory region; hence adding a field offset will not produce a location |
|---|
| 649 | outside of the original location's region. *) |
|---|
| 650 | | eval_Efield_struct: ∀a,i,ty,l,ofs,id,fList,delta,tr. |
|---|
| 651 | eval_lvalue ge e m a l ofs tr → |
|---|
| 652 | typeof a = Tstruct id fList → |
|---|
| 653 | field_offset i fList = OK ? delta → |
|---|
| 654 | eval_lvalue ge e m (Expr (Efield a i) ty) l (add ofs (repr delta)) tr |
|---|
| 655 | | eval_Efield_union: ∀a,i,ty,l,ofs,id,fList,tr. |
|---|
| 656 | eval_lvalue ge e m a l ofs tr → |
|---|
| 657 | typeof a = Tunion id fList → |
|---|
| 658 | eval_lvalue ge e m (Expr (Efield a i) ty) l ofs tr. |
|---|
| 659 | |
|---|
| 660 | let rec eval_expr_ind (ge:genv) (e:env) (m:mem) |
|---|
| 661 | (P:∀a,v,tr. eval_expr ge e m a v tr → Prop) |
|---|
| 662 | (eci:∀i,ty. P ??? (eval_Econst_int ge e m i ty)) |
|---|
| 663 | (ecF:∀f,ty. P ??? (eval_Econst_float ge e m f ty)) |
|---|
| 664 | (elv:∀a,ty,loc,ofs,v,tr,H1,H2. P ??? (eval_Elvalue ge e m a ty loc ofs v tr H1 H2)) |
|---|
| 665 | (ead:∀a,ty,r,loc,pc,ofs,tr,H. P ??? (eval_Eaddrof ge e m a ty r loc pc ofs tr H)) |
|---|
| 666 | (esz:∀ty',ty. P ??? (eval_Esizeof ge e m ty' ty)) |
|---|
| 667 | (eun:∀op,a,ty,v1,v,tr,H1,H2. P a v1 tr H1 → P ??? (eval_Eunop ge e m op a ty v1 v tr H1 H2)) |
|---|
| 668 | (ebi:∀op,a1,a2,ty,v1,v2,v,tr1,tr2,H1,H2,H3. P a1 v1 tr1 H1 → P a2 v2 tr2 H2 → P ??? (eval_Ebinop ge e m op a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3)) |
|---|
| 669 | (ect:∀a1,a2,a3,ty,v1,v2,tr1,tr2,H1,H2,H3. P a1 v1 tr1 H1 → P a2 v2 tr2 H3 → P ??? (eval_Econdition_true ge e m a1 a2 a3 ty v1 v2 tr1 tr2 H1 H2 H3)) |
|---|
| 670 | (ecf:∀a1,a2,a3,ty,v1,v3,tr1,tr2,H1,H2,H3. P a1 v1 tr1 H1 → P a3 v3 tr2 H3 → P ??? (eval_Econdition_false ge e m a1 a2 a3 ty v1 v3 tr1 tr2 H1 H2 H3)) |
|---|
| 671 | (eo1:∀a1,a2,ty,v1,tr,H1,H2. P a1 v1 tr H1 → P ??? (eval_Eorbool_1 ge e m a1 a2 ty v1 tr H1 H2)) |
|---|
| 672 | (eo2:∀a1,a2,ty,v1,v2,v,tr1,tr2,H1,H2,H3,H4. P a1 v1 tr1 H1 → P a2 v2 tr2 H3 → P ??? (eval_Eorbool_2 ge e m a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4)) |
|---|
| 673 | (ea1:∀a1,a2,ty,v1,tr,H1,H2. P a1 v1 tr H1 → P ??? (eval_Eandbool_1 ge e m a1 a2 ty v1 tr H1 H2)) |
|---|
| 674 | (ea2:∀a1,a2,ty,v1,v2,v,tr1,tr2,H1,H2,H3,H4. P a1 v1 tr1 H1 → P a2 v2 tr2 H3 → P ??? (eval_Eandbool_2 ge e m a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4)) |
|---|
| 675 | (ecs:∀a,ty,ty',v1,v,tr,H1,H2. P a v1 tr H1 → P ??? (eval_Ecast ge e m a ty ty' v1 v tr H1 H2)) |
|---|
| 676 | (eco:∀a,ty,v,l,tr,H. P a v tr H → P ??? (eval_Ecost ge e m a ty v l tr H)) |
|---|
| 677 | (a:expr) (v:val) (tr:trace) (ev:eval_expr ge e m a v tr) on ev : P a v tr ev ≝ |
|---|
| 678 | match ev with |
|---|
| 679 | [ eval_Econst_int i ty ⇒ eci i ty |
|---|
| 680 | | eval_Econst_float f ty ⇒ ecF f ty |
|---|
| 681 | | eval_Elvalue a ty loc ofs v tr H1 H2 ⇒ elv a ty loc ofs v tr H1 H2 |
|---|
| 682 | | eval_Eaddrof a ty r loc pc ofs tr H ⇒ ead a ty r loc pc ofs tr H |
|---|
| 683 | | eval_Esizeof ty' ty ⇒ esz ty' ty |
|---|
| 684 | | eval_Eunop op a ty v1 v tr H1 H2 ⇒ eun op a ty v1 v tr H1 H2 (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a v1 tr H1) |
|---|
| 685 | | eval_Ebinop op a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 ⇒ ebi op a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a1 v1 tr1 H1) (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a2 v2 tr2 H2) |
|---|
| 686 | | eval_Econdition_true a1 a2 a3 ty v1 v2 tr1 tr2 H1 H2 H3 ⇒ ect a1 a2 a3 ty v1 v2 tr1 tr2 H1 H2 H3 (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a1 v1 tr1 H1) (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a2 v2 tr2 H3) |
|---|
| 687 | | eval_Econdition_false a1 a2 a3 ty v1 v3 tr1 tr2 H1 H2 H3 ⇒ ecf a1 a2 a3 ty v1 v3 tr1 tr2 H1 H2 H3 (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a1 v1 tr1 H1) (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a3 v3 tr2 H3) |
|---|
| 688 | | eval_Eorbool_1 a1 a2 ty v1 tr H1 H2 ⇒ eo1 a1 a2 ty v1 tr H1 H2 (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a1 v1 tr H1) |
|---|
| 689 | | eval_Eorbool_2 a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4 ⇒ eo2 a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4 (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a1 v1 tr1 H1) (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a2 v2 tr2 H3) |
|---|
| 690 | | eval_Eandbool_1 a1 a2 ty v1 tr H1 H2 ⇒ ea1 a1 a2 ty v1 tr H1 H2 (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a1 v1 tr H1) |
|---|
| 691 | | eval_Eandbool_2 a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4 ⇒ ea2 a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4 (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a1 v1 tr1 H1) (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a2 v2 tr2 H3) |
|---|
| 692 | | eval_Ecast a ty ty' v1 v tr H1 H2 ⇒ ecs a ty ty' v1 v tr H1 H2 (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a v1 tr H1) |
|---|
| 693 | | eval_Ecost a ty v l tr H ⇒ eco a ty v l tr H (eval_expr_ind ge e m P eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco a v tr H) |
|---|
| 694 | ]. |
|---|
| 695 | |
|---|
| 696 | inverter eval_expr_inv_ind for eval_expr : Prop. |
|---|
| 697 | |
|---|
| 698 | let rec eval_lvalue_ind (ge:genv) (e:env) (m:mem) |
|---|
| 699 | (P:∀a,loc,ofs,tr. eval_lvalue ge e m a loc ofs tr → Prop) |
|---|
| 700 | (lvl:∀id,l,ty,H. P ???? (eval_Evar_local ge e m id l ty H)) |
|---|
| 701 | (lvg:∀id,l,ty,H1,H2. P ???? (eval_Evar_global ge e m id l ty H1 H2)) |
|---|
| 702 | (lde:∀a,ty,r,l,pc,ofs,tr,H. P ???? (eval_Ederef ge e m a ty r l pc ofs tr H)) |
|---|
| 703 | (lfs:∀a,i,ty,l,ofs,id,fList,delta,tr,H1,H2,H3. P a l ofs tr H1 → P ???? (eval_Efield_struct ge e m a i ty l ofs id fList delta tr H1 H2 H3)) |
|---|
| 704 | (lfu:∀a,i,ty,l,ofs,id,fList,tr,H1,H2. P a l ofs tr H1 → P ???? (eval_Efield_union ge e m a i ty l ofs id fList tr H1 H2)) |
|---|
| 705 | (a:expr) (loc:block) (ofs:int) (tr:trace) (ev:eval_lvalue ge e m a loc ofs tr) on ev : P a loc ofs tr ev ≝ |
|---|
| 706 | match ev with |
|---|
| 707 | [ eval_Evar_local id l ty H ⇒ lvl id l ty H |
|---|
| 708 | | eval_Evar_global id l ty H1 H2 ⇒ lvg id l ty H1 H2 |
|---|
| 709 | | eval_Ederef a ty r l pc ofs tr H ⇒ lde a ty r l pc ofs tr H |
|---|
| 710 | | eval_Efield_struct a i ty l ofs id fList delta tr H1 H2 H3 ⇒ lfs a i ty l ofs id fList delta tr H1 H2 H3 (eval_lvalue_ind ge e m P lvl lvg lde lfs lfu a l ofs tr H1) |
|---|
| 711 | | eval_Efield_union a i ty l ofs id fList tr H1 H2 ⇒ lfu a i ty l ofs id fList tr H1 H2 (eval_lvalue_ind ge e m P lvl lvg lde lfs lfu a l ofs tr H1) |
|---|
| 712 | ]. |
|---|
| 713 | |
|---|
| 714 | (* |
|---|
| 715 | ninverter eval_lvalue_inv_ind for eval_lvalue : Prop. |
|---|
| 716 | *) |
|---|
| 717 | |
|---|
| 718 | definition eval_lvalue_inv_ind : |
|---|
| 719 | ∀x1: genv. |
|---|
| 720 | ∀x2: env. |
|---|
| 721 | ∀x3: mem. |
|---|
| 722 | ∀x4: expr. |
|---|
| 723 | ∀x6: block. |
|---|
| 724 | ∀x7: int. |
|---|
| 725 | ∀x8: trace. |
|---|
| 726 | ∀P: |
|---|
| 727 | ∀_z1430: expr. |
|---|
| 728 | ∀_z1428: block. ∀_z1427: int. ∀_z1426: trace. Prop. |
|---|
| 729 | ∀_H1: ?. |
|---|
| 730 | ∀_H2: ?. |
|---|
| 731 | ∀_H3: ?. |
|---|
| 732 | ∀_H4: ?. |
|---|
| 733 | ∀_H5: ?. |
|---|
| 734 | ∀_Hterm: eval_lvalue x1 x2 x3 x4 x6 x7 x8. |
|---|
| 735 | P x4 x6 x7 x8 |
|---|
| 736 | := |
|---|
| 737 | (λx1:genv. |
|---|
| 738 | (λx2:env. |
|---|
| 739 | (λx3:mem. |
|---|
| 740 | (λx4:expr. |
|---|
| 741 | (λx6:block. |
|---|
| 742 | (λx7:int. |
|---|
| 743 | (λx8:trace. |
|---|
| 744 | (λP:∀_z1430: expr. |
|---|
| 745 | ∀_z1428: block. |
|---|
| 746 | ∀_z1427: int. ∀_z1426: trace. Prop. |
|---|
| 747 | (λH1:?. |
|---|
| 748 | (λH2:?. |
|---|
| 749 | (λH3:?. |
|---|
| 750 | (λH4:?. |
|---|
| 751 | (λH5:?. |
|---|
| 752 | (λHterm:eval_lvalue x1 x2 x3 x4 x6 x7 x8. |
|---|
| 753 | ((λHcut:∀z1435: eq expr x4 x4. |
|---|
| 754 | ∀z1433: eq block x6 x6. |
|---|
| 755 | ∀z1432: eq int x7 x7. |
|---|
| 756 | ∀z1431: eq trace x8 x8. |
|---|
| 757 | P x4 x6 x7 x8. |
|---|
| 758 | (Hcut (refl expr x4) |
|---|
| 759 | (refl block x6) |
|---|
| 760 | (refl int x7) (refl trace x8))) |
|---|
| 761 | ?))))))))))))))). |
|---|
| 762 | [ @(eval_lvalue_ind x1 x2 x3 (λa,loc,ofs,tr,e. ∀e1:eq ? x4 a. ∀e3:eq ? x6 loc. ∀e4:eq ? x7 ofs. ∀e5:eq ? x8 tr. P a loc ofs tr) … Hterm) |
|---|
| 763 | [ @H1 | @H2 | @H3 | @H4 | @H5 ] |
|---|
| 764 | | *: skip |
|---|
| 765 | ] qed. |
|---|
| 766 | |
|---|
| 767 | let rec eval_expr_ind2 (ge:genv) (e:env) (m:mem) |
|---|
| 768 | (P:∀a,v,tr. eval_expr ge e m a v tr → Prop) |
|---|
| 769 | (Q:∀a,loc,ofs,tr. eval_lvalue ge e m a loc ofs tr → Prop) |
|---|
| 770 | (eci:∀i,ty. P ??? (eval_Econst_int ge e m i ty)) |
|---|
| 771 | (ecF:∀f,ty. P ??? (eval_Econst_float ge e m f ty)) |
|---|
| 772 | (elv:∀a,ty,loc,ofs,v,tr,H1,H2. Q (Expr a ty) loc ofs tr H1 → P ??? (eval_Elvalue ge e m a ty loc ofs v tr H1 H2)) |
|---|
| 773 | (ead:∀a,ty,r,loc,pc,ofs,tr,H. Q a loc ofs tr H → P ??? (eval_Eaddrof ge e m a ty r loc ofs tr H pc)) |
|---|
| 774 | (esz:∀ty',ty. P ??? (eval_Esizeof ge e m ty' ty)) |
|---|
| 775 | (eun:∀op,a,ty,v1,v,tr,H1,H2. P a v1 tr H1 → P ??? (eval_Eunop ge e m op a ty v1 v tr H1 H2)) |
|---|
| 776 | (ebi:∀op,a1,a2,ty,v1,v2,v,tr1,tr2,H1,H2,H3. P a1 v1 tr1 H1 → P a2 v2 tr2 H2 → P ??? (eval_Ebinop ge e m op a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3)) |
|---|
| 777 | (ect:∀a1,a2,a3,ty,v1,v2,tr1,tr2,H1,H2,H3. P a1 v1 tr1 H1 → P a2 v2 tr2 H3 → P ??? (eval_Econdition_true ge e m a1 a2 a3 ty v1 v2 tr1 tr2 H1 H2 H3)) |
|---|
| 778 | (ecf:∀a1,a2,a3,ty,v1,v3,tr1,tr2,H1,H2,H3. P a1 v1 tr1 H1 → P a3 v3 tr2 H3 → P ??? (eval_Econdition_false ge e m a1 a2 a3 ty v1 v3 tr1 tr2 H1 H2 H3)) |
|---|
| 779 | (eo1:∀a1,a2,ty,v1,tr,H1,H2. P a1 v1 tr H1 → P ??? (eval_Eorbool_1 ge e m a1 a2 ty v1 tr H1 H2)) |
|---|
| 780 | (eo2:∀a1,a2,ty,v1,v2,v,tr1,tr2,H1,H2,H3,H4. P a1 v1 tr1 H1 → P a2 v2 tr2 H3 → P ??? (eval_Eorbool_2 ge e m a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4)) |
|---|
| 781 | (ea1:∀a1,a2,ty,v1,tr,H1,H2. P a1 v1 tr H1 → P ??? (eval_Eandbool_1 ge e m a1 a2 ty v1 tr H1 H2)) |
|---|
| 782 | (ea2:∀a1,a2,ty,v1,v2,v,tr1,tr2,H1,H2,H3,H4. P a1 v1 tr1 H1 → P a2 v2 tr2 H3 → P ??? (eval_Eandbool_2 ge e m a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4)) |
|---|
| 783 | (ecs:∀a,ty,ty',v1,v,tr,H1,H2. P a v1 tr H1 → P ??? (eval_Ecast ge e m a ty ty' v1 v tr H1 H2)) |
|---|
| 784 | (eco:∀a,ty,v,l,tr,H. P a v tr H → P ??? (eval_Ecost ge e m a ty v l tr H)) |
|---|
| 785 | (lvl:∀id,l,ty,H. Q ???? (eval_Evar_local ge e m id l ty H)) |
|---|
| 786 | (lvg:∀id,l,ty,H1,H2. Q ???? (eval_Evar_global ge e m id l ty H1 H2)) |
|---|
| 787 | (lde:∀a,ty,r,l,pc,ofs,tr,H. P a (Vptr r l pc ofs) tr H → Q ???? (eval_Ederef ge e m a ty r l pc ofs tr H)) |
|---|
| 788 | (lfs:∀a,i,ty,l,ofs,id,fList,delta,tr,H1,H2,H3. Q a l ofs tr H1 → Q ???? (eval_Efield_struct ge e m a i ty l ofs id fList delta tr H1 H2 H3)) |
|---|
| 789 | (lfu:∀a,i,ty,l,ofs,id,fList,tr,H1,H2. Q a l ofs tr H1 → Q ???? (eval_Efield_union ge e m a i ty l ofs id fList tr H1 H2)) |
|---|
| 790 | |
|---|
| 791 | (a:expr) (v:val) (tr:trace) (ev:eval_expr ge e m a v tr) on ev : P a v tr ev ≝ |
|---|
| 792 | match ev with |
|---|
| 793 | [ eval_Econst_int i ty ⇒ eci i ty |
|---|
| 794 | | eval_Econst_float f ty ⇒ ecF f ty |
|---|
| 795 | | eval_Elvalue a ty loc ofs v tr H1 H2 ⇒ elv a ty loc ofs v tr H1 H2 (eval_lvalue_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu (Expr a ty) loc ofs tr H1) |
|---|
| 796 | | eval_Eaddrof a ty r loc ofs tr H pc ⇒ ead a ty r loc pc ofs tr H (eval_lvalue_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a loc ofs tr H) |
|---|
| 797 | | eval_Esizeof ty' ty ⇒ esz ty' ty |
|---|
| 798 | | eval_Eunop op a ty v1 v tr H1 H2 ⇒ eun op a ty v1 v tr H1 H2 (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a v1 tr H1) |
|---|
| 799 | | eval_Ebinop op a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 ⇒ ebi op a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a1 v1 tr1 H1) (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a2 v2 tr2 H2) |
|---|
| 800 | | eval_Econdition_true a1 a2 a3 ty v1 v2 tr1 tr2 H1 H2 H3 ⇒ ect a1 a2 a3 ty v1 v2 tr1 tr2 H1 H2 H3 (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a1 v1 tr1 H1) (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a2 v2 tr2 H3) |
|---|
| 801 | | eval_Econdition_false a1 a2 a3 ty v1 v3 tr1 tr2 H1 H2 H3 ⇒ ecf a1 a2 a3 ty v1 v3 tr1 tr2 H1 H2 H3 (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a1 v1 tr1 H1) (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a3 v3 tr2 H3) |
|---|
| 802 | | eval_Eorbool_1 a1 a2 ty v1 tr H1 H2 ⇒ eo1 a1 a2 ty v1 tr H1 H2 (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a1 v1 tr H1) |
|---|
| 803 | | eval_Eorbool_2 a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4 ⇒ eo2 a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4 (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a1 v1 tr1 H1) (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a2 v2 tr2 H3) |
|---|
| 804 | | eval_Eandbool_1 a1 a2 ty v1 tr H1 H2 ⇒ ea1 a1 a2 ty v1 tr H1 H2 (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a1 v1 tr H1) |
|---|
| 805 | | eval_Eandbool_2 a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4 ⇒ ea2 a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4 (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a1 v1 tr1 H1) (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a2 v2 tr2 H3) |
|---|
| 806 | | eval_Ecast a ty ty' v1 v tr H1 H2 ⇒ ecs a ty ty' v1 v tr H1 H2 (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a v1 tr H1) |
|---|
| 807 | | eval_Ecost a ty v l tr H ⇒ eco a ty v l tr H (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a v tr H) |
|---|
| 808 | ] |
|---|
| 809 | and eval_lvalue_ind2 (ge:genv) (e:env) (m:mem) |
|---|
| 810 | (P:∀a,v,tr. eval_expr ge e m a v tr → Prop) |
|---|
| 811 | (Q:∀a,loc,ofs,tr. eval_lvalue ge e m a loc ofs tr → Prop) |
|---|
| 812 | (eci:∀i,ty. P ??? (eval_Econst_int ge e m i ty)) |
|---|
| 813 | (ecF:∀f,ty. P ??? (eval_Econst_float ge e m f ty)) |
|---|
| 814 | (elv:∀a,ty,loc,ofs,v,tr,H1,H2. Q (Expr a ty) loc ofs tr H1 → P ??? (eval_Elvalue ge e m a ty loc ofs v tr H1 H2)) |
|---|
| 815 | (ead:∀a,ty,r,loc,pc,ofs,tr,H. Q a loc ofs tr H → P ??? (eval_Eaddrof ge e m a ty r loc ofs tr H pc)) |
|---|
| 816 | (esz:∀ty',ty. P ??? (eval_Esizeof ge e m ty' ty)) |
|---|
| 817 | (eun:∀op,a,ty,v1,v,tr,H1,H2. P a v1 tr H1 → P ??? (eval_Eunop ge e m op a ty v1 v tr H1 H2)) |
|---|
| 818 | (ebi:∀op,a1,a2,ty,v1,v2,v,tr1,tr2,H1,H2,H3. P a1 v1 tr1 H1 → P a2 v2 tr2 H2 → P ??? (eval_Ebinop ge e m op a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3)) |
|---|
| 819 | (ect:∀a1,a2,a3,ty,v1,v2,tr1,tr2,H1,H2,H3. P a1 v1 tr1 H1 → P a2 v2 tr2 H3 → P ??? (eval_Econdition_true ge e m a1 a2 a3 ty v1 v2 tr1 tr2 H1 H2 H3)) |
|---|
| 820 | (ecf:∀a1,a2,a3,ty,v1,v3,tr1,tr2,H1,H2,H3. P a1 v1 tr1 H1 → P a3 v3 tr2 H3 → P ??? (eval_Econdition_false ge e m a1 a2 a3 ty v1 v3 tr1 tr2 H1 H2 H3)) |
|---|
| 821 | (eo1:∀a1,a2,ty,v1,tr,H1,H2. P a1 v1 tr H1 → P ??? (eval_Eorbool_1 ge e m a1 a2 ty v1 tr H1 H2)) |
|---|
| 822 | (eo2:∀a1,a2,ty,v1,v2,v,tr1,tr2,H1,H2,H3,H4. P a1 v1 tr1 H1 → P a2 v2 tr2 H3 → P ??? (eval_Eorbool_2 ge e m a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4)) |
|---|
| 823 | (ea1:∀a1,a2,ty,v1,tr,H1,H2. P a1 v1 tr H1 → P ??? (eval_Eandbool_1 ge e m a1 a2 ty v1 tr H1 H2)) |
|---|
| 824 | (ea2:∀a1,a2,ty,v1,v2,v,tr1,tr2,H1,H2,H3,H4. P a1 v1 tr1 H1 → P a2 v2 tr2 H3 → P ??? (eval_Eandbool_2 ge e m a1 a2 ty v1 v2 v tr1 tr2 H1 H2 H3 H4)) |
|---|
| 825 | (ecs:∀a,ty,ty',v1,v,tr,H1,H2. P a v1 tr H1 → P ??? (eval_Ecast ge e m a ty ty' v1 v tr H1 H2)) |
|---|
| 826 | (eco:∀a,ty,v,l,tr,H. P a v tr H → P ??? (eval_Ecost ge e m a ty v l tr H)) |
|---|
| 827 | (lvl:∀id,l,ty,H. Q ???? (eval_Evar_local ge e m id l ty H)) |
|---|
| 828 | (lvg:∀id,l,ty,H1,H2. Q ???? (eval_Evar_global ge e m id l ty H1 H2)) |
|---|
| 829 | (lde:∀a,ty,r,l,pc,ofs,tr,H. P a (Vptr r l pc ofs) tr H → Q ???? (eval_Ederef ge e m a ty r l pc ofs tr H)) |
|---|
| 830 | (lfs:∀a,i,ty,l,ofs,id,fList,delta,tr,H1,H2,H3. Q a l ofs tr H1 → Q ???? (eval_Efield_struct ge e m a i ty l ofs id fList delta tr H1 H2 H3)) |
|---|
| 831 | (lfu:∀a,i,ty,l,ofs,id,fList,tr,H1,H2. Q a l ofs tr H1 → Q ???? (eval_Efield_union ge e m a i ty l ofs id fList tr H1 H2)) |
|---|
| 832 | (a:expr) (loc:block) (ofs:int) (tr:trace) (ev:eval_lvalue ge e m a loc ofs tr) on ev : Q a loc ofs tr ev ≝ |
|---|
| 833 | match ev with |
|---|
| 834 | [ eval_Evar_local id l ty H ⇒ lvl id l ty H |
|---|
| 835 | | eval_Evar_global id l ty H1 H2 ⇒ lvg id l ty H1 H2 |
|---|
| 836 | | eval_Ederef a ty r l pc ofs tr H ⇒ lde a ty r l pc ofs tr H (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a (Vptr r l pc ofs) tr H) |
|---|
| 837 | | eval_Efield_struct a i ty l ofs id fList delta tr H1 H2 H3 ⇒ lfs a i ty l ofs id fList delta tr H1 H2 H3 (eval_lvalue_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a l ofs tr H1) |
|---|
| 838 | | eval_Efield_union a i ty l ofs id fList tr H1 H2 ⇒ lfu a i ty l ofs id fList tr H1 H2 (eval_lvalue_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu a l ofs tr H1) |
|---|
| 839 | ]. |
|---|
| 840 | |
|---|
| 841 | definition combined_expr_lvalue_ind ≝ |
|---|
| 842 | λge,e,m,P,Q,eci,ecF,elv,ead,esz,eun,ebi,ect,ecf,eo1,eo2,ea1,ea2,ecs,eco,lvl,lvg,lde,lfs,lfu. |
|---|
| 843 | conj ?? |
|---|
| 844 | (eval_expr_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu) |
|---|
| 845 | (eval_lvalue_ind2 ge e m P Q eci ecF elv ead esz eun ebi ect ecf eo1 eo2 ea1 ea2 ecs eco lvl lvg lde lfs lfu). |
|---|
| 846 | |
|---|
| 847 | (* * [eval_lvalue ge e m a b ofs] defines the evaluation of expression [a] |
|---|
| 848 | in l-value position. The result is the memory location [b, ofs] |
|---|
| 849 | that contains the value of the expression [a]. *) |
|---|
| 850 | |
|---|
| 851 | (* |
|---|
| 852 | Scheme eval_expr_ind22 := Minimality for eval_expr Sort Prop |
|---|
| 853 | with eval_lvalue_ind2 := Minimality for eval_lvalue Sort Prop. |
|---|
| 854 | *) |
|---|
| 855 | |
|---|
| 856 | (* * [eval_exprlist ge e m al vl] evaluates a list of r-value |
|---|
| 857 | expressions [al] to their values [vl]. *) |
|---|
| 858 | |
|---|
| 859 | inductive eval_exprlist (ge:genv) (e:env) (m:mem) : list expr → list val → trace → Prop ≝ |
|---|
| 860 | | eval_Enil: |
|---|
| 861 | eval_exprlist ge e m (nil ?) (nil ?) E0 |
|---|
| 862 | | eval_Econs: ∀a,bl,v,vl,tr1,tr2. |
|---|
| 863 | eval_expr ge e m a v tr1 → |
|---|
| 864 | eval_exprlist ge e m bl vl tr2 → |
|---|
| 865 | eval_exprlist ge e m (a :: bl) (v :: vl) (tr1⧺tr2). |
|---|
| 866 | |
|---|
| 867 | (*End EXPR.*) |
|---|
| 868 | |
|---|
| 869 | (* * ** Transition semantics for statements and functions *) |
|---|
| 870 | |
|---|
| 871 | (* * Continuations *) |
|---|
| 872 | |
|---|
| 873 | inductive cont: Type[0] := |
|---|
| 874 | | Kstop: cont |
|---|
| 875 | | Kseq: statement -> cont -> cont |
|---|
| 876 | (**r [Kseq s2 k] = after [s1] in [s1;s2] *) |
|---|
| 877 | | Kwhile: expr -> statement -> cont -> cont |
|---|
| 878 | (**r [Kwhile e s k] = after [s] in [while (e) s] *) |
|---|
| 879 | | Kdowhile: expr -> statement -> cont -> cont |
|---|
| 880 | (**r [Kdowhile e s k] = after [s] in [do s while (e)] *) |
|---|
| 881 | | Kfor2: expr -> statement -> statement -> cont -> cont |
|---|
| 882 | (**r [Kfor2 e2 e3 s k] = after [s] in [for(e1;e2;e3) s] *) |
|---|
| 883 | | Kfor3: expr -> statement -> statement -> cont -> cont |
|---|
| 884 | (**r [Kfor3 e2 e3 s k] = after [e3] in [for(e1;e2;e3) s] *) |
|---|
| 885 | | Kswitch: cont -> cont |
|---|
| 886 | (**r catches [break] statements arising out of [switch] *) |
|---|
| 887 | | Kcall: option (block × int × type) -> (**r where to store result *) |
|---|
| 888 | function -> (**r calling function *) |
|---|
| 889 | env -> (**r local env of calling function *) |
|---|
| 890 | cont -> cont. |
|---|
| 891 | |
|---|
| 892 | (* * Pop continuation until a call or stop *) |
|---|
| 893 | |
|---|
| 894 | let rec call_cont (k: cont) : cont := |
|---|
| 895 | match k with |
|---|
| 896 | [ Kseq s k => call_cont k |
|---|
| 897 | | Kwhile e s k => call_cont k |
|---|
| 898 | | Kdowhile e s k => call_cont k |
|---|
| 899 | | Kfor2 e2 e3 s k => call_cont k |
|---|
| 900 | | Kfor3 e2 e3 s k => call_cont k |
|---|
| 901 | | Kswitch k => call_cont k |
|---|
| 902 | | _ => k |
|---|
| 903 | ]. |
|---|
| 904 | |
|---|
| 905 | definition is_call_cont : cont → Prop ≝ λk. |
|---|
| 906 | match k with |
|---|
| 907 | [ Kstop => True |
|---|
| 908 | | Kcall _ _ _ _ => True |
|---|
| 909 | | _ => False |
|---|
| 910 | ]. |
|---|
| 911 | |
|---|
| 912 | (* * States *) |
|---|
| 913 | |
|---|
| 914 | inductive state: Type[0] := |
|---|
| 915 | | State: |
|---|
| 916 | ∀f: function. |
|---|
| 917 | ∀s: statement. |
|---|
| 918 | ∀k: cont. |
|---|
| 919 | ∀e: env. |
|---|
| 920 | ∀m: mem. state |
|---|
| 921 | | Callstate: |
|---|
| 922 | ∀fd: fundef. |
|---|
| 923 | ∀args: list val. |
|---|
| 924 | ∀k: cont. |
|---|
| 925 | ∀m: mem. state |
|---|
| 926 | | Returnstate: |
|---|
| 927 | ∀res: val. |
|---|
| 928 | ∀k: cont. |
|---|
| 929 | ∀m: mem. state. |
|---|
| 930 | |
|---|
| 931 | (* * Find the statement and manufacture the continuation |
|---|
| 932 | corresponding to a label *) |
|---|
| 933 | |
|---|
| 934 | let rec find_label (lbl: label) (s: statement) (k: cont) |
|---|
| 935 | on s: option (statement × cont) := |
|---|
| 936 | match s with |
|---|
| 937 | [ Ssequence s1 s2 => |
|---|
| 938 | match find_label lbl s1 (Kseq s2 k) with |
|---|
| 939 | [ Some sk => Some ? sk |
|---|
| 940 | | None => find_label lbl s2 k |
|---|
| 941 | ] |
|---|
| 942 | | Sifthenelse a s1 s2 => |
|---|
| 943 | match find_label lbl s1 k with |
|---|
| 944 | [ Some sk => Some ? sk |
|---|
| 945 | | None => find_label lbl s2 k |
|---|
| 946 | ] |
|---|
| 947 | | Swhile a s1 => |
|---|
| 948 | find_label lbl s1 (Kwhile a s1 k) |
|---|
| 949 | | Sdowhile a s1 => |
|---|
| 950 | find_label lbl s1 (Kdowhile a s1 k) |
|---|
| 951 | | Sfor a1 a2 a3 s1 => |
|---|
| 952 | match find_label lbl a1 (Kseq (Sfor Sskip a2 a3 s1) k) with |
|---|
| 953 | [ Some sk => Some ? sk |
|---|
| 954 | | None => |
|---|
| 955 | match find_label lbl s1 (Kfor2 a2 a3 s1 k) with |
|---|
| 956 | [ Some sk => Some ? sk |
|---|
| 957 | | None => find_label lbl a3 (Kfor3 a2 a3 s1 k) |
|---|
| 958 | ] |
|---|
| 959 | ] |
|---|
| 960 | | Sswitch e sl => |
|---|
| 961 | find_label_ls lbl sl (Kswitch k) |
|---|
| 962 | | Slabel lbl' s' => |
|---|
| 963 | match ident_eq lbl lbl' with |
|---|
| 964 | [ inl _ ⇒ Some ? 〈s', k〉 |
|---|
| 965 | | inr _ ⇒ find_label lbl s' k |
|---|
| 966 | ] |
|---|
| 967 | | _ => None ? |
|---|
| 968 | ] |
|---|
| 969 | |
|---|
| 970 | and find_label_ls (lbl: label) (sl: labeled_statements) (k: cont) |
|---|
| 971 | on sl: option (statement × cont) := |
|---|
| 972 | match sl with |
|---|
| 973 | [ LSdefault s => find_label lbl s k |
|---|
| 974 | | LScase _ s sl' => |
|---|
| 975 | match find_label lbl s (Kseq (seq_of_labeled_statement sl') k) with |
|---|
| 976 | [ Some sk => Some ? sk |
|---|
| 977 | | None => find_label_ls lbl sl' k |
|---|
| 978 | ] |
|---|
| 979 | ]. |
|---|
| 980 | |
|---|
| 981 | (* * Transition relation *) |
|---|
| 982 | |
|---|
| 983 | (* Strip off outer pointer for use when comparing function types. *) |
|---|
| 984 | definition fun_typeof ≝ |
|---|
| 985 | λe. match typeof e with |
|---|
| 986 | [ Tvoid ⇒ Tvoid |
|---|
| 987 | | Tint a b ⇒ Tint a b |
|---|
| 988 | | Tfloat a ⇒ Tfloat a |
|---|
| 989 | | Tpointer _ ty ⇒ ty |
|---|
| 990 | | Tarray a b c ⇒ Tarray a b c |
|---|
| 991 | | Tfunction a b ⇒ Tfunction a b |
|---|
| 992 | | Tstruct a b ⇒ Tstruct a b |
|---|
| 993 | | Tunion a b ⇒ Tunion a b |
|---|
| 994 | | Tcomp_ptr a b ⇒ Tcomp_ptr a b |
|---|
| 995 | ]. |
|---|
| 996 | |
|---|
| 997 | (* XXX: note that cost labels in exprs expose a particular eval order. *) |
|---|
| 998 | |
|---|
| 999 | inductive step (ge:genv) : state → trace → state → Prop ≝ |
|---|
| 1000 | |
|---|
| 1001 | | step_assign: ∀f,a1,a2,k,e,m,loc,ofs,v2,m',tr1,tr2. |
|---|
| 1002 | eval_lvalue ge e m a1 loc ofs tr1 → |
|---|
| 1003 | eval_expr ge e m a2 v2 tr2 → |
|---|
| 1004 | store_value_of_type (typeof a1) m loc ofs v2 = Some ? m' → |
|---|
| 1005 | step ge (State f (Sassign a1 a2) k e m) |
|---|
| 1006 | (tr1⧺tr2) (State f Sskip k e m') |
|---|
| 1007 | |
|---|
| 1008 | | step_call_none: ∀f,a,al,k,e,m,vf,vargs,fd,tr1,tr2. |
|---|
| 1009 | eval_expr ge e m a vf tr1 → |
|---|
| 1010 | eval_exprlist ge e m al vargs tr2 → |
|---|
| 1011 | find_funct ?? ge vf = Some ? fd → |
|---|
| 1012 | type_of_fundef fd = fun_typeof a → |
|---|
| 1013 | step ge (State f (Scall (None ?) a al) k e m) |
|---|
| 1014 | (tr1⧺tr2) (Callstate fd vargs (Kcall (None ?) f e k) m) |
|---|
| 1015 | |
|---|
| 1016 | | step_call_some: ∀f,lhs,a,al,k,e,m,loc,ofs,vf,vargs,fd,tr1,tr2,tr3. |
|---|
| 1017 | eval_lvalue ge e m lhs loc ofs tr1 → |
|---|
| 1018 | eval_expr ge e m a vf tr2 → |
|---|
| 1019 | eval_exprlist ge e m al vargs tr3 → |
|---|
| 1020 | find_funct ?? ge vf = Some ? fd → |
|---|
| 1021 | type_of_fundef fd = fun_typeof a → |
|---|
| 1022 | step ge (State f (Scall (Some ? lhs) a al) k e m) |
|---|
| 1023 | (tr1⧺tr2⧺tr3) (Callstate fd vargs (Kcall (Some ? 〈〈loc, ofs〉, typeof lhs〉) f e k) m) |
|---|
| 1024 | |
|---|
| 1025 | | step_seq: ∀f,s1,s2,k,e,m. |
|---|
| 1026 | step ge (State f (Ssequence s1 s2) k e m) |
|---|
| 1027 | E0 (State f s1 (Kseq s2 k) e m) |
|---|
| 1028 | | step_skip_seq: ∀f,s,k,e,m. |
|---|
| 1029 | step ge (State f Sskip (Kseq s k) e m) |
|---|
| 1030 | E0 (State f s k e m) |
|---|
| 1031 | | step_continue_seq: ∀f,s,k,e,m. |
|---|
| 1032 | step ge (State f Scontinue (Kseq s k) e m) |
|---|
| 1033 | E0 (State f Scontinue k e m) |
|---|
| 1034 | | step_break_seq: ∀f,s,k,e,m. |
|---|
| 1035 | step ge (State f Sbreak (Kseq s k) e m) |
|---|
| 1036 | E0 (State f Sbreak k e m) |
|---|
| 1037 | |
|---|
| 1038 | | step_ifthenelse_true: ∀f,a,s1,s2,k,e,m,v1,tr. |
|---|
| 1039 | eval_expr ge e m a v1 tr → |
|---|
| 1040 | is_true v1 (typeof a) → |
|---|
| 1041 | step ge (State f (Sifthenelse a s1 s2) k e m) |
|---|
| 1042 | tr (State f s1 k e m) |
|---|
| 1043 | | step_ifthenelse_false: ∀f,a,s1,s2,k,e,m,v1,tr. |
|---|
| 1044 | eval_expr ge e m a v1 tr → |
|---|
| 1045 | is_false v1 (typeof a) → |
|---|
| 1046 | step ge (State f (Sifthenelse a s1 s2) k e m) |
|---|
| 1047 | tr (State f s2 k e m) |
|---|
| 1048 | |
|---|
| 1049 | | step_while_false: ∀f,a,s,k,e,m,v,tr. |
|---|
| 1050 | eval_expr ge e m a v tr → |
|---|
| 1051 | is_false v (typeof a) → |
|---|
| 1052 | step ge (State f (Swhile a s) k e m) |
|---|
| 1053 | tr (State f Sskip k e m) |
|---|
| 1054 | | step_while_true: ∀f,a,s,k,e,m,v,tr. |
|---|
| 1055 | eval_expr ge e m a v tr → |
|---|
| 1056 | is_true v (typeof a) → |
|---|
| 1057 | step ge (State f (Swhile a s) k e m) |
|---|
| 1058 | tr (State f s (Kwhile a s k) e m) |
|---|
| 1059 | | step_skip_or_continue_while: ∀f,x,a,s,k,e,m. |
|---|
| 1060 | x = Sskip ∨ x = Scontinue → |
|---|
| 1061 | step ge (State f x (Kwhile a s k) e m) |
|---|
| 1062 | E0 (State f (Swhile a s) k e m) |
|---|
| 1063 | | step_break_while: ∀f,a,s,k,e,m. |
|---|
| 1064 | step ge (State f Sbreak (Kwhile a s k) e m) |
|---|
| 1065 | E0 (State f Sskip k e m) |
|---|
| 1066 | |
|---|
| 1067 | | step_dowhile: ∀f,a,s,k,e,m. |
|---|
| 1068 | step ge (State f (Sdowhile a s) k e m) |
|---|
| 1069 | E0 (State f s (Kdowhile a s k) e m) |
|---|
| 1070 | | step_skip_or_continue_dowhile_false: ∀f,x,a,s,k,e,m,v,tr. |
|---|
| 1071 | x = Sskip ∨ x = Scontinue → |
|---|
| 1072 | eval_expr ge e m a v tr → |
|---|
| 1073 | is_false v (typeof a) → |
|---|
| 1074 | step ge (State f x (Kdowhile a s k) e m) |
|---|
| 1075 | tr (State f Sskip k e m) |
|---|
| 1076 | | step_skip_or_continue_dowhile_true: ∀f,x,a,s,k,e,m,v,tr. |
|---|
| 1077 | x = Sskip ∨ x = Scontinue → |
|---|
| 1078 | eval_expr ge e m a v tr → |
|---|
| 1079 | is_true v (typeof a) → |
|---|
| 1080 | step ge (State f x (Kdowhile a s k) e m) |
|---|
| 1081 | tr (State f (Sdowhile a s) k e m) |
|---|
| 1082 | | step_break_dowhile: ∀f,a,s,k,e,m. |
|---|
| 1083 | step ge (State f Sbreak (Kdowhile a s k) e m) |
|---|
| 1084 | E0 (State f Sskip k e m) |
|---|
| 1085 | |
|---|
| 1086 | | step_for_start: ∀f,a1,a2,a3,s,k,e,m. |
|---|
| 1087 | a1 ≠ Sskip → |
|---|
| 1088 | step ge (State f (Sfor a1 a2 a3 s) k e m) |
|---|
| 1089 | E0 (State f a1 (Kseq (Sfor Sskip a2 a3 s) k) e m) |
|---|
| 1090 | | step_for_false: ∀f,a2,a3,s,k,e,m,v,tr. |
|---|
| 1091 | eval_expr ge e m a2 v tr → |
|---|
| 1092 | is_false v (typeof a2) → |
|---|
| 1093 | step ge (State f (Sfor Sskip a2 a3 s) k e m) |
|---|
| 1094 | tr (State f Sskip k e m) |
|---|
| 1095 | | step_for_true: ∀f,a2,a3,s,k,e,m,v,tr. |
|---|
| 1096 | eval_expr ge e m a2 v tr → |
|---|
| 1097 | is_true v (typeof a2) → |
|---|
| 1098 | step ge (State f (Sfor Sskip a2 a3 s) k e m) |
|---|
| 1099 | tr (State f s (Kfor2 a2 a3 s k) e m) |
|---|
| 1100 | | step_skip_or_continue_for2: ∀f,x,a2,a3,s,k,e,m. |
|---|
| 1101 | x = Sskip ∨ x = Scontinue → |
|---|
| 1102 | step ge (State f x (Kfor2 a2 a3 s k) e m) |
|---|
| 1103 | E0 (State f a3 (Kfor3 a2 a3 s k) e m) |
|---|
| 1104 | | step_break_for2: ∀f,a2,a3,s,k,e,m. |
|---|
| 1105 | step ge (State f Sbreak (Kfor2 a2 a3 s k) e m) |
|---|
| 1106 | E0 (State f Sskip k e m) |
|---|
| 1107 | | step_skip_for3: ∀f,a2,a3,s,k,e,m. |
|---|
| 1108 | step ge (State f Sskip (Kfor3 a2 a3 s k) e m) |
|---|
| 1109 | E0 (State f (Sfor Sskip a2 a3 s) k e m) |
|---|
| 1110 | |
|---|
| 1111 | | step_return_0: ∀f,k,e,m. |
|---|
| 1112 | fn_return f = Tvoid → |
|---|
| 1113 | step ge (State f (Sreturn (None ?)) k e m) |
|---|
| 1114 | E0 (Returnstate Vundef (call_cont k) (free_list m (blocks_of_env e))) |
|---|
| 1115 | | step_return_1: ∀f,a,k,e,m,v,tr. |
|---|
| 1116 | fn_return f ≠ Tvoid → |
|---|
| 1117 | eval_expr ge e m a v tr → |
|---|
| 1118 | step ge (State f (Sreturn (Some ? a)) k e m) |
|---|
| 1119 | tr (Returnstate v (call_cont k) (free_list m (blocks_of_env e))) |
|---|
| 1120 | | step_skip_call: ∀f,k,e,m. |
|---|
| 1121 | is_call_cont k → |
|---|
| 1122 | fn_return f = Tvoid → |
|---|
| 1123 | step ge (State f Sskip k e m) |
|---|
| 1124 | E0 (Returnstate Vundef k (free_list m (blocks_of_env e))) |
|---|
| 1125 | |
|---|
| 1126 | | step_switch: ∀f,a,sl,k,e,m,n,tr. |
|---|
| 1127 | eval_expr ge e m a (Vint n) tr → |
|---|
| 1128 | step ge (State f (Sswitch a sl) k e m) |
|---|
| 1129 | tr (State f (seq_of_labeled_statement (select_switch n sl)) (Kswitch k) e m) |
|---|
| 1130 | | step_skip_break_switch: ∀f,x,k,e,m. |
|---|
| 1131 | x = Sskip ∨ x = Sbreak → |
|---|
| 1132 | step ge (State f x (Kswitch k) e m) |
|---|
| 1133 | E0 (State f Sskip k e m) |
|---|
| 1134 | | step_continue_switch: ∀f,k,e,m. |
|---|
| 1135 | step ge (State f Scontinue (Kswitch k) e m) |
|---|
| 1136 | E0 (State f Scontinue k e m) |
|---|
| 1137 | |
|---|
| 1138 | | step_label: ∀f,lbl,s,k,e,m. |
|---|
| 1139 | step ge (State f (Slabel lbl s) k e m) |
|---|
| 1140 | E0 (State f s k e m) |
|---|
| 1141 | |
|---|
| 1142 | | step_goto: ∀f,lbl,k,e,m,s',k'. |
|---|
| 1143 | find_label lbl (fn_body f) (call_cont k) = Some ? 〈s', k'〉 → |
|---|
| 1144 | step ge (State f (Sgoto lbl) k e m) |
|---|
| 1145 | E0 (State f s' k' e m) |
|---|
| 1146 | |
|---|
| 1147 | | step_internal_function: ∀f,vargs,k,m,e,m1,m2. |
|---|
| 1148 | alloc_variables empty_env m ((fn_params f) @ (fn_vars f)) e m1 → |
|---|
| 1149 | bind_parameters e m1 (fn_params f) vargs m2 → |
|---|
| 1150 | step ge (Callstate (Internal f) vargs k m) |
|---|
| 1151 | E0 (State f (fn_body f) k e m2) |
|---|
| 1152 | |
|---|
| 1153 | | step_external_function: ∀id,targs,tres,vargs,k,m,vres,t. |
|---|
| 1154 | event_match (external_function id targs tres) vargs t vres → |
|---|
| 1155 | step ge (Callstate (External id targs tres) vargs k m) |
|---|
| 1156 | t (Returnstate vres k m) |
|---|
| 1157 | |
|---|
| 1158 | | step_returnstate_0: ∀v,f,e,k,m. |
|---|
| 1159 | step ge (Returnstate v (Kcall (None ?) f e k) m) |
|---|
| 1160 | E0 (State f Sskip k e m) |
|---|
| 1161 | |
|---|
| 1162 | | step_returnstate_1: ∀v,f,e,k,m,m',loc,ofs,ty. |
|---|
| 1163 | store_value_of_type ty m loc ofs v = Some ? m' → |
|---|
| 1164 | step ge (Returnstate v (Kcall (Some ? 〈〈loc, ofs〉, ty〉) f e k) m) |
|---|
| 1165 | E0 (State f Sskip k e m') |
|---|
| 1166 | |
|---|
| 1167 | | step_cost: ∀f,lbl,s,k,e,m. |
|---|
| 1168 | step ge (State f (Scost lbl s) k e m) |
|---|
| 1169 | (Echarge lbl) (State f s k e m). |
|---|
| 1170 | (* |
|---|
| 1171 | (** * Alternate big-step semantics *) |
|---|
| 1172 | |
|---|
| 1173 | (** ** Big-step semantics for terminating statements and functions *) |
|---|
| 1174 | |
|---|
| 1175 | (** The execution of a statement produces an ``outcome'', indicating |
|---|
| 1176 | how the execution terminated: either normally or prematurely |
|---|
| 1177 | through the execution of a [break], [continue] or [return] statement. *) |
|---|
| 1178 | |
|---|
| 1179 | inductive outcome: Type[0] := |
|---|
| 1180 | | Out_break: outcome (**r terminated by [break] *) |
|---|
| 1181 | | Out_continue: outcome (**r terminated by [continue] *) |
|---|
| 1182 | | Out_normal: outcome (**r terminated normally *) |
|---|
| 1183 | | Out_return: option val -> outcome. (**r terminated by [return] *) |
|---|
| 1184 | |
|---|
| 1185 | inductive out_normal_or_continue : outcome -> Prop := |
|---|
| 1186 | | Out_normal_or_continue_N: out_normal_or_continue Out_normal |
|---|
| 1187 | | Out_normal_or_continue_C: out_normal_or_continue Out_continue. |
|---|
| 1188 | |
|---|
| 1189 | inductive out_break_or_return : outcome -> outcome -> Prop := |
|---|
| 1190 | | Out_break_or_return_B: out_break_or_return Out_break Out_normal |
|---|
| 1191 | | Out_break_or_return_R: ∀ov. |
|---|
| 1192 | out_break_or_return (Out_return ov) (Out_return ov). |
|---|
| 1193 | |
|---|
| 1194 | Definition outcome_switch (out: outcome) : outcome := |
|---|
| 1195 | match out with |
|---|
| 1196 | | Out_break => Out_normal |
|---|
| 1197 | | o => o |
|---|
| 1198 | end. |
|---|
| 1199 | |
|---|
| 1200 | Definition outcome_result_value (out: outcome) (t: type) (v: val) : Prop := |
|---|
| 1201 | match out, t with |
|---|
| 1202 | | Out_normal, Tvoid => v = Vundef |
|---|
| 1203 | | Out_return None, Tvoid => v = Vundef |
|---|
| 1204 | | Out_return (Some v'), ty => ty <> Tvoid /\ v'=v |
|---|
| 1205 | | _, _ => False |
|---|
| 1206 | end. |
|---|
| 1207 | |
|---|
| 1208 | (** [exec_stmt ge e m1 s t m2 out] describes the execution of |
|---|
| 1209 | the statement [s]. [out] is the outcome for this execution. |
|---|
| 1210 | [m1] is the initial memory state, [m2] the final memory state. |
|---|
| 1211 | [t] is the trace of input/output events performed during this |
|---|
| 1212 | evaluation. *) |
|---|
| 1213 | |
|---|
| 1214 | inductive exec_stmt: env -> mem -> statement -> trace -> mem -> outcome -> Prop := |
|---|
| 1215 | | exec_Sskip: ∀e,m. |
|---|
| 1216 | exec_stmt e m Sskip |
|---|
| 1217 | E0 m Out_normal |
|---|
| 1218 | | exec_Sassign: ∀e,m,a1,a2,loc,ofs,v2,m'. |
|---|
| 1219 | eval_lvalue e m a1 loc ofs -> |
|---|
| 1220 | eval_expr e m a2 v2 -> |
|---|
| 1221 | store_value_of_type (typeof a1) m loc ofs v2 = Some m' -> |
|---|
| 1222 | exec_stmt e m (Sassign a1 a2) |
|---|
| 1223 | E0 m' Out_normal |
|---|
| 1224 | | exec_Scall_none: ∀e,m,a,al,vf,vargs,f,t,m',vres. |
|---|
| 1225 | eval_expr e m a vf -> |
|---|
| 1226 | eval_exprlist e m al vargs -> |
|---|
| 1227 | Genv.find_funct ge vf = Some f -> |
|---|
| 1228 | type_of_fundef f = typeof a -> |
|---|
| 1229 | eval_funcall m f vargs t m' vres -> |
|---|
| 1230 | exec_stmt e m (Scall None a al) |
|---|
| 1231 | t m' Out_normal |
|---|
| 1232 | | exec_Scall_some: ∀e,m,lhs,a,al,loc,ofs,vf,vargs,f,t,m',vres,m''. |
|---|
| 1233 | eval_lvalue e m lhs loc ofs -> |
|---|
| 1234 | eval_expr e m a vf -> |
|---|
| 1235 | eval_exprlist e m al vargs -> |
|---|
| 1236 | Genv.find_funct ge vf = Some f -> |
|---|
| 1237 | type_of_fundef f = typeof a -> |
|---|
| 1238 | eval_funcall m f vargs t m' vres -> |
|---|
| 1239 | store_value_of_type (typeof lhs) m' loc ofs vres = Some m'' -> |
|---|
| 1240 | exec_stmt e m (Scall (Some lhs) a al) |
|---|
| 1241 | t m'' Out_normal |
|---|
| 1242 | | exec_Sseq_1: ∀e,m,s1,s2,t1,m1,t2,m2,out. |
|---|
| 1243 | exec_stmt e m s1 t1 m1 Out_normal -> |
|---|
| 1244 | exec_stmt e m1 s2 t2 m2 out -> |
|---|
| 1245 | exec_stmt e m (Ssequence s1 s2) |
|---|
| 1246 | (t1 ** t2) m2 out |
|---|
| 1247 | | exec_Sseq_2: ∀e,m,s1,s2,t1,m1,out. |
|---|
| 1248 | exec_stmt e m s1 t1 m1 out -> |
|---|
| 1249 | out <> Out_normal -> |
|---|
| 1250 | exec_stmt e m (Ssequence s1 s2) |
|---|
| 1251 | t1 m1 out |
|---|
| 1252 | | exec_Sifthenelse_true: ∀e,m,a,s1,s2,v1,t,m',out. |
|---|
| 1253 | eval_expr e m a v1 -> |
|---|
| 1254 | is_true v1 (typeof a) -> |
|---|
| 1255 | exec_stmt e m s1 t m' out -> |
|---|
| 1256 | exec_stmt e m (Sifthenelse a s1 s2) |
|---|
| 1257 | t m' out |
|---|
| 1258 | | exec_Sifthenelse_false: ∀e,m,a,s1,s2,v1,t,m',out. |
|---|
| 1259 | eval_expr e m a v1 -> |
|---|
| 1260 | is_false v1 (typeof a) -> |
|---|
| 1261 | exec_stmt e m s2 t m' out -> |
|---|
| 1262 | exec_stmt e m (Sifthenelse a s1 s2) |
|---|
| 1263 | t m' out |
|---|
| 1264 | | exec_Sreturn_none: ∀e,m. |
|---|
| 1265 | exec_stmt e m (Sreturn None) |
|---|
| 1266 | E0 m (Out_return None) |
|---|
| 1267 | | exec_Sreturn_some: ∀e,m,a,v. |
|---|
| 1268 | eval_expr e m a v -> |
|---|
| 1269 | exec_stmt e m (Sreturn (Some a)) |
|---|
| 1270 | E0 m (Out_return (Some v)) |
|---|
| 1271 | | exec_Sbreak: ∀e,m. |
|---|
| 1272 | exec_stmt e m Sbreak |
|---|
| 1273 | E0 m Out_break |
|---|
| 1274 | | exec_Scontinue: ∀e,m. |
|---|
| 1275 | exec_stmt e m Scontinue |
|---|
| 1276 | E0 m Out_continue |
|---|
| 1277 | | exec_Swhile_false: ∀e,m,a,s,v. |
|---|
| 1278 | eval_expr e m a v -> |
|---|
| 1279 | is_false v (typeof a) -> |
|---|
| 1280 | exec_stmt e m (Swhile a s) |
|---|
| 1281 | E0 m Out_normal |
|---|
| 1282 | | exec_Swhile_stop: ∀e,m,a,v,s,t,m',out',out. |
|---|
| 1283 | eval_expr e m a v -> |
|---|
| 1284 | is_true v (typeof a) -> |
|---|
| 1285 | exec_stmt e m s t m' out' -> |
|---|
| 1286 | out_break_or_return out' out -> |
|---|
| 1287 | exec_stmt e m (Swhile a s) |
|---|
| 1288 | t m' out |
|---|
| 1289 | | exec_Swhile_loop: ∀e,m,a,s,v,t1,m1,out1,t2,m2,out. |
|---|
| 1290 | eval_expr e m a v -> |
|---|
| 1291 | is_true v (typeof a) -> |
|---|
| 1292 | exec_stmt e m s t1 m1 out1 -> |
|---|
| 1293 | out_normal_or_continue out1 -> |
|---|
| 1294 | exec_stmt e m1 (Swhile a s) t2 m2 out -> |
|---|
| 1295 | exec_stmt e m (Swhile a s) |
|---|
| 1296 | (t1 ** t2) m2 out |
|---|
| 1297 | | exec_Sdowhile_false: ∀e,m,s,a,t,m1,out1,v. |
|---|
| 1298 | exec_stmt e m s t m1 out1 -> |
|---|
| 1299 | out_normal_or_continue out1 -> |
|---|
| 1300 | eval_expr e m1 a v -> |
|---|
| 1301 | is_false v (typeof a) -> |
|---|
| 1302 | exec_stmt e m (Sdowhile a s) |
|---|
| 1303 | t m1 Out_normal |
|---|
| 1304 | | exec_Sdowhile_stop: ∀e,m,s,a,t,m1,out1,out. |
|---|
| 1305 | exec_stmt e m s t m1 out1 -> |
|---|
| 1306 | out_break_or_return out1 out -> |
|---|
| 1307 | exec_stmt e m (Sdowhile a s) |
|---|
| 1308 | t m1 out |
|---|
| 1309 | | exec_Sdowhile_loop: ∀e,m,s,a,m1,m2,t1,t2,out,out1,v. |
|---|
| 1310 | exec_stmt e m s t1 m1 out1 -> |
|---|
| 1311 | out_normal_or_continue out1 -> |
|---|
| 1312 | eval_expr e m1 a v -> |
|---|
| 1313 | is_true v (typeof a) -> |
|---|
| 1314 | exec_stmt e m1 (Sdowhile a s) t2 m2 out -> |
|---|
| 1315 | exec_stmt e m (Sdowhile a s) |
|---|
| 1316 | (t1 ** t2) m2 out |
|---|
| 1317 | | exec_Sfor_start: ∀e,m,s,a1,a2,a3,out,m1,m2,t1,t2. |
|---|
| 1318 | a1 <> Sskip -> |
|---|
| 1319 | exec_stmt e m a1 t1 m1 Out_normal -> |
|---|
| 1320 | exec_stmt e m1 (Sfor Sskip a2 a3 s) t2 m2 out -> |
|---|
| 1321 | exec_stmt e m (Sfor a1 a2 a3 s) |
|---|
| 1322 | (t1 ** t2) m2 out |
|---|
| 1323 | | exec_Sfor_false: ∀e,m,s,a2,a3,v. |
|---|
| 1324 | eval_expr e m a2 v -> |
|---|
| 1325 | is_false v (typeof a2) -> |
|---|
| 1326 | exec_stmt e m (Sfor Sskip a2 a3 s) |
|---|
| 1327 | E0 m Out_normal |
|---|
| 1328 | | exec_Sfor_stop: ∀e,m,s,a2,a3,v,m1,t,out1,out. |
|---|
| 1329 | eval_expr e m a2 v -> |
|---|
| 1330 | is_true v (typeof a2) -> |
|---|
| 1331 | exec_stmt e m s t m1 out1 -> |
|---|
| 1332 | out_break_or_return out1 out -> |
|---|
| 1333 | exec_stmt e m (Sfor Sskip a2 a3 s) |
|---|
| 1334 | t m1 out |
|---|
| 1335 | | exec_Sfor_loop: ∀e,m,s,a2,a3,v,m1,m2,m3,t1,t2,t3,out1,out. |
|---|
| 1336 | eval_expr e m a2 v -> |
|---|
| 1337 | is_true v (typeof a2) -> |
|---|
| 1338 | exec_stmt e m s t1 m1 out1 -> |
|---|
| 1339 | out_normal_or_continue out1 -> |
|---|
| 1340 | exec_stmt e m1 a3 t2 m2 Out_normal -> |
|---|
| 1341 | exec_stmt e m2 (Sfor Sskip a2 a3 s) t3 m3 out -> |
|---|
| 1342 | exec_stmt e m (Sfor Sskip a2 a3 s) |
|---|
| 1343 | (t1 ** t2 ** t3) m3 out |
|---|
| 1344 | | exec_Sswitch: ∀e,m,a,t,n,sl,m1,out. |
|---|
| 1345 | eval_expr e m a (Vint n) -> |
|---|
| 1346 | exec_stmt e m (seq_of_labeled_statement (select_switch n sl)) t m1 out -> |
|---|
| 1347 | exec_stmt e m (Sswitch a sl) |
|---|
| 1348 | t m1 (outcome_switch out) |
|---|
| 1349 | |
|---|
| 1350 | (** [eval_funcall m1 fd args t m2 res] describes the invocation of |
|---|
| 1351 | function [fd] with arguments [args]. [res] is the value returned |
|---|
| 1352 | by the call. *) |
|---|
| 1353 | |
|---|
| 1354 | with eval_funcall: mem -> fundef -> list val -> trace -> mem -> val -> Prop := |
|---|
| 1355 | | eval_funcall_internal: ∀m,f,vargs,t,e,m1,m2,m3,out,vres. |
|---|
| 1356 | alloc_variables empty_env m (f.(fn_params) ++ f.(fn_vars)) e m1 -> |
|---|
| 1357 | bind_parameters e m1 f.(fn_params) vargs m2 -> |
|---|
| 1358 | exec_stmt e m2 f.(fn_body) t m3 out -> |
|---|
| 1359 | outcome_result_value out f.(fn_return) vres -> |
|---|
| 1360 | eval_funcall m (Internal f) vargs t (Mem.free_list m3 (blocks_of_env e)) vres |
|---|
| 1361 | | eval_funcall_external: ∀m,id,targs,tres,vargs,t,vres. |
|---|
| 1362 | event_match (external_function id targs tres) vargs t vres -> |
|---|
| 1363 | eval_funcall m (External id targs tres) vargs t m vres. |
|---|
| 1364 | |
|---|
| 1365 | Scheme exec_stmt_ind2 := Minimality for exec_stmt Sort Prop |
|---|
| 1366 | with eval_funcall_ind2 := Minimality for eval_funcall Sort Prop. |
|---|
| 1367 | |
|---|
| 1368 | (** ** Big-step semantics for diverging statements and functions *) |
|---|
| 1369 | |
|---|
| 1370 | (** Coinductive semantics for divergence. |
|---|
| 1371 | [execinf_stmt ge e m s t] holds if the execution of statement [s] |
|---|
| 1372 | diverges, i.e. loops infinitely. [t] is the possibly infinite |
|---|
| 1373 | trace of observable events performed during the execution. *) |
|---|
| 1374 | |
|---|
| 1375 | Coinductive execinf_stmt: env -> mem -> statement -> traceinf -> Prop := |
|---|
| 1376 | | execinf_Scall_none: ∀e,m,a,al,vf,vargs,f,t. |
|---|
| 1377 | eval_expr e m a vf -> |
|---|
| 1378 | eval_exprlist e m al vargs -> |
|---|
| 1379 | Genv.find_funct ge vf = Some f -> |
|---|
| 1380 | type_of_fundef f = typeof a -> |
|---|
| 1381 | evalinf_funcall m f vargs t -> |
|---|
| 1382 | execinf_stmt e m (Scall None a al) t |
|---|
| 1383 | | execinf_Scall_some: ∀e,m,lhs,a,al,loc,ofs,vf,vargs,f,t. |
|---|
| 1384 | eval_lvalue e m lhs loc ofs -> |
|---|
| 1385 | eval_expr e m a vf -> |
|---|
| 1386 | eval_exprlist e m al vargs -> |
|---|
| 1387 | Genv.find_funct ge vf = Some f -> |
|---|
| 1388 | type_of_fundef f = typeof a -> |
|---|
| 1389 | evalinf_funcall m f vargs t -> |
|---|
| 1390 | execinf_stmt e m (Scall (Some lhs) a al) t |
|---|
| 1391 | | execinf_Sseq_1: ∀e,m,s1,s2,t. |
|---|
| 1392 | execinf_stmt e m s1 t -> |
|---|
| 1393 | execinf_stmt e m (Ssequence s1 s2) t |
|---|
| 1394 | | execinf_Sseq_2: ∀e,m,s1,s2,t1,m1,t2. |
|---|
| 1395 | exec_stmt e m s1 t1 m1 Out_normal -> |
|---|
| 1396 | execinf_stmt e m1 s2 t2 -> |
|---|
| 1397 | execinf_stmt e m (Ssequence s1 s2) (t1 *** t2) |
|---|
| 1398 | | execinf_Sifthenelse_true: ∀e,m,a,s1,s2,v1,t. |
|---|
| 1399 | eval_expr e m a v1 -> |
|---|
| 1400 | is_true v1 (typeof a) -> |
|---|
| 1401 | execinf_stmt e m s1 t -> |
|---|
| 1402 | execinf_stmt e m (Sifthenelse a s1 s2) t |
|---|
| 1403 | | execinf_Sifthenelse_false: ∀e,m,a,s1,s2,v1,t. |
|---|
| 1404 | eval_expr e m a v1 -> |
|---|
| 1405 | is_false v1 (typeof a) -> |
|---|
| 1406 | execinf_stmt e m s2 t -> |
|---|
| 1407 | execinf_stmt e m (Sifthenelse a s1 s2) t |
|---|
| 1408 | | execinf_Swhile_body: ∀e,m,a,v,s,t. |
|---|
| 1409 | eval_expr e m a v -> |
|---|
| 1410 | is_true v (typeof a) -> |
|---|
| 1411 | execinf_stmt e m s t -> |
|---|
| 1412 | execinf_stmt e m (Swhile a s) t |
|---|
| 1413 | | execinf_Swhile_loop: ∀e,m,a,s,v,t1,m1,out1,t2. |
|---|
| 1414 | eval_expr e m a v -> |
|---|
| 1415 | is_true v (typeof a) -> |
|---|
| 1416 | exec_stmt e m s t1 m1 out1 -> |
|---|
| 1417 | out_normal_or_continue out1 -> |
|---|
| 1418 | execinf_stmt e m1 (Swhile a s) t2 -> |
|---|
| 1419 | execinf_stmt e m (Swhile a s) (t1 *** t2) |
|---|
| 1420 | | execinf_Sdowhile_body: ∀e,m,s,a,t. |
|---|
| 1421 | execinf_stmt e m s t -> |
|---|
| 1422 | execinf_stmt e m (Sdowhile a s) t |
|---|
| 1423 | | execinf_Sdowhile_loop: ∀e,m,s,a,m1,t1,t2,out1,v. |
|---|
| 1424 | exec_stmt e m s t1 m1 out1 -> |
|---|
| 1425 | out_normal_or_continue out1 -> |
|---|
| 1426 | eval_expr e m1 a v -> |
|---|
| 1427 | is_true v (typeof a) -> |
|---|
| 1428 | execinf_stmt e m1 (Sdowhile a s) t2 -> |
|---|
| 1429 | execinf_stmt e m (Sdowhile a s) (t1 *** t2) |
|---|
| 1430 | | execinf_Sfor_start_1: ∀e,m,s,a1,a2,a3,t. |
|---|
| 1431 | execinf_stmt e m a1 t -> |
|---|
| 1432 | execinf_stmt e m (Sfor a1 a2 a3 s) t |
|---|
| 1433 | | execinf_Sfor_start_2: ∀e,m,s,a1,a2,a3,m1,t1,t2. |
|---|
| 1434 | a1 <> Sskip -> |
|---|
| 1435 | exec_stmt e m a1 t1 m1 Out_normal -> |
|---|
| 1436 | execinf_stmt e m1 (Sfor Sskip a2 a3 s) t2 -> |
|---|
| 1437 | execinf_stmt e m (Sfor a1 a2 a3 s) (t1 *** t2) |
|---|
| 1438 | | execinf_Sfor_body: ∀e,m,s,a2,a3,v,t. |
|---|
| 1439 | eval_expr e m a2 v -> |
|---|
| 1440 | is_true v (typeof a2) -> |
|---|
| 1441 | execinf_stmt e m s t -> |
|---|
| 1442 | execinf_stmt e m (Sfor Sskip a2 a3 s) t |
|---|
| 1443 | | execinf_Sfor_next: ∀e,m,s,a2,a3,v,m1,t1,t2,out1. |
|---|
| 1444 | eval_expr e m a2 v -> |
|---|
| 1445 | is_true v (typeof a2) -> |
|---|
| 1446 | exec_stmt e m s t1 m1 out1 -> |
|---|
| 1447 | out_normal_or_continue out1 -> |
|---|
| 1448 | execinf_stmt e m1 a3 t2 -> |
|---|
| 1449 | execinf_stmt e m (Sfor Sskip a2 a3 s) (t1 *** t2) |
|---|
| 1450 | | execinf_Sfor_loop: ∀e,m,s,a2,a3,v,m1,m2,t1,t2,t3,out1. |
|---|
| 1451 | eval_expr e m a2 v -> |
|---|
| 1452 | is_true v (typeof a2) -> |
|---|
| 1453 | exec_stmt e m s t1 m1 out1 -> |
|---|
| 1454 | out_normal_or_continue out1 -> |
|---|
| 1455 | exec_stmt e m1 a3 t2 m2 Out_normal -> |
|---|
| 1456 | execinf_stmt e m2 (Sfor Sskip a2 a3 s) t3 -> |
|---|
| 1457 | execinf_stmt e m (Sfor Sskip a2 a3 s) (t1 *** t2 *** t3) |
|---|
| 1458 | | execinf_Sswitch: ∀e,m,a,t,n,sl. |
|---|
| 1459 | eval_expr e m a (Vint n) -> |
|---|
| 1460 | execinf_stmt e m (seq_of_labeled_statement (select_switch n sl)) t -> |
|---|
| 1461 | execinf_stmt e m (Sswitch a sl) t |
|---|
| 1462 | |
|---|
| 1463 | (** [evalinf_funcall ge m fd args t] holds if the invocation of function |
|---|
| 1464 | [fd] on arguments [args] diverges, with observable trace [t]. *) |
|---|
| 1465 | |
|---|
| 1466 | with evalinf_funcall: mem -> fundef -> list val -> traceinf -> Prop := |
|---|
| 1467 | | evalinf_funcall_internal: ∀m,f,vargs,t,e,m1,m2. |
|---|
| 1468 | alloc_variables empty_env m (f.(fn_params) ++ f.(fn_vars)) e m1 -> |
|---|
| 1469 | bind_parameters e m1 f.(fn_params) vargs m2 -> |
|---|
| 1470 | execinf_stmt e m2 f.(fn_body) t -> |
|---|
| 1471 | evalinf_funcall m (Internal f) vargs t. |
|---|
| 1472 | |
|---|
| 1473 | End SEMANTICS. |
|---|
| 1474 | *) |
|---|
| 1475 | (* * * Whole-program semantics *) |
|---|
| 1476 | |
|---|
| 1477 | (* * Execution of whole programs are described as sequences of transitions |
|---|
| 1478 | from an initial state to a final state. An initial state is a [Callstate] |
|---|
| 1479 | corresponding to the invocation of the ``main'' function of the program |
|---|
| 1480 | without arguments and with an empty continuation. *) |
|---|
| 1481 | |
|---|
| 1482 | inductive initial_state (p: clight_program): state -> Prop := |
|---|
| 1483 | | initial_state_intro: ∀b,f,ge,m0. |
|---|
| 1484 | globalenv Genv ?? p = OK ? ge → |
|---|
| 1485 | init_mem Genv ?? p = OK ? m0 → |
|---|
| 1486 | find_symbol ?? ge (prog_main ?? p) = Some ? b → |
|---|
| 1487 | find_funct_ptr ?? ge b = Some ? f → |
|---|
| 1488 | initial_state p (Callstate f (nil ?) Kstop m0). |
|---|
| 1489 | |
|---|
| 1490 | (* * A final state is a [Returnstate] with an empty continuation. *) |
|---|
| 1491 | |
|---|
| 1492 | inductive final_state: state -> int -> Prop := |
|---|
| 1493 | | final_state_intro: ∀r,m. |
|---|
| 1494 | final_state (Returnstate (Vint r) Kstop m) r. |
|---|
| 1495 | |
|---|
| 1496 | (* * Execution of a whole program: [exec_program p beh] |
|---|
| 1497 | holds if the application of [p]'s main function to no arguments |
|---|
| 1498 | in the initial memory state for [p] has [beh] as observable |
|---|
| 1499 | behavior. *) |
|---|
| 1500 | |
|---|
| 1501 | definition exec_program : clight_program → program_behavior → Prop ≝ λp,beh. |
|---|
| 1502 | ∀ge. globalenv ??? p = OK ? ge → |
|---|
| 1503 | program_behaves (mk_transrel ?? step) (initial_state p) final_state ge beh. |
|---|
| 1504 | (* |
|---|
| 1505 | (** Big-step execution of a whole program. *) |
|---|
| 1506 | |
|---|
| 1507 | inductive bigstep_program_terminates (p: program): trace -> int -> Prop := |
|---|
| 1508 | | bigstep_program_terminates_intro: ∀b,f,m1,t,r. |
|---|
| 1509 | let ge := Genv.globalenv p in |
|---|
| 1510 | let m0 := Genv.init_mem p in |
|---|
| 1511 | Genv.find_symbol ge p.(prog_main) = Some b -> |
|---|
| 1512 | Genv.find_funct_ptr ge b = Some f -> |
|---|
| 1513 | eval_funcall ge m0 f nil t m1 (Vint r) -> |
|---|
| 1514 | bigstep_program_terminates p t r. |
|---|
| 1515 | |
|---|
| 1516 | inductive bigstep_program_diverges (p: program): traceinf -> Prop := |
|---|
| 1517 | | bigstep_program_diverges_intro: ∀b,f,t. |
|---|
| 1518 | let ge := Genv.globalenv p in |
|---|
| 1519 | let m0 := Genv.init_mem p in |
|---|
| 1520 | Genv.find_symbol ge p.(prog_main) = Some b -> |
|---|
| 1521 | Genv.find_funct_ptr ge b = Some f -> |
|---|
| 1522 | evalinf_funcall ge m0 f nil t -> |
|---|
| 1523 | bigstep_program_diverges p t. |
|---|
| 1524 | |
|---|
| 1525 | (** * Implication from big-step semantics to transition semantics *) |
|---|
| 1526 | |
|---|
| 1527 | Section BIGSTEP_TO_TRANSITIONS. |
|---|
| 1528 | |
|---|
| 1529 | Variable prog: program. |
|---|
| 1530 | Let ge : genv := Genv.globalenv prog. |
|---|
| 1531 | |
|---|
| 1532 | Definition exec_stmt_eval_funcall_ind |
|---|
| 1533 | (PS: env -> mem -> statement -> trace -> mem -> outcome -> Prop) |
|---|
| 1534 | (PF: mem -> fundef -> list val -> trace -> mem -> val -> Prop) := |
|---|
| 1535 | fun a b c d e f g h i j k l m n o p q r s t u v w x y => |
|---|
| 1536 | conj (exec_stmt_ind2 ge PS PF a b c d e f g h i j k l m n o p q r s t u v w x y) |
|---|
| 1537 | (eval_funcall_ind2 ge PS PF a b c d e f g h i j k l m n o p q r s t u v w x y). |
|---|
| 1538 | |
|---|
| 1539 | inductive outcome_state_match |
|---|
| 1540 | (e: env) (m: mem) (f: function) (k: cont): outcome -> state -> Prop := |
|---|
| 1541 | | osm_normal: |
|---|
| 1542 | outcome_state_match e m f k Out_normal (State f Sskip k e m) |
|---|
| 1543 | | osm_break: |
|---|
| 1544 | outcome_state_match e m f k Out_break (State f Sbreak k e m) |
|---|
| 1545 | | osm_continue: |
|---|
| 1546 | outcome_state_match e m f k Out_continue (State f Scontinue k e m) |
|---|
| 1547 | | osm_return_none: ∀k'. |
|---|
| 1548 | call_cont k' = call_cont k -> |
|---|
| 1549 | outcome_state_match e m f k |
|---|
| 1550 | (Out_return None) (State f (Sreturn None) k' e m) |
|---|
| 1551 | | osm_return_some: ∀a,v,k'. |
|---|
| 1552 | call_cont k' = call_cont k -> |
|---|
| 1553 | eval_expr ge e m a v -> |
|---|
| 1554 | outcome_state_match e m f k |
|---|
| 1555 | (Out_return (Some v)) (State f (Sreturn (Some a)) k' e m). |
|---|
| 1556 | |
|---|
| 1557 | Lemma is_call_cont_call_cont: |
|---|
| 1558 | ∀k. is_call_cont k -> call_cont k = k. |
|---|
| 1559 | Proof. |
|---|
| 1560 | destruct k; simpl; intros; contradiction || auto. |
|---|
| 1561 | Qed. |
|---|
| 1562 | |
|---|
| 1563 | Lemma exec_stmt_eval_funcall_steps: |
|---|
| 1564 | (∀e,m,s,t,m',out. |
|---|
| 1565 | exec_stmt ge e m s t m' out -> |
|---|
| 1566 | ∀f,k. exists S, |
|---|
| 1567 | star step ge (State f s k e m) t S |
|---|
| 1568 | /\ outcome_state_match e m' f k out S) |
|---|
| 1569 | /\ |
|---|
| 1570 | (∀m,fd,args,t,m',res. |
|---|
| 1571 | eval_funcall ge m fd args t m' res -> |
|---|
| 1572 | ∀k. |
|---|
| 1573 | is_call_cont k -> |
|---|
| 1574 | star step ge (Callstate fd args k m) t (Returnstate res k m')). |
|---|
| 1575 | Proof. |
|---|
| 1576 | apply exec_stmt_eval_funcall_ind; intros. |
|---|
| 1577 | |
|---|
| 1578 | (* skip *) |
|---|
| 1579 | econstructor; split. apply star_refl. constructor. |
|---|
| 1580 | |
|---|
| 1581 | (* assign *) |
|---|
| 1582 | econstructor; split. apply star_one. econstructor; eauto. constructor. |
|---|
| 1583 | |
|---|
| 1584 | (* call none *) |
|---|
| 1585 | econstructor; split. |
|---|
| 1586 | eapply star_left. econstructor; eauto. |
|---|
| 1587 | eapply star_right. apply H4. simpl; auto. econstructor. reflexivity. traceEq. |
|---|
| 1588 | constructor. |
|---|
| 1589 | |
|---|
| 1590 | (* call some *) |
|---|
| 1591 | econstructor; split. |
|---|
| 1592 | eapply star_left. econstructor; eauto. |
|---|
| 1593 | eapply star_right. apply H5. simpl; auto. econstructor; eauto. reflexivity. traceEq. |
|---|
| 1594 | constructor. |
|---|
| 1595 | |
|---|
| 1596 | (* sequence 2 *) |
|---|
| 1597 | destruct (H0 f (Kseq s2 k)) as [S1 [A1 B1]]. inv B1. |
|---|
| 1598 | destruct (H2 f k) as [S2 [A2 B2]]. |
|---|
| 1599 | econstructor; split. |
|---|
| 1600 | eapply star_left. econstructor. |
|---|
| 1601 | eapply star_trans. eexact A1. |
|---|
| 1602 | eapply star_left. constructor. eexact A2. |
|---|
| 1603 | reflexivity. reflexivity. traceEq. |
|---|
| 1604 | auto. |
|---|
| 1605 | |
|---|
| 1606 | (* sequence 1 *) |
|---|
| 1607 | destruct (H0 f (Kseq s2 k)) as [S1 [A1 B1]]. |
|---|
| 1608 | set (S2 := |
|---|
| 1609 | match out with |
|---|
| 1610 | | Out_break => State f Sbreak k e m1 |
|---|
| 1611 | | Out_continue => State f Scontinue k e m1 |
|---|
| 1612 | | _ => S1 |
|---|
| 1613 | end). |
|---|
| 1614 | exists S2; split. |
|---|
| 1615 | eapply star_left. econstructor. |
|---|
| 1616 | eapply star_trans. eexact A1. |
|---|
| 1617 | unfold S2; inv B1. |
|---|
| 1618 | congruence. |
|---|
| 1619 | apply star_one. apply step_break_seq. |
|---|
| 1620 | apply star_one. apply step_continue_seq. |
|---|
| 1621 | apply star_refl. |
|---|
| 1622 | apply star_refl. |
|---|
| 1623 | reflexivity. traceEq. |
|---|
| 1624 | unfold S2; inv B1; congruence || econstructor; eauto. |
|---|
| 1625 | |
|---|
| 1626 | (* ifthenelse true *) |
|---|
| 1627 | destruct (H2 f k) as [S1 [A1 B1]]. |
|---|
| 1628 | exists S1; split. |
|---|
| 1629 | eapply star_left. eapply step_ifthenelse_true; eauto. eexact A1. traceEq. |
|---|
| 1630 | auto. |
|---|
| 1631 | |
|---|
| 1632 | (* ifthenelse false *) |
|---|
| 1633 | destruct (H2 f k) as [S1 [A1 B1]]. |
|---|
| 1634 | exists S1; split. |
|---|
| 1635 | eapply star_left. eapply step_ifthenelse_false; eauto. eexact A1. traceEq. |
|---|
| 1636 | auto. |
|---|
| 1637 | |
|---|
| 1638 | (* return none *) |
|---|
| 1639 | econstructor; split. apply star_refl. constructor. auto. |
|---|
| 1640 | |
|---|
| 1641 | (* return some *) |
|---|
| 1642 | econstructor; split. apply star_refl. econstructor; eauto. |
|---|
| 1643 | |
|---|
| 1644 | (* break *) |
|---|
| 1645 | econstructor; split. apply star_refl. constructor. |
|---|
| 1646 | |
|---|
| 1647 | (* continue *) |
|---|
| 1648 | econstructor; split. apply star_refl. constructor. |
|---|
| 1649 | |
|---|
| 1650 | (* while false *) |
|---|
| 1651 | econstructor; split. |
|---|
| 1652 | apply star_one. eapply step_while_false; eauto. |
|---|
| 1653 | constructor. |
|---|
| 1654 | |
|---|
| 1655 | (* while stop *) |
|---|
| 1656 | destruct (H2 f (Kwhile a s k)) as [S1 [A1 B1]]. |
|---|
| 1657 | set (S2 := |
|---|
| 1658 | match out' with |
|---|
| 1659 | | Out_break => State f Sskip k e m' |
|---|
| 1660 | | _ => S1 |
|---|
| 1661 | end). |
|---|
| 1662 | exists S2; split. |
|---|
| 1663 | eapply star_left. eapply step_while_true; eauto. |
|---|
| 1664 | eapply star_trans. eexact A1. |
|---|
| 1665 | unfold S2. inversion H3; subst. |
|---|
| 1666 | inv B1. apply star_one. constructor. |
|---|
| 1667 | apply star_refl. |
|---|
| 1668 | reflexivity. traceEq. |
|---|
| 1669 | unfold S2. inversion H3; subst. constructor. inv B1; econstructor; eauto. |
|---|
| 1670 | |
|---|
| 1671 | (* while loop *) |
|---|
| 1672 | destruct (H2 f (Kwhile a s k)) as [S1 [A1 B1]]. |
|---|
| 1673 | destruct (H5 f k) as [S2 [A2 B2]]. |
|---|
| 1674 | exists S2; split. |
|---|
| 1675 | eapply star_left. eapply step_while_true; eauto. |
|---|
| 1676 | eapply star_trans. eexact A1. |
|---|
| 1677 | eapply star_left. |
|---|
| 1678 | inv H3; inv B1; apply step_skip_or_continue_while; auto. |
|---|
| 1679 | eexact A2. |
|---|
| 1680 | reflexivity. reflexivity. traceEq. |
|---|
| 1681 | auto. |
|---|
| 1682 | |
|---|
| 1683 | (* dowhile false *) |
|---|
| 1684 | destruct (H0 f (Kdowhile a s k)) as [S1 [A1 B1]]. |
|---|
| 1685 | exists (State f Sskip k e m1); split. |
|---|
| 1686 | eapply star_left. constructor. |
|---|
| 1687 | eapply star_right. eexact A1. |
|---|
| 1688 | inv H1; inv B1; eapply step_skip_or_continue_dowhile_false; eauto. |
|---|
| 1689 | reflexivity. traceEq. |
|---|
| 1690 | constructor. |
|---|
| 1691 | |
|---|
| 1692 | (* dowhile stop *) |
|---|
| 1693 | destruct (H0 f (Kdowhile a s k)) as [S1 [A1 B1]]. |
|---|
| 1694 | set (S2 := |
|---|
| 1695 | match out1 with |
|---|
| 1696 | | Out_break => State f Sskip k e m1 |
|---|
| 1697 | | _ => S1 |
|---|
| 1698 | end). |
|---|
| 1699 | exists S2; split. |
|---|
| 1700 | eapply star_left. apply step_dowhile. |
|---|
| 1701 | eapply star_trans. eexact A1. |
|---|
| 1702 | unfold S2. inversion H1; subst. |
|---|
| 1703 | inv B1. apply star_one. constructor. |
|---|
| 1704 | apply star_refl. |
|---|
| 1705 | reflexivity. traceEq. |
|---|
| 1706 | unfold S2. inversion H1; subst. constructor. inv B1; econstructor; eauto. |
|---|
| 1707 | |
|---|
| 1708 | (* dowhile loop *) |
|---|
| 1709 | destruct (H0 f (Kdowhile a s k)) as [S1 [A1 B1]]. |
|---|
| 1710 | destruct (H5 f k) as [S2 [A2 B2]]. |
|---|
| 1711 | exists S2; split. |
|---|
| 1712 | eapply star_left. apply step_dowhile. |
|---|
| 1713 | eapply star_trans. eexact A1. |
|---|
| 1714 | eapply star_left. |
|---|
| 1715 | inv H1; inv B1; eapply step_skip_or_continue_dowhile_true; eauto. |
|---|
| 1716 | eexact A2. |
|---|
| 1717 | reflexivity. reflexivity. traceEq. |
|---|
| 1718 | auto. |
|---|
| 1719 | |
|---|
| 1720 | (* for start *) |
|---|
| 1721 | destruct (H1 f (Kseq (Sfor Sskip a2 a3 s) k)) as [S1 [A1 B1]]. inv B1. |
|---|
| 1722 | destruct (H3 f k) as [S2 [A2 B2]]. |
|---|
| 1723 | exists S2; split. |
|---|
| 1724 | eapply star_left. apply step_for_start; auto. |
|---|
| 1725 | eapply star_trans. eexact A1. |
|---|
| 1726 | eapply star_left. constructor. eexact A2. |
|---|
| 1727 | reflexivity. reflexivity. traceEq. |
|---|
| 1728 | auto. |
|---|
| 1729 | |
|---|
| 1730 | (* for false *) |
|---|
| 1731 | econstructor; split. |
|---|
| 1732 | eapply star_one. eapply step_for_false; eauto. |
|---|
| 1733 | constructor. |
|---|
| 1734 | |
|---|
| 1735 | (* for stop *) |
|---|
| 1736 | destruct (H2 f (Kfor2 a2 a3 s k)) as [S1 [A1 B1]]. |
|---|
| 1737 | set (S2 := |
|---|
| 1738 | match out1 with |
|---|
| 1739 | | Out_break => State f Sskip k e m1 |
|---|
| 1740 | | _ => S1 |
|---|
| 1741 | end). |
|---|
| 1742 | exists S2; split. |
|---|
| 1743 | eapply star_left. eapply step_for_true; eauto. |
|---|
| 1744 | eapply star_trans. eexact A1. |
|---|
| 1745 | unfold S2. inversion H3; subst. |
|---|
| 1746 | inv B1. apply star_one. constructor. |
|---|
| 1747 | apply star_refl. |
|---|
| 1748 | reflexivity. traceEq. |
|---|
| 1749 | unfold S2. inversion H3; subst. constructor. inv B1; econstructor; eauto. |
|---|
| 1750 | |
|---|
| 1751 | (* for loop *) |
|---|
| 1752 | destruct (H2 f (Kfor2 a2 a3 s k)) as [S1 [A1 B1]]. |
|---|
| 1753 | destruct (H5 f (Kfor3 a2 a3 s k)) as [S2 [A2 B2]]. inv B2. |
|---|
| 1754 | destruct (H7 f k) as [S3 [A3 B3]]. |
|---|
| 1755 | exists S3; split. |
|---|
| 1756 | eapply star_left. eapply step_for_true; eauto. |
|---|
| 1757 | eapply star_trans. eexact A1. |
|---|
| 1758 | eapply star_trans with (s2 := State f a3 (Kfor3 a2 a3 s k) e m1). |
|---|
| 1759 | inv H3; inv B1. |
|---|
| 1760 | apply star_one. constructor. auto. |
|---|
| 1761 | apply star_one. constructor. auto. |
|---|
| 1762 | eapply star_trans. eexact A2. |
|---|
| 1763 | eapply star_left. constructor. |
|---|
| 1764 | eexact A3. |
|---|
| 1765 | reflexivity. reflexivity. reflexivity. reflexivity. traceEq. |
|---|
| 1766 | auto. |
|---|
| 1767 | |
|---|
| 1768 | (* switch *) |
|---|
| 1769 | destruct (H1 f (Kswitch k)) as [S1 [A1 B1]]. |
|---|
| 1770 | set (S2 := |
|---|
| 1771 | match out with |
|---|
| 1772 | | Out_normal => State f Sskip k e m1 |
|---|
| 1773 | | Out_break => State f Sskip k e m1 |
|---|
| 1774 | | Out_continue => State f Scontinue k e m1 |
|---|
| 1775 | | _ => S1 |
|---|
| 1776 | end). |
|---|
| 1777 | exists S2; split. |
|---|
| 1778 | eapply star_left. eapply step_switch; eauto. |
|---|
| 1779 | eapply star_trans. eexact A1. |
|---|
| 1780 | unfold S2; inv B1. |
|---|
| 1781 | apply star_one. constructor. auto. |
|---|
| 1782 | apply star_one. constructor. auto. |
|---|
| 1783 | apply star_one. constructor. |
|---|
| 1784 | apply star_refl. |
|---|
| 1785 | apply star_refl. |
|---|
| 1786 | reflexivity. traceEq. |
|---|
| 1787 | unfold S2. inv B1; simpl; econstructor; eauto. |
|---|
| 1788 | |
|---|
| 1789 | (* call internal *) |
|---|
| 1790 | destruct (H2 f k) as [S1 [A1 B1]]. |
|---|
| 1791 | eapply star_left. eapply step_internal_function; eauto. |
|---|
| 1792 | eapply star_right. eexact A1. |
|---|
| 1793 | inv B1; simpl in H3; try contradiction. |
|---|
| 1794 | (* Out_normal *) |
|---|
| 1795 | assert (fn_return f = Tvoid /\ vres = Vundef). |
|---|
| 1796 | destruct (fn_return f); auto || contradiction. |
|---|
| 1797 | destruct H5. subst vres. apply step_skip_call; auto. |
|---|
| 1798 | (* Out_return None *) |
|---|
| 1799 | assert (fn_return f = Tvoid /\ vres = Vundef). |
|---|
| 1800 | destruct (fn_return f); auto || contradiction. |
|---|
| 1801 | destruct H6. subst vres. |
|---|
| 1802 | rewrite <- (is_call_cont_call_cont k H4). rewrite <- H5. |
|---|
| 1803 | apply step_return_0; auto. |
|---|
| 1804 | (* Out_return Some *) |
|---|
| 1805 | destruct H3. subst vres. |
|---|
| 1806 | rewrite <- (is_call_cont_call_cont k H4). rewrite <- H5. |
|---|
| 1807 | eapply step_return_1; eauto. |
|---|
| 1808 | reflexivity. traceEq. |
|---|
| 1809 | |
|---|
| 1810 | (* call external *) |
|---|
| 1811 | apply star_one. apply step_external_function; auto. |
|---|
| 1812 | Qed. |
|---|
| 1813 | |
|---|
| 1814 | Lemma exec_stmt_steps: |
|---|
| 1815 | ∀e,m,s,t,m',out. |
|---|
| 1816 | exec_stmt ge e m s t m' out -> |
|---|
| 1817 | ∀f,k. exists S, |
|---|
| 1818 | star step ge (State f s k e m) t S |
|---|
| 1819 | /\ outcome_state_match e m' f k out S. |
|---|
| 1820 | Proof (proj1 exec_stmt_eval_funcall_steps). |
|---|
| 1821 | |
|---|
| 1822 | Lemma eval_funcall_steps: |
|---|
| 1823 | ∀m,fd,args,t,m',res. |
|---|
| 1824 | eval_funcall ge m fd args t m' res -> |
|---|
| 1825 | ∀k. |
|---|
| 1826 | is_call_cont k -> |
|---|
| 1827 | star step ge (Callstate fd args k m) t (Returnstate res k m'). |
|---|
| 1828 | Proof (proj2 exec_stmt_eval_funcall_steps). |
|---|
| 1829 | |
|---|
| 1830 | Definition order (x y: unit) := False. |
|---|
| 1831 | |
|---|
| 1832 | Lemma evalinf_funcall_forever: |
|---|
| 1833 | ∀m,fd,args,T,k. |
|---|
| 1834 | evalinf_funcall ge m fd args T -> |
|---|
| 1835 | forever_N step order ge tt (Callstate fd args k m) T. |
|---|
| 1836 | Proof. |
|---|
| 1837 | cofix CIH_FUN. |
|---|
| 1838 | assert (∀e,m,s,T,f,k. |
|---|
| 1839 | execinf_stmt ge e m s T -> |
|---|
| 1840 | forever_N step order ge tt (State f s k e m) T). |
|---|
| 1841 | cofix CIH_STMT. |
|---|
| 1842 | intros. inv H. |
|---|
| 1843 | |
|---|
| 1844 | (* call none *) |
|---|
| 1845 | eapply forever_N_plus. |
|---|
| 1846 | apply plus_one. eapply step_call_none; eauto. |
|---|
| 1847 | apply CIH_FUN. eauto. traceEq. |
|---|
| 1848 | (* call some *) |
|---|
| 1849 | eapply forever_N_plus. |
|---|
| 1850 | apply plus_one. eapply step_call_some; eauto. |
|---|
| 1851 | apply CIH_FUN. eauto. traceEq. |
|---|
| 1852 | |
|---|
| 1853 | (* seq 1 *) |
|---|
| 1854 | eapply forever_N_plus. |
|---|
| 1855 | apply plus_one. econstructor. |
|---|
| 1856 | apply CIH_STMT; eauto. traceEq. |
|---|
| 1857 | (* seq 2 *) |
|---|
| 1858 | destruct (exec_stmt_steps _ _ _ _ _ _ H0 f (Kseq s2 k)) as [S1 [A1 B1]]. |
|---|
| 1859 | inv B1. |
|---|
| 1860 | eapply forever_N_plus. |
|---|
| 1861 | eapply plus_left. constructor. eapply star_trans. eexact A1. |
|---|
| 1862 | apply star_one. constructor. reflexivity. reflexivity. |
|---|
| 1863 | apply CIH_STMT; eauto. traceEq. |
|---|
| 1864 | |
|---|
| 1865 | (* ifthenelse true *) |
|---|
| 1866 | eapply forever_N_plus. |
|---|
| 1867 | apply plus_one. eapply step_ifthenelse_true; eauto. |
|---|
| 1868 | apply CIH_STMT; eauto. traceEq. |
|---|
| 1869 | (* ifthenelse false *) |
|---|
| 1870 | eapply forever_N_plus. |
|---|
| 1871 | apply plus_one. eapply step_ifthenelse_false; eauto. |
|---|
| 1872 | apply CIH_STMT; eauto. traceEq. |
|---|
| 1873 | |
|---|
| 1874 | (* while body *) |
|---|
| 1875 | eapply forever_N_plus. |
|---|
| 1876 | eapply plus_one. eapply step_while_true; eauto. |
|---|
| 1877 | apply CIH_STMT; eauto. traceEq. |
|---|
| 1878 | (* while loop *) |
|---|
| 1879 | destruct (exec_stmt_steps _ _ _ _ _ _ H2 f (Kwhile a s0 k)) as [S1 [A1 B1]]. |
|---|
| 1880 | eapply forever_N_plus with (s2 := State f (Swhile a s0) k e m1). |
|---|
| 1881 | eapply plus_left. eapply step_while_true; eauto. |
|---|
| 1882 | eapply star_right. eexact A1. |
|---|
| 1883 | inv H3; inv B1; apply step_skip_or_continue_while; auto. |
|---|
| 1884 | reflexivity. reflexivity. |
|---|
| 1885 | apply CIH_STMT; eauto. traceEq. |
|---|
| 1886 | |
|---|
| 1887 | (* dowhile body *) |
|---|
| 1888 | eapply forever_N_plus. |
|---|
| 1889 | eapply plus_one. eapply step_dowhile. |
|---|
| 1890 | apply CIH_STMT; eauto. |
|---|
| 1891 | traceEq. |
|---|
| 1892 | |
|---|
| 1893 | (* dowhile loop *) |
|---|
| 1894 | destruct (exec_stmt_steps _ _ _ _ _ _ H0 f (Kdowhile a s0 k)) as [S1 [A1 B1]]. |
|---|
| 1895 | eapply forever_N_plus with (s2 := State f (Sdowhile a s0) k e m1). |
|---|
| 1896 | eapply plus_left. eapply step_dowhile. |
|---|
| 1897 | eapply star_right. eexact A1. |
|---|
| 1898 | inv H1; inv B1; eapply step_skip_or_continue_dowhile_true; eauto. |
|---|
| 1899 | reflexivity. reflexivity. |
|---|
| 1900 | apply CIH_STMT. eauto. |
|---|
| 1901 | traceEq. |
|---|
| 1902 | |
|---|
| 1903 | (* for start 1 *) |
|---|
| 1904 | assert (a1 <> Sskip). red; intros; subst. inv H0. |
|---|
| 1905 | eapply forever_N_plus. |
|---|
| 1906 | eapply plus_one. apply step_for_start; auto. |
|---|
| 1907 | apply CIH_STMT; eauto. |
|---|
| 1908 | traceEq. |
|---|
| 1909 | |
|---|
| 1910 | (* for start 2 *) |
|---|
| 1911 | destruct (exec_stmt_steps _ _ _ _ _ _ H1 f (Kseq (Sfor Sskip a2 a3 s0) k)) as [S1 [A1 B1]]. |
|---|
| 1912 | inv B1. |
|---|
| 1913 | eapply forever_N_plus. |
|---|
| 1914 | eapply plus_left. eapply step_for_start; eauto. |
|---|
| 1915 | eapply star_right. eexact A1. |
|---|
| 1916 | apply step_skip_seq. |
|---|
| 1917 | reflexivity. reflexivity. |
|---|
| 1918 | apply CIH_STMT; eauto. |
|---|
| 1919 | traceEq. |
|---|
| 1920 | |
|---|
| 1921 | (* for body *) |
|---|
| 1922 | eapply forever_N_plus. |
|---|
| 1923 | apply plus_one. eapply step_for_true; eauto. |
|---|
| 1924 | apply CIH_STMT; eauto. |
|---|
| 1925 | traceEq. |
|---|
| 1926 | |
|---|
| 1927 | (* for next *) |
|---|
| 1928 | destruct (exec_stmt_steps _ _ _ _ _ _ H2 f (Kfor2 a2 a3 s0 k)) as [S1 [A1 B1]]. |
|---|
| 1929 | eapply forever_N_plus. |
|---|
| 1930 | eapply plus_left. eapply step_for_true; eauto. |
|---|
| 1931 | eapply star_trans. eexact A1. |
|---|
| 1932 | apply star_one. |
|---|
| 1933 | inv H3; inv B1; apply step_skip_or_continue_for2; auto. |
|---|
| 1934 | reflexivity. reflexivity. |
|---|
| 1935 | apply CIH_STMT; eauto. |
|---|
| 1936 | traceEq. |
|---|
| 1937 | |
|---|
| 1938 | (* for body *) |
|---|
| 1939 | destruct (exec_stmt_steps _ _ _ _ _ _ H2 f (Kfor2 a2 a3 s0 k)) as [S1 [A1 B1]]. |
|---|
| 1940 | destruct (exec_stmt_steps _ _ _ _ _ _ H4 f (Kfor3 a2 a3 s0 k)) as [S2 [A2 B2]]. |
|---|
| 1941 | inv B2. |
|---|
| 1942 | eapply forever_N_plus. |
|---|
| 1943 | eapply plus_left. eapply step_for_true; eauto. |
|---|
| 1944 | eapply star_trans. eexact A1. |
|---|
| 1945 | eapply star_left. inv H3; inv B1; apply step_skip_or_continue_for2; auto. |
|---|
| 1946 | eapply star_right. eexact A2. |
|---|
| 1947 | constructor. |
|---|
| 1948 | reflexivity. reflexivity. reflexivity. reflexivity. |
|---|
| 1949 | apply CIH_STMT; eauto. |
|---|
| 1950 | traceEq. |
|---|
| 1951 | |
|---|
| 1952 | (* switch *) |
|---|
| 1953 | eapply forever_N_plus. |
|---|
| 1954 | eapply plus_one. eapply step_switch; eauto. |
|---|
| 1955 | apply CIH_STMT; eauto. |
|---|
| 1956 | traceEq. |
|---|
| 1957 | |
|---|
| 1958 | (* call internal *) |
|---|
| 1959 | intros. inv H0. |
|---|
| 1960 | eapply forever_N_plus. |
|---|
| 1961 | eapply plus_one. econstructor; eauto. |
|---|
| 1962 | apply H; eauto. |
|---|
| 1963 | traceEq. |
|---|
| 1964 | Qed. |
|---|
| 1965 | |
|---|
| 1966 | Theorem bigstep_program_terminates_exec: |
|---|
| 1967 | ∀t,r. bigstep_program_terminates prog t r -> exec_program prog (Terminates t r). |
|---|
| 1968 | Proof. |
|---|
| 1969 | intros. inv H. unfold ge0, m0 in *. |
|---|
| 1970 | econstructor. |
|---|
| 1971 | econstructor. eauto. eauto. |
|---|
| 1972 | apply eval_funcall_steps. eauto. red; auto. |
|---|
| 1973 | econstructor. |
|---|
| 1974 | Qed. |
|---|
| 1975 | |
|---|
| 1976 | Theorem bigstep_program_diverges_exec: |
|---|
| 1977 | ∀T. bigstep_program_diverges prog T -> |
|---|
| 1978 | exec_program prog (Reacts T) \/ |
|---|
| 1979 | exists t, exec_program prog (Diverges t) /\ traceinf_prefix t T. |
|---|
| 1980 | Proof. |
|---|
| 1981 | intros. inv H. |
|---|
| 1982 | set (st := Callstate f nil Kstop m0). |
|---|
| 1983 | assert (forever step ge0 st T). |
|---|
| 1984 | eapply forever_N_forever with (order := order). |
|---|
| 1985 | red; intros. constructor; intros. red in H. elim H. |
|---|
| 1986 | eapply evalinf_funcall_forever; eauto. |
|---|
| 1987 | destruct (forever_silent_or_reactive _ _ _ _ _ _ H) |
|---|
| 1988 | as [A | [t [s' [T' [B [C D]]]]]]. |
|---|
| 1989 | left. econstructor. econstructor. eauto. eauto. auto. |
|---|
| 1990 | right. exists t. split. |
|---|
| 1991 | econstructor. econstructor; eauto. eauto. auto. |
|---|
| 1992 | subst T. rewrite <- (E0_right t) at 1. apply traceinf_prefix_app. constructor. |
|---|
| 1993 | Qed. |
|---|
| 1994 | |
|---|
| 1995 | End BIGSTEP_TO_TRANSITIONS. |
|---|
| 1996 | |
|---|
| 1997 | |
|---|
| 1998 | |
|---|
| 1999 | *) |
|---|
| 2000 | |
|---|
| 2001 | |
|---|