用coq编写隐式证明对象的不可能模式
我试图使用coq作为一种依赖类型的编程语言。我创建了以下小程序:用coq编写隐式证明对象的不可能模式,coq,Coq,我试图使用coq作为一种依赖类型的编程语言。我创建了以下小程序: Inductive Good : list nat -> Set := | GoodNonEmpty : forall h t, Good (h :: t). Definition get_first(l : list nat)(good : Good l) : nat := match l with | h :: t => h | nil => match good
Inductive Good : list nat -> Set :=
| GoodNonEmpty : forall h t, Good (h :: t).
Definition get_first(l : list nat)(good : Good l) : nat :=
match l with
| h :: t => h
| nil =>
match good with
end
end.
我为非空列表定义了一个类型,并创建了一个函数,该函数获取此类列表的第一个元素,前提是有证据证明它不是空的。我很好地处理了head项由两个项组成的情况,但我不能处理空列表这一不可能的情况。我如何在coq中做到这一点?一种比您的尝试更简单的方法是:
Definition get_first (l : list nat) (good : Good l) : nat :=
match good with
| GoodNonEmpty h _ => h
end.
这里有一种方法可以按照你想要的方式来做。您会注意到,证明“Good nil”不存在是非常冗长的,内联的
Definition get_first (l : list nat) (good : Good l) : nat :=
(
match l as l' return (Good l' -> nat) with
| nil =>
fun (goodnil : Good nil) =>
(
match goodnil in (Good l'') return (nil = l'' -> nat) with
| GoodNonEmpty h t =>
fun H => False_rect _ (nil_cons H)
end
)
(@eq_refl _ nil)
| h :: _ => fun _ => h
end
) good.
您当然可以在外部定义其中一些内容并重用它。不过,我不知道最佳做法是什么。也许有人可以用更短的方法来做同样的事情
编辑: 顺便说一句,在验证模式下,您可以以更简单的方式获得几乎相同的结果:
Definition get_first' (l : list nat) (good : Good l) : nat.
Proof.
destruct l. inversion good. exact n.
Defined.
然后你可以:
Print get_first'.
看看Coq是如何定义它的。然而,对于更复杂的事情,您最好遵循来自#coq IRC渠道的gdsfhl提出的解决方案:
你可以看到,他使用refine
策略提供了要编写的术语框架的一部分,并推迟了缺少的证据