Functional programming Coq:证明;镜头在“合成”下关闭;
我是一个功能性程序员,对Coq完全陌生。事实上,我刚做完。特别是,我对这种语言感兴趣,它可以形式化一些与光学相关的定律。例如,我想知道如何对其进行编码 我开始处理GetPut。前面提到的教程不包括记录,但我认为它们是我需要编码镜头的东西。据我所知,组合方法应该作为一个定义来实现。最后,我假设我的定理需要接收合成透镜的GetPut证据,以通过等式证明相同的定律适用于合成透镜。不是很有帮助,但这是我的(不完整和错误)证明框架:Functional programming Coq:证明;镜头在“合成”下关闭;,functional-programming,coq,proof,lenses,Functional Programming,Coq,Proof,Lenses,我是一个功能性程序员,对Coq完全陌生。事实上,我刚做完。特别是,我对这种语言感兴趣,它可以形式化一些与光学相关的定律。例如,我想知道如何对其进行编码 我开始处理GetPut。前面提到的教程不包括记录,但我认为它们是我需要编码镜头的东西。据我所知,组合方法应该作为一个定义来实现。最后,我假设我的定理需要接收合成透镜的GetPut证据,以通过等式证明相同的定律适用于合成透镜。不是很有帮助,但这是我的(不完整和错误)证明框架: Record lens (S : Type) (A : Type) :=
Record lens (S : Type) (A : Type) := mkLens {
get : S -> A;
put : S -> A -> S }.
Definition compose_ln (S A B : Type) (ln1: lens S A) (ln2 : lens A B) : lens S B :=
{| get := fun (s : S) => get ln1 s;
put := fun (s : S) (a : A) => put ln1 s (put ln2 (get ln1 s) a) |}.
Theorem closed_GetPut :
(forall S A B : Type,
(forall (s : S),
(forall (ln1 : lens S A) (ln2 : lens A B),
(exists GetPut_proof : ln1 (* ln1 holds GetPut? *)),
(exists GetPut_proof : ln2 (* ln2 holds GetPut? *)),
(put (compose_ln ln1 ln2) s (get (compose_ln ln1 ln2) s) = s)))).
Proof.
(* ... *)
Qed.
话虽如此:
- 我写这个证明的方法对吗?还有其他更好的方法吗
- 在哪里可以找到类似的示例作为指导示例
- 基于我的FP背景,有什么更好的材料可以继续学习Coq?(我在想本杰明·C·皮尔斯的作品。)
谢谢大家! 这看起来大致合理,但需要一些整理 首先,您最好删除两个“存在”量词(将它们更改为普通含义)
第二,最后两个假设的类型不应该仅仅是“ln1”和“ln2”,而是类似于“表现非常好的ln1”和“表现非常好的ln2”。(然后最终结果的类型可以是“非常好的表现(合成ln2 ln2)”。在阅读了的第一章之后(如果你的背景是功能性的,我肯定会推荐),我能够实现透镜在Coq中合成时关闭的证明。首先,我们需要定义
透镜和合成:
Record lens (S A : Type) := {
get : S -> A;
put : S -> A -> S }.
Definition compose {S A B : Type} (ln1 : lens S A) (ln2 : lens A B) : lens S B :=
{| get := fun (s : S) => ln2.(get A B) (ln1.(get S A) s);
put := fun (s : S) (b : B) => ln1.(put S A) s (ln2.(put A B) (ln1.(get S A) s) b) |}.
(*)注意访问记录字段的固定语法
然后,我们需要声明涉及的属性,以最终达到行为良好的(由@Benjamin Pierce在接受的答案中建议):
一旦定义了属性,下一个(也是最大的)挑战在于证明性能良好的透镜在合成条件下是闭合的。为此,我们可以使用以下定理框架:
Theorem compose_is_closed : forall (S A B : Type) (ln1 : lens S A) (ln2 : lens A B),
very_well_behaved ln1 -> very_well_behaved ln2 -> very_well_behaved (compose ln1 ln2).
Proof.
(* tactics here *)
Qed.
现在,我的Coq知识非常有限,这就是为什么我没有在这里包括战术,因为我觉得我当前的实现仍然很幼稚。无论如何,如果你对它感到好奇,你可以找到全部证据。当然,这是一个更好的结构!但是,我现在看不到非常好的背后的原因。我的存在
直觉是基于“hd具有列表非空的证明”一节。它是否表现得非常好
类似于hd\u never\u fail
(用GetPut
,PutGet
等替换safety\u-proof
)?我的意思是,它是一个定义吗?你想要的是定义一个属性(即,从镜头到道具的函数)表示镜头表现良好意味着什么。然后,定理变成“如果两个镜头表现良好,那么它们的组合也很好。”看看《软件基础》的第一卷可能是一个非常有效的方法来加速这一切。太好了,我会这样做。非常感谢!我已经发表了一篇博客文章(),在那里我们展示了与这篇文章非常相似的证明,以防你感兴趣。
Theorem compose_is_closed : forall (S A B : Type) (ln1 : lens S A) (ln2 : lens A B),
very_well_behaved ln1 -> very_well_behaved ln2 -> very_well_behaved (compose ln1 ln2).
Proof.
(* tactics here *)
Qed.