是否有可能证明‘所有n:nat,le n 0->;n=0.`在Coq中不使用反转?

是否有可能证明‘所有n:nat,le n 0->;n=0.`在Coq中不使用反转?,coq,coq-tactic,Coq,Coq Tactic,在中,它们定义了小于或等于的以下归纳定义: Inductive le (n : nat) : nat -> Prop := | le_n : le n n | le_S : forall m : nat, le n m -> le n (S m). 我的理解是,它定义了两种类型的构造函数: le_n它接受任何自然数并构造le n的证明 le_S取任意自然数m,作为le n m的证明,并构造le n(S m) 到目前为止还不错。然而,他们接着介

在中,它们定义了小于或等于的以下归纳定义:

Inductive le (n : nat) : nat -> Prop :=
          | le_n : le n n
          | le_S : forall m : nat, le n m -> le n (S m).
我的理解是,它定义了两种类型的构造函数:

  • le_n
    它接受任何自然数并构造
    le n
    的证明
  • le_S
    取任意自然数
    m
    ,作为
    le n m
    的证明,并构造
    le n(S m)
  • 到目前为止还不错。然而,他们接着介绍下面的引理和证明

    Lemma tricky : forall n:nat, le n 0 -> n = 0.
    Proof.
      intros n0 H.
      inversion H.
      trivial.
    Qed.
    
    “反转”步骤是我感到困惑的地方。我知道除非n等于0,否则无法构造len0,因为0没有后继项,但我不确定反转策略是如何计算出来的

    为了更好地理解它在做什么,我尝试在不使用反转策略的情况下证明这个引理。但是,到目前为止,我所有的尝试(即在n0和H上使用elim,尝试使用
    for all n:nat、0 S n.
    等)都失败了

    虽然我的“计算机科学”大脑完全可以接受这种推理,但我的“数学家大脑”在接受这一点上有点困难,因为没有假设这是构建
    le
    居民的唯一方法。这让我想到,也许使用反转策略是唯一的方法


    在没有反转策略的情况下,有可能证明这个引理吗?如果是这样的话,怎么做呢?

    有可能证明这个引理而不倒置:重要的一点是对适当的目标进行归纳(消除)

    首先请注意,当您将
    elim
    应用于
    len0
    类型的假设时,下面发生的是Coq将应用与
    le
    相关的消除原理。在这里,该消除原理被称为
    le_ind
    ,您可以查询其类型:

    forall (n : nat) (P : nat -> Prop),
           P n ->
           (forall m : nat, n <= m -> P m -> P (S m)) ->
           forall n0 : nat, n <= n0 -> P n0
    
    所有这些推广
    0
    的工作实际上就是
    inversion
    为您所做的

    请注意,我提出的谓词
    p
    不是唯一可能的解决方案。另一个有趣的解决方案是基于
    match
    (关键字是小规模反转)和
    P(n0):=match n0和0=>n=0 | S=>True end
    。 而且,战术最终总是会产生赤裸裸的加里纳术语,所以你总是可以(至少在理论上)写出一个术语来证明任何战术都是一样的。下面是一个使用Coq强大但冗长的模式匹配的示例:

    Definition pf : forall n, le n 0 -> n = 0 :=
      fun n H =>
        match H
              in le _ q
              return match q return Prop with
                     | 0 => n = q
                     | S _ => True
                     end
        with
        | le_n _ => match n with 0 => eq_refl | S _ => I end
        | le_S _ _ _ => I
        end.
    
    编辑:使用
    记住
    策略简化战术脚本。最初的提议是手工重新实现
    记住

    set (q := 0). (* change all the 0s in the goal into q and add it as hypothesis *)
      intro H.
      generalize (eq_refl : q = 0). (* introduce q = 0 *)
      revert H.
      generalize q ; clear q.  (* generalizes q *)
      (* Now the goal is of the shape
         forall q : nat, n <= q -> q = 0 -> n = q
         and we can apply elim *)
      intros q H ; elim H.
    
    set(q:=0)。(*将目标中的所有0更改为q,并将其添加为假设*)
    介绍H。
    推广(等式:q=0)。(*引入q=0*)
    回复H。
    推广q;明确的问题。(*推广了q*)
    (*现在目标是形状
    对于所有q:nat,nq=0->n=q
    我们可以应用elim*)
    简介q H;艾琳H。
    
    问题在于
    归纳法
    elim
    策略忘记了一个事实,即在
    len0
    中,第二个参数是
    0
    。 有两种情况是可能的,要么证明
    len0
    leu n
    ,要么证明是
    leu S
    。事实上,第二种情况是不可能的,因为
    0sn
    ,但策略不会知道这一点

    inversion
    更接近于
    destruct
    而不是
    归纳
    ,因为它不会给你任何归纳假设。它将查看你给出的命题的所有构造器,并查看哪些构造器可以导致它。这一次,它很聪明,它认为只有当您拥有
    0sn
    并放弃它时,
    leu s
    才适用

    手工操作的一种方法是简单地强制Coq记住第二个参数是
    0

    Lemma tricky : forall n, le n 0 -> n = 0.
    Proof.
      assert (h : forall n m, m = 0 -> le n m -> n = 0).
      { intros n m e h.
        induction h.
        - assumption.
        - discriminate.
      }
      intros n hyp.
      eapply h.
      - reflexivity.
      - assumption.
    Qed.
    
    如你所见,我通过添加一个等式来推广引理。
    discrime
    策略允许你从一个荒谬的假设(如
    0=sn
    )中得出一个目标。在交换
    h
    的两个假设时,可以按照西奥的方法设计一个使用SSReflect的简短证明:

    Lemma tricky n (len0 : le n 0) : n = 0.
    Proof.
      have h m : le n m -> m = 0 -> n = 0 by elim. 
      exact: (h 0).
    Qed.    
    

    当你
    destruct
    时,假设
    ntrue | 0=>False结束)为HF。
    在HF中重写Heqm。
    应用假ind,HF。
    Qed。
    
    Lemma tricky n (len0 : le n 0) : n = 0.
    Proof.
      have h m : le n m -> m = 0 -> n = 0 by elim. 
      exact: (h 0).
    Qed.    
    
    Goal forall n, n <= 0 -> n = 0.
      remember 0 as m. 
      destruct 1. 
      - reflexivity.
      - pose proof (I : match S m with S _ => True | 0 => False end) as HF.
        rewrite Heqm in HF.
        apply False_ind, HF.
    Qed.