Mercurial > cpdt > repo
comparison src/GeneralRec.v @ 352:ab60b10890ed
Non-termination monad
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Wed, 26 Oct 2011 16:57:11 -0400 |
parents | bb1a470c1757 |
children | 3322367e955d |
comparison
equal
deleted
inserted
replaced
351:bb1a470c1757 | 352:ab60b10890ed |
---|---|
273 (forall x : A, (forall y : A, R y x -> P y) -> P x) -> | 273 (forall x : A, (forall y : A, R y x -> P y) -> P x) -> |
274 forall a : A, P a | 274 forall a : A, P a |
275 ]] | 275 ]] |
276 | 276 |
277 Some more recent Coq features provide more convenient syntax for defining recursive functions. Interested readers can consult the Coq manual about the commands %\index{Function}%[Function] and %\index{Program Fixpoint}%[Program Fixpoint]. *) | 277 Some more recent Coq features provide more convenient syntax for defining recursive functions. Interested readers can consult the Coq manual about the commands %\index{Function}%[Function] and %\index{Program Fixpoint}%[Program Fixpoint]. *) |
278 | |
279 | |
280 (** * A Non-Termination Monad *) | |
281 | |
282 Section computation. | |
283 Variable A : Type. | |
284 | |
285 Definition computation := | |
286 {f : nat -> option A | |
287 | forall (n : nat) (v : A), | |
288 f n = Some v | |
289 -> forall (n' : nat), n' >= n | |
290 -> f n' = Some v}. | |
291 | |
292 Definition runTo (m : computation) (n : nat) (v : A) := | |
293 proj1_sig m n = Some v. | |
294 | |
295 Definition run (m : computation) (v : A) := | |
296 exists n, runTo m n v. | |
297 End computation. | |
298 | |
299 Hint Unfold runTo. | |
300 | |
301 Ltac run' := unfold run, runTo in *; try red; crush; | |
302 repeat (match goal with | |
303 | [ _ : proj1_sig ?E _ = _ |- _ ] => | |
304 match goal with | |
305 | [ x : _ |- _ ] => | |
306 match x with | |
307 | E => destruct E | |
308 end | |
309 end | |
310 | [ |- context[match ?M with exist _ _ => _ end] ] => let Heq := fresh "Heq" in | |
311 case_eq M; intros ? ? Heq; try rewrite Heq in *; try subst | |
312 | [ _ : context[match ?M with exist _ _ => _ end] |- _ ] => let Heq := fresh "Heq" in | |
313 case_eq M; intros ? ? Heq; try rewrite Heq in *; subst | |
314 | [ H : forall n v, ?E n = Some v -> _, | |
315 _ : context[match ?E ?N with Some _ => _ | None => _ end] |- _ ] => | |
316 specialize (H N); destruct (E N); try rewrite (H _ (refl_equal _)) by auto; try discriminate | |
317 | [ H : forall n v, ?E n = Some v -> _, H' : ?E _ = Some _ |- _ ] => rewrite (H _ _ H') by auto | |
318 end; simpl in *); eauto 7. | |
319 | |
320 Ltac run := run'; repeat (match goal with | |
321 | [ H : forall n v, ?E n = Some v -> _ | |
322 |- context[match ?E ?N with Some _ => _ | None => _ end] ] => | |
323 specialize (H N); destruct (E N); try rewrite (H _ (refl_equal _)) by auto; try discriminate | |
324 end; run'). | |
325 | |
326 Lemma ex_irrelevant : forall P : Prop, P -> exists n : nat, P. | |
327 exists 0; auto. | |
328 Qed. | |
329 | |
330 Hint Resolve ex_irrelevant. | |
331 | |
332 Require Import Max. | |
333 | |
334 Ltac max := intros n m; generalize (max_spec_le n m); crush. | |
335 | |
336 Lemma max_1 : forall n m, max n m >= n. | |
337 max. | |
338 Qed. | |
339 | |
340 Lemma max_2 : forall n m, max n m >= m. | |
341 max. | |
342 Qed. | |
343 | |
344 Hint Resolve max_1 max_2. | |
345 | |
346 Lemma ge_refl : forall n, n >= n. | |
347 crush. | |
348 Qed. | |
349 | |
350 Hint Resolve ge_refl. | |
351 | |
352 Hint Extern 1 => match goal with | |
353 | [ H : _ = exist _ _ _ |- _ ] => rewrite H | |
354 end. | |
355 | |
356 Section Bottom. | |
357 Variable A : Type. | |
358 | |
359 Definition Bottom : computation A. | |
360 exists (fun _ : nat => @None A); abstract run. | |
361 Defined. | |
362 | |
363 Theorem run_Bottom : forall v, ~run Bottom v. | |
364 run. | |
365 Qed. | |
366 End Bottom. | |
367 | |
368 Section Return. | |
369 Variable A : Type. | |
370 Variable v : A. | |
371 | |
372 Definition Return : computation A. | |
373 intros; exists (fun _ : nat => Some v); abstract run. | |
374 Defined. | |
375 | |
376 Theorem run_Return : run Return v. | |
377 run. | |
378 Qed. | |
379 | |
380 Theorem run_Return_inv : forall x, run Return x -> x = v. | |
381 run. | |
382 Qed. | |
383 End Return. | |
384 | |
385 Hint Resolve run_Return. | |
386 | |
387 Section Bind. | |
388 Variables A B : Type. | |
389 Variable m1 : computation A. | |
390 Variable m2 : A -> computation B. | |
391 | |
392 Definition Bind : computation B. | |
393 exists (fun n => | |
394 let (f1, Hf1) := m1 in | |
395 match f1 n with | |
396 | None => None | |
397 | Some v => | |
398 let (f2, Hf2) := m2 v in | |
399 f2 n | |
400 end); abstract run. | |
401 Defined. | |
402 | |
403 Require Import Max. | |
404 | |
405 Theorem run_Bind : forall (v1 : A) (v2 : B), | |
406 run m1 v1 | |
407 -> run (m2 v1) v2 | |
408 -> run Bind v2. | |
409 run; match goal with | |
410 | [ x : nat, y : nat |- _ ] => exists (max x y) | |
411 end; run. | |
412 Qed. | |
413 | |
414 Theorem run_Bind_inv : forall (v2 : B), | |
415 run Bind v2 | |
416 -> exists v1 : A, | |
417 run m1 v1 | |
418 /\ run (m2 v1) v2. | |
419 run. | |
420 Qed. | |
421 End Bind. | |
422 | |
423 Hint Resolve run_Bind. | |
424 | |
425 Notation "x <- m1 ; m2" := | |
426 (Bind m1 (fun x => m2)) (right associativity, at level 70). | |
427 | |
428 Definition meq A (m1 m2 : computation A) := forall n, proj1_sig m1 n = proj1_sig m2 n. | |
429 | |
430 Theorem left_identity : forall A B (a : A) (f : A -> computation B), | |
431 meq (Bind (Return a) f) (f a). | |
432 run. | |
433 Qed. | |
434 | |
435 Theorem right_identity : forall A (m : computation A), | |
436 meq (Bind m (@Return _)) m. | |
437 run. | |
438 Qed. | |
439 | |
440 Theorem associativity : forall A B C (m : computation A) (f : A -> computation B) (g : B -> computation C), | |
441 meq (Bind (Bind m f) g) (Bind m (fun x => Bind (f x) g)). | |
442 run. | |
443 Qed. | |
444 | |
445 Section monotone_runTo. | |
446 Variable A : Type. | |
447 Variable c : computation A. | |
448 Variable v : A. | |
449 | |
450 Theorem monotone_runTo : forall (n1 : nat), | |
451 runTo c n1 v | |
452 -> forall n2, n2 >= n1 | |
453 -> runTo c n2 v. | |
454 run. | |
455 Qed. | |
456 End monotone_runTo. | |
457 | |
458 Hint Resolve monotone_runTo. | |
459 | |
460 Section lattice. | |
461 Variable A : Type. | |
462 | |
463 Definition leq (x y : option A) := | |
464 forall v, x = Some v -> y = Some v. | |
465 End lattice. | |
466 | |
467 Hint Unfold leq. | |
468 | |
469 Section Fix. | |
470 Variables A B : Type. | |
471 Variable f : (A -> computation B) -> (A -> computation B). | |
472 | |
473 Hypothesis f_continuous : forall n v v1 x, | |
474 runTo (f v1 x) n v | |
475 -> forall (v2 : A -> computation B), | |
476 (forall x, leq (proj1_sig (v1 x) n) (proj1_sig (v2 x) n)) | |
477 -> runTo (f v2 x) n v. | |
478 | |
479 Fixpoint Fix' (n : nat) (x : A) : computation B := | |
480 match n with | |
481 | O => Bottom _ | |
482 | S n' => f (Fix' n') x | |
483 end. | |
484 | |
485 Hint Extern 1 (_ >= _) => omega. | |
486 Hint Unfold leq. | |
487 | |
488 Lemma Fix'_ok : forall steps n x v, proj1_sig (Fix' n x) steps = Some v | |
489 -> forall n', n' >= n | |
490 -> proj1_sig (Fix' n' x) steps = Some v. | |
491 unfold runTo in *; induction n; crush; | |
492 match goal with | |
493 | [ H : _ >= _ |- _ ] => inversion H; crush; eauto | |
494 end. | |
495 Qed. | |
496 | |
497 Hint Resolve Fix'_ok. | |
498 | |
499 Hint Extern 1 (proj1_sig _ _ = _) => simpl; | |
500 match goal with | |
501 | [ |- proj1_sig ?E _ = _ ] => eapply (proj2_sig E) | |
502 end. | |
503 | |
504 Definition Fix : A -> computation B. | |
505 intro x; exists (fun n => proj1_sig (Fix' n x) n); abstract run. | |
506 Defined. | |
507 | |
508 Definition extensional (f : (A -> computation B) -> (A -> computation B)) := | |
509 forall g1 g2 n, | |
510 (forall x, proj1_sig (g1 x) n = proj1_sig (g2 x) n) | |
511 -> forall x, proj1_sig (f g1 x) n = proj1_sig (f g2 x) n. | |
512 | |
513 Hypothesis f_extensional : extensional f. | |
514 | |
515 Theorem run_Fix : forall x v, | |
516 run (f Fix x) v | |
517 -> run (Fix x) v. | |
518 run; match goal with | |
519 | [ n : nat |- _ ] => exists (S n); eauto | |
520 end. | |
521 Qed. | |
522 End Fix. | |
523 | |
524 Hint Resolve run_Fix. | |
525 | |
526 Lemma leq_Some : forall A (x y : A), leq (Some x) (Some y) | |
527 -> x = y. | |
528 intros ? ? ? H; generalize (H _ (refl_equal _)); crush. | |
529 Qed. | |
530 | |
531 Lemma leq_None : forall A (x y : A), leq (Some x) None | |
532 -> False. | |
533 intros ? ? ? H; generalize (H _ (refl_equal _)); crush. | |
534 Qed. | |
535 | |
536 Definition mergeSort' : forall A, (A -> A -> bool) -> list A -> computation (list A). | |
537 refine (fun A le => Fix | |
538 (fun (mergeSort : list A -> computation (list A)) | |
539 (ls : list A) => | |
540 if le_lt_dec 2 (length ls) | |
541 then let lss := partition ls in | |
542 ls1 <- mergeSort (fst lss); | |
543 ls2 <- mergeSort (snd lss); | |
544 Return (merge le ls1 ls2) | |
545 else Return ls) _); abstract (run; | |
546 repeat (match goal with | |
547 | [ |- context[match ?E with O => _ | S _ => _ end] ] => destruct E | |
548 end; run); | |
549 repeat match goal with | |
550 | [ H : forall x, leq (proj1_sig (?f x) _) (proj1_sig (?g x) _) |- _ ] => | |
551 match goal with | |
552 | [ H1 : f ?arg = _, H2 : g ?arg = _ |- _ ] => | |
553 generalize (H arg); rewrite H1; rewrite H2; clear H1 H2; simpl; intro | |
554 end | |
555 end; run; repeat match goal with | |
556 | [ H : _ |- _ ] => (apply leq_None in H; tauto) || (apply leq_Some in H; subst) | |
557 end; auto). | |
558 Defined. | |
559 | |
560 Print mergeSort'. | |
561 | |
562 Lemma test_mergeSort' : run (mergeSort' leb (1 :: 2 :: 36 :: 8 :: 19 :: nil)) | |
563 (1 :: 2 :: 8 :: 19 :: 36 :: nil). | |
564 exists 4; reflexivity. | |
565 Qed. | |
566 | |
567 Definition looper : bool -> computation unit. | |
568 refine (Fix (fun looper (b : bool) => | |
569 if b then Return tt else looper b) _); | |
570 abstract (unfold leq in *; run; | |
571 repeat match goal with | |
572 | [ x : unit |- _ ] => destruct x | |
573 | [ x : bool |- _ ] => destruct x | |
574 end; auto). | |
575 Defined. | |
576 | |
577 Lemma test_looper : run (looper true) tt. | |
578 exists 1; reflexivity. | |
579 Qed. |