「SF-LC」15 Extraction
Basic Extraction
- OCaml (most mature)
 - Haskell (mostly works)
 - Scheme (a bit out of date)
 
1  | Extraction "imp1.ml" ceval_step.  | 
When Coq processes this command:
1  | The file imp1.ml has been created by extraction.  | 
Controlling Extraction of Specific Types
如果不做任何处理的话…生成的 ml 里的 nat 则都会是 Church Numeral…
We can tell Coq how to extract certain
Inductivedefinitions to specific OCaml types.
we must say:
- how the Coq type itself should be represented in OCaml
 - how each constructor should be translated
 
1  | Extract Inductive bool ⇒ "bool" [ "true" "false" ].  | 
also, for non-enumeration types (where the constructors take arguments),
we give an OCaml expression that can be used as a “recursor” over elements of the type. (Think Church numerals.)
1  | Extract Inductive nat ⇒ "int"  | 
1  | Extract Constant plus ⇒ "( + )".  | 
注意:保证提取结果的合理性是你的责任。
1  | Extract Constant minus ⇒ "( - )".  | 
比如这么做很诱人……但是我们 Coq 的定义里 0 - 1 = 0, OCaml 的 int 则会有负数…
Recursor 的理论与实现 - a “encoding” of case expression and sum type
1  | Fixpoint ceval_step (st : state) (c : com) (i : nat)  | 
1  | let rec ceval_step st c = function  | 
1  | let rec ceval_step st c i =  | 
注意我们是如何使用 “recursor” 来替代 case, match, pattern matching 得。
recall sum type 在 PLT 中的语法与语义:
1  | T ::=  | 
1  | e → e'  | 
可以发现 case 表达式可以理解为一种特殊的 application,会将其 argument 根据某种 tag (这里为构造函数) apply 到对应的 case body 上,
每个 case body 都是和 lambda abstraction 同构的一种 binder:
 L(x) => e1     ===   λx.e1
 R(x) => e2     ===   λx.e2 
 case v e1|e2   ===   (λx.e1|e2) v      -- `e1` or `e2` depends on the _tag_ wrapped on `v`
这个角度也解释了 Haskell/SML 在申明函数时直接对参数写 pattern match 的理论合理性.
根据经验几乎所有的 binding 都可以被 desugar 成函数(即 lambda expression).
难点在于我们如何 re-implement 这个 tag 的 switch 机制?
对于 Inductive nat 翻译到 OCaml int 时,这个机制可以用 v =? 0 来判断,因此我们的 recursor 实现为
1  | fun zero succ (* partial application *)  | 






