2

任务。

假设我们给 Coq 定义如下:

Inductive R2 : nat -> list nat -> Prop :=
| c1 : R2 0 []
| c2 : forall n l, R2 n l -> R2 (S n) (n :: l)
| c3 : forall n l, R2 (S n) l -> R2 n l.

以下哪个命题是可证明的?

我证明了三分之二。

Example Example_R21 : R2 2 [1;0].
Proof.
  apply c2. apply c2. apply c1.
Qed.

Example Example_R22 : R2 1 [1;2;1;0].
Proof.
  repeat constructor.
Qed.

第三个是不可证明的,因为c3只会增加n,永远不会等于list的头部+1。但是如何正式证明它是不可证明的呢?

Example Example_R23 : not (R2 6 [3;2;1;0]).
Proof.

Qed.

更新 1

Fixpoint gen (n: nat) : list nat :=
  match n with
  | 0 => []
  | S n' => (n' :: gen n')
  end.

Lemma R2_gen : forall (n : nat) (l : list nat), R2 n l -> l = gen n.
Proof.
  intros n l H. induction H.
  - simpl. reflexivity.
  - simpl. rewrite IHR2. reflexivity.
  - simpl in IHR2. ?
4

5 回答 5

2

您必须在R2. 基本上,如果你有R2 6 (3 :: _),那么它必须是 a c3(没有其他构造函数适合),所以它包含一个R2 7 (3 :: _),它也必须是c3,它包含R2 8 (3 :: _)等等。这个链是无限的,所以你永远不会到达终点。因此,您可以将False其用作归纳的目标,而您将永远无法达到实际必须生产的基本情况False。仅仅使用是不够的inversion。倒置实际上只是所需归纳的一个步骤,而对上下文中任何其他事物的归纳都无济于事。

在归纳过程中,第一个参数会发生变化。具体来说,它总是大于S 3(这就是让我们排除其他构造函数的原因),所以我们需要概括k第一个参数总是在哪里5 + k(从k = 1我们有的情况开始6)。

Example Example_R23 : not (R2 6 [3;2;1;0]).
Proof.
  set (xs := [2; 1; 0]).
  change 6 with (5 + 1).
  set (x := 3). (* sets are not strictly needed, but help clean things up *)
  generalize 1 as k.
  intros k.
  (* Everything up to here is just generalizing over k *)
  remember (S (S x) + k) as n eqn:prf_n.
  remember (x :: xs) as l eqn:prf_l.
  intros no.
  revert k prf_n prf_l.
  induction no as [ | n' l' _ _ | n' l' _ rec_no]
  ; intros k prf_n prf_l.
  - discriminate.
  - injection prf_l as -> ->.
    discriminate.
  - subst.
    (* Everything up to here is combined inversion and induction *)
    eapply rec_no.
    + apply plus_n_Sm.
    + reflexivity.
Defined.

我们可以通过使用实验策略来极大地减少这个证明dependent induction,它取代了中间的inversiony 部分。

Example Example_R23 : not (R2 6 [3;2;1;0]).
Proof.
  set (xs := [2; 1; 0]).
  change 6 with (5 + 1).
  set (x := 3).
  generalize 1 as k.
  intros k no.
  dependent induction no generalizing k.
  eapply IHno.
  - apply plus_n_Sm.
  - reflexivity.
Defined.

另一种清理形式是将广义证明提取到引理中:

Lemma R2_head x k xs : ~R2 (S (S x) + k) (x :: xs).
Proof.
  intros no.
  dependent induction no generalizing k.
  - clear no IHno. (* Another "infinite chain" contradiction *)
    rename x into prf_x, x0 into x.
    induction x as [ | x rec_x].
    + discriminate.
    + injection prf_x.
      apply rec_x.
  - eapply IHno.
    + apply plus_n_Sm.
    + reflexivity.
Defined.
Example Example_R232 : not (R2 6 [3;2;1;0]) := R2_head 3 _ _.
于 2020-07-30T18:43:50.210 回答
2

这是一个使用目标泛化技术的简单证明。

首先,我们证明了一个比我们实际提出的更普遍的性质。

From Coq Require Import Lia.

Lemma R2_len n l : R2 n l -> n <= length l.
Proof. induction 1; simpl; lia. Qed.

现在我们的示例是更一般属性的简单具体实例。

Example Example_R23 : not (R2 6 [3;2;1;0]).
Proof. intros H%R2_len; simpl in H; lia. Qed.
于 2020-07-30T19:34:53.440 回答
2

这相当于@HTNW 的证明

Lemma R2_head' {a n l}: R2 a (n::l) -> a <= S n.
  intros H; dependent induction H; 
    try pose proof (IHR2 _ _ eq_refl); lia.
Qed.
  
Example Example_R23 : not (R2 6 [3;2;1;0]).
Proof. intros C; pose proof (R2_head' C); lia. Qed.
于 2020-07-30T22:10:19.353 回答
1

not AA -> False。你应该通过案例来介绍荒谬的假设和推理(参见倒置策略)。

于 2020-07-30T16:57:24.757 回答
0

您可以编写一个函数来从nat参数生成列表(我们称之为gen)并证明R2 n l -> l = gen n。由此,您可以通过证明 来证明您的命题l <> gen n

于 2020-07-30T18:09:00.257 回答