Coq 感应式中X的消除不正确”;或
我试图在Coq上定义一个相对简单的函数:Coq 感应式中X的消除不正确”;或,coq,Coq,我试图在Coq上定义一个相对简单的函数: (* Preliminaries *) Require Import Vector. Definition Vnth {A:Type} {n} (v : Vector.t A n) : forall i, i < n -> A. admit. Defined. (* Problematic definition below *) Definition VnthIndexMapped {A:Type}
(* Preliminaries *)
Require Import Vector.
Definition Vnth {A:Type} {n} (v : Vector.t A n) : forall i, i < n -> A. admit. Defined.
(* Problematic definition below *)
Definition VnthIndexMapped {A:Type}
{i o:nat}
(x: Vector.t (option A) i)
(f': nat -> option nat)
(f'_spec: forall x, x<o ->
(forall z,(((f' x) = Some z) -> z < i)) \/
(f' x = None))
(n:nat) (np: n<o)
: option A
:=
match (f' n) as fn, (f'_spec n np) return f' n = fn -> option A with
| None, _ => fun _ => None
| Some z, or_introl zc1 => fun p => Vnth x z (zc1 z p)
| Some z, or_intror _ => fun _ => None (* impossible case *)
end.
我想我理解这个限制的原因,但是我很难想出一个解决办法。这样的事情如何实现?基本上,我有一个函数
f'
,对于这个函数,我有一个单独的证明,证明小于'o'的值,它要么返回None
,要么返回a(一些z)
其中z
小于i
,我试图在我的定义中使用它。问题是,您希望通过检查f''u spec
的内容来构建术语。此分离存在于Prop
,因此它只能构建其他Prop
。您想在类型中构建更多的东西。因此,您需要一个至少存在于集合中的析取版本(通常在类型中)。我建议您将Foo\/Bar
语句替换为sumbool
,它使用符号{Foo}+{Bar}
有两种方法可以解决这样的问题:简单的方法和困难的方法
简单的方法是思考你是否在做比你必须做的更复杂的事情。在这种情况下,如果仔细观察,您会发现您的f''u spec
相当于以下语句,这避免了\/
:
Lemma f'_spec_equiv i o (f': nat -> option nat) :
(forall x, x<o ->
(forall z,(((f' x) = Some z) -> z < i)) \/
(f' x = None))
<-> (forall x, x<o -> forall z,(((f' x) = Some z) -> z < i)).
Proof.
split.
- intros f'_spec x Hx z Hf.
destruct (f'_spec _ Hx); eauto; congruence.
- intros f'_spec x Hx.
left. eauto.
Qed.
这个定义使用了一个证据,证明了f''u spec
的两个公式是等价的,但是如果它们不是等价的,那么同样的想法也适用,并且你有一些引理允许你从一个引理到另一个引理
我个人不太喜欢这种风格,因为它很难使用,而且适合阅读复杂的程序。但它也有它的用途…谢谢!使用“sumbool”而不是\/还有什么其他含义?有什么潜在的问题吗?基本上如果我给你P:A\/B,你就不知道这是真的。你只知道其中一个是。通过{A}+{B},您还可以知道哪一个是真的(因为您可以分解这个术语)。谢天谢地,它是由我定义的,我能够将它更改为您建议的更简单的版本。谢谢
Lemma f'_spec_equiv i o (f': nat -> option nat) :
(forall x, x<o ->
(forall z,(((f' x) = Some z) -> z < i)) \/
(f' x = None))
<-> (forall x, x<o -> forall z,(((f' x) = Some z) -> z < i)).
Proof.
split.
- intros f'_spec x Hx z Hf.
destruct (f'_spec _ Hx); eauto; congruence.
- intros f'_spec x Hx.
left. eauto.
Qed.
Definition VnthIndexMapped {A:Type}
{i o:nat}
(x: Vector.t (option A) i)
(f': nat -> option nat)
(f'_spec: forall x, x<o ->
(forall z,(((f' x) = Some z) -> z < i)) \/
(f' x = None))
(n:nat) (np: n<o)
: option A
:=
match (f' n) as fn return f' n = fn -> option A with
| None => fun _ => None
| Some z => fun p =>
let p' := proj1 (f'_spec_equiv i o f') f'_spec n np z p in
Vnth x z p'
end eq_refl.