(* Exponential representation of natural numbers *)
(* Dependencies *)
needs "../formal_lp/arith/nat.hl";;
module Num_exp_theory = struct
open Arith_options;;
let base_const = mk_small_numeral base;;
(* num_exp definition *)
let num_exp_tm = mk_eq (`(num_exp:num->num->num) n e`,
mk_binop `( * ):num->num->num` `n:num` (mk_binop `EXP` base_const `e:num`));;
(* let num_exp = new_definition `num_exp n e = n * 2 EXP e`;; *)
(**********************************)
(* Theorems *)
let NUM_EXP_ADD = prove(`!n1 e1 n2 e2. e1 <= e2 ==>
num_exp n1 e1 +
num_exp n2 e2 =
num_exp (n1 +
num_exp n2 (e2 - e1)) e1`,
REPEAT STRIP_TAC THEN
REWRITE_TAC[
num_exp] THEN
REWRITE_TAC[ARITH_RULE `(a + b * c) * d = a * d + b * (c * d):num`] THEN
REWRITE_TAC[GSYM
EXP_ADD] THEN
ASM_SIMP_TAC[ARITH_RULE `e1 <= e2 ==> e2 - e1 + e1 = e2:num`]);;
(* NUM_EXP_LE *)
let NUM_EXP_LE1 = prove(`!n1 e1 n2 e2 r. e2 <= e1 /\ e1 - e2 = r /\ n2 <=
num_exp n1 r
==>
num_exp n2 e2 <=
num_exp n1 e1`,
REPEAT GEN_TAC THEN REWRITE_TAC[
num_exp] THEN
STRIP_TAC THEN
POP_ASSUM MP_TAC THEN POP_ASSUM (fun
th -> REWRITE_TAC[SYM
th]) THEN DISCH_TAC THEN
MP_TAC (ARITH_RULE `e2 <= e1 ==> e1 = (e1 - e2) + e2:num`) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN(fun
th -> ONCE_REWRITE_TAC[
th]) THEN
REWRITE_TAC[
EXP_ADD;
MULT_ASSOC] THEN
ASM_REWRITE_TAC[
LE_MULT_RCANCEL]);;
let NUM_EXP_LE2 = prove(`!n1 e1 n2 e2 r. e1 <= e2 /\ e2 - e1 = r /\
num_exp n2 r <= n1
==>
num_exp n2 e2 <=
num_exp n1 e1`,
REPEAT GEN_TAC THEN REWRITE_TAC[
num_exp] THEN
STRIP_TAC THEN
POP_ASSUM MP_TAC THEN POP_ASSUM (fun
th -> REWRITE_TAC[SYM
th]) THEN DISCH_TAC THEN
MP_TAC (ARITH_RULE `e1 <= e2 ==> e2 = (e2 - e1) + e1:num`) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN(fun
th -> ONCE_REWRITE_TAC[
th]) THEN
REWRITE_TAC[
EXP_ADD;
MULT_ASSOC] THEN
ASM_REWRITE_TAC[
LE_MULT_RCANCEL]);;
(* NUM_EXP_LT *)
end;;