我试图在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
的抽象版本,而不是实例化类型类时给出的实现。
我做错了什么?
答案 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 :: [ ]
使用simpl
或cbv
,您可以获得map
的实例(事实上,您将map S
的结果应用于1 :: 2 :: 3 :: []
,因此目标变得微不足道。我不知道为什么展开fmap
或破坏ListFunctor
会产生通用的fmap0
。