how to simplify a equality statement - coq

In hypothesis, I have a natural number that cannot be zero.When we add this number
to an another function,whose output is also natural number. I have to prove that result of addition of these two values equal to zero is false. I should not dig about f,because addition of anything in non zero term ,become equal to zero is false statement.
`H : (m =? 0) = false
(f+ m =? 0) = false`

Short answer:
Require Import Lia.
rewrite !Nat.eqb_neq; lia.
Long answer:
I feel sorry that this question arises. Historically, most of the reasoning in Coq about equality is done with the eq concept, with the notation m = n, not with the boolean equality, on which you rely here. It is also important to know that Coq has a specific notation for "disequality" or "non-equality" : m <> n stands for ~ (m = n).
So if you add typed the following statement instead, there would be an easy solution:
Require Import Arith Lia.
Lemma example1 f m : m <> 0 -> f + m <> 0.
Proof. lia. Qed.
Unfortunately, this does not work for the way you express your statement:
Lemma example2 f m : (m =? 0) = false -> (f + m =? 0) = false.
Proof.
Fail lia.
If you call Search with the following pattern, you see that the boolean comparison expression is logically equivalent to basic equality, but only if you use specific theorems to express this:
Search (_ =? _).
Nat.eqb_refl: forall x : nat, (x =? x) = true
beq_nat_refl: forall n : nat, true = (n =? n)
Nat.eqb_sym: forall x y : nat, (x =? y) = (y =? x)
Nat.eqb_spec: forall x y : nat, Bool.reflect (x = y) (x =? y)
beq_nat_eq: forall n m : nat, true = (n =? m) -> n = m
beq_nat_true: forall n m : nat, (n =? m) = true -> n = m
Nat.eqb_eq: forall n m : nat, (n =? m) = true <-> n = m
beq_nat_false: forall n m : nat, (n =? m) = false -> n <> m
Nat.eqb_neq: forall x y : nat, (x =? y) = false <-> x <> y
Nat.pow2_bits_eqb: forall n m : nat, Nat.testbit (2 ^ n) m = (n =? m)
Nat.bit0_eqb: forall a : nat, Nat.testbit a 0 = (a mod 2 =? 1)
Nat.eqb_compare:
forall x y : nat, (x =? y) = match x ?= y with
| Eq => true
| _ => false
end
Nat.setbit_eqb:
forall a n m : nat,
Nat.testbit (Nat.setbit a n) m = ((n =? m) || Nat.testbit a m)%bool
Nat.clearbit_eqb:
forall a n m : nat,
Nat.testbit (Nat.clearbit a n) m = (Nat.testbit a m && negb (n =? m))%bool
Nat.testbit_eqb: forall a n : nat, Nat.testbit a n = ((a / 2 ^ n) mod 2 =? 1)
But there is no theorem that expresses the interaction of addition with equality to 0. You can also see this using a more precise pattern.
Search (_ =? _) 0 (_ + _).
This returns nothing.
On the other hand, if you type
Search (_ = _) 0 (_ + _).
You see many theorems, one of which is relevant to your problem.
Nat.eq_add_0: forall n m : nat, n + m = 0 <-> n = 0 /\ m = 0
And this one is enough to solve the problem, if it is expressed with _ = _ instead of _ =? _. So to solve your specific problem, we need first to transform comparisons using _ =? _ into equality statements,and then do logical reasoning using the available theorems. In the first search result, we have the theorem Nat.eqb_neq that is adapted to your situation. Continuing on the proof of example2 above, we can write:
Rewrite !Nat.eqb_neq.
The goal becomes:
f, m : nat
============================
m <> 0 -> f + m <> 0
Now, we could do logical reasoning using the theorem Nat.eq_add_0.
rewrite Nat.eq_add_0.
We can finish the proof by small step like this.
intros mn0 [fis0 mis0]; case mn0; assumption.
we can also ask an automatic tool to finish the proof for us:
tauto.
But going a little backward in time, we can also observe the statement after rewriting with Nat.eqb_neq. This is a statement in linear arithmetic (it contains comparisons, natural numbers, and no product between variables). This statement is in the scope of a tactic for this theory, the one used most often now is lia.

Related

How to prove a odd number is the successor of double of nat in coq?

I have the odd number definition as below:
Definition Odd n := exists k, n = 2*k+1.
And I have an oddb define that whether a number is odd or not.
Fixpoint oddb (n : nat) { struct n } : bool :=
match n with
| 0 => false
| 1 => true
| S (S n) => oddb n
end.
I am trying to prove if a number is the successor of a double of nat; then it is a odd number.
Theorem question_1c:
forall n, Odd n -> (oddb n = true).
Proof.
unfold Odd. intros. inversion H.
rewrite H0. simpl. induction x.
- simpl. reflexivity.
- Admitted.
I stuck on the second goal.. it showed that I need to prove Sx.. and the hypothesis I have from now seems like not helpful...
1 subgoal
n : nat
H : exists k : nat, n = 2 * k + 1
x : nat
H0 : n = 2 * S x + 1
IHx : n = 2 * x + 1 -> oddb (x + (x + 0) + 1) = true
______________________________________(1/1)
oddb (S x + (S x + 0) + 1) = true
Can anyone help me?? tHnak you
Standard induction let you jump from n to n+1. Here with your odd function
you need to jump from n to n+2. So what is needed is a stronger induction. One way to do this is to prove:
Theorem question_1c:
forall n m, m <= n -> Odd m -> (oddb m = true).
by standard induction on n (but for all m smaller)

How to simplify a statement of lemma

I have a Contradictory statements in hypothesis. Want to convert it into true=false. Thanks for guidence in advance. Here is code
n < current_value 0 (n :: l)
current_value 0 (n :: l)<= n.
The question could be a lot more complete. What is the type of n? I'll assume that it is nat.
Starting like this:
Lemma manual:
forall current_value n l P,
n < current_value 0 (n :: l) ->
current_value 0 (n :: l) <= n ->
P.
Proof.
intros.
We arrive at a state that looks like this (omitting things we don't need):
H : n < current_value 0 (n :: l)
H0 : current_value 0 (n :: l) ≤ n
-----
P
The strategy will be to prove that H and H0 together lead to a contradiction from which we can prove any statement P.
We know that n < m (if m stands for the expression current_value 0 (n :: l)) and also m <= n. What can we prove from this? You can search for relevant lemmas using the Search command with a pattern that summarizes what you know:
Search (?n < ?m -> ?m <= ?p -> _).
This query means "given that I know that n < m and also m <= p for the same m, what can I deduce?". The named variables in the query need the ? prefix, they can stand for any expressions. They are not related to any variables you might have in the current environment.
One of the search hits is this (in PeanoNat, which you will have to import):
Nat.lt_le_trans:
forall n m p : nat, n < m -> m <= p -> n < p
So given this lemma we should be able to prove n < n and see if we can make progress from there.
{
apply Nat.lt_le_trans with (m := current_value 0 (n :: l)).
auto.
auto.
}
Now we have:
H1 : n < n
-----
P
So now we have a more "obvious" contradiction in an assumption. Do we have a lemma for proving that this is indeed false?
Search (~ ?n < ?n).
This gives:
Nat.lt_irrefl: forall x : nat, ~ x < x
So then:
apply Nat.lt_irrefl in H1.
We arrive at:
H1 : False
-----
P
This is a tautology that we can prove with tauto:
tauto.
Qed.
Doing such simple arithmetic manually can get very tedious, so there is a lot of automation for doing it. Here's a simpler method using the lia tactic:
Require Import Lia.
Lemma automatic:
forall current_value n l P,
n < current_value 0 (n :: l) ->
current_value 0 (n :: l) <= n ->
P.
Proof.
intros.
lia.
Qed.
Internally this will do some sort of similar reasoning, proving a contradiction in the assumptions.

Check less or equal natural number in coq

I have function (beq_nat_refl) which determines the equality of two natural numbers and gives a boolean. But now I want to prove a lemma stating that a natural number x is less or equal to x.
May I use the above function (beq_nat_refl)?
Theorem beq_nat_refl :
forall n : nat,
true = beq_nat n n.
Theorem leq_nat :
forall x:nat,
x <= x.
That would work if you would define x <= y as x < y || x == y; however this is not the definition, so usually the proof of x <= x tends to be induction [on the computational case] or by applying the base constructor if using a witness.
Here is a straightforward path to proving leq_nat from similar definitions:
Fixpoint leb (n m : nat) : bool :=
match n, m with
| 0 , _ => true
| _ , 0 => false
| S n, S m => leb n m
end.
Lemma leb_nat_refl : forall (n : nat), leb n n = true.
Proof.
induction n; simpl.
+ reflexivity.
+ assumption.
Qed.
Lemma leb_nat_reflect : forall (n : nat), leb n n = true <-> n <= n.
Proof.
induction n; simpl; split; intros.
+ constructor.
+ reflexivity.
+ constructor.
+ apply IHn. constructor.
Qed.
Theorem leq_nat : forall (n : nat), n <= n.
Proof.
intros.
apply leb_nat_reflect.
apply leb_nat_refl.
Qed.

Tactics: stuck in eqb_trans

Trying to solve eqb_trans I became stuck:
Theorem eqb_trans : forall n m p,
n =? m = true ->
m =? p = true ->
n =? p = true.
Obviously, we should use eqb_true to solve it:
Theorem eqb_true : forall n m,
n =? m = true -> n = m.
--------------------------------------------
Proof.
intros n m p H1 H2. apply eqb_true in H1.
apply eqb_true with (n:=m)(m:=p) in H2.
At this point we have:
n, m, p : nat
H1 : n = m
H2 : m = p
============================
(n =? p) = true
Now I wanted to use eqb_true upon the goal:
apply eqb_true with (m:=p).
But here we get an error:
Unable to unify "?M1056 = p" with "(n =? p) = true".
Why doesn't it work? How to fix?
When you apply a lemma to the goal, it is the conclusion of the lemma that must unify with the goal rather than its premise. The conclusion of this lemma is of the form _ = _, while your goal is (_ =? _) = true. These two cannot be unified, which leads to the error you see.
To prove eqb_trans, you need the converse of eqb_true, namely
forall n m, n = m -> (n =? m) = true,
which, after some simplification, is equivalent to
forall n, (n =? n) = true.
Theorem eqb_trans : forall n m p,
n =? m = true ->
m =? p = true ->
n =? p = true.
Proof.
intros n m p.
repeat rewrite Nat.eqb_eq.
intros.
rewrite H.
exact H0.
Qed.
-- Check Nat.eqb_eq.
Nat.eqb_eq
: forall n m : nat, (n =? m) = true <-> n = m

even (n + m) -> even n /\ even m \/ odd n /\ odd m

How can I prove this lemma:
Lemma even_plus_split n m :
even (n + m) -> even n /\ even m \/ odd n /\ odd m.
These are the only libraries and definition that can be used:
Require Import Arith.
Require Import Coq.omega.Omega.
Definition even (n: nat) := exists k, n = 2 * k.
Definition odd (n: nat) := exists k, n = 2 * k + 1.
I am new to Coq and confused about it. Can you give me a solution? Thanks in advance!
the code so far:
Lemma even_plus_split n m :
even (n + m) -> even n /\ even m \/ odd n /\ odd m.
Proof.
intros.
unfold even.
unfold even in H.
destruct H as [k H].
unfold odd.
exists (1/2*k).
result so far:
1 subgoal
n, m, k : nat
H : n + m = 2 * k
______________________________________(1/1)
(exists k0 : nat, n = 2 * k0) /\ (exists k0 : nat, m = 2 * k0) \/
(exists k0 : nat, n = 2 * k0 + 1) /\ (exists k0 : nat, m = 2 * k0 + 1)
I just want to make k0 equals to 1/2*k, and therefore I suppose it would make sense, but I can't do that.
I just want to make k0 equals to 1/2*k, and therefore I suppose it would make sense, but I can't do that.
There is a function called Nat.div2, which divides a natural number by 2. Running Search Nat.div2.
Nat.le_div2: forall n : nat, Nat.div2 (S n) <= n
Nat.lt_div2: forall n : nat, 0 < n -> Nat.div2 n < n
Nat.div2_decr: forall a n : nat, a <= S n -> Nat.div2 a <= n
Nat.div2_wd: Morphisms.Proper (Morphisms.respectful eq eq) Nat.div2
Nat.div2_spec: forall a : nat, Nat.div2 a = Nat.shiftr a 1
Nnat.N2Nat.inj_div2: forall a : N, N.to_nat (N.div2 a) = Nat.div2 (N.to_nat a)
Nnat.Nat2N.inj_div2: forall n : nat, N.of_nat (Nat.div2 n) = N.div2 (N.of_nat n)
Nat.div2_double: forall n : nat, Nat.div2 (2 * n) = n
Nat.div2_div: forall a : nat, Nat.div2 a = a / 2
Nat.div2_succ_double: forall n : nat, Nat.div2 (S (2 * n)) = n
Nat.div2_odd: forall a : nat, a = 2 * Nat.div2 a + Nat.b2n (Nat.odd a)
Nat.div2_bitwise:
forall (op : bool -> bool -> bool) (n a b : nat),
Nat.div2 (Nat.bitwise op (S n) a b) = Nat.bitwise op n (Nat.div2 a) (Nat.div2 b)
Of these, the most promising seems to be Nat.div2_odd: forall a : nat, a = 2 * Nat.div2 a + Nat.b2n (Nat.odd a). If you pose proof this lemma, you can destruct (Nat.odd a) and use simpl to get that either a = 2 * Nat.div2 a or a = 2 * Nat.div2 a + 1, for whichever a you choose.
This may not give you a solution directly (I am not convinced that setting k0 to k / 2 is the right decision), but if it does not, you should make sure that you can figure out how to prove this fact on paper before you try it in Coq. Coq is very good at making sure that you don't make any jumps of logic that you're not allowed to make; it's extremely bad at helping you figure out how to prove a fact that you don't yet know how to prove.
Everybody who tries to answer seems to be dancing around the fact that you actually chose a wrong direction for this proof. Here is a example:
if n = 601 and m = 399, then n + m = 2 * 500,
n = 2 * 300 + 1, and m = 2 * 199 + 1.
Between 500, 300, and 199, the 1/2 ratio does not appear anywhere.
Still the statement (even n /\ even m) / (odd n /\ odd m) is definitely true.
So for now, you have more a math problem than a Coq problem.
You have to make a proof for universally quantified numbers n and m, but somehow this proof should also work for specific choices of these numbers. So in a sense you can make the mental exercise of testing your proof on examples.