I am new to Coq, and my primary interest is in using it to do simple real analysis problems. For a first exercise, I managed to bash through a proof that x^2+2x tends to 0 as x tends to 0. See code below.
This seems pretty clunky, and I would be interested in any general feedback on how to shorten this proof, or good practice for improving its readability. However, my main question is whether there are any Coq tactics for automating simple tasks involving the real numbers, along the lines of field
and lra
but better.
possible example 1: are there any tactics to prove identities for the functions from Rbasic_fun
, such as the absolute value? For example, half my proof is dedicated to showing that |x*x|+|2*x|=|x||x|+2|x| !
possible example 2: are there any tactics to automate the use of the lemmas from Rineq
, such as Rlt_le
, Rle_trans
, Rplus_le_compat_r
and Rmult_le_compat_r
? That is, lemmas that a human proof-creator would use to "chain together" a sequence of inequalities.
Require Import Rbase.
Require Import Rbasic_fun.
Require Import Lra.
Local Open Scope R_scope.
Definition limit (f:R -> R)
(D:R -> Prop) (l:R) (x0:R) :=
forall eps:R,
eps > 0 ->
exists delta : R,
delta > 0 /\
(forall x:R, D x /\ Rabs (x - x0) < delta -> Rabs ((f x) - l) < eps).
Lemma limitf : limit (fun (x:R) => x*x + 2 *x) (fun x => True) 0 0.
Proof.
unfold limit; intros.
split with (Rmin (eps/3) 1); split.
assert (eps / 3 > 0) by lra; clear H.
assert (1>0) by lra.
apply (Rmin_Rgt_r (eps/3) 1). apply (conj H0 H).
intros. destruct H0. clear H0. replace (x-0) with x in H1 by field.
apply (Rmin_Rgt_l (eps/3) 1) in H1. destruct H1.
assert (Rabs (x*x+2*x -0) <= Rabs(x*x)+Rabs(2*x)).
replace (x*x+2*x-0) with (x*x+2*x) by field.
apply Rabs_triang.
assert (Rabs(2*x) = 2 * Rabs(x)).
assert (Rabs(2*x) = Rabs(2) * Rabs(x)).
apply (Rabs_mult _ _).
assert (Rabs 2 = 2).
apply (Rabs_right _). lra.
replace (Rabs 2) with 2 in H3 by H4. apply H3.
replace (Rabs (2 * x)) with (2 * Rabs x) in H2 by H3. clear H3.
assert (Rabs(x*x) = Rabs(x)*Rabs(x)).
apply Rabs_mult.
replace (Rabs(x*x)) with (Rabs(x)*Rabs(x)) in H2 by H3. clear H3.
assert (Rabs x * Rabs x <= 1 * Rabs x).
apply Rmult_le_compat_r. apply Rabs_pos. apply Rlt_le. auto.
apply (Rplus_le_compat_r (2 * Rabs x) _ _) in H3.
apply (Rle_trans _ _ _ H2) in H3. clear H2.
replace (1 * Rabs x + 2 * Rabs x) with (3 * Rabs x) in H3 by field.
assert (3 * Rabs x < eps) by lra.
apply (Rle_lt_trans _ _ _ H3). auto.
Qed.
Here is the proof using coquelicot, it can probably be made nicer with some of the tactics, but this was quite straight forward. Whenever I wondered what lemma to use, I did
Search
to find a lemma with the term in its conclusion...Edit:
Here is the proof of your lemma above using lemmas from Coq's standard library instead. I found them by relying heavily on
Search
. Perhaps this approach makes it less heavy to do similar proofs for you.