+intros.elim n.
+simplify.rewrite < plus_n_O.rewrite < plus_n_O.assumption.
+apply lt_plus.assumption.assumption.
+qed. *)
+
+ntheorem monotonic_lt_times_l:
+ ∀c:nat. O < c → monotonic nat lt (λt.(t*c)).
+#c; #posc; #n; #m; #ltnm;
+nelim ltnm; nnormalize;
+ ##[napplyS monotonic_lt_plus_l;//;
+ ##|#a; #_; #lt1; napply (transitive_le ??? lt1);//;
+ ##]
+nqed.
+
+ntheorem monotonic_lt_times_r:
+ ∀c:nat. O < c → monotonic nat lt (λt.(c*t)).
+(* /2/ lentissimo *)
+#c; #posc; #n; #m; #ltnm;
+(* why?? napplyS (monotonic_lt_times_l c posc n m ltnm); *)
+nrewrite > (symmetric_times c n);
+nrewrite > (symmetric_times c m);
+napply monotonic_lt_times_l;//;
+nqed.
+
+ntheorem lt_to_le_to_lt_times:
+∀n,m,p,q:nat. n < m → p ≤ q → O < q → n*p < m*q.
+#n; #m; #p; #q; #ltnm; #lepq; #posq;
+napply (le_to_lt_to_lt ? (n*q));
+ ##[napply monotonic_le_times_r;//;
+ ##|napply monotonic_lt_times_l;//;
+ ##]
+nqed.
+
+ntheorem lt_times:∀n,m,p,q:nat. n<m → p<q → n*p < m*q.
+#n; #m; #p; #q; #ltnm; #ltpq;
+napply lt_to_le_to_lt_times;/2/;
+nqed.
+
+ntheorem lt_times_n_to_lt_l:
+∀n,p,q:nat. O < n → p*n < q*n → p < q.
+#n; #p; #q; #posn; #Hlt;
+nelim (decidable_lt p q);//;
+#nltpq;napply False_ind;
+napply (lt_to_not_le ? ? Hlt);
+napply monotonic_le_times_l;/3/;
+nqed.
+
+ntheorem lt_times_n_to_lt_r:
+∀n,p,q:nat. O < n → n*p < n*q → p < q.
+#n; #p; #q; #posn; #Hlt;
+napply (lt_times_n_to_lt_l ??? posn);//;
+nqed.
+
+(*
+theorem nat_compare_times_l : \forall n,p,q:nat.
+nat_compare p q = nat_compare ((S n) * p) ((S n) * q).
+intros.apply nat_compare_elim.intro.
+apply nat_compare_elim.
+intro.reflexivity.
+intro.absurd (p=q).
+apply (inj_times_r n).assumption.
+apply lt_to_not_eq. assumption.
+intro.absurd (q<p).
+apply (lt_times_to_lt_r n).assumption.
+apply le_to_not_lt.apply lt_to_le.assumption.
+intro.rewrite < H.rewrite > nat_compare_n_n.reflexivity.
+intro.apply nat_compare_elim.intro.
+absurd (p<q).
+apply (lt_times_to_lt_r n).assumption.
+apply le_to_not_lt.apply lt_to_le.assumption.
+intro.absurd (q=p).
+symmetry.
+apply (inj_times_r n).assumption.
+apply lt_to_not_eq.assumption.
+intro.reflexivity.
+qed. *)
+
+(* times and plus
+theorem lt_times_plus_times: \forall a,b,n,m:nat.
+a < n \to b < m \to a*m + b < n*m.
+intros 3.
+apply (nat_case n)
+ [intros.apply False_ind.apply (not_le_Sn_O ? H)
+ |intros.simplify.
+ rewrite < sym_plus.
+ unfold.
+ change with (S b+a*m1 \leq m1+m*m1).
+ apply le_plus
+ [assumption
+ |apply le_times
+ [apply le_S_S_to_le.assumption
+ |apply le_n
+ ]
+ ]
+ ]
+qed. *)
+
+(************************** minus ******************************)
+
+nlet rec minus n m ≝
+ match n with
+ [ O ⇒ O
+ | S p ⇒
+ match m with
+ [ O ⇒ S p
+ | S q ⇒ minus p q ]].
+
+interpretation "natural minus" 'minus x y = (minus x y).
+
+ntheorem minus_S_S: ∀n,m:nat.S n - S m = n -m.
+//; nqed.
+
+ntheorem minus_O_n: ∀n:nat.O=O-n.
+#n; ncases n; //; nqed.
+
+ntheorem minus_n_O: ∀n:nat.n=n-O.
+#n; ncases n; //; nqed.
+
+ntheorem minus_n_n: ∀n:nat.O=n-n.
+#n; nelim n; //; nqed.
+
+ntheorem minus_Sn_n: ∀n:nat. S O = (S n)-n.
+#n; nelim n; //; nqed.
+
+ntheorem minus_Sn_m: ∀m,n:nat. m ≤ n → S n -m = S (n-m).
+(* qualcosa da capire qui
+#n; #m; #lenm; nelim lenm; napplyS refl_eq. *)
+napply nat_elim2;
+ ##[//
+ ##|#n; #abs; napply False_ind; /2/.
+ ##|#n; #m; #Hind; #c; napplyS Hind; /2/;
+ ##]
+nqed.
+
+ntheorem not_eq_to_le_to_le_minus:
+ ∀n,m.n ≠ m → n ≤ m → n ≤ m - 1.
+#n; #m; ncases m;//; #m; nnormalize;
+#H; #H1; napply le_S_S_to_le;
+napplyS (not_eq_to_le_to_lt n (S m) H H1);
+nqed.
+
+ntheorem eq_minus_S_pred: ∀n,m. n - (S m) = pred(n -m).
+napply nat_elim2; //; nqed.
+
+ntheorem plus_minus:
+∀m,n,p:nat. m ≤ n → (n-m)+p = (n+p)-m.
+napply nat_elim2;
+ ##[//
+ ##|#n; #p; #abs; napply False_ind; /2/;
+ ##|nnormalize;/3/;
+ ##]
+nqed.
+
+ntheorem minus_plus_m_m: ∀n,m:nat.n = (n+m)-m.
+#n; #m; napplyS (plus_minus m m n); //; nqed.
+
+ntheorem plus_minus_m_m: ∀n,m:nat.
+m \leq n \to n = (n-m)+m.
+#n; #m; #lemn; napplyS symmetric_eq;
+napplyS (plus_minus m n m); //; nqed.
+
+ntheorem le_plus_minus_m_m: ∀n,m:nat. n ≤ (n-m)+m.
+#n; nelim n;
+ ##[//
+ ##|#a; #Hind; #m; ncases m;//;
+ nnormalize; #n;napplyS le_S_S;//
+ ##]
+nqed.
+
+ntheorem minus_to_plus :∀n,m,p:nat.
+ m ≤ n → n-m = p → n = m+p.
+#n; #m; #p; #lemn; #eqp; napplyS plus_minus_m_m; //;
+nqed.
+
+ntheorem plus_to_minus :∀n,m,p:nat.n = m+p → n-m = p.
+(* /4/ done in 43.5 *)
+#n; #m; #p; #eqp;
+napply symmetric_eq;
+napplyS (minus_plus_m_m p m);
+nqed.
+
+ntheorem minus_pred_pred : ∀n,m:nat. O < n → O < m →
+pred n - pred m = n - m.
+#n; #m; #posn; #posm;
+napply (lt_O_n_elim n posn);
+napply (lt_O_n_elim m posm);//.
+nqed.
+
+(*
+theorem eq_minus_n_m_O: \forall n,m:nat.
+n \leq m \to n-m = O.
+intros 2.
+apply (nat_elim2 (\lambda n,m.n \leq m \to n-m = O)).
+intros.simplify.reflexivity.
+intros.apply False_ind.
+apply not_le_Sn_O;
+[2: apply H | skip].
+intros.
+simplify.apply H.apply le_S_S_to_le. apply H1.
+qed.
+
+theorem le_SO_minus: \forall n,m:nat.S n \leq m \to S O \leq m-n.
+intros.elim H.elim (minus_Sn_n n).apply le_n.
+rewrite > minus_Sn_m.
+apply le_S.assumption.
+apply lt_to_le.assumption.
+qed.
+
+theorem minus_le_S_minus_S: \forall n,m:nat. m-n \leq S (m-(S n)).
+intros.
+apply (nat_elim2 (\lambda n,m.m-n \leq S (m-(S n)))).
+intro.elim n1.simplify.apply le_n_Sn.
+simplify.rewrite < minus_n_O.apply le_n.
+intros.simplify.apply le_n_Sn.
+intros.simplify.apply H.
+qed.
+
+theorem lt_minus_S_n_to_le_minus_n : \forall n,m,p:nat. m-(S n) < p \to m-n \leq p.
+intros 3.intro.
+(* autobatch *)
+(* end auto($Revision: 9739 $) proof: TIME=1.33 SIZE=100 DEPTH=100 *)
+apply (trans_le (m-n) (S (m-(S n))) p).
+apply minus_le_S_minus_S.
+assumption.
+qed.
+
+theorem le_minus_m: \forall n,m:nat. n-m \leq n.
+intros.apply (nat_elim2 (\lambda m,n. n-m \leq n)).
+intros.rewrite < minus_n_O.apply le_n.
+intros.simplify.apply le_n.
+intros.simplify.apply le_S.assumption.