Coq 感应式中X的消除不正确”;或

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}

我试图在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}
    {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.