Proof that "if m <= n then max(m, n) = n" in Coq - coq

Yesterday I asked a question here about a proof in Coq and the answer helped me a lot, I was able to solve many exercises alone and discover new features. Today I have another exercise, which states that For all m, n, if m <= n then max(m,n) = n. I tried to do induction after m, but I got stuck. Any help would be appreciated!
Fixpoint max (m n : Nat) : Nat :=
match m with
| O => n
| S m' => match n with
| O => m
| S n' => S (max m' n')
end
end.
Fixpoint le_Nat (m n : Nat) : bool :=
match m with
| O => true
| S m' => match n with
| O => false
| S n' => (le_Nat m' n')
end
end.
Lemma:
Lemma le_max_true :
forall m n,
le_Nat m n = true ->
max m n = n.
Proof.
...
Qed.

Let's consider the 4th sub-goal.
1 goal (ID 39)
m : nat
IHm : forall n : nat, le_nat m n = true -> max m n = n
n : nat
============================
le_nat m n = true -> S (max m n) = S n
rewrite IHm is able to replace (max m N) with N(for any N), under the condition le_nat m N = true.
By an intro H, you push an hypothesis of type le_nat m n = true into the context. Then your rewrite IHm generates two (trivial) sub-goals.
In short, in order to solve the 4th sub-goal, you may start with intro H; rewrite IHm.
If you forget the intro H, you get an unsolvable goal:
m : Nat
IHm : forall n : Nat, le_Nat m n = true -> max m n = n
n : Nat
============================
le_Nat m n = true

You need to do induction on both m and n (m and then n). After that, the goal is relatively straightforward.

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)

Coq: Proving conat is either finite or infinite

I have a definition of conat which can represent both finite and infinite values, a conversion from nat, a definition of infinity, and a bisimulation relation:
CoInductive conat : Set := O' | S' (n : conat).
Fixpoint toCo (n : nat) : conat := match n with
| O => O'
| S n' => S' (toCo n') end.
CoFixpoint inf : conat := S' inf.
CoInductive bisim : conat -> conat -> Prop :=
| OO : bisim O' O'
| SS : forall n m : conat, bisim n m -> bisim (S' n) (S' m).
Notation "x == y" := (bisim x y) (at level 70).
I want to prove that conat is either finite or infinite (I'm not 100% sure that this is the correct formulation):
(* This is the goal *)
Theorem fin_or_inf : forall n : conat, (exists m : nat, toCo m == n) \/ (n == inf).
I couldn't prove it so far, but I could prove another statement that, if a conat is not finite, it is infinite (again, not 100% sure about the formulation):
(* I have a proof for this *)
Theorem not_fin_then_inf : forall n : conat, ~ (exists m : nat, toCo m == n) -> (n == inf).
I have no idea how to go from not_fin_then_inf to fin_or_inf though.
Is my definition of fin_or_inf correct?
Can I prove fin_or_inf, either using not_fin_then_inf or not using it?
Also, I found that bridging the gap between the two theorems involves decidability of bisimulation (or extension thereof). I think the decidability theorem could be stated as
Lemma bisim_dec : forall n m : conat, n == m \/ ~ (n == m).
Can I prove bisim_dec or any similar statement on bisimulation?
Edit
The original motivation to prove "either finite or infinite" was to prove commutativity and associativity of coplus:
CoFixpoint coplus (n m : conat) := match n with
| O' => m
| S' n' => S' (coplus n' m)
end.
Notation "x ~+ y" := (coplus x y) (at level 50, left associativity).
Theorem coplus_comm : forall n m, n ~+ m == m ~+ n.
Theorem coplus_assoc : forall n m p, n ~+ m ~+ p == n ~+ (m ~+ p).
Going through the same way as nat's + does not work because it requires transitivity of == with a lemma analogous to plus_n_Sm, which makes the cofix call unguarded. Otherwise, I have to destruct both n and m, and then I'm stuck at the goal n ~+ S' m == m ~+ S' n.
If I choose an alternative definition of coplus:
CoFixpoint coplus (n m : conat) := match n, m with
| O', O' => O'
| O', S' m' => S' m'
| S' n', O' => S' n'
| S' n', S' m' => S' (S' (coplus n' m'))
end.
Then coplus_comm is easy, but coplus_assoc becomes near-impossible to prove instead.
Can I indeed prove coplus_comm with the first definition of coplus, or coplus_assoc with the second?

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

Coq: remove constructor from both sides of goal

Consider the following partial proof:
Theorem test : forall (n m : nat),
n = m -> S n = S m.
Proof.
intros n m H.
Executing until this point gives me the following:
1 subgoal
n, m : nat
H : n = m
______________________________________(1/1)
S n = S m
I would like to remove the Ss from the goal, obtaining the goal n = m. Is there a tactic that does this?
You are looking for the f_equal tactic.

Split conjunction goal into subgoals

Consider the following toy exercise:
Theorem swap_id: forall (m n : nat), m = n -> (m, n) = (n, m).
Proof.
intros m n H.
At this point I have the following:
1 subgoal
m, n : nat
H : m = n
______________________________________(1/1)
(m, n) = (n, m)
I would like to split the goal into two subgoals, m = n and n = m. Is there a tactic which does that?
Solve using the f_equal tactic:
Theorem test: forall (m n : nat), m = n -> (m, n) = (n, m).
Proof.
intros m n H. f_equal.
With state:
2 subgoals
m, n : nat
H : m = n
______________________________________(1/2)
m = n
______________________________________(2/2)
n = m