SF习题答案(4)(LF-POLY-church)


本部分答案针对第4章Poly的最后一个习题,church数有关的函数定义与定理证明,因为需要一些准备知识,因此单独形成一节进行介绍。

一、church数

church数是lambda演算的一个应用,在介绍church数之前,先对lambda演算进行一个简单的介绍。

1.1 λ 表达式/项

变量(Variable) 形式:x
变量名可能是一个字符或字符串,它表示一个参数(形参)或者一个值(实参)
抽象(Abstraction) 形式:λx.M
它表示获取一个参数x并返回M的lambda函数,M是一个合法lambda表达式,且符号λ和.表示绑定变量x于该函数抽象的函数体M。简单来说就是表示一个形参为x的函数M。
应用(Application) 形式:M N
它表示将函数M应用于参数N,其中M、N均为合法lambda表达式。简单来说就是给函数M输入实参N。

1.2 λ 归约

α 转换
一个lambda函数抽象在更名绑定变量前后是等价的,即:
α: λx.x ≡ λy.y
β 归约
一个lambda函数抽象中自由变量的替换
β: ((λV.E) E′) ≡ E[V := E′]
η 归约
清除lambda表达式中存在的冗余函数抽象
η:λx.M x ≡ M

1.3 church数

应用某个函数的次数(因此为非负的整数)——丘奇数(Church Numeral)。基本形式如下:
在这里插入图片描述

二、Coq中的church数

接下来我们完成Coq中church数相关定义于定理的证

2.1 基本定义

在Coq中对于church数的基本定义如下:

Definition cnat := forall X : Type, (X -> X) -> X -> X.
Definition one : cnat := fun (X : Type) (f : X -> X) (x : X) => f x.
Definition two : cnat := fun (X : Type) (f : X -> X) (x : X) => f (f x).
Definition zero : cnat := fun (X : Type) (f : X -> X) (x : X) => x.

我们看cnat的定义,对于任意类型X,定义一个X -> X的函数,在给出一个属于X的变量,得出最终一个属于X类型的值,这就是一个基本的church数。我们观察对zero、one、two的定义,都符合这样的定义方式。

2.2 练习1,church_succ

定义church数中的后继succ函数,输入一个cnat类型的数,同时也输出一个cnat类型。

Definition succ (n : cnat) : cnat :=
  fun (X : Type) (f : X -> X) (x : X) => f (n X f x).
Example succ_1 : succ zero = one.
Proof. reflexivity. Qed.
Example succ_2 : succ one = two.
Proof. reflexivity. Qed.
Example succ_3 : succ two = three.
Proof. reflexivity. Qed.

要怎么理解这里的f (n X f x),X和f在=>给出了定义,我们知道cnat的类型为forall X : Type, (X -> X) -> X -> X。所以,看括号里的(n X f x),我们对于cnat类型变量给出了X,(X->X)也就是f,和属于X的变量x,那么(n X f x)的输出也一定是个属于类型X的值,在外面加上f,结果同样是属于类型X的值。完成succ的定义。

2.3 练习2,church_plus

同样的,church_plus的定义如下;

Definition plus (n m : cnat) : cnat :=
  fun (X : Type) (f : X -> X) (x : X) => (n X f (m X f x)).
Example plus_1 : plus zero one = one.
Proof. reflexivity. Qed.
Example plus_2 : plus two three = plus three two.
Proof. reflexivity. Qed.
Example plus_3 :
  plus (plus two two) three = plus one (plus three three).
Proof. reflexivity. Qed.
Definition four : cnat :=
  fun (X : Type) (f : X -> X) (x : X) => f (f (f (f x))).
Example plus_4 :
  plus two two = four.
Proof. reflexivity. Qed.
比较简单,因为前面只定义了zero、one、two,所以例子的验证就是不断在加这3个完成验证,我们定义了four,也证明plus two two = fou,从而说明我们plus 的定义是正确的。

2.4 练习3,church_mult

乘法的关键是对f的变换,nm既是对n中的f变为m次f,从而万册灰姑娘nm的计算,代码如下:

Definition mult (n m : cnat) : cnat :=
  fun (X : Type) (f : X -> X) (x : X) => n X (m X f) x.
Example mult_1 : mult one one = one.
Proof. reflexivity. Qed.
Example mult_2 : mult zero (plus three three) = zero.
Proof. reflexivity. Qed.
Example mult_3 : mult two three = plus three three.
Proof. reflexivity. Qed.
Definition six : cnat :=
  fun (X : Type) (f : X -> X) (x : X) =>  f (f (f (f (f (f x))))).
Example mult_4 : mult two three = six.
Proof. reflexivity. Qed.

2.5 练习4,church_exp

这里本书作者给了提示。“Hint: Polymorphism plays a crucial role here.”。多态是关键,那么我们很自然的就会想到类型的多态。后面作者又说“choosing the right type to iterate over can be tricky.”所以,这里我们知道,关键就是类型X的变换,代码如下:

Definition exp (n m : cnat) : cnat :=
  fun X => (m (X->X)) (n X).
Example exp_1 : exp two two = plus two two.
Proof. reflexivity. Qed.
Example exp_2 : exp three zero = one.
Proof. reflexivity. Qed.
Example exp_3 : exp three two = plus (mult two (mult two two)) one.
Proof. reflexivity. Qed.

之前留下的一部分LF第四章POLY答案的小尾巴,这里和大家分享。针对Coq的学习,学习完前4章其实已经差不多可以开始一些实际代码的形式化验证工作了,大家可以看相关论文学习验证思路与方法了。Software Foundations也已经从之前的4本书变成了6本书,Coq社区的建设也更加完善。书中多次强调不要分享代码,之后我也就不在网上分享相应的代码了,有学习Coq的小伙伴欢迎留言交流。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值