如何处理右侧存在的函数?

时间:2016-11-16 14:47:49

标签: coq

我不确定我是否在问题标题中使用了正确的单词,所以这里是代码:

Lemma In_map_iff :
  forall (A B : Type) (f : A -> B) (l : list A) (y : B),
    In y (map f l) <->
    exists x, f x = y /\ In x l.
Proof.
  intros A B f l y.
  split.
  - intros.
    induction l.
    + intros. inversion H.
    + exists x.
      simpl.
      simpl in H.
      destruct H.
      * split.
        { apply H. } 
        { left. reflexivity. }
      * split.
  A : Type
  B : Type
  f : A -> B
  x : A
  l : list A
  y : B
  H : In y (map f l)
  IHl : In y (map f l) -> exists x : A, f x = y /\ In x l
  ============================
  f x = y

基本上,没有太多可以继续使用此证明,我只能在induction上使用l并在替换目标中的x之后获得上述表单。如果IHl有一个forall而不是exists,我可以替换那里的东西,但我不知道该怎么做。

我已经暂时停留在这个问题上了一段时间,但与发生这种问题的其他问题不同,我无法在网上找到这个解决方案。这是一个问题,因为我自己经历这本书,所以除了像SO这样的地方,没有人可以问。

我很欣赏一些提示。谢谢。

Lemma In_map_iff :
  forall (A B : Type) (f : A -> B) (l : list A) (y : B),
    In y (map f l) <->
    exists x, f x = y /\ In x l.
Proof.
  intros A B f l y.
  split.
  - intros.
    induction l.
    + intros. inversion H.
    + simpl.
      simpl in H.
      destruct H.
      * exists x.
        split.
        { apply H. }
        { left. reflexivity. }
      * destruct IHl.
        -- apply H.
        -- exists x0.
           destruct H0.
           ++ split.
              ** apply H0.
              ** right. apply H1.
  - intros.
    inversion H.
    induction l.
    + intros.
      inversion H.
      inversion H1.
      inversion H3.
    + simpl.
      right.
      apply IHl.
      * inversion H.
        inversion H0.
        inversion H2.
        exists x.
        split.
        -- reflexivity.
        -- destruct H3.
  A : Type
  B : Type
  f : A -> B
  x0 : A
  l : list A
  y : B
  H : exists x : A, f x = y /\ In x (x0 :: l)
  x : A
  H0 : f x = y /\ In x (x0 :: l)
  IHl : (exists x : A, f x = y /\ In x l) ->
        f x = y /\ In x l -> In y (map f l)
  x1 : A
  H1 : f x1 = y /\ In x1 (x0 :: l)
  H2 : f x = y
  H3 : x0 = x
  H4 : f x = y
  ============================
  In x l

我设法做了一个案子,但现在我被困在另一个案子里。说实话,既然我已经花了5个小时处理一个需要15分钟的问题,我开始认为我可能会考虑遗传编程。

2 个答案:

答案 0 :(得分:2)

H可以通过两种不同的方式获得,请尝试destruct H。从那以后,我认为很容易得到证据,但是要小心你破坏H的顺序并实例化你的存在主义。

答案 1 :(得分:1)

这是一个证据,其结构与纸笔证明相同(至少是第一个->部分)。当您看到<tactic>...时,它意味着; intuition(因为Proof with intuition.声明),即将intuition策略应用于<tactic>生成的所有子目标。 intuition使我们不会做冗长的逻辑演绎,可以用一系列applyrewrite策略取而代之,利用一些逻辑引理。

正如@ejgallego所指出的那样,关键在于证明你可以destruct存在假设并从中获得某些类型的居民。在试图证明存在目标时,这是至关重要的。

Require Import Coq.Lists.List.

Lemma some_SF_lemma :
  forall (A B : Type) (f : A -> B) (l : list A) (y : B),
    In y (map f l) <->
    exists x, f x = y /\ In x l.
Proof with intuition.
  intros A B f l y. split; intro H.
  - (* -> *)
    induction l as [ | h l'].
    + (* l = [] *)
      contradiction.
    + (* l = h :: l' *)
      destruct H.
      * exists h...
      * destruct (IHl' H) as [x H'].
        exists x...
  - (* <- *)
    admit.
Admitted.