Mercurial > cpdt > repo
comparison src/MoreDep.v @ 95:7804f9d5249f
Correctness of insertion
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 07 Oct 2008 21:49:35 -0400 |
parents | affdf00759d8 |
children | b78a55b30f4a |
comparison
equal
deleted
inserted
replaced
94:affdf00759d8 | 95:7804f9d5249f |
---|---|
351 Inductive rbtree : color -> nat -> Set := | 351 Inductive rbtree : color -> nat -> Set := |
352 | Leaf : rbtree Black 0 | 352 | Leaf : rbtree Black 0 |
353 | RedNode : forall n, rbtree Black n -> nat-> rbtree Black n -> rbtree Red n | 353 | RedNode : forall n, rbtree Black n -> nat-> rbtree Black n -> rbtree Red n |
354 | BlackNode : forall c1 c2 n, rbtree c1 n -> nat -> rbtree c2 n -> rbtree Black (S n). | 354 | BlackNode : forall c1 c2 n, rbtree c1 n -> nat -> rbtree c2 n -> rbtree Black (S n). |
355 | 355 |
356 Require Import Max Min. | |
357 | |
358 Section depth. | |
359 Variable f : nat -> nat -> nat. | |
360 | |
361 Fixpoint depth c n (t : rbtree c n) {struct t} : nat := | |
362 match t with | |
363 | Leaf => 0 | |
364 | RedNode _ t1 _ t2 => S (f (depth t1) (depth t2)) | |
365 | BlackNode _ _ _ t1 _ t2 => S (f (depth t1) (depth t2)) | |
366 end. | |
367 End depth. | |
368 | |
369 Theorem depth_min : forall c n (t : rbtree c n), depth min t >= n. | |
370 induction t; crush; | |
371 match goal with | |
372 | [ |- context[min ?X ?Y] ] => destruct (min_dec X Y) | |
373 end; crush. | |
374 Qed. | |
375 | |
376 Lemma depth_max' : forall c n (t : rbtree c n), match c with | |
377 | Red => depth max t <= 2 * n + 1 | |
378 | Black => depth max t <= 2 * n | |
379 end. | |
380 induction t; crush; | |
381 match goal with | |
382 | [ |- context[max ?X ?Y] ] => destruct (max_dec X Y) | |
383 end; crush. | |
384 | |
385 destruct c1; crush. | |
386 destruct c2; crush. | |
387 Qed. | |
388 | |
389 Theorem depth_max : forall c n (t : rbtree c n), depth max t <= 2 * n + 1. | |
390 intros; generalize (depth_max' t); destruct c; crush. | |
391 Qed. | |
392 | |
393 Theorem balanced : forall c n (t : rbtree c n), 2 * depth min t + 1 >= depth max t. | |
394 intros; generalize (depth_min t); generalize (depth_max t); crush. | |
395 Qed. | |
396 | |
397 | |
356 Inductive rtree : nat -> Set := | 398 Inductive rtree : nat -> Set := |
357 | RedNode' : forall c1 c2 n, rbtree c1 n -> nat -> rbtree c2 n -> rtree n. | 399 | RedNode' : forall c1 c2 n, rbtree c1 n -> nat -> rbtree c2 n -> rtree n. |
358 | 400 |
359 Notation "{< x >}" := (existT _ _ x). | 401 Notation "{< x >}" := (existT _ _ x). |
360 | 402 |
364 match t1 in rbtree c n return rbtree _ n -> rbtree c2 n -> { c : color & rbtree c (S n) } with | 406 match t1 in rbtree c n return rbtree _ n -> rbtree c2 n -> { c : color & rbtree c (S n) } with |
365 | RedNode _ a x b => fun c d => {<RedNode (BlackNode a x b) y (BlackNode c data d)>} | 407 | RedNode _ a x b => fun c d => {<RedNode (BlackNode a x b) y (BlackNode c data d)>} |
366 | t1' => fun t2 => | 408 | t1' => fun t2 => |
367 match t2 in rbtree c n return rbtree _ n -> rbtree c2 n -> { c : color & rbtree c (S n) } with | 409 match t2 in rbtree c n return rbtree _ n -> rbtree c2 n -> { c : color & rbtree c (S n) } with |
368 | RedNode _ b x c => fun a d => {<RedNode (BlackNode a y b) x (BlackNode c data d)>} | 410 | RedNode _ b x c => fun a d => {<RedNode (BlackNode a y b) x (BlackNode c data d)>} |
369 | b => fun a t => {<BlackNode a data b>} | 411 | b => fun a t => {<BlackNode (RedNode a y b) data t>} |
370 end t1' | 412 end t1' |
371 end t2 | 413 end t2 |
372 end. | 414 end. |
373 | 415 |
374 Definition balance2 n (a : rtree n) (data : nat) c2 := | 416 Definition balance2 n (a : rtree n) (data : nat) c2 := |
377 match t1 in rbtree c n return rbtree _ n -> rbtree c2 n -> { c : color & rbtree c (S n) } with | 419 match t1 in rbtree c n return rbtree _ n -> rbtree c2 n -> { c : color & rbtree c (S n) } with |
378 | RedNode _ b y c => fun d a => {<RedNode (BlackNode a data b) y (BlackNode c z d)>} | 420 | RedNode _ b y c => fun d a => {<RedNode (BlackNode a data b) y (BlackNode c z d)>} |
379 | t1' => fun t2 => | 421 | t1' => fun t2 => |
380 match t2 in rbtree c n return rbtree _ n -> rbtree c2 n -> { c : color & rbtree c (S n) } with | 422 match t2 in rbtree c n return rbtree _ n -> rbtree c2 n -> { c : color & rbtree c (S n) } with |
381 | RedNode _ c z' d => fun b a => {<RedNode (BlackNode a data b) z (BlackNode c z' d)>} | 423 | RedNode _ c z' d => fun b a => {<RedNode (BlackNode a data b) z (BlackNode c z' d)>} |
382 | b => fun t a => {<BlackNode a data b>} | 424 | b => fun a t => {<BlackNode t data (RedNode a z b)>} |
383 end t1' | 425 end t1' |
384 end t2 | 426 end t2 |
385 end. | 427 end. |
428 | |
429 Section present. | |
430 Variable x : nat. | |
431 | |
432 Fixpoint present c n (t : rbtree c n) {struct t} : Prop := | |
433 match t with | |
434 | Leaf => False | |
435 | RedNode _ a y b => present a \/ x = y \/ present b | |
436 | BlackNode _ _ _ a y b => present a \/ x = y \/ present b | |
437 end. | |
438 | |
439 Definition rpresent n (t : rtree n) : Prop := | |
440 match t with | |
441 | RedNode' _ _ _ a y b => present a \/ x = y \/ present b | |
442 end. | |
443 End present. | |
386 | 444 |
387 Section insert. | 445 Section insert. |
388 Variable x : nat. | 446 Variable x : nat. |
389 | 447 |
390 Definition insResult c n := | 448 Definition insResult c n := |
432 Implicit Arguments makeBlack [c n]. | 490 Implicit Arguments makeBlack [c n]. |
433 | 491 |
434 Definition insert c n (t : rbtree c n) : insertResult c n := | 492 Definition insert c n (t : rbtree c n) : insertResult c n := |
435 makeBlack (ins t). | 493 makeBlack (ins t). |
436 | 494 |
437 Fixpoint present c n (t : rbtree c n) {struct t} : bool := | 495 Record rbtree' : Set := Rbtree' { |
438 match t with | 496 rtC : color; |
439 | Leaf => false | 497 rtN : nat; |
440 | RedNode _ a y b => | 498 rtT : rbtree rtC rtN |
441 if eq_nat_dec x y | 499 }. |
442 then true | 500 |
443 else if le_lt_dec x y | 501 Section present. |
444 then present a | 502 Variable z : nat. |
445 else present b | 503 |
446 | BlackNode _ _ _ a y b => | 504 Lemma present_balance1 : forall n (a : rtree n) (y : nat) c2 (b : rbtree c2 n) , |
447 if eq_nat_dec x y | 505 present z (projT2 (balance1 a y b)) |
448 then true | 506 <-> rpresent z a \/ z = y \/ present z b. |
449 else if le_lt_dec x y | 507 destruct a; crush; |
450 then present a | 508 repeat match goal with |
451 else present b | 509 | [ H : context[match ?T with |
452 end. | 510 | Leaf => _ |
453 | 511 | RedNode _ _ _ _ => _ |
454 Definition rpresent n (t : rtree n) : bool := | 512 | BlackNode _ _ _ _ _ _ => _ |
455 match t with | 513 end] |- _ ] => pose T; dep_destruct T; crush |
456 | RedNode' _ _ _ a y b => | 514 | [ |- context[match ?T with |
457 if eq_nat_dec x y | 515 | Leaf => _ |
458 then true | 516 | RedNode _ _ _ _ => _ |
459 else if le_lt_dec x y | 517 | BlackNode _ _ _ _ _ _ => _ |
460 then present a | 518 end] ] => pose T; dep_destruct T; crush |
461 else present b | 519 end. |
462 end. | 520 Qed. |
521 | |
522 Lemma present_balance2 : forall n (a : rtree n) (y : nat) c2 (b : rbtree c2 n) , | |
523 present z (projT2 (balance2 a y b)) | |
524 <-> rpresent z a \/ z = y \/ present z b. | |
525 destruct a; crush; | |
526 repeat match goal with | |
527 | [ H : context[match ?T with | |
528 | Leaf => _ | |
529 | RedNode _ _ _ _ => _ | |
530 | BlackNode _ _ _ _ _ _ => _ | |
531 end] |- _ ] => pose T; dep_destruct T; crush | |
532 | [ |- context[match ?T with | |
533 | Leaf => _ | |
534 | RedNode _ _ _ _ => _ | |
535 | BlackNode _ _ _ _ _ _ => _ | |
536 end] ] => pose T; dep_destruct T; crush | |
537 end. | |
538 Qed. | |
539 | |
540 Definition present_insResult c n := | |
541 match c return (rbtree c n -> insResult c n -> Prop) with | |
542 | Red => fun t r => rpresent z r <-> z = x \/ present z t | |
543 | Black => fun t r => present z (projT2 r) <-> z = x \/ present z t | |
544 end. | |
545 | |
546 Theorem present_ins : forall c n (t : rbtree c n), | |
547 present_insResult t (ins t). | |
548 induction t; crush; | |
549 repeat (match goal with | |
550 | [ H : context[if ?E then _ else _] |- _ ] => destruct E | |
551 | [ |- context[if ?E then _ else _] ] => destruct E | |
552 | [ H : context[match ?C with Red => _ | Black => _ end] |- _ ] => destruct C | |
553 end; crush); | |
554 try match goal with | |
555 | [ H : context[balance1 ?A ?B ?C] |- _ ] => | |
556 generalize (present_balance1 A B C) | |
557 end; | |
558 try match goal with | |
559 | [ H : context[balance2 ?A ?B ?C] |- _ ] => | |
560 generalize (present_balance2 A B C) | |
561 end; | |
562 try match goal with | |
563 | [ |- context[balance1 ?A ?B ?C] ] => | |
564 generalize (present_balance1 A B C) | |
565 end; | |
566 try match goal with | |
567 | [ |- context[balance2 ?A ?B ?C] ] => | |
568 generalize (present_balance2 A B C) | |
569 end; | |
570 intuition; | |
571 match goal with | |
572 | [ z : nat, x : nat |- _ ] => | |
573 match goal with | |
574 | [ H : z = x |- _ ] => rewrite H in *; clear H | |
575 end | |
576 end; | |
577 tauto. | |
578 Qed. | |
579 | |
580 Theorem present_insert_Red : forall n (t : rbtree Red n), | |
581 present z (insert t) | |
582 <-> (z = x \/ present z t). | |
583 unfold insert; inversion t; | |
584 generalize (present_ins t); simpl; | |
585 dep_destruct (ins t); tauto. | |
586 Qed. | |
587 | |
588 Theorem present_insert_Black : forall n (t : rbtree Black n), | |
589 present z (projT2 (insert t)) | |
590 <-> (z = x \/ present z t). | |
591 unfold insert; inversion t; | |
592 generalize (present_ins t); simpl; | |
593 dep_destruct (ins t); tauto. | |
594 Qed. | |
595 End present. | |
463 End insert. | 596 End insert. |
464 | |
465 | |
466 Require Import Max Min. | |
467 | |
468 Section depth. | |
469 Variable f : nat -> nat -> nat. | |
470 | |
471 Fixpoint depth c n (t : rbtree c n) {struct t} : nat := | |
472 match t with | |
473 | Leaf => 0 | |
474 | RedNode _ t1 _ t2 => S (f (depth t1) (depth t2)) | |
475 | BlackNode _ _ _ t1 _ t2 => S (f (depth t1) (depth t2)) | |
476 end. | |
477 End depth. | |
478 | |
479 Theorem depth_min : forall c n (t : rbtree c n), depth min t >= n. | |
480 induction t; crush; | |
481 match goal with | |
482 | [ |- context[min ?X ?Y] ] => destruct (min_dec X Y) | |
483 end; crush. | |
484 Qed. | |
485 | |
486 Lemma depth_max' : forall c n (t : rbtree c n), match c with | |
487 | Red => depth max t <= 2 * n + 1 | |
488 | Black => depth max t <= 2 * n | |
489 end. | |
490 induction t; crush; | |
491 match goal with | |
492 | [ |- context[max ?X ?Y] ] => destruct (max_dec X Y) | |
493 end; crush. | |
494 | |
495 destruct c1; crush. | |
496 destruct c2; crush. | |
497 Qed. | |
498 | |
499 Theorem depth_max : forall c n (t : rbtree c n), depth max t <= 2 * n + 1. | |
500 intros; generalize (depth_max' t); destruct c; crush. | |
501 Qed. | |
502 | |
503 Theorem balanced : forall c n (t : rbtree c n), 2 * depth min t + 1 >= depth max t. | |
504 intros; generalize (depth_min t); generalize (depth_max t); crush. | |
505 Qed. | |
506 | 597 |
507 | 598 |
508 (** * A Certified Regular Expression Matcher *) | 599 (** * A Certified Regular Expression Matcher *) |
509 | 600 |
510 (** Another interesting example is regular expressions with dependent types that express which predicates over strings particular regexps implement. We can then assign a dependent type to a regular expression matching function, guaranteeing that it always decides the string property that we expect it to decide. | 601 (** Another interesting example is regular expressions with dependent types that express which predicates over strings particular regexps implement. We can then assign a dependent type to a regular expression matching function, guaranteeing that it always decides the string property that we expect it to decide. |