comparison src/Coinductive.v @ 64:739c2818d6e2

Co-inductive evaluation example
author Adam Chlipala <adamc@hcoop.net>
date Tue, 30 Sep 2008 17:47:59 -0400
parents fe7d37dfbd26
children 21bb59c56b98
comparison
equal deleted inserted replaced
63:fe7d37dfbd26 64:739c2818d6e2
303 303
304 Guarded. *) 304 Guarded. *)
305 Abort. 305 Abort.
306 306
307 (** The standard [auto] machinery sees that our goal matches an assumption and so applies that assumption, even though this violates guardedness. One usually starts a proof like this by [destruct]ing some parameter and running a custom tactic to figure out the first proof rule to apply for each case. Alternatively, there are tricks that can be played with "hiding" the co-inductive hypothesis. We will see examples of effective co-inductive proving in later chapters. *) 307 (** The standard [auto] machinery sees that our goal matches an assumption and so applies that assumption, even though this violates guardedness. One usually starts a proof like this by [destruct]ing some parameter and running a custom tactic to figure out the first proof rule to apply for each case. Alternatively, there are tricks that can be played with "hiding" the co-inductive hypothesis. We will see examples of effective co-inductive proving in later chapters. *)
308
309
310 (** * Simple Modeling of Non-Terminating Programs *)
311
312 (** We close the chapter with a quick motivating example for more complex uses of co-inductive types. We will define a co-inductive semantics for a simple assembly language and use that semantics to prove that an optimization function is sound. We start by defining a type of instructions. *)
313
314 Inductive reg : Set := R1 | R2.
315 Definition label := nat.
316
317 Inductive instrs : Set :=
318 | Const : reg -> nat -> instrs -> instrs
319 | Add : reg -> reg -> reg -> instrs -> instrs
320 | Halt : reg -> instrs
321 | Jeq : reg -> reg -> label -> instrs -> instrs.
322
323 Definition program := list instrs.
324
325 Section regmap.
326 Variable A : Set.
327
328 Record regmap : Set := Regmap {
329 VR1 : A;
330 VR2 : A
331 }.
332
333 Definition empty v : regmap := Regmap v v.
334 Definition get (rm : regmap) (r : reg) : A :=
335 match r with
336 | R1 => VR1 rm
337 | R2 => VR2 rm
338 end.
339 Definition set (rm : regmap) (r : reg) (v : A) : regmap :=
340 match r with
341 | R1 => Regmap v (VR2 rm)
342 | R2 => Regmap (VR1 rm) v
343 end.
344 End regmap.
345
346 Section run.
347 Variable prog : program.
348
349 CoInductive run : regmap nat -> instrs -> nat -> Prop :=
350 | RConst : forall rm r n is v,
351 run (set rm r n) is v
352 -> run rm (Const r n is) v
353 | RAdd : forall rm r r1 r2 is v,
354 run (set rm r (get rm r1 + get rm r2)) is v
355 -> run rm (Add r r1 r2 is) v
356 | RHalt : forall rm r,
357 run rm (Halt r) (get rm r)
358 | RJeq_eq : forall rm r1 r2 l is is' v,
359 get rm r1 = get rm r2
360 -> nth_error prog l = Some is'
361 -> run rm is' v
362 -> run rm (Jeq r1 r2 l is) v
363 | RJeq_neq : forall rm r1 r2 l is v,
364 get rm r1 <> get rm r2
365 -> run rm is v
366 -> run rm (Jeq r1 r2 l is) v.
367 End run.
368
369 Fixpoint constFold (rm : regmap (option nat)) (is : instrs) {struct is} : instrs :=
370 match is with
371 | Const r n is => Const r n (constFold (set rm r (Some n)) is)
372 | Add r r1 r2 is =>
373 match get rm r1, get rm r2 with
374 | Some n1, Some n2 => Const r (n1 + n2) (constFold (set rm r (Some (n1 + n2))) is)
375 | _, _ => Add r r1 r2 (constFold (set rm r None) is)
376 end
377 | Halt _ => is
378 | Jeq r1 r2 l is => Jeq r1 r2 l (constFold rm is)
379 end.
380
381 Definition regmapCompat (rm : regmap nat) (rm' : regmap (option nat)) :=
382 forall r, match get rm' r with
383 | None => True
384 | Some v => get rm r = v
385 end.
386
387 Ltac compat := unfold regmapCompat in *; crush;
388 match goal with
389 | [ |- match get _ ?R with Some _ => _ | None => _ end ] => destruct R; crush
390 end.
391
392 Lemma regmapCompat_set_None : forall rm rm' r n,
393 regmapCompat rm rm'
394 -> regmapCompat (set rm r n) (set rm' r None).
395 destruct r; compat.
396 Qed.
397
398 Lemma regmapCompat_set_Some : forall rm rm' r n,
399 regmapCompat rm rm'
400 -> regmapCompat (set rm r n) (set rm' r (Some n)).
401 destruct r; compat.
402 Qed.
403
404 Require Import Arith.
405
406 Section constFold_ok.
407 Variable prog : program.
408
409 Theorem constFold_ok : forall rm is v,
410 run prog rm is v
411 -> forall rm', regmapCompat rm rm'
412 -> run prog rm (constFold rm' is) v.
413 Hint Resolve regmapCompat_set_None regmapCompat_set_Some.
414 Hint Constructors run.
415
416 cofix.
417 destruct 1; crush; eauto;
418 repeat match goal with
419 | [ H : regmapCompat _ _ |- run _ _ (match get ?RM ?R with Some _ => _ | None => _ end) _ ] =>
420 generalize (H R); destruct (get RM R); crush
421 end.
422 Qed.
423 End constFold_ok.
424
425 Print constFold_ok.