How to deal with division in COQ? - coq

How to deal with with the division in a goal?
Because I have a goal which is clearly true... However I cannot use lia and I think that this is related to the division.
2 ^ k / 2 ≤ 2 ^ k
Bellow is my COQ screen:

There is no automation for division on naturals - they don't even form a field. But the corresponding lemmas are not hard to find with Search:
Require Import Lia.
Goal forall k:N, 2 ^ k / 2 <= 2 ^ k.
Proof.
intros k.
Search (?a/?b <= ?a/?c).
Search (_/1).
rewrite <- N.div_1_r.
apply N.div_le_compat_l.
lia.
Qed.
If you have really complicated terms, you can embed the goal into reals using floor (a/b) for integer a/b and then use coq-interval. The embedding is easy to automate and coq-interval is quite powerful for proving real inequalities, but it might choke if you have more than a few floors. You can combine it with coq-gappa then to get rid of the floors. It gets quite involved then, but still fully automated. But be aware that it might not be able to prove very tight inequalities, since it uses real analysis.
Nia (Require Import Psatz), as suggested by Ana, can't solve this (and I honestly stopped trying it).

Division on natural numbers is not as easy to manage as on rationals or reals (think 1 / 3). One way out of this could be to try to reframe your constraints with multiplication instead; for instance, n < m / p can sometimes be handled as n * p < m. Otherwise, using a library for rationals could be a solution.

Related

Reusing lia tactic to prove decidability

I have an abstract syntax for Presburger arithmetic, along with a fixpoint function determining a given formula's propositional denotation (you can see it here: https://gist.github.com/d4hines/d9a0c674f324cab46d2cf0967bde1ac3).
I'd like to prove that the truth value of any given formula is decidable. Since it's Presburger arithmetic, I know it must decidable. I've heard that the decision procedures for Presburger arithmetic are very complicated. I'd like to reuse the existing one in Coq.
How can I do this?
Thanks!
There are a few reasons why lia will not be of great help to you.
A small true goal like exists x : Z, 2 < x < 4 is not solved by lia: this tactic is not complete for Prestburger arithmetic
Even if lia was complete for Presburger, it would act as an oracle: giving you an answer every time you need one for a true formula. But when presented with a false formula, lia only says to Coq I can't do it, it does not say I have a proof that this can't be done. In other words, the information that a proof procedure is complete may not be stored in the Coq system as a Coq readable proof.

exact value of the derivative on Coq

I want to represent the exact value of the derivative.
I can calculate an approximation like this.
Require Import Coq.Reals.Reals.
Open Scope R_scope.
Definition QuadraticFunction (x:R) := x^2.
Definition differentiation (x:R)(I:R -> R):=
let h := 0.000000001 in
((I (x+h)) - (I x)) / h.
But, we can not calculate the exact value of the derivative on the computer.
For that reason, I want to represent the exact value with the inductive type or others somehow.
I know D_in of Reals.Rderiv, which returns Prop.
I need your help. Thank you.
I need to make four remarks
You should look at coquelicot, this is an extension library on top of Reals that has a nicer treatment of derivatives.
There is no inductive type involved in the presentation of real numbers. In fact, it is part of theoretical folklore that real numbers cannot be represented as an inductive type, in the sense that we usually mean. In an inductive type, you can usually compare two elements by a finite computation. In real numbers, such a comparison faces the difficulty that some numbers are defined by a process of infinite refinement. One of the foundations of the real numbers is that the set is complete, meaning that every Cauchy sequence has a limit. This is often used as a way to define new real numbers.
what does it mean to calculate a number? How do you calculate PI (the circle ratio). You cannot return 3.14, because it is not the exact value. So you need to keep PI as the result. But why would PI be better than (4 * atan(1)), or
lim(4 - 4/3 + 4/5 - 4/7 ...)? So, you do not calculate real numbers as you would do with pocket calculators, because you need to keep the precision. The best you can do, is to return an exact representation as rational value when the real number is rational, an "understandable symbolic expression", or an interval approximation. But interval approximations are not exact, and understandable symbolic expression is an ambiguous specification. How do you choose which expression is most understandable?
There is no function that takes an arbitrary function and returns its derivative in a point as a real number, because we have to take into account that some functions are not derivable everywhere. The Reals library does have a function that makes it possible to talk about the value of a derivative for a derivable function. This is called derive.
Here is a script that does the whole process.
Require Import Coq.Reals.Reals.
Require Import Coq.Reals.Reals.
Open Scope R_scope.
Definition QuadraticFunction (x:R) := x^2.
Lemma derivable_qf : derivable QuadraticFunction.
Proof.
now repeat apply derivable_mult;
(apply derivable_id || apply derivable_const).
Qed.
Definition QuadraticFunctionDerivative :=
derive QuadraticFunction derivable_qf.
Now you have a name for the derivative function, and you can even show that it is equal to another simple function. But whether this other simple function is the result of calculating the derivative is subjective. Here is an example using just the Reals library, but using Coquelicot would give a much more concise script (because derivative computation can be automated, interested readers should also look at the answer by #larsr to the same question).
Lemma QuadraticFunctionDerivativeSimple (x : R) :
QuadraticFunctionDerivative x = 2 * x.
Proof.
unfold QuadraticFunctionDerivative, derive, QuadraticFunction; simpl.
rewrite derive_pt_eq.
replace (2 * x) with (1 * (x * 1) + x * (1 * 1 + x * 0)) by ring.
apply (derivable_pt_lim_mult (fun x => x) (fun x => x * 1)).
apply derivable_pt_lim_id.
apply (derivable_pt_lim_mult (fun x => x) (fun x => 1)).
apply derivable_pt_lim_id.
apply derivable_pt_lim_const.
Qed.
This is probably not the best way to solve the problem, but it is the one I came up with after thinking about the problem for a few minutes.
I recommend #Yves' thoughtful answer, and also want to recommend Coquelicot because of its very readable formalisation of Real Analysis.
Coquelicot has a theorem for the derivative of (f x) ^ n, and in your case f = id (the identity function) and n = 2, so using Coquelicot's theorem, you could prove your lemma like this:
From Coquelicot Require Import Coquelicot.
Require Import Reals.
Open Scope R.
Goal forall x, is_derive (fun x => x^2) x (2*x).
intros x.
evar (e:R). replace (2*x) with e.
apply is_derive_pow.
apply is_derive_id.
unfold e, one. simpl. ring.
Qed.
Coquelicot separates the proof that the derivative exists (is_derive) from a function (Derive) that "computes" the derivative, and has a theorem showing that Derive gives the right answer if the derivative exists.
is_derive_unique: is_derive f x l -> Derive f x = l
This makes it much easier to work with derivatives in expressions with rewrite that using the formulation in the standard library. Just do the rewrites, and the proofs that the derivative really exists ends up as side-conditions.
(Note that I used evars above. It is useful to do that if you want to be able to apply a theorem, but the expressions are not "obviously" (i.e. computationally) equal to Coq. I for similar reasons find it useful to do eapply is_derive_ext to do rewrites inside the function that is being worked on. Just a hint...)
Also, Coquelicot has some useful tactics that can automate some of the reasoning. For example:
Lemma Derive_x3_plus_cos x: Derive (fun x => x^3 + cos x) x = 3*(x^2) - sin x.
apply is_derive_unique.
auto_derive; auto; ring.
Qed.

How is "less than" defined for real numbers in Coq?

I am just wondering how is the "less than" relationship defined for real numbers.
I understand that for natural numbers (nat), < can be defined recursively in terms of one number being the (1+) successor S of another number. I heard that many things about real numbers are axiomatic in Coq and do not compute.
But I am wondering whether there is a minimum set of axioms for real numbers in Coq based upon which other properties/relations can be derived. (e.g. Coq.Reals.RIneq has it that Rplus_0_r : forall r, r + 0 = r. is an axiom, among others)
In particular, I am interested in whether the relationships such as < or <= can be defined on top of the equality relationship. For example, I can imagine that in conventional math, given two numbers r1 r2:
r1 < r2 <=> exists s, s > 0 /\ r1 + s = r2.
But does this hold in the constructive logic of Coq? And can I use this to at least do some reasoning about inequalities (instead of rewriting axioms all the time)?
Coq.Reals.RIneq has it that Rplus_0_r : forall r, r + 0 = r. is an axiom, among others
Nitpick: Rplus_0_r is not an axiom but Rplus_0_l is. You can get a list of them in the module Coq.Reals.Raxioms and a list of the parameters used in Coq.Reals.Rdefinitions.
As you can see "greater than (or equal)" and "less than or equal" are all defined in terms of "less than" which is postulated rather than introduced using the proposition you suggest.
It looks like Rlt could indeed be defined in the fashion you suggest: the two propositions are provably equivalent as shown below.
Require Import Reals.
Require Import Psatz.
Open Scope R_scope.
Goal forall (r1 r2 : R), r1 < r2 <-> exists s, s > 0 /\ r1 + s = r2.
Proof.
intros r1 r2; split.
- intros H; exists (r2 - r1); split; [lra | ring].
- intros [s [s_pos eq]]; lra.
Qed.
However you would still need to define what it means to be "strictly positive" for the s > 0 bit to make sense and it's not at all clear that you'd have fewer axioms in the end (e.g. the notion of being strictly positive should be closed under addition, multiplication, etc.).
Indeed, the Coq.Real library is a bit weak in the sense that it is totally specified as axioms, and at some (brief) points in the past it was even inconsistent.
So the definition of le is a bit "ad hoc" in the sense that from the point of view of the system it carries zero computational meaning, being just a constant and a few axioms. You could well add the axiom "x < x" and Coq could do nothing to detect it.
It is worth pointing to some alternative constructions of the Reals for Coq:
My favourite classical construction is the one done in the four Color theorem by Georges Gonthier and B. Werner: http://research.microsoft.com/en-us/downloads/5464e7b1-bd58-4f7c-bfe1-5d3b32d42e6d/
It only uses the excluded middle axiom (mainly to compare real numbers) so the confidence in its consistency is very high.
The best known axiom-free characterization of the reals is the C-CORN project, http://corn.cs.ru.nl/ but we aware that constructive analysis significantly differs from the usual one.

Simplifying Rational Expressions and Proving Trivial Rational Equivalences in Coq

Which tactics can I use to perform simplifications of rational expressions and prove trivial rational equivalences as shown in the following example?
Require Import Coq.QArith.QArith.
Open Scope Q_scope.
Lemma Example : (0 + 0) / 1 == 0.
I don't know much about rational in Coq, but if their implementation is constructive, you'll be able to simplify such expressions using simpl (you might need to first unfold some definitions) or compute. Since reflexivity is done modulo conversion, it should also solve such goals.
However, you might have trouble simplifying expression with free variable (for example that
forall q:Q, (q + 0) / 1 = q.
Maybe there's a tactic like omega dedicated to this task. You could maybe try with ring or lia.

Theorem plus_n_n_injective, exercise

Help needed with an exercise from Software Foundations. This is the theorem:
Theorem plus_n_n_injective : ∀n m,
n + n = m + m →
n = m.
Proof.
I end up with n = 0 as goal and n + n = 0 as hypothesis. How to move on?
n + n cannot be simplified further because n is a variable, not a type constructor.
You can expose all the construction cases of n by destructing it as Ptival said. However using inversion in this context seems to me a bit extreme and not what this Sf exercise is about.
When replaced by the O constructor, O + O will reduce (using simpl for example) to O and reflexivity should do the trick.
When replaced by the S constructor, S foo + bar will always reduce to the shape S something, which can't be equal to O (the easiest way to assert that is by using discriminate) because they are two constructors of the same type.
Best,
V.
If you inspect n (destruct it), it's either going to be 0 in which case the goal is provable by reflexivity, or S n' in which case the hypothesis is contradictory by congruence/inversion.
The trick to solving this problem can be garnered from the Theorem for length_snoc' previously shown in the same chapter.
As this was the first time so far in the book that introducing some of the variable/hypothesis after doing an induction on n, this may come off as unusual to newcomers (like me). This allows you to get a more general hypotheses in your context after proving for the base case.
As mentioned before, you will be able to prove some goals simply by reflexivity. Some of them can be proven by inversion on a false hypotheses in your context(those should become straightforward once you spot them, the idea that 2 + 2 = 5 -> anything is true can go a long way).
Finally, you will have to rework one of your hypotheses using the previously defined lemmas plus_n_Sm and eq_add_S as well as symmetry to be able to apply the more general hypotheses we discussed earlier.