在Coq证明中展开匿名函数

时间:2015-01-20 04:51:45

标签: coq

我试图在Coq中证明涉及使用类型类的东西。

特定类型类与此Functor类型类几乎相同:https://gist.github.com/aztek/2911378

我的实例看起来像这样:

Instance ListFunctor : Functor list := { fmap := map }.
  (* Proof stuff here *)
Defined.

map是标准库中列表的映射。

我所做的“证明”基本上只是一个单元测试:

Example list_map_test : fmap (fun x => x + 1) (1::2::3::nil) = (2::3::4::nil).

我的目标看起来像这样,我被困住了:

(let (fmap0, _, _) := ListFunctor in fmap0) nat nat
 (fun x : nat => x + 1) (1 :: 2 :: 3 :: nil) = 2 :: 3 :: 4 :: nil

Coq将实例解析为获取fmap0,然后使用args nat nat (fun x : nat => x + 1) (1 :: 2 :: 3 :: nil)应用生成的匿名函数。

作为我的证明的下一步,我想展开fmap0或匿名函数。

我该怎么做?我做不到unfold fmap0

我的期望是fmap0是标准的lib map,因为这是我给实例的。

我能够自己破坏实例,但这显示了fmap0的抽象版本,而不是实例化类型类时给出的实现。

我做错了什么?

2 个答案:

答案 0 :(得分:3)

如果f是匿名函数(即某种形式为fun x => expr),那么simpl就足够了。如果它是一个标识符并且您无法展开它,那么(1)它是在您的上下文中绑定的局部变量,或者(2)它是通过Qed定义的全局定义。在后一种情况下,只需从定义中删除Qed,将其替换为Defined。在前一种情况下,我猜您应该尝试展开或简化expr1,以便Coq可以访问f的实际定义(反过来,这可能需要删除{{1}来自其他全局定义的。)

答案 1 :(得分:1)

我不确切知道为什么,但如果你直接简化目标

1 subgoal
______________________________________(1/1)
fmap (λ x : nat, (x + 1)%nat) (1 :: 2 :: 3 :: [ ]) = 2 :: 3 :: 4 :: [ ]

使用simplcbv,您可以获得map的实例(事实上,您将map S的结果应用于1 :: 2 :: 3 :: [],因此目标变得微不足道。我不知道为什么展开fmap或破坏ListFunctor会产生通用的fmap0