Coq中的定理证明


10

背景

我正在独自学习帮助,Coq。到目前为止,我已经匆匆完成了Yves Bertot的Coq阅读。现在,我的目标是证明与自然数有关的一些基本结果,并以所谓的除法算法结束。但是,在实现该目标的过程中,我遇到了一些挫折。特别是,以下两个结果已经证明(双关语意)比我最初想象的要困难得多。实际上,经过多次徒劳的尝试之后,我不得不手工证明它们(如下所示)。显然,这并不能帮助我更加精通Coq。这就是为什么我转向这个论坛。我希望这个网站上的某人能够并且愿意帮助我将下面的证明转换为Coq接受的证明。衷心感谢所有帮助!

定理A

对于所有证明:x,yN

x<S(y)x<yI(N,x,y)

假设。因此,存在一个与 因此,通过(皮亚诺1b和3)x<S(y)zN

(*)I(N,x+S(z),S(y))
I(N,x+z,y)

定义一个谓词

Q(u):=(I(N,x+u,y)x<yI(N,x,y)

证明就足够了。我们通过对的归纳来证明这一点。要看,不是说成立,那么Peano 1a就是为真。因此,。现在,我们证明:假设。根据这个定义,我们有,因此在这种情况下也有。最后,皮亚诺的第五个公理给出,通过我们得到。 Ž Q 0 Ñ X + 0 ÿ Ñ X ÿ X < Ý Ñ X ÿ Q 小号v Ñ x + S v y x <Q(z)zQ(0)I(N,x+0,y)I(N,x,y)x<yI(n,x,y)Q(S(v))I(N,x+S(v),y)X < Ý Ñ X ÿ Q Ž * X < Ý Ñ X ÿ x<yx<yI(N,x,y)Q(z)()x<yI(N,x,y)

()

定理B

对于所有证明:X < Ý Ñ X ÿ ÿ < Xx,yN

x<yI(N,x,y)y<x

如果则根据定义,如果则也根据定义。如果那么根据传递性和自反性,我们有,这是一个矛盾。因此,不超过一种说法是正确的。¬ Ñ X ÿ X > Ý ¬ Ñ X ÿ X > ý ý > X Ñ X ÿ x<y¬I(N,x,y)x>y¬I(N,x,y)x>y y>xI(N,x,y)

我们使固定并在归纳。当对于所有,我们都有,这证明了基本情况。接下来,假设定理对成立;现在我们要证明的定理。从对的三分法中可以看出三种情况:和。如果,则显然。如果,则(对于所有都是)。最后,假设X Ñ 0 ÿ 0 < Ý Ñ 0 ÿ ÿ X 小号X X X < Ý Ñ X ÿ X > ý X > Ý 小号X > y I N x y yxI(N,0,y)0<yI(N,0,y)yxS(x)xx<y,I(N,x,y)x>yx>yS(x)>yI(N,x,y)小号X > X X Ñ X < Ý 小号X < Ý Ñ 小号X ÿ S(x)>yS(x)>xxNx<y然后,根据定理A,我们得到或,无论哪种情况,我们都完成了。 S(x)<yI(N,S(x),y)

()

我希望证明的定理可以在Coq中表示如下。

引理less_lem(xy:N):less x(成功y)->或(less xy)(IN xy)。

定理Ntrichotomy:(总xy:N或(较少xy)(或(IN xy)(较少yx)))。

有用的结果

在这里,我收集了一些已定义的结果,并证明了这一点。这些是我上面提到的。* 这是到目前为止我设法编写的代码,请注意,大多数代码都由定义组成。*

(* Sigma types *)


Inductive Sigma (A:Set)(B:A -> Set) :Set :=
  Spair: forall a:A, forall b : B a,Sigma A B.

Definition E (A:Set)(B:A -> Set)
  (C: Sigma A B -> Set)
  (c: Sigma A B)
  (d: (forall x:A, forall y:B x, 
      C (Spair A B x y))): C c :=

match c as c0 return (C c0) with
| Spair a b => d a b
end. 


(* Binary sum type *)

Inductive sum' (A B:Set):Set := 
inl': A -> sum' A B | inr': B -> sum' A B.

Print sum'_rect.

Definition D (A B : Set)(C: sum' A B -> Set)
(c: sum' A B)
(d: (forall x:A, C (inl' A B x)))
(e: (forall y:B, C (inr' A B y))): C c :=

match c as c0 return C c0 with
| inl' x => d x
| inr' y => e y
end.

(* Three useful finite sets *)

Inductive N_0: Set :=.

Definition R_0
  (C:N_0 -> Set)
  (c: N_0): C c :=
match c as c0 return (C c0) with
end.

Inductive N_1: Set := zero_1:N_1.

Definition R_1 
  (C:N_1 -> Set)
  (c: N_1)
  (d_zero: C zero_1): C c :=
match c as c0 return (C c0) with
  | zero_1 => d_zero
end.

Inductive N_2: Set := zero_2:N_2 | one_2:N_2.

Definition R_2 
  (C:N_2 -> Set)
  (c: N_2)
  (d_zero: C zero_2)
  (d_one: C one_2): C c :=
match c as c0 return (C c0) with
  | zero_2 => d_zero
  | one_2  => d_one
end.


(* Natural numbers *)

Inductive N:Set :=
zero: N | succ : N -> N.

Print N. 

Print N_rect.

Definition R 
  (C:N -> Set)
  (d: C zero)
  (e: (forall x:N, C x -> C (succ x))):
  (forall n:N, C n) :=
fix F (n: N): C n :=
  match n as n0 return (C n0) with
  | zero => d
  | succ n0 => e n0 (F n0)
  end.

(* Boolean to truth-value converter *)

Definition Tr (c:N_2) : Set :=
match c as c0 with
  | zero_2 => N_0
  | one_2 => N_1
end.

(* Identity type *)

Inductive I (A: Set)(x: A) : A -> Set :=
r :  I A x x.

Print I_rect.

Theorem J 
  (A:Set)
  (C: (forall x y:A, 
              forall z: I A x y, Set))
  (d: (forall x:A, C x x (r A x)))
  (a:A)(b:A)(c:I A a b): C a b c.
induction c.
apply d.
Defined.

(* functions are extensional wrt
  identity types *)

Theorem I_I_extensionality (A B: Set)(f: A -> B):
(forall x y:A, I A x y -> I B (f x) (f y)).
Proof.
intros x y P.
induction P.
apply r.
Defined.


(* addition *)

Definition add (m n:N) : N 
 := R (fun z=> N) m (fun x y => succ y) n.

(* multiplication *)

Definition mul (m n:N) : N 
 := R (fun z=> N) zero (fun x y => add y m) n.


(* Axioms of Peano verified *)

Theorem P1a: (forall x: N, I N (add x zero) x).
intro x.
(* force use of definitional equality
  by applying reflexivity *)
apply r.
Defined.


Theorem P1b: (forall x y: N, 
I N (add x (succ y)) (succ (add x y))).
intros.
apply r.
Defined.


Theorem P2a: (forall x: N, I N (mul x zero) zero).
intros.
apply r.
Defined.


Theorem P2b: (forall x y: N, 
I N (mul x (succ y)) (add (mul x y) x)).
intros.
apply r.
Defined.

Definition pd (n: N): N :=
R (fun _=> N) zero (fun x y=> x) n.

(* alternatively
Definition pd (x: N): N :=
match x as x0 with
  | zero => zero
  | succ n0 => n0
end.
*)

Theorem P3: (forall x y:N, 
I N (succ x) (succ y) -> I N x y).
intros x y p.
apply (I_I_extensionality N N pd (succ x) (succ y)).
apply p.
Defined.

Definition not (A:Set): Set:= (A -> N_0).

Definition isnonzero (n: N): N_2:=
R (fun _ => N_2) zero_2 (fun x y => one_2) n.


Theorem P4 : (forall x:N, 
not (I N (succ x) zero)).
intro x.
intro p.

apply (J N (fun x y z => 
    Tr (isnonzero x) -> Tr (isnonzero y))
    (fun x => (fun t => t)) (succ x) zero)
.
apply p.
simpl.
apply zero_1.
Defined.

Theorem P5 (P:N -> Set):
P zero -> (forall x:N, P x -> P (succ x))
   -> (forall x:N, P x).
intros base step n.
apply R.
apply base.
apply step.
Defined.

(* I(A,-,-) is an equivalence relation *)

Lemma Ireflexive (A:Set): (forall x:A, I A x x).
intro x.
apply r.
Defined.

Lemma Isymmetric (A:Set): (forall x y:A, I A x y -> I A y x).
intros x y P.
induction P.
apply r.
Defined.

Lemma Itransitive (A:Set): 
(forall x y z:A, I A x y -> I A y z -> I A x z).
intros x y z P Q.
induction P.
assumption.
Defined.


Lemma succ_cong : (forall m n:N, I N m n -> I N (succ m) (succ n)).
intros m n H.
induction H.
apply r.
Defined.

Lemma zeroadd: (forall n:N, I N (add zero n) n).
intro n.
induction n.
simpl.
apply r.
apply succ_cong.
auto.

Defined.

Lemma succadd: (forall m n:N, I N (add (succ m) n) (succ (add m n))).
intros.
induction n.
simpl.
apply r.
simpl.
apply succ_cong.
auto.

Defined.

Lemma commutative_add: (forall m n:N, I N (add m n) (add n m)).
intros n m; elim n.
apply zeroadd.
intros y H; elim (succadd m y).
simpl.
rewrite succadd.
apply succ_cong.
assumption.


Defined.

Lemma associative_add: (forall m n k:N, 
I N (add (add m n) k) (add m (add n k))).
intros m n k.
induction k.
simpl.
apply Ireflexive.
simpl.
apply succ_cong.
assumption.
Defined.

Definition or (A B : Set):= sum' A B.


Definition less (m n: N) :=
 Sigma N (fun z => I N (add m (succ z)) n).



Lemma less_lem (x y:N) : 
less x (succ y) -> or (less x y) (I N x y).
intro.
destruct H.
right.

(* Here is where I'm working right now *)

Defined.


Theorem Ntrichotomy: (forall x y:N, 
or (less x y) (or (I N x y) (less y x))).

3
要了解您有多远,如果您到目前为止已发布Coq代码,这将有所帮助,以便我们可以加载它并检查我们提出的建议是否适合您的定义。
吉尔(Gilles)“所以,别再邪恶了”

1
一些评论和澄清的问题:-仅使用句法相等(在Coq中为“ =“)而不是I(N,x,y)就足以满足您的目的吗?是否有理由按定义的方式使用“或”?Coq(很好,Coq的基本库)具有一种表达逻辑分离的方式,可以促进证明的某些方面。同样,有一种方法可以定义“较少”的代码,它可能对您更有用。为此,您可能需要看一下Software Foundations的早期章节。当这本书的结尾...
Luke Mathieson 2013年

...是关于验证程序等的内容,开始是对Coq的很好的介绍,并具有一些定理,如练习和示例一样。它是免费的,而且实际上都是用Coq脚本编写的,因此您可以在阅读过程中进行练习并进行编译。对于您在这里所做的事情,“基础知识”,“归纳法”,“支撑理论”和“逻辑”一章中有一些有趣的内容,并且可能还有中间的相关内容。
路加·马西森

1
另一个注意事项是,Thm P5(归纳原理)以更强的形式(结构归纳)内置于Coq中,因此您无需明确地将其作为公理。
路加·马蒂森

我已经发布了到目前为止已经编写的Coq代码。
user11942 2013年

Answers:


7

Coq比纸质证明更为残酷:当您在纸质证明中写下“我们已经完成”或“很明显”时,通常要说服Coq要做的事情还很多。

现在,我对您的代码进行了一些清理,同时尝试保持相同的精神。你可以在这里找到它。

几点评论:

  1. 我使用内置的数据类型和定义,认为不会损害您的意图。请注意,如果我使用内置的等式代替identity内置的“小于”关系,则证明会容易得多,因为许多引理都在已知定理的数据库中,每次调用时都要检查

    auto with arith.
    
  2. 我使用了一些您可能不知道的策略,但是“真正的” Coq超级用户手头将拥有更加强大的策略,并编写了自己的策略来简化工作。我始终建议将CPDT作为学习如何有效使用战术的地方。

  3. 我使用符号和制表符来提高可读性,并使用诸如匹配之类的内置结构以及induction使事情更易于证明和重构的策略。特别是,您对的定义less很难使用,您可以看到我如何将其从略微修改 为等效的(但更易于使用) 这种“定义调整”的发生的情况很多在正式证明。X X + + 1 = Ñ

    x, m+(x+1)=n
    x, (x+m)+1=n
  4. 尽管您可以在此处获得此类问题的答案,但我强烈建议您将工作提交给Coq-Club,其目的是明确回答此类问题。


1
好答案,科迪!得知有像您这样慷慨的人愿意帮助需要帮助的人,真是太好了。我由衷的感谢!我绝对会看看CPDT和Coq-Club;随着我继续努力证明Coq中的除法算法,我很可能在不久的将来都需要这两个。
user11942

谢谢!请注意,这通常被称为“欧几里得除法”,并且已经存在于某些库中(尽管超过了整数)
Cody 2013年

这并不令我感到惊讶,我看过的Coq库中存有大量的定义,引理和定理。我将最迟在明天提出我对欧几里得除法算法的问题。
user11942

4

Cody的回答非常好,并且满足了您有关将证明转换为Coq的问题。作为对此的补充,我想添加相同的结果,但使用不同的途径进行了证明,主要是为了说明一些Coq,并演示只需很少的额外工作就可以在语法上证明的内容。这并不是说这是最短的路线-只是一条不同的路线。证明仅包括一个附加的辅助引理,并且仅依赖于基本定义,我不介绍加法,乘法或它们的任何属性或功能可扩展性,并且唯一的Peano公理是<= b->的简单形式a + c <= b + c在辅助引理中(仅对于c = 1)和结构归纳法,归纳法是免费提供的归纳法类型。

像Cody一样,我认为这没有什么区别,我使用了预定义的类型等,因此在证明之前,我将描述这些类型:

  • 我将内建的nat类型用于自然数,它具有(直到精确的命名)与您的定义相同的定义:

归纳nat:设置:= O:nat | S:NAT-> NAT

  • 我分别使用内置的le和lt分别小于或等于和小于,为便于阅读,这些符号的缩写为“ <=”和“ <”。它们的定义是:

归纳文件:nat-> nat-> Prop:=
| le_n:forall n,le nn
| le_S:forall nm,(le nm)->(le n(S m))。

定义lt(nm:nat):= le(S n)m。

  • 内置的eq(简写为“ =”)在语法上是相等的,并且与您的“ I”相同,其中一个构造函数只说任何东西都等于自己。对称和传递属性从那里很容易证明,但是在这种情况下我们将不需要它们。以下eq的定义已内置符号。

归纳式(A:类型)(x:A):A-> Prop:= eq_refl:x = x

  • 最后,我使用了命题或(简写为“ \ /”-反斜杠正斜杠),它有两个构造函数,基本上可以证明您有证据支持左参数或右参数。Coq还具有左右两种速记策略,分别表示“ apply or_introl”和“ apply or_intror”。

归纳或(AB:属性):属性:=
or_introl:A-> A / B | or_intror:B-> A / B

现在,下面是我的证明,原则上,如果标记不碍事,您应该可以将其剪切并粘贴到Coq .v文件中,然后它将起作用。我添加了注释来注意一些有趣的地方,但是它们都在(* *)分隔符中,因此您不必删除它们。

Theorem lt_or_eq: forall (n m : nat),
  n < S m -> n < m \/ n = m.
Proof.
(*
  This proof is just a case analysis on n and m, whether they're zero or
  a successor of something.
*)
destruct n as [|n']; destruct m as [|m']. 

(*n = 0, m = 0*)
intros.
  right. reflexivity.

(*n = 0, m = S m'*)
intros H.
  inversion H.
  inversion H1.
  left. unfold lt. constructor.
  (*The constructor tactic tries to match the goal to a constructor
    that's in the environment.*) 
  left. unfold lt. constructor. assumption.
  (*Assumption tries to match the goal to something that's in the
    current context*)

(*n = S n', m = 0
  This case is false, so we can invert our way out of it.*)
intros.
  inversion H. inversion H1.

(*n = S n', m = S m'*)
intros.
  inversion H.
    right. reflexivity.
    left. unfold lt. assumption.
Qed.


(*
  The following lemma with be useful in the proof of the trichotomy theorem,
  it's pretty obviously true, and easy to prove. The interesting part for
  anyone relatively new to Coq is that the induction is done on the
  hypothesis "a <= b", rather than on either a or b.
*)
Lemma a_le_b_implies_Sa_le_Sb: forall a b, a <= b -> S a <= S b.
Proof.
  intros a b Hyp.
  induction Hyp.
  constructor.
  constructor.
  apply IHHyp.
Qed.

(*
  The proof of the trichotomy theorem is a little more involved than the
  last one but again we don't use anything particularly tricky. 
  Other than the helper lemma above, we don't use anything other than the
  definitions.

  The proof proceeds by induction on n, then induction on m.  My personal
  feeling is that this can probably be shortened.  
*)
Theorem trich: forall (n m : nat),
  n < m \/ n = m \/ m < n.
Proof.
  induction n.
    induction m.
      right. left. reflexivity.
        inversion IHm.
          left. unfold lt. constructor. unfold lt in H. assumption.
          inversion H.
          left. unfold lt. subst. constructor.
          inversion H0.     
    induction m.
      assert (n < 0 \/ n = 0 \/ 0 < n).
      apply IHn.
      inversion H.
      inversion H0.
      inversion H0.
      right. right. subst. unfold lt. constructor.
      right. right. unfold lt. constructor. assumption.
      inversion IHm. unfold lt in H.
      left. unfold lt. constructor. assumption.
      inversion H; subst.
      left. unfold lt. constructor.
      inversion H0.
      right. left. reflexivity.
      right. right. apply lt_or_eq in H0.

      inversion H0.
      apply a_le_b_implies_Sa_le_Sb. assumption.
      subst. unfold lt. apply a_le_b_implies_Sa_le_Sb. assumption.
Qed.

(*
  The following is just to show what can be done with some of the tactics
  The omega tactic implements a Pressburger arithmetic solver, so anything
  with natural numbers, plus, multiplication by constants, and basic logic
  can just be solved. Not very interesting for practicing Coq, but cool to
  know.
*)

Require Import Omega.

Example trich' : forall (n m : nat),
  n < m \/ n = m \/ m < n.
Proof.
  intros.
  omega.
Qed.

另一个奇妙的答案!对于您为回答我的问题所付出的时间和精力,我表示由衷的感谢。
user11942
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.