我只是Coq的初学者,我一直试图证明一些关于自然数的基本定理。我已经完成了一些,但不是很优雅,但是完成后更少。但是我完全坚持完成这个定理:
Theorem add_increase: (forall a b: nat, a > 0 -> a + b > b).
Proof.
intros A.
intros B.
intros H.
case B.
输入此内容,我得到此输出:
2 subgoals
A, B : nat
H : A > 0
______________________________________(1/2)
A + 0 > 0
______________________________________(2/2)
forall n : nat, A + S n > S n
显然,第一个目标很简单,可以简化为假设H
。但是,我只是无法弄清楚如何进行这种直接的简化。
答案 0 :(得分:3)
简化这一点的一种方法是使用一个相当无聊的引理
Lemma add_zero_r : forall n, n + 0 = n.
Proof.
intros n. induction n. reflexivity.
simpl. rewrite IHn. reflexivity.
Qed.
然后使用它来重写你的目标:
Theorem add_increase: (forall a b: nat, a > 0 -> a + b > b).
Proof.
intros A.
intros B.
intros H.
case B.
rewrite (add_zero_r A).
assumption.
为了完成另一个证明案例,我使用了一个小引理和一个策略,可以简化证明自然界不平等的东西的任务。
首先,我导入了Omega
库。
Require Import Omega.
证明另一个无聊的事实。
Lemma add_succ_r : forall n m, n + (S m) = S (n + m).
Proof.
intros n m. induction n. reflexivity.
simpl. rewrite IHn. reflexivity.
Qed.
并返回add_increase prove
我们有以下目标:
A, B : nat
H : A > 0
============================
forall n : nat, A + S n > S n
可以通过以下方式解决:
intros C.
rewrite (add_succ_r A C).
omega.
同样,我使用之前证明的引理来重写目标。 omega
策略非常有用,因为它是所谓的quantifier free Presburger arithmetic的完整决策程序,并且根据您的上下文,它可以解决目标automagically
。
以下是您的证明的完整解决方案:
Require Import Omega.
Lemma add_zero_r : forall n, n + 0 = n.
Proof.
intros n. induction n. reflexivity.
simpl. rewrite IHn. reflexivity.
Qed.
Lemma add_succ_r : forall n m, n + (S m) = S (n + m).
Proof.
intros n m. induction n. reflexivity.
simpl. rewrite IHn. reflexivity.
Qed.
Theorem add_increase: (forall a b: nat, a > 0 -> a + b > b).
Proof.
intros A.
intros B.
intros H.
case B.
rewrite (add_zero_r A).
assumption.
intros C.
rewrite (add_succ_r A C).
omega.
Qed.
答案 1 :(得分:3)
几个常见的引理,例如a + 0 = 0
等,放在提示数据库arith
中。有了它们,auto
通常可以解决许多此类简单目标,因此请使用auto with arith.
Require Import Arith.
Theorem add_increase: (forall a b: nat, a > 0 -> a + b > b).
destruct a; intros b H.
- inversion H. (* base case, H: 0 > 0 *)
- simpl. auto with arith.
Qed.
要查看使用了哪些词条auto
,您可以Print add_increase.
在这种情况下,auto
使用了三个词条,并且可以通过auto using gt_le_S, le_lt_n_Sm, le_plus_r.
<明确地将它们提供给自动/ p>
一般情况下,当您需要一个您认为应该已经证明的引理时,可以使用SearchAbout
进行搜索。使用_
作为通配符,或?a
作为指定的通配符。在你的情况下,你想要一些关于在右边添加零的东西,所以
SearchAbout ( _ + 0 = _ ).
返回
plus_0_r: forall n : nat, n + 0 = n
NPeano.Nat.add_0_r: forall n : nat, n + 0 = n
你甚至可以在图书馆找到一个与你想要证明的接近的引理。
SearchAbout ( _ > _ -> _ + _ > _ ).
查找
plus_gt_compat_l: forall n m p : nat, n > m -> p + n > p + m
非常接近add_increase
。
Theorem add_increase: (forall a b: nat, a > 0 -> a + b > b).
intros.
pose (plus_gt_compat_l a 0 b H) as A.
repeat rewrite (plus_comm b) in A.
apply A.
Qed.
答案 2 :(得分:1)
使用不同自然数字库ssrnat
和ssreflect证明语言(库需要)的另一种解决方案:
From mathcomp Require Import ssreflect ssrfun ssrbool eqtype ssrnat seq.
Theorem add_increase a b : 0 < a -> b < a + b.
Proof. by rewrite -{1}[b]add0n ltn_add2r. Qed.
ltn_add2r : (m + p < n + p) = (m < n)
引理通过p
上的归纳证明,直接通过p
上的归纳加上交换性和其他简单的加法性质来证明。
答案 3 :(得分:0)
请注意,如果我们采用omega
策略,则可以这样做:
Theorem add_increase : forall a b: nat, a > 0 -> a + b > b.
Proof. intros a b. omega. Qed.