coq中的从属模式匹配

时间:2014-04-22 19:52:56

标签: coq

以下代码(当然不是完整的证明)尝试在依赖产品上进行模式匹配:

Record fail : Set :=
  mkFail {
      i : nat ;
      f : forall x, x < i -> nat
    }.

Definition failomat : forall (m : nat) (f : forall x, x < m -> nat), nat.
Proof.
  intros.
  apply 0.
Qed.

Function fail_hard_omat fl : nat := failomat (i fl) (f fl).

Definition failhard fl : fail_hard_omat fl = 0.
refine ((fun fl =>
          match fl with
            | mkFail 0 _ => _
            | mkFail (S n) _ => _
          end) fl).

尝试执行此操作时出现的错误是

Toplevel input, characters 0-125:
Error: Illegal application (Type Error): 
The term "mkFail" of type
 "forall i : nat, (forall x : nat, x < i -> nat) -> fail"
cannot be applied to the terms
 "i" : "nat"
 "f0" : "forall x : nat, x < i0 -> nat"
The 2nd term has type "forall x : nat, x < i0 -> nat"
which should be coercible to "forall x : nat, x < i -> nat".

似乎替换以某种方式未达到内部类型参数。

2 个答案:

答案 0 :(得分:2)

在使用Program命令后,我设法构建了一个可能适合您的精简版,但我不理解我所做的一切。主要思想是通过引入中间平等来帮助Coq进行替换,这些中间平等将作为替换中的桥梁

    refine ((fun fl =>

    match fl as fl0 return (fl0 = fl -> fail_hard_omat fl0 = 0) with
      | mkFail n bar =>
        match n as n0 return (forall foo: (forall x:nat, x < n0 -> nat), 
           mkFail n0 foo = fl -> fail_hard_omat (mkFail n0 foo) = 0) with 
       | O => _
       | S p => _
       end bar
    end (eq_refl fl) ) fl).

无论如何,我不知道你的目的是什么,但我建议永远不要“手工”写依赖匹配,并依靠Coq的策略。在您的情况下,如果您使用Definition failomat而不是Defined.定义Qed,则可以展开它,并且您不需要依赖匹配。

希望它有所帮助, 诉

注意:bar的两个出现都可以用下划线替换。

答案 1 :(得分:2)

使用natfail的感应组合器的另一种方法是使用Print nat_rect. Print fail_rect. Definition failhard : forall fl, fail_hard_omat fl = 0. Proof. refine (fail_rect _ _). (* Performs induction (projection) on fl. *) refine (nat_rect _ _ _). (* Performs induction on fl's first component. *) Show Proof. 和{{1}}的感应组合器。

{{1}}