对Coq中Record结构中的模式匹配感到困惑

时间:2016-03-28 15:04:01

标签: coq

我一直在使用Coq很短的时间,我仍然碰到了一些东西。我已经定义了一个带有Record结构的集合。现在我需要进行一些模式匹配才能使用它,但是我在使用它时遇到了问题。首先,这些是我的要素。

   Inductive element : Set :=
| empty  : element
.
.
.
| fun_m : element -> element -> element
| n_fun : nat -> element -> element
.

我选择具有某些特征的元素,以下一个方式制作它们的子集:

Inductive esp_char : elements -> Prop :=
| esp1 : esp_char empty
| esp2 : forall (n : nat )(E : element), esp_char E -> esp_char (n_fun n E).

Record especial : Set := mk_esp{ E : element ; C : (esp_char E)}.

现在,我需要在'especial'元素上使用定义和修复点,只需要我选择的两个元素。我已经阅读了关于Record的文档,我得到的是我需要做这样的事情:

Fixpoint Size (E : especial): nat :=
match E with
|{|E := empty |}     => 0
|{|E := n_fun n E0|} => (Size E0) + 1
end.

当然这告诉我,我错过了元素的归纳部分的所有内容,所以我添加{|E := _ |}=> 0或任何东西,只是为了使感应充满。即使这样做,我也会发现这个问题:

|{|E := n_fun n E0|} => (Size E0) + 1

Error:
In environment
Size : especial -> nat
E : especial
f : element
i : esp_char f
n : nat
E0 : element
The term "E0" has type "element" while it is expected to have type "especial".

我无法做的就是修复最后一件事,我有一个引理证明如果n_fun n E0是'特殊'那么E0是特殊的,但是我不能这么做在Fixpoint内部。我还定义了“所有元素”的大小,然后在定义中选择了“特殊”的大小,但我希望能够直接在集合“特殊”上进行直接模式匹配。感谢您的投入。

编辑:忘记提及我也有强制要求总是发送元素。

编辑:这是我发布之前的方法:

Fixpoint ElementSize (E : element): nat :=
match E with
| n_fun n E0 => (ElementSize E0) + 1
| _  => 0
 end.

Definition Size (E : especial) := ElementSize E.

2 个答案:

答案 0 :(得分:0)

我试过这样做:

Lemma mk_especial_proof n E : esp_char (n_fun n E) -> esp_char E.
Proof. now intros U; inversion U. Qed.

Fixpoint Size (E : especial): nat := 
match E with
|{|E := empty              |} => 0
|{|E := n_fun n E0; C := P |} => (Size (mk_esp E0 (mk_especial_proof _ _ P))) + 1
|{|E := fun_m E1 E2        |} => 0
end.

然而,终止检查将失败。我不熟悉如何用记录克服这个问题。我明确地遵循我在评论中提到的方法(使用基本数据类型的修复点)。

编辑:添加了单一修复点解决方案。

Fixpoint size_e e :=
  match e with
  | empty       => 0
  | fun_m e1 e2 => 0
  | n_fun _   e => 1 + size_e e
  end.

Definition size_esp e := size_e (E e).

答案 1 :(得分:0)

我将您的示例简化为此,但您可以轻松返回到您的定义。我们有一个集合,以及由归纳谓词定义的子集。通常使用符号{b | Small b}来使用sigma类型,但它实际上与示例中使用的Record定义相同,所以不要介意: - )。

Inductive Big : Set :=    (* a big set *)
| A
| B (b0 b1:Big)
| C (b: Big).

Inductive Small : Big -> Prop :=   (* a subset *)
| A' : Small A
| C' (b:Big) : Small b ->  Small (C b).

Record small := mk_small { b:Big ; P:Small b }.

这是一个解决方案。

Lemma Small_lemma: forall b, Small (C b) -> Small b.
Proof. intros b H; now inversion H. Qed.

Fixpoint size (b : Big) : Small b -> nat :=
    match b with
      | A => fun _ => 0
      | B _ _ => fun _ => 0
      | C b' => fun H => 1 + size b' (Small_lemma _ H)
    end.

Definition Size (s:small) : nat :=
  let (b,H) := s in size b H.

为了能够在H - 分支中使用假设match,它将作为函数参数发送到分支。否则,不会在H项上执行b的销毁,而Coq无法证明我们在H上进行了结构递归。