Library prosa.util.nat


(* ----------------------------------[ coqtop ]---------------------------------

Welcome to Coq 8.11.2 (June 2020)

----------------------------------------------------------------------------- *)


Require Export prosa.util.tactics prosa.util.ssromega.
From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq fintype bigop div.

(* Additional lemmas about natural numbers. *)
Section NatLemmas.

  Lemma subh1 :
     m n p,
      m n
      m - n + p = m + p - n.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 23)
  
  ============================
  forall m n p : nat, n <= m -> m - n + p = m + p - n

----------------------------------------------------------------------------- *)


  Proof. by ins; ssromega.
(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


Qed.

  Lemma subh2 :
     m1 m2 n1 n2,
      m1 m2
      n1 n2
      (m1 + n1) - (m2 + n2) = m1 - m2 + (n1 - n2).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 30)
  
  ============================
  forall m1 m2 n1 n2 : nat,
  m2 <= m1 -> n2 <= n1 -> m1 + n1 - (m2 + n2) = m1 - m2 + (n1 - n2)

----------------------------------------------------------------------------- *)


  Proof. by ins; ssromega.
(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


Qed.

  Lemma subh3:
     m n p,
      m + p n
      m n - p.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 34)
  
  ============================
  forall m n p : nat, m + p <= n -> m <= n - p

----------------------------------------------------------------------------- *)


  Proof.
    clear.
    intros.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 38)
  
  m, n, p : nat
  H : m + p <= n
  ============================
  m <= n - p

----------------------------------------------------------------------------- *)


    rewrite <- leq_add2r with (p := p).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 39)
  
  m, n, p : nat
  H : m + p <= n
  ============================
  m + p <= n - p + p

----------------------------------------------------------------------------- *)


    rewrite subh1 //.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 45)
  
  m, n, p : nat
  H : m + p <= n
  ============================
  m + p <= n + p - p

subgoal 2 (ID 46) is:
 p <= n

----------------------------------------------------------------------------- *)


    - by rewrite -addnBA // subnn addn0.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 46)
  
  m, n, p : nat
  H : m + p <= n
  ============================
  p <= n

----------------------------------------------------------------------------- *)


    - by apply leq_trans with (m+p); first rewrite leq_addl.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


  Qed.

  (* Simplify [n + a - b + b - a = n] if [n >= b]. *)
  Lemma subn_abba:
     n a b,
      n b
      n + a - b + b - a = n.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 40)
  
  ============================
  forall n a b : nat, b <= n -> n + a - b + b - a = n

----------------------------------------------------------------------------- *)


  Proof.
    moven a b le_bn.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 44)
  
  n, a, b : nat
  le_bn : b <= n
  ============================
  n + a - b + b - a = n

----------------------------------------------------------------------------- *)


    rewrite subnK;
      first by rewrite -addnBA // subnn addn0 //.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 50)
  
  n, a, b : nat
  le_bn : b <= n
  ============================
  b <= n + a

----------------------------------------------------------------------------- *)


    rewrite -[b]addn0.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 94)
  
  n, a, b : nat
  le_bn : b <= n
  ============================
  b + 0 <= n + a

----------------------------------------------------------------------------- *)


    apply leq_trans with (n := n + 0); rewrite !addn0 //.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 114)
  
  n, a, b : nat
  le_bn : b <= n
  ============================
  n <= n + a

----------------------------------------------------------------------------- *)


    apply leq_addr.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


  Qed.

  Lemma add_subC:
     a b c,
      a c
      b c
      a + (b - c ) = a - c + b.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 46)
  
  ============================
  forall a b c : nat, c <= a -> c <= b -> a + (b - c) = a - c + b

----------------------------------------------------------------------------- *)


  Proof.
    intros× AgeC BgeC.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 51)
  
  a, b, c : nat
  AgeC : c <= a
  BgeC : c <= b
  ============================
  a + (b - c) = a - c + b

----------------------------------------------------------------------------- *)


    induction b;induction c;intros;try ssromega.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


  Qed.

  (* TODO: remove when mathcomp minimum required version becomes 1.10.0 *)
  Lemma ltn_subLR:
     a b c,
      a - c < b
      a < b + c.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 50)
  
  ============================
  forall a b c : nat, a - c < b -> a < b + c

----------------------------------------------------------------------------- *)


  Proof.
    intros× AC.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 54)
  
  a, b, c : nat
  AC : a - c < b
  ============================
  a < b + c

----------------------------------------------------------------------------- *)


ssromega.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


  Qed.

  (* We can drop additive terms on the lesser side of an inequality. *)
  Lemma leq_addk:
     m n k,
      n + k m
      n m.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 54)
  
  ============================
  forall m n k : nat, n + k <= m -> n <= m

----------------------------------------------------------------------------- *)


  Proof.
    movem n p.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 57)
  
  m, n, p : nat
  ============================
  n + p <= m -> n <= m

----------------------------------------------------------------------------- *)


    apply leq_trans.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 58)
  
  m, n, p : nat
  ============================
  n <= n + p

----------------------------------------------------------------------------- *)


    by apply leq_addr.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


  Qed.

End NatLemmas.

Section Interval.

  (* Trivially, points before the start of an interval, or past the end of an
     interval, are not included in the interval. *)

  Lemma point_not_in_interval:
     t1 t2 t',
      t2 t' t' < t1
       t,
        t1 t < t2
         t t'.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 24)
  
  ============================
  forall t1 t2 t' : nat,
  t2 <= t' \/ t' < t1 -> forall t : nat, t1 <= t < t2 -> t <> t'

----------------------------------------------------------------------------- *)


  Proof.
    movet1 t2 t' EXCLUDED t /andP [GEQ_t1 LT_t2] EQ.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 71)
  
  t1, t2, t' : nat
  EXCLUDED : t2 <= t' \/ t' < t1
  t : nat
  GEQ_t1 : t1 <= t
  LT_t2 : t < t2
  EQ : t = t'
  ============================
  False

----------------------------------------------------------------------------- *)


    subst.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 79)
  
  t1, t2, t' : nat
  EXCLUDED : t2 <= t' \/ t' < t1
  LT_t2 : t' < t2
  GEQ_t1 : t1 <= t'
  ============================
  False

----------------------------------------------------------------------------- *)


    case EXCLUDED ⇒ [INEQ | INEQ];
      eapply leq_ltn_trans in INEQ; eauto;
      by rewrite ltnn in INEQ.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


  Qed.

End Interval.

Section NatOrderLemmas.

  (* Mimic the way implicit arguments are used in [ssreflect]. *)
  Set Implicit Arguments.
  Unset Strict Implicit.

  (* [ltn_leq_trans]: Establish that [m < p] if [m < n] and [n <= p], to mirror the
     lemma [leq_ltn_trans] in [ssrnat].

     NB: There is a good reason for this lemma to be "missing" in [ssrnat] --
     since [m < n] is defined as [m.+1 <= n], [ltn_leq_trans] is just
     [m.+1 <= n -> n <= p -> m.+1 <= p], that is [@leq_trans n m.+1 p].

     Nonetheless we introduce it here because an additional (even though
     arguably redundant) lemma doesn't hurt, and for newcomers the apparent
     absence of the mirror case of [leq_ltn_trans] can be somewhat confusing.  *)

  Lemma ltn_leq_trans n m p : m < n n p m < p.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 24)
  
  n, m, p : nat
  ============================
  m < n -> n <= p -> m < p

----------------------------------------------------------------------------- *)


  Proof. exact (@leq_trans n m.+1 p).
(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


Qed.

End NatOrderLemmas.