Coq 证明中使用了错误的类型类实例
Wrong Typeclass Instance used in Coq Proof
我正在尝试根据 CoqExtLib 中定义的有限映射执行以下证明。但是,我遇到了一个问题,证明中出现的 RelDec
实例与我认为声明的实例不同。
Require Import ExtLib.Data.Map.FMapAList.
Require ExtLib.Structures.Sets.
Module DSet := ExtLib.Structures.Sets.
Require ExtLib.Structures.Maps.
Module Map := ExtLib.Structures.Maps.
Require Import ExtLib.Data.Nat.
Require Import Coq.Lists.List.
Definition Map k v := alist k v.
Definition loc := nat.
Definition sigma : Type := (Map loc nat).
Lemma not_in_sigma : forall (l l' : loc) (e : nat) (s : sigma),
l <> l' ->
Map.lookup l ((l',e)::s) = Map.lookup l s.
intros. simpl. assert ( RelDec.rel_dec l l' = true -> l = l').
pose (ExtLib.Core.RelDec.rel_dec_correct l l') as i. destruct i.
(*i := RelDec.rel_dec_correct l l' : RelDec.rel_dec l l' = true <-> l >= l'*)
如您所见,我试图利用这样一个事实,即如果 rel_dec
的两个输入不相等,则其计算结果必须为 false。这似乎符合 ExtLib.Data.Nat 中给出的定义:
Global Instance RelDec_eq : RelDec (@eq nat) :=
{ rel_dec := EqNat.beq_nat }.
但是,在我上面显示的代码中,它使用 >=
而不是 =
作为有限映射参数化的关系,所以我不能应用定理 rel_dec_correct
.
为什么会这样?如何选择 RelDec 的实例?在证明有关由类型类限定的类型的定理时,我需要做些什么特别的事情吗?我怎样才能得到适用于相等而不是大于的 rel_dec_correct
版本?
要解决此问题,您可能需要设置 Debug Typeclasses
选项:
Set Debug Typeclasses.
assert ( RelDec.rel_dec l l' = true -> l = l').
或者,或者,使用 Set Printing Implicit
来揭示 Coq 已经拾取的实例。
后者告诉我们它是 RelDec_ge
,因为目标现在具有以下形式:
@RelDec.rel_dec loc ge RelDec_ge l l' = true -> l = l'
显然 Coq 选择的实例对您的目的来说是错误的,但是您可以像这样锁定您想要的关系:
assert ( RelDec.eq_dec l l' = true -> l = l').
现在 apply (RelDec.rel_dec_correct l l').
解决了目标,但是 pose
不起作用,因为没有信息可以将目标与有用的实例联系起来。 pose
策略只会找到 RelDec nat <rel>
的实例(您可以用这个白话列出所有实例:Print Instances RelDec.RelDec.
)。
B.C 的 tutorial on typeclasses 非常好。皮尔斯你可能想看看。
我正在尝试根据 CoqExtLib 中定义的有限映射执行以下证明。但是,我遇到了一个问题,证明中出现的 RelDec
实例与我认为声明的实例不同。
Require Import ExtLib.Data.Map.FMapAList.
Require ExtLib.Structures.Sets.
Module DSet := ExtLib.Structures.Sets.
Require ExtLib.Structures.Maps.
Module Map := ExtLib.Structures.Maps.
Require Import ExtLib.Data.Nat.
Require Import Coq.Lists.List.
Definition Map k v := alist k v.
Definition loc := nat.
Definition sigma : Type := (Map loc nat).
Lemma not_in_sigma : forall (l l' : loc) (e : nat) (s : sigma),
l <> l' ->
Map.lookup l ((l',e)::s) = Map.lookup l s.
intros. simpl. assert ( RelDec.rel_dec l l' = true -> l = l').
pose (ExtLib.Core.RelDec.rel_dec_correct l l') as i. destruct i.
(*i := RelDec.rel_dec_correct l l' : RelDec.rel_dec l l' = true <-> l >= l'*)
如您所见,我试图利用这样一个事实,即如果 rel_dec
的两个输入不相等,则其计算结果必须为 false。这似乎符合 ExtLib.Data.Nat 中给出的定义:
Global Instance RelDec_eq : RelDec (@eq nat) :=
{ rel_dec := EqNat.beq_nat }.
但是,在我上面显示的代码中,它使用 >=
而不是 =
作为有限映射参数化的关系,所以我不能应用定理 rel_dec_correct
.
为什么会这样?如何选择 RelDec 的实例?在证明有关由类型类限定的类型的定理时,我需要做些什么特别的事情吗?我怎样才能得到适用于相等而不是大于的 rel_dec_correct
版本?
要解决此问题,您可能需要设置 Debug Typeclasses
选项:
Set Debug Typeclasses.
assert ( RelDec.rel_dec l l' = true -> l = l').
或者,或者,使用 Set Printing Implicit
来揭示 Coq 已经拾取的实例。
后者告诉我们它是 RelDec_ge
,因为目标现在具有以下形式:
@RelDec.rel_dec loc ge RelDec_ge l l' = true -> l = l'
显然 Coq 选择的实例对您的目的来说是错误的,但是您可以像这样锁定您想要的关系:
assert ( RelDec.eq_dec l l' = true -> l = l').
现在 apply (RelDec.rel_dec_correct l l').
解决了目标,但是 pose
不起作用,因为没有信息可以将目标与有用的实例联系起来。 pose
策略只会找到 RelDec nat <rel>
的实例(您可以用这个白话列出所有实例:Print Instances RelDec.RelDec.
)。
B.C 的 tutorial on typeclasses 非常好。皮尔斯你可能想看看。