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 :=