Trivial lemma on real numbers on Coq - coq

I want to prove following lemma.
Require Import Reals.Reals.
Open Scope R_scope.
Lemma trivial_lemma (r1 r2:R) : r1 - (r1 - r2) = r2.
Proof.
rewrite <- Ropp_minus_distr.
rewrite Ropp_plus_distr.
rewrite Ropp_involutive.
rewrite Ropp_minus_distr'.
Abort.
I know Rplus_opp_l, but I cannot apply it to my goal because of r2.
Please tell me your solution.

First you should know that the automatic tactic ring solves this kind of goals autommatically. In the long run, you should rely on this tactic often if you wish to be productive.
Second, it appears (through Search) that the library does not contain many lemmas about subtraction. In this case, you may have to unfold this operator to end up with a goal that has the more primitive addition and opposite operations. Here is a sequence of rewrites that does your work.
unfold Rminus.
rewrite Ropp_plus_distr.
rewrite Ropp_involutive.
rewrite <- Rplus_assoc.
rewrite Rplus_opp_r.
rewrite Rplus_0_l.
easy.
The fact that the library does not contain basic lemmas like this is an indication that the library designers intend users to rely more on the ring tactic.

Related

Remove useless hypothesis from context

Sometimes I have a hypothesis in my proof context that I've used already, and now I know I won't need it anymore. In order to keep my context tidy while I work on the proof, I'd like to remove this hypothesis. Is there a tactic to do that?
If you use the SSReflect proof language, you can clear an hypothesis H by using the {H} notation. This can be done inline after many tactics such as move or rewrite, as in:
rewrite foo bar => {H}
Use the clear tactic:
Before:
1 goal
stuff ...
H : T
============================
goal
clear H.
After:
1 goal
stuff ...
============================
goal

Alternative tactic for `ssreflect`'s `move=>`

I like using the move=> tactic from the ssreflect library in cases when the goal is an implication (e.g. A -> B), to make the premise a hypothesis, and make the conclusion the new goal. However, I don't always want to use ssreflect.
Is there another Coq tactic that does the same thing without using ssreflect?
You can always use intros: intros pat is roughly equivalent to move=> pat. Unfortunately, Coq and ssreflect use a different syntax for introduction patterns, so the two are not interchangeable.
Note that nowadays ssreflect is part of the Coq distribution, so you can use the tactic language by simply doing From Coq Require Import ssreflect., without the need for installing a separate library.

Finding rewrite rules

I have a hard time finding the available rewrite rules for my situation. As I don't want to bother you with each rewrite question, I was wondering do you have some tips for finding suitable rewrite rules?
Do you have any tips on how to solve and or search for rewriting the following example:
1 subgoal
H: P
H0: Q
__________
R
And say I have Lemma Join: P /\ Q = R
In order to do this rewrite, I suppose I need to get H and H0 first rewritten into P /\ Q.
So how would you solve or find the rewrite rules for such a case?
Another example
H: a <= b
____________
b < a
I am confident there should exists some commutativity rewrite rule for this, but how can I best find this rule?
Many thanks in advance!
First a tip so you don't run into this problem later: Don't confuse equality of types for logical equivalence. What you usually mean in your first example above is that P/\Q <-> R, not that the type P/\Q is definitionally the same type as R.
With regards to your question about finding lemmas in the library; yes, it is very important to be able to find things there. Coq's Search command lets you find all (Required) lemmas that contain a certain pattern somewhere in it, or some particular string. The latter is useful because the library tends to have a somewhat predicable naming scheme, for instance the names for lemmas about decidability often contains then string "dec", commutativity lemmas often are called something with "comm" etc.
Try for example to search for decidability lemmas about integers, i.e. lemmas that have the term Z somewhere inside them, and the name contains the string "dec".
Require Import ZArith.
Search "dec" Z.
Back to your question; in your case you want to find a lemma that ends with "something and something", so you can use the pattern ( _ /\ _ )
Search ( _ /\ _ ).
However, you get awfully many hits, because many lemmas ends with "something and something".
In your particular case, you perhaps want to narrow the search to
Search (?a -> ?b -> ?a /\ ?b).
but be careful when you are using pattern variables, because perhaps the lemma you was looking for had the arguments in the other order.
In this particular case you found the lemma
conj: forall [A B : Prop], A -> B -> A /\ B
which is not really a lemma but the actual constructor for the inductive type. It is just a function. And remember, every theorem/lemma etc. in type theory is "just a function". Even rewriting is just function application.
Anyway, take seriously the task of learning to find lemmas, and to read the output from Search. It will help you a lot.
Btw, the pattern matching syntax is like the term syntax but with holes or variables, which you will also use when you are writing Ltac tactics, so it is useful to know for many reasons.

apply rewrite tactic to sub-expression

How can I apply rewrite -> targetting only a sub-expression? For example, consider this theorem:
Parameter add : nat -> nat -> nat.
Axiom comm : forall a b, add a b = add b a.
Theorem t1 : forall a b : nat,
(add (add a b) (add a (add a b))) =
(add (add a b) (add a (add b a))).
Intuitively, it requires commuting only one (add a b) sub-expression, but if I do rewrite -> (comm a b), it rewrites all the occurrences. How can I target a particular sub-expression?
This is a case where the ssreflect matching facilities will usually be more convenient than "at" [I'd dare to say sub-term rewrites are often a cause of people switching to ssreflect's rewrite]. In particular:
rewrite {pos}[pat]lemma will select occurrences pos of pattern pat to rewrite,
pat can be a contextual pattern that may allow you improve the robustness of your scripts.
You can target a specific occurrence with the rewrite tactic using the suffix at N. Occurrences are numbered from 1 in left-to-right order. You can rewrite multiple occurrencess by separating their indices with spaces. You need Require Import Setoid. The at suffix is also available with some other tactics that target occurrences of a term, including many tactics that perform conversions (change, unfold, fold, etc.), set, destruct, etc.
intros.
rewrite -> (comm a b) at 2.
rewrite -> (comm _ _).
reflexivity.
There are other possible approaches, especially if all you need is to apply equalities. The congruence tactic can find what to rewrite and apply symmetry and transitivity on its own, but you need to prime it by adding all equivalences to the context (in the form of universally-quantified equalities), it won't query hint databases.
assert (Comm := comm).
congruence.
To get more automation, Hint Rewrite creates a database of theorems which the tactic autorewrite will try applying. For more advanced automation, look up generalized rewriting with setoids, which I'm not sufficiently familiar with to expound on.

Coq: viewing proof term during proof script writing

So, I've got a proof that looks like this:
induction t; intros; inversion H ; crush.
It solves all my goals, but when I do Qed, I get the following error:
Cannot guess decreasing argument of fix.
So somewhere in the generated proof term, there's non-well-founded recursion. The problem is, I have no idea where.
Is there a way to debug this kind of error, or to see the (possibly non halting) proof term that the tactics script generates?
You can use Show Proof. to view the proof term so far.
Another command that can help with seeing where the recursion went wrong is Guarded., which runs the termination checker on the proof term so far. You'll need to break apart the tactic script into independent sentences to use it, though. Here's an example:
Fixpoint f (n:nat) : nat.
Proof.
apply plus.
exact (f n).
Guarded.
(* fails with:
Error:
Recursive definition of f is ill-formed.
...
*)
Defined.
You can use the Show Proof. command inside proof mode to print the proof term produced so far.
In addition to the other excellent answers, I also want to point out that using induction inside an interactive-mode Fixpoint is usually a mistake, because you're recursing twice. Writing fixpoints in interactive mode is often tricky because most automation tools will happily make a recursive call at every possible opportunity, even when it would be ill-founded.
I would advise to use Definition instead of Fixpoint and use induction in the proof script. This invokes the explicit recursor, which allows for much better control of automation. The disadvantage is decreased flexibility since fixpoints have fewer restrictions than recursors - but as we've seen, that is both a blessing and a curse.