Mercurial > cpdt > repo
comparison src/DataStruct.v @ 398:05efde66559d
Get it working in Coq 8.4beta1; use nice coqdoc notation for italics
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Wed, 06 Jun 2012 11:25:13 -0400 |
parents | d1276004eec9 |
children | fc03a67810e8 |
comparison
equal
deleted
inserted
replaced
397:d62ed7381a0b | 398:05efde66559d |
---|---|
1 (* Copyright (c) 2008-2011, Adam Chlipala | 1 (* Copyright (c) 2008-2012, Adam Chlipala |
2 * | 2 * |
3 * This work is licensed under a | 3 * This work is licensed under a |
4 * Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 | 4 * Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 |
5 * Unported License. | 5 * Unported License. |
6 * The license text is available at: | 6 * The license text is available at: |
367 (** We are starting to develop the tools behind dependent typing's amazing advantage over alternative approaches in several important areas. Here, we have implemented complete syntax, typing rules, and evaluation semantics for simply typed lambda calculus without even needing to define a syntactic substitution operation. We did it all without a single line of proof, and our implementation is manifestly executable. Other, more common approaches to language formalization often state and prove explicit theorems about type safety of languages. In the above example, we got type safety, termination, and other meta-theorems for free, by reduction to CIC, which we know has those properties. *) | 367 (** We are starting to develop the tools behind dependent typing's amazing advantage over alternative approaches in several important areas. Here, we have implemented complete syntax, typing rules, and evaluation semantics for simply typed lambda calculus without even needing to define a syntactic substitution operation. We did it all without a single line of proof, and our implementation is manifestly executable. Other, more common approaches to language formalization often state and prove explicit theorems about type safety of languages. In the above example, we got type safety, termination, and other meta-theorems for free, by reduction to CIC, which we know has those properties. *) |
368 | 368 |
369 | 369 |
370 (** * Recursive Type Definitions *) | 370 (** * Recursive Type Definitions *) |
371 | 371 |
372 (** %\index{recursive type definition}%There is another style of datatype definition that leads to much simpler definitions of the [get] and [hget] definitions above. Because Coq supports %``%#"#type-level computation,#"#%''% we can redo our inductive definitions as %\textit{%#<i>#recursive#</i>#%}% definitions. *) | 372 (** %\index{recursive type definition}%There is another style of datatype definition that leads to much simpler definitions of the [get] and [hget] definitions above. Because Coq supports %``%#"#type-level computation,#"#%''% we can redo our inductive definitions as _recursive_ definitions. *) |
373 | 373 |
374 (* EX: Come up with an alternate [ilist] definition that makes it easier to write [get]. *) | 374 (* EX: Come up with an alternate [ilist] definition that makes it easier to write [get]. *) |
375 | 375 |
376 Section filist. | 376 Section filist. |
377 Variable A : Set. | 377 Variable A : Set. |
566 "forall n : nat, filist tree n -> tree" | 566 "forall n : nat, filist tree n -> tree" |
567 >> | 567 >> |
568 | 568 |
569 The special-case rule for nested datatypes only works with nested uses of other inductive types, which could be replaced with uses of new mutually inductive types. We defined [filist] recursively, so it may not be used for nested recursion. | 569 The special-case rule for nested datatypes only works with nested uses of other inductive types, which could be replaced with uses of new mutually inductive types. We defined [filist] recursively, so it may not be used for nested recursion. |
570 | 570 |
571 Our final solution uses yet another of the inductive definition techniques introduced in Chapter 3, %\index{reflexive inductive type}%reflexive types. Instead of merely using [fin] to get elements out of [ilist], we can %\textit{%#<i>#define#</i>#%}% [ilist] in terms of [fin]. For the reasons outlined above, it turns out to be easier to work with [ffin] in place of [fin]. *) | 571 Our final solution uses yet another of the inductive definition techniques introduced in Chapter 3, %\index{reflexive inductive type}%reflexive types. Instead of merely using [fin] to get elements out of [ilist], we can _define_ [ilist] in terms of [fin]. For the reasons outlined above, it turns out to be easier to work with [ffin] in place of [fin]. *) |
572 | 572 |
573 Inductive tree : Set := | 573 Inductive tree : Set := |
574 | Leaf : A -> tree | 574 | Leaf : A -> tree |
575 | Node : forall n, (ffin n -> tree) -> tree. | 575 | Node : forall n, (ffin n -> tree) -> tree. |
576 | 576 |
606 match t with | 606 match t with |
607 | Leaf n => Leaf (S n) | 607 | Leaf n => Leaf (S n) |
608 | Node _ f => Node (fun idx => inc (f idx)) | 608 | Node _ f => Node (fun idx => inc (f idx)) |
609 end. | 609 end. |
610 | 610 |
611 (** Now we are ready to prove the theorem where we got stuck before. We will not need to define any new induction principle, but it %\textit{%#<i>#will#</i>#%}% be helpful to prove some lemmas. *) | 611 (** Now we are ready to prove the theorem where we got stuck before. We will not need to define any new induction principle, but it _will_ be helpful to prove some lemmas. *) |
612 | 612 |
613 Lemma plus_ge : forall x1 y1 x2 y2, | 613 Lemma plus_ge : forall x1 y1 x2 y2, |
614 x1 >= x2 | 614 x1 >= x2 |
615 -> y1 >= y2 | 615 -> y1 >= y2 |
616 -> x1 + y1 >= x2 + y2. | 616 -> x1 + y1 >= x2 + y2. |
816 end] ] => dep_destruct E | 816 end] ] => dep_destruct E |
817 | [ |- context[if ?B then _ else _] ] => destruct B | 817 | [ |- context[if ?B then _ else _] ] => destruct B |
818 end; crush). | 818 end; crush). |
819 Qed. | 819 Qed. |
820 | 820 |
821 (** It is also useful to know that the result of a call to [cond] is not changed by substituting new tests and bodies functions, so long as the new functions have the same input-output behavior as the old. It turns out that, in Coq, it is not possible to prove in general that functions related in this way are equal. We treat this issue with our discussion of axioms in a later chapter. For now, it suffices to prove that the particular function [cond] is %\textit{%#<i>#extensional#</i>#%}%; that is, it is unaffected by substitution of functions with input-output equivalents. *) | 821 (** It is also useful to know that the result of a call to [cond] is not changed by substituting new tests and bodies functions, so long as the new functions have the same input-output behavior as the old. It turns out that, in Coq, it is not possible to prove in general that functions related in this way are equal. We treat this issue with our discussion of axioms in a later chapter. For now, it suffices to prove that the particular function [cond] is _extensional_; that is, it is unaffected by substitution of functions with input-output equivalents. *) |
822 | 822 |
823 Lemma cond_ext : forall (A : Set) (default : A) n (tests tests' : ffin n -> bool) | 823 Lemma cond_ext : forall (A : Set) (default : A) n (tests tests' : ffin n -> bool) |
824 (bodies bodies' : ffin n -> A), | 824 (bodies bodies' : ffin n -> A), |
825 (forall idx, tests idx = tests' idx) | 825 (forall idx, tests idx = tests' idx) |
826 -> (forall idx, bodies idx = bodies' idx) | 826 -> (forall idx, bodies idx = bodies' idx) |