以下代码(当然不是完整的证明)尝试在依赖产品上进行模式匹配:
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".
似乎替换以某种方式未达到内部类型参数。
答案 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)
使用nat
和fail
的感应组合器的另一种方法是使用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}}