模式匹配案例中的统一

124*_*316 3 pattern-matching unification coq dependent-type reflect

我试图编写一个类型为forall n, option (n = 1).

我选择option作为reflect避免提供否定案例证明的替代方法。所以Some扮演角色ReflectT并持有证明,None而不持有否定证明。

Definition is_1 n: bool:=
  match n with
    1 => true |
    _ => false
  end.

Lemma is_1_complete : forall n, is_1 n = true -> n = 1.
intros.
destruct n. simpl in H. discriminate.
destruct n. reflexivity.
simpl in H. discriminate.
Qed.

Lemma a_nat_is_1_or_not: forall n, option (n = 1).
intros.
cut (is_1 n = true -> n = 1).
- 
intros.
destruct n. exact None.
destruct n. simpl in H. exact (Some (H (eq_refl))).
exact None.
-
exact (is_1_complete n).
Qed.
Run Code Online (Sandbox Code Playgroud)

我已经完成了战术。a_nat_is_1_or_not是证明。我认为我可以直接写定义,所以我尝试了。

Definition a_nat_is_1_or_not' n: option (n = 1) :=
  match is_1 n with
     true => Some (is_1_complete n eq_refl)
     | false => None
  end.
Run Code Online (Sandbox Code Playgroud)

但是 Coq 说

Error:
In environment
n : nat
The term "eq_refl" has type "is_1 n = is_1 n"
while it is expected to have type "is_1 n = true" (cannot unify "is_1 n" and
"true").
Run Code Online (Sandbox Code Playgroud)

这似乎is_1 n不能统一,以truetrue自身的模式匹配的情况。

所以我尝试了一个更简单的例子。

Definition every_true_is_I x: x = I :=
  match x with
     I => eq_refl
  end.
Run Code Online (Sandbox Code Playgroud)

有用。

a_nat_is_1_or_not'和 和有every_truer_is_I什么区别?我错过了什么吗?我能做些什么来编写一个有效的定义forall n, is_1 n = true -> n = 1.

小智 6

不同之处在于,在 中a_nat_is_1_or_not',您依赖于类型为 的外部术语is_1 n = true -> _。如果你想a_nat_is_1_or_not'看起来像every_true_is_I,你必须确保所有出现的is_1 n都被模式匹配覆盖:

Definition a_nat_is_1_or_not' n: option (n = 1) :=
  match is_1 n as b return ((b = true -> _) -> _) with
  | true => fun H => Some (H eq_refl)
  | false => fun _ => None
  end (is_1_complete n).
Run Code Online (Sandbox Code Playgroud)

注意如何is_1_complete在模式匹配之外实例化,以便处理is_1 n(renamed b) 的出现。

还有另一种方法可以做到这一点,也许更惯用一点。而不是概括整个上下文,您只需保留足够的信息来填补所有漏洞:

Definition a_nat_is_1_or_not' n: option (n = 1) :=
  match is_1 n as b return (is_1 n = b -> _) with
  | true => fun H => Some (is_1_complete n H)
  | false => fun _ => None
  end eq_refl.
Run Code Online (Sandbox Code Playgroud)

但想法是一样的。通过eq_refl在模式匹配之外实例化,在匹配时不会丢失任何信息is_1 n