Coq 对“护航模式”使用模式匹配表达式的析构函数

Coq 对“护航模式”使用模式匹配表达式的析构函数,coq,Coq,就本问题而言,假设我有: Parameter eq_bool : forall (A:Type), A -> A -> bool. Arguments eq_bool {A} _ _. Axiom eq_bool_correct : forall (A:Type) (x y:A), eq_bool x y = true -> x = y. Axiom eq_bool_correct' : forall (A:Type) (x y:A), x = y -&

就本问题而言,假设我有:

Parameter eq_bool : forall (A:Type), A -> A -> bool.

Arguments eq_bool {A} _ _.

Axiom eq_bool_correct : forall (A:Type) (x y:A),
    eq_bool x y = true -> x = y.

Axiom eq_bool_correct' : forall (A:Type) (x y:A),
     x = y -> eq_bool x y = true.
我有一个函数,它给出了两个值xy:a,只要x=y,它就返回x=y的一些证明,否则就不返回。此函数通过eq_bool x y上的模式匹配来实现,以测试相等性,并使用护航模式作为技巧,在代码中访问与匹配分支对应的相等性证明:

Definition test (A:Type) (x y:A) : option (x = y) :=
    match eq_bool x y as b return eq_bool x y = b -> option (x = y) with
    | true  => fun p => Some (eq_bool_correct A x y p)
    | false => fun _ => None
    end (eq_refl (eq_bool x y)).
我现在试图证明关于此函数的一个简单结果:

Theorem basic: forall (A:Type) (x y:A),
    x = y -> test A x y <> None.
Proof.
    intros A x y H. rewrite H. unfold test.

A : Type
x, y : A
H : x = y
============================
(if eq_bool y y as b return (eq_bool y y = b -> option (y = y))
 then fun p : eq_bool y y = true => Some (eq_bool_correct A y y p)
 else fun _ : eq_bool y y = false => None) eq_refl <> None

我知道我必须阅读CPDT,特别是在车队模式上,但我有一个更好的学习经验,适合初学者的软件基金会:在我目前的技能水平,除了销毁,我想不出任何东西,希望有人能提出一种方法来完成这个证明。

这是一种典型的情况,粗心的抽象会导致术语类型错误。一般来说,您希望使用稍微不同的原则来避免这些问题,在sumbool或reflect上进行匹配可能会提供更好的结果

在这种特殊情况下,为了让事情顺利进行,您首先需要对目标进行一点概括,这样它就不会依赖于eq_refl,这在匹配时是一个问题,因为它的键入规则太严格,然后选择适当的子项。我使用ssreflect模式语言,因为它更方便:

(* Do From Coq Require Import ssreflect. *)
Theorem basic (A : Type) (x y : A) (p : x = y) : test x y <> None.
Proof.
rewrite p /test; move: eq_refl; case: {2 3}(eq_dec y y) => //.
by rewrite eq_dec_correct'.
Qed.
请注意,在这里,通过仔细选择参数,我们可以避免执行模式选择的技巧。关键步骤是将匹配中的布尔值与护航参数中的eq_dec_见证解除链接,这样我们仍然可以正确地键入对eq_dec_correct的调用。最后一点有趣的是,我们还必须将eq_dec x=eq_dec x x转换为eq_dec x=b,因此我们需要对等式证明进行抽象


但正如我之前所说的,你可能想要定义一个更一般的引理。[为什么不使用eqtype中已经存在的一些引理?]

@Yves谢谢你,我已经相应地编辑了我的文章。非常感谢你抽出时间。我会尝试一切,如果不清楚,我会回复。我还没有时间使用ssreflect,但我相信它会自然出现在我的学习课程中,但是用basic0抽象b和eq_refl非常有效。非常感谢。
(* Do From Coq Require Import ssreflect. *)
Theorem basic (A : Type) (x y : A) (p : x = y) : test x y <> None.
Proof.
rewrite p /test; move: eq_refl; case: {2 3}(eq_dec y y) => //.
by rewrite eq_dec_correct'.
Qed.
Theorem basic0 (A : Type) (x : A) b (p : eq_dec x x = b) :
  match b as b1 return eq_dec x x = b1 -> option (x = x) with
  | true  => fun p => Some (eq_dec_correct p)
  | false => fun _ => None
  end p <> None.
Proof. by case: b p; rewrite ?eq_dec_correct'. Qed.

Theorem basic1 (A : Type) (x y : A) (p : x = y) : test x y <> None.
Proof. by rewrite p; apply: basic0. Qed.