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.