(* This code is copyrighted by its authors; it is distributed under  *)
(* the terms of the LGPL license (see LICENSE and description files) *)
(* Contribution to the Coq Library   V6.3 (July 1999)                    *)
(****************************************************************************)
(*                                                                          *)
(*                                                                          *)
(*                   Solange Coupet-Grimal & Line Jakubiec                  *)
(*                                                                          *)
(*                                                                          *)
(*              Laboratoire d'Informatique de Marseille                     *)
(*               CMI-Technopole de Chateau-Gombert                          *)
(*                   39, Rue F. Joliot Curie                                *)
(*                   13453 MARSEILLE Cedex 13                               *)
(*           e-mail:{Solange.Coupet,Line.Jakubiec}@lim.univ-mrs.fr          *)
(*                                                                          *)
(*                                                                          *)
(*                                Coq V5.10                                 *)
(*                              May 30th 1996                               *)
(*                                                                          *)
(****************************************************************************)
(*                                Lib_Exp.v                                 *)
(****************************************************************************)
Require Export Lib_Mult.
Fixpoint exp_2 (n : nat) : nat :=
match n return nat with
| O =>
(*O*)  1 (*S p*)
| S p => 2 * exp_2 p
end.
Fixpoint exp_n (n m : nat) {struct m} : nat :=
match m return nat with
| O =>
(*O*)  1 (*S p*)
| S p => n * exp_n n p
end.
(************************************************************************)
(********************************* Base 2 *******************************)
(************************************************************************)
simple induction n; auto with arith.
intros.
change (exp_2 (S n0) = 2 * exp_n 2 n0) in |- *.
elim H; auto with arith.
Qed.
Hint Resolve eq_exp_2_exp_n.
intro.
rewrite plus_mult.
change (2 * exp_2 n = 2 * exp_2 n) in |- *.
reflexivity.
Qed.
Hint Resolve exp_2_n_plus_n.
intros.
rewrite exp_2_n_plus_n.
rewrite S_pred_n; auto with arith.
Qed.
Hint Resolve exp_2_plus_pn_pn.
simple induction n; auto with arith.
intros.
simpl in |- *.
elim plus_n_O; auto with arith.
Qed.
Hint Resolve exp_2_le_pn_n.
simple induction n; auto with arith.
intros.
simpl in |- *.
elim plus_n_O; auto with arith.
Qed.
Hint Resolve exp_2_pos.
intros.
elim H; auto with arith.
intros.
simpl in |- *.
elim plus_n_O.
elim H1; auto with arith.
Qed.
Hint Resolve exp_2_incr.
simple induction n.
intro.
simpl in |- *.
elim plus_n_O; reflexivity.
intros.
simpl in |- *.
elim plus_n_O.
apply sym_equal.
elim plus_n_O.
rewrite H.
elim mult_plus_distr_r; reflexivity.
Qed.
Hint Resolve exp_2_n_plus_m.
(************************************************************************)
(********************************** Base n ******************************)
(************************************************************************)
simple induction p; auto with arith.
intros.
simpl in |- *.
apply le_mult_csts; auto with arith.
Qed.
Hint Resolve exp_n_incr.
simple induction n; auto with arith.
intros.
simpl in |- *.
rewrite H; auto with arith.
Qed.
Hint Resolve exp_n_neutre.
simple induction p.
simpl in |- *.
elim plus_n_O.
elim mult_n_Sm.
auto with arith.
elim mult_n_O; auto with arith.
clear p; intros p H_rec.
elim plus_n_Sm.
simpl in |- *.
rewrite H_rec.
elim mult_assoc_reverse.
rewrite (mult_comm n (exp_n n m)).
auto with arith.
Qed.
Hint Resolve exp_n_plus_mult.

Lemma exp_n_permut :
forall n m p : nat, exp_n n (m * p) = exp_n (exp_n n p) m.