comparison src/StackMachine.v @ 471:51a8472aca68

Batch of changes based on proofreader feedback
author Adam Chlipala <adam@chlipala.net>
date Mon, 08 Oct 2012 16:04:49 -0400
parents b36876d4611e
children 1fd4109f7b31
comparison
equal deleted inserted replaced
470:0df6dde807ab 471:51a8472aca68
146 (** With the two programming languages defined, we can turn to the compiler definition. *) 146 (** With the two programming languages defined, we can turn to the compiler definition. *)
147 147
148 148
149 (** ** Translation *) 149 (** ** Translation *)
150 150
151 (** Our compiler itself is now unsurprising. The list concatenation operator %\index{Gallina operators!++}%[++] comes from the Coq standard library. *) 151 (** Our compiler itself is now unsurprising. The list concatenation operator %\index{Gallina operators!++}\coqdocnotation{%#<tt>#++#</tt>#%}% comes from the Coq standard library. *)
152 152
153 Fixpoint compile (e : exp) : prog := 153 Fixpoint compile (e : exp) : prog :=
154 match e with 154 match e with
155 | Const n => iConst n :: nil 155 | Const n => iConst n :: nil
156 | Binop b e1 e2 => compile e2 ++ compile e1 ++ iBinop b :: nil 156 | Binop b e1 e2 => compile e2 ++ compile e1 ++ iBinop b :: nil
301 end) ((iConst n :: nil) ++ p) s = 301 end) ((iConst n :: nil) ++ p) s =
302 progDenote p (n :: s) 302 progDenote p (n :: s)
303 303
304 ]] 304 ]]
305 305
306 This last [unfold] has left us with an anonymous fixpoint version of [progDenote], which will generally happen when unfolding recursive definitions. Note that Coq has automatically renamed the [fix] arguments [p] and [s] to [p0] and [s0], to avoid clashes with our local free variables. There is also a subterm [None (A:=stack)], which has an annotation specifying that the type of the term ought to be [option stack]. This is phrased as an explicit instantiation of a named type parameter [A] from the definition of [option]. 306 This last [unfold] has left us with an anonymous recursive definition of [progDenote] (similarly to how [fun] or "lambda" constructs in general allow anonymous non-recursive functions), which will generally happen when unfolding recursive definitions. Note that Coq has automatically renamed the [fix] arguments [p] and [s] to [p0] and [s0], to avoid clashes with our local free variables. There is also a subterm [None (A:=stack)], which has an annotation specifying that the type of the term ought to be [option stack]. This is phrased as an explicit instantiation of a named type parameter [A] from the definition of [option].
307 307
308 Fortunately, in this case, we can eliminate the complications of anonymous recursion right away, since the structure of the argument ([iConst n :: nil) ++ p] is known, allowing us to simplify the internal pattern match with the [simpl] tactic, which applies the same reduction strategy that we used earlier with [Eval] (and whose details we still postpone).%\index{tactics!simpl}% 308 Fortunately, in this case, we can eliminate the complications of anonymous recursion right away, since the structure of the argument ([iConst n :: nil) ++ p] is known, allowing us to simplify the internal pattern match with the [simpl] tactic, which applies the same reduction strategy that we used earlier with [Eval] (and whose details we still postpone).%\index{tactics!simpl}%
309 *) 309 *)
310 310
311 simpl. 311 simpl.
388 progDenote ((compile e2 ++ compile e1 ++ iBinop b :: nil) ++ p) s = 388 progDenote ((compile e2 ++ compile e1 ++ iBinop b :: nil) ++ p) s =
389 progDenote p (binopDenote b (expDenote e1) (expDenote e2) :: s) 389 progDenote p (binopDenote b (expDenote e1) (expDenote e2) :: s)
390 390
391 ]] 391 ]]
392 392
393 What we need is the associative law of list concatenation, which is available as a theorem [app_assoc_reverse] in the standard library.%\index{Vernacular commands!Check}% *) 393 What we need is the associative law of list concatenation, which is available as a theorem [app_assoc_reverse] in the standard library.%\index{Vernacular commands!Check}% (Here and elsewhere, it is possible to tell the difference between inputs and outputs to Coq by periods at the ends of the inputs.) *)
394 394
395 Check app_assoc_reverse. 395 Check app_assoc_reverse.
396 (** %\vspace{-.15in}%[[ 396 (** %\vspace{-.15in}%[[
397 app_assoc_reverse 397 app_assoc_reverse
398 : forall (A : Type) (l m n : list A), (l ++ m) ++ n = l ++ m ++ n 398 : forall (A : Type) (l m n : list A), (l ++ m) ++ n = l ++ m ++ n
585 | TLt => leb 585 | TLt => leb
586 end. 586 end.
587 587
588 (** This function has just a few differences from the denotation functions we saw earlier. First, [tbinop] is an indexed type, so its indices become additional arguments to [tbinopDenote]. Second, we need to perform a genuine%\index{dependent pattern matching}% _dependent pattern match_, where the necessary _type_ of each case body depends on the _value_ that has been matched. At this early stage, we will not go into detail on the many subtle aspects of Gallina that support dependent pattern-matching, but the subject is central to Part II of the book. 588 (** This function has just a few differences from the denotation functions we saw earlier. First, [tbinop] is an indexed type, so its indices become additional arguments to [tbinopDenote]. Second, we need to perform a genuine%\index{dependent pattern matching}% _dependent pattern match_, where the necessary _type_ of each case body depends on the _value_ that has been matched. At this early stage, we will not go into detail on the many subtle aspects of Gallina that support dependent pattern-matching, but the subject is central to Part II of the book.
589 589
590 The same tricks suffice to define an expression denotation function in an unsurprising way: 590 The same tricks suffice to define an expression denotation function in an unsurprising way. Note that the [type] arguments to the [TBinop] constructor must be included explicitly in pattern-matching, but here we write underscores because we do not need to refer to those arguments directly. *)
591 *)
592 591
593 Fixpoint texpDenote t (e : texp t) : typeDenote t := 592 Fixpoint texpDenote t (e : texp t) : typeDenote t :=
594 match e with 593 match e with
595 | TNConst n => n 594 | TNConst n => n
596 | TBConst b => b 595 | TBConst b => b