Mercurial > cpdt > repo
comparison src/Firstorder.v @ 290:758778c0468c
PC comments for FirstOrder
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Wed, 10 Nov 2010 15:37:01 -0500 |
parents | 76043a960a38 |
children | d5787b70cf48 |
comparison
equal
deleted
inserted
replaced
289:4662b6f099b0 | 290:758778c0468c |
---|---|
1 (* Copyright (c) 2008-2009, Adam Chlipala | 1 (* Copyright (c) 2008-2010, 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: |
48 | Bool : type | 48 | Bool : type |
49 | Arrow : type -> type -> type. | 49 | Arrow : type -> type -> type. |
50 | 50 |
51 (** It is useful to define a syntax extension that lets us write function types in more standard notation. *) | 51 (** It is useful to define a syntax extension that lets us write function types in more standard notation. *) |
52 | 52 |
53 (** printing --> $\longrightarrow$ *) | |
53 Infix "-->" := Arrow (right associativity, at level 60). | 54 Infix "-->" := Arrow (right associativity, at level 60). |
54 | 55 |
55 (** Now we turn to a typing judgment. We will need to define it in terms of typing contexts, which we represent as lists of pairs of variables and types. *) | 56 (** Now we turn to a typing judgment. We will need to define it in terms of typing contexts, which we represent as lists of pairs of variables and types. *) |
56 | 57 |
57 Definition ctx := list (var * type). | 58 Definition ctx := list (var * type). |
58 | 59 |
59 (** The definitions of our judgments will be prettier if we write them using mixfix syntax. To define a judgment for looking up the type of a variable in a context, we first %\textit{%#</i>#reserve#</i>#%}% a notation for the judgment. Reserved notations enable mutually-recursive definition of a judgment and its notation; in this sense, the reservation is like a forward declaration in C. *) | 60 (** The definitions of our judgments will be prettier if we write them using mixfix syntax. To define a judgment for looking up the type of a variable in a context, we first %\textit{%#</i>#reserve#</i>#%}% a notation for the judgment. Reserved notations enable mutually-recursive definition of a judgment and its notation; in this sense, the reservation is like a forward declaration in C. *) |
60 | 61 |
62 (** printing |-v $\vdash_\mathsf{v}$ *) | |
61 Reserved Notation "G |-v x : t" (no associativity, at level 90, x at next level). | 63 Reserved Notation "G |-v x : t" (no associativity, at level 90, x at next level). |
62 | 64 |
63 (** Now we define the judgment itself, for variable typing, using a [where] clause to associate a notation definition. *) | 65 (** Now we define the judgment itself, for variable typing, using a [where] clause to associate a notation definition. *) |
64 | 66 |
65 Inductive lookup : ctx -> var -> type -> Prop := | 67 Inductive lookup : ctx -> var -> type -> Prop := |
74 | 76 |
75 Hint Constructors lookup. | 77 Hint Constructors lookup. |
76 | 78 |
77 (** The same technique applies to defining the main typing judgment. We use an [at next level] clause to cause the argument [e] of the notation to be parsed at a low enough precedence level. *) | 79 (** The same technique applies to defining the main typing judgment. We use an [at next level] clause to cause the argument [e] of the notation to be parsed at a low enough precedence level. *) |
78 | 80 |
81 (** printing |-e $\vdash_\mathsf{e}$ *) | |
79 Reserved Notation "G |-e e : t" (no associativity, at level 90, e at next level). | 82 Reserved Notation "G |-e e : t" (no associativity, at level 90, e at next level). |
80 | 83 |
81 Inductive hasType : ctx -> exp -> type -> Prop := | 84 Inductive hasType : ctx -> exp -> type -> Prop := |
82 | TConst : forall G b, | 85 | TConst : forall G b, |
83 G |-e Const b : Bool | 86 G |-e Const b : Bool |
260 Qed. | 263 Qed. |
261 End subst. | 264 End subst. |
262 | 265 |
263 Hint Resolve subst_hasType_closed. | 266 Hint Resolve subst_hasType_closed. |
264 | 267 |
265 (** A notation for substitution will make the operational semantics easier to read. *) | 268 (** A notation for substitution will make the operational semantics easier to read. %The ASCII operator \texttt{\textasciitilde{}>} will afterward be rendered as $\leadsto$.% *) |
266 | 269 |
270 (** printing ~> $\leadsto$ *) | |
267 Notation "[ x ~> e1 ] e2" := (subst x e1 e2) (no associativity, at level 80). | 271 Notation "[ x ~> e1 ] e2" := (subst x e1 e2) (no associativity, at level 80). |
268 | 272 |
269 (** To define a call-by-value small-step semantics, we rely on a standard judgment characterizing which expressions are values. *) | 273 (** To define a call-by-value small-step semantics, we rely on a standard judgment characterizing which expressions are values. *) |
270 | 274 |
271 Inductive val : exp -> Prop := | 275 Inductive val : exp -> Prop := |
292 | 296 |
293 where "e1 ==> e2" := (step e1 e2). | 297 where "e1 ==> e2" := (step e1 e2). |
294 | 298 |
295 Hint Constructors step. | 299 Hint Constructors step. |
296 | 300 |
297 (** The progress theorem says that any well-typed expression can take a step. To deal with limitations of the [induction] tactic, we put most of the proof in a lemma whose statement uses the usual trick of introducing extra equality hypotheses. *) | 301 (** The progress theorem says that any well-typed expression that is not a value can take a step. To deal with limitations of the [induction] tactic, we put most of the proof in a lemma whose statement uses the usual trick of introducing extra equality hypotheses. *) |
298 | 302 |
299 Lemma progress' : forall G e t, G |-e e : t | 303 Lemma progress' : forall G e t, G |-e e : t |
300 -> G = nil | 304 -> G = nil |
301 -> val e \/ exists e', e ==> e'. | 305 -> val e \/ exists e', e ==> e'. |
302 induction 1; crush; eauto; | 306 induction 1; crush; eauto; |
444 induction G1; inversion 1; crush. | 448 induction G1; inversion 1; crush. |
445 Qed. | 449 Qed. |
446 | 450 |
447 Implicit Arguments subst_eq [t G1]. | 451 Implicit Arguments subst_eq [t G1]. |
448 | 452 |
449 Lemma subst_eq' : forall t G1 x, | 453 Lemma subst_neq' : forall t G1 x, |
450 G1 ++ xt :: nil |-v x : t | 454 G1 ++ xt :: nil |-v x : t |
451 -> x <> length G1 | 455 -> x <> length G1 |
452 -> G1 |-v x : t. | 456 -> G1 |-v x : t. |
453 induction G1; inversion 1; crush; | 457 induction G1; inversion 1; crush; |
454 match goal with | 458 match goal with |
455 | [ H : nil |-v _ : _ |- _ ] => inversion H | 459 | [ H : nil |-v _ : _ |- _ ] => inversion H |
456 end. | 460 end. |
457 Qed. | 461 Qed. |
458 | 462 |
459 Hint Resolve subst_eq'. | 463 Hint Resolve subst_neq'. |
460 | 464 |
461 Lemma subst_neq : forall v t G1, | 465 Lemma subst_neq : forall v t G1, |
462 G1 ++ xt :: nil |-v v : t | 466 G1 ++ xt :: nil |-v v : t |
463 -> v <> length G1 | 467 -> v <> length G1 |
464 -> G1 |-e Var v : t. | 468 -> G1 |-e Var v : t. |
570 End DeBruijn. | 574 End DeBruijn. |
571 | 575 |
572 | 576 |
573 (** * Locally Nameless Syntax *) | 577 (** * Locally Nameless Syntax *) |
574 | 578 |
575 (** The most popular Coq syntax encoding today is the %\textit{%#<i>#locally nameless#</i>#%}% style, which has been around for a while but was popularized recently by Aydemir et al., following a methodology summarized in their paper "Engineering Formal Metatheory." #<a href="http://www.cis.upenn.edu/~plclub/oregon08/">#A specialized tutorial by that group#</a>#%\footnote{\url{http://www.cis.upenn.edu/~plclub/oregon08/}}% explains the approach, based on a library. In this section, we will build up all of the necessary ingredients from scratch. | 579 (** The most popular Coq syntax encoding today is the %\textit{%#<i>#locally nameless#</i>#%}% style, which has been around for a while but was popularized recently by Aydemir et al., following a methodology summarized in their paper %``%#"#Engineering Formal Metatheory.#"#%''% #<a href="http://www.cis.upenn.edu/~plclub/oregon08/">#A specialized tutorial by that group#</a>#%\footnote{\url{http://www.cis.upenn.edu/~plclub/oregon08/}}% explains the approach, based on a library. In this section, we will build up all of the necessary ingredients from scratch. |
576 | 580 |
577 The one-sentence summary of locally nameless encoding is that we represent free variables as concrete syntax does, and we represent bound variables with de Bruijn indices. Many proofs involve reasoning about terms transplanted into different free variable contexts; concrete encoding of free variables means that, to perform such a transplanting, we need no fix-up operation to adjust de Bruijn indices. At the same time, use of de Bruijn indices for local variables gives us canonical representations of expressions, with respect to the usual convention of alpha-equivalence. This makes many operations, including substitution of open terms in open terms, easier to implement. | 581 The one-sentence summary of locally nameless encoding is that we represent free variables as concrete syntax does, and we represent bound variables with de Bruijn indices. Many proofs involve reasoning about terms transplanted into different free variable contexts; concrete encoding of free variables means that, to perform such a transplanting, we need no fix-up operation to adjust de Bruijn indices. At the same time, use of de Bruijn indices for local variables gives us canonical representations of expressions, with respect to the usual convention of alpha-equivalence. This makes many operations, including substitution of open terms in open terms, easier to implement. |
578 | 582 |
579 The "Engineering Formal Metatheory" methodology involves a number of subtle design decisions, which we will describe as they appear in the latest version of our running example. *) | 583 The %``%#"#Engineering Formal Metatheory#"#%''% methodology involves a number of subtle design decisions, which we will describe as they appear in the latest version of our running example. *) |
580 | 584 |
581 Module LocallyNameless. | 585 Module LocallyNameless. |
582 | 586 |
583 Definition free_var := string. | 587 Definition free_var := string. |
584 Definition bound_var := nat. | 588 Definition bound_var := nat. |
614 | 618 |
615 where "G |-v x : t" := (lookup G x t). | 619 where "G |-v x : t" := (lookup G x t). |
616 | 620 |
617 Hint Constructors lookup. | 621 Hint Constructors lookup. |
618 | 622 |
619 (** The first unusual operation we need is %\textit{%#<i>#opening#</i>#%}%, where we replace a particular bound variable with a particular free variable. Whenever we "go under a binder," in the typing judgment or elsewhere, we choose a new free variable to replace the old bound variable of the binder. Opening implements the replacement of one by the other. It is like a specialized version of the substitution function we used for pure de Bruijn terms. *) | 623 (** The first unusual operation we need is %\textit{%#<i>#opening#</i>#%}%, where we replace a particular bound variable with a particular free variable. Whenever we %``%#"#go under a binder,#"#%''% in the typing judgment or elsewhere, we choose a new free variable to replace the old bound variable of the binder. Opening implements the replacement of one by the other. It is like a specialized version of the substitution function we used for pure de Bruijn terms. We implement opening with both the richly-typed natural number equality test [eq_nat_dec] that we have discussed previously and with another standard library function [le_lt_dec], which is an analogous richly-typed test for [<=]. *) |
620 | 624 |
621 Section open. | 625 Section open. |
622 Variable x : free_var. | 626 Variable x : free_var. |
623 | 627 |
624 Fixpoint open (n : bound_var) (e : exp) : exp := | 628 Fixpoint open (n : bound_var) (e : exp) : exp := |