前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >「SF-LC」15 Extraction

「SF-LC」15 Extraction

作者头像
零式的天空
发布2022-03-14 14:44:39
5070
发布2022-03-14 14:44:39
举报
文章被收录于专栏:零域Blog

Basic Extraction

  • OCaml (most mature)
  • Haskell (mostly works)
  • Scheme (a bit out of date)
代码语言:javascript
复制
Extraction "imp1.ml" ceval_step.

When Coq processes this command:

代码语言:javascript
复制
The file imp1.ml has been created by extraction.
The file imp1.mli has been created by extraction.

Controlling Extraction of Specific Types

如果不做任何处理的话…生成的 ml 里的 nat 则都会是 Church Numeral…

We can tell Coq how to extract certain Inductive definitions to specific OCaml types. we must say:

  1. how the Coq type itself should be represented in OCaml
  2. how each constructor should be translated
代码语言:javascript
复制
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.)

代码语言:javascript
复制
Extract Inductive nat ⇒ "int"
  [ "0" "(fun x → x + 1)" ]
  "(fun zero succ n →
      if n=0 then zero () else succ (n-1))".
代码语言:javascript
复制
Extract Constant plus ⇒ "( + )".
Extract Constant mult ⇒ "( * )".
Extract Constant eqb ⇒ "( = )".

注意:保证提取结果的合理性是你的责任。

代码语言:javascript
复制
Extract Constant minus ⇒ "( - )".

比如这么做很诱人……但是我们 Coq 的定义里 0 - 1 = 0, OCaml 的 int 则会有负数…

Recursor 的理论与实现 - a “encoding” of case expression and sum type

代码语言:javascript
复制
Fixpoint ceval_step (st : state) (c : com) (i : nat)
                    : option state :=
  match i with
  | O => None
  | S i' =>
    match c with
代码语言:javascript
复制
let rec ceval_step st c = function
  | O -> None
  | S i' ->
    (match c with
代码语言:javascript
复制
let rec ceval_step st c i =
  (fun zero succ n -> if n=0 then zero () else succ (n-1))
    (fun _ -> None)     (* zero *)
    (fun i' ->          (* succ *)
    match c with

注意我们是如何使用 “recursor” 来替代 case, match, pattern matching 得。

recall sum type 在 PLT 中的语法与语义:

代码语言:javascript
复制
T ::= 
  T + T

e ::=
  case e of
    | L(e) => e
    | R(e) => e
代码语言:javascript
复制
                 e → e' 
             ------------- (work inside constructor)
             C(e) -> C(e')

                 e → e' 
     -------------------------------   (work on the expr match against)
     case e of ... →  case e' of ...

-----------------------------------------------  (match Left constructor, substitute)
case L(v) of L(x) => e1 | R(y) => e2 → e1 [v/x]

-----------------------------------------------  (match Right constructor, substitute)
case R(v) of L(x) => e1 | R(y) => e2 → e1 [v/x]

可以发现 case 表达式可以理解为一种特殊的 application,会将其 argument 根据某种 tag (这里为构造函数) apply 到对应的 case body 上, 每个 case body 都是和 lambda abstraction 同构的一种 binder:

代码语言:javascript
复制
 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 这个 tagswitch 机制?

对于 Inductive nat 翻译到 OCaml int 时,这个机制可以用 v =? 0 来判断,因此我们的 recursor 实现为

代码语言:javascript
复制
fun zero succ                (* partial application  *)
  n -> if n=0                (* 判断 tag ... *)
       then zero ()          (* 0   case =>  (λx.e1) v *)
       else succ (n-1)       (* S n case =>  (λx.e2) v *)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Basic Extraction
  • Controlling Extraction of Specific Types
    • Recursor 的理论与实现 - a “encoding” of case expression and sum type
    相关产品与服务
    NAT 网关
    NAT 网关(NAT Gateway)提供 IP 地址转换服务,为腾讯云内资源提供高性能的 Internet 访问服务。通过 NAT 网关,在腾讯云上的资源可以更安全的访问 Internet,保护私有网络信息不直接暴露公网;您也可以通过 NAT 网关实现海量的公网访问,最大支持1000万以上的并发连接数;NAT 网关还支持 IP 级流量管控,可实时查看流量数据,帮助您快速定位异常流量,排查网络故障。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档