(* for good measure, we will define exponentiation for nat and prove that lognat is correct *)
Fixpoint expnat(a e : nat) : nat :=
  match e with
    | 0 => 1
    | (S e') => a * (expnat a e')
  end.

(* Specifications: *)
Lemma mult_ne : forall a b, a <> 0 -> b <> 0 -> a * b <> 0.
Theorem expnat_nz : forall a e, (a <> 0) -> (expnat a e) <> 0.
Lemma nz_2 : 2 <> 0.
Theorem expnat_2_nz: forall e, (expnat 2 e) <> 0.
Theorem expnat_2_monotonic : forall e1 e2, e1 <= e2 -> (expnat 2 e1 <= expnat 2 e2).
Theorem lognat_correct_eq : forall(b : nat)(pf : (expnat 2 b) <> 0), (lognat pf) = b.
Lemma fold_add : forall a, a + (a + 0) = 2*a.
Theorem lognat_ge_monotonic_b : forall(a : nat)(pf1 : (a <> 0))(pf2: (S a) <> 0), (lognat pf2) >= (lognat pf1).
Lemma ge_trans : forall a b c, a >= b -> b >= c -> a >= c.
Lemma lognat_ge_monotonic_h : forall (c a b : nat)(pfa : a <> 0)(pfb : b <> 0), a >= b -> c = (a - b) -> (lognat pfa) >= (lognat pfb).
Lemma lognat_ge_monotonic : forall (a b : nat)(pfa : a <> 0)(pfb : b <> 0), a >= b -> (lognat pfa) >= (lognat pfb).
Lemma lognat_monotonic : forall (a b : nat)(pfa : a <> 0)(pfb : b <> 0), a <= b -> (lognat pfa) <= (lognat pfb).
Theorem mt : forall P Q: Prop, (P -> Q) -> (~Q -> ~P).
Lemma ge_not : forall a b, ~(a >= b) -> a < b.
Lemma lognat_ge_monotonic_mt : forall (a b : nat)(pfa : a <> 0)(pfb : b <> 0), (lognat pfa) < (lognat pfb) -> a < b.
Lemma lognat_correct2 : forall(a : nat)(pf : a <> 0), a < (expnat 2 (S (lognat pf))).
Lemma lognat_odd : forall(a : nat)(pf1 : (2 * a) <> 0)(pf2 : (S (2 * a)) <> 0), ((lognat pf2) = (lognat pf1)).
Lemma double_s : forall a, (S (S (2 * a))) = 2 * (S a).
Lemma lognat_double_eq : forall a b (pf1: 2 * a <> 0)(pf2: 2 * b <> 0)(pf3 : a <> 0) (pf4: b <> 0), lognat pf3 = lognat pf4 -> lognat pf1 = lognat pf2.
Lemma nat_comp : forall(a : nat), exists x : nat, (a = (2 * x) \/ a = (S (2 * x))).
Lemma lognat_correct1 : forall(b a : nat)(pf : a <> 0), (lognat pf) = b -> (expnat 2 b) <= a.
Theorem lognat_correct : forall(a : nat)(pf : a <> 0), (expnat 2 (lognat pf)) <= a < (expnat 2 (S (lognat pf))).
Lemma lognat_prod_sum_gen_h : forall (a' a b: nat)(pf1 : (a <> 0))(pf2 : (b <> 0))(pf3 : a * b <> 0), lognat pf1 = a' -> a' + lognat pf2 <= lognat pf3.
Theorem lognat_prod_sum_gen : forall (a b: nat)(pf1 : (a <> 0))(pf2 : (b <> 0))(pf3 : a * b <> 0), lognat pf1 + lognat pf2 <= lognat pf3.
Lemma lognat_0_1 : forall n (pf : n <> 0), lognat pf = 0 -> n = 1.
Lemma lognat_succ_h : forall a n (pf1 : n <> 0)(pf2: (S n) <> 0), a = lognat pf1 -> lognat pf2 = a \/ lognat pf2 = S (a).
Lemma lognat_succ : forall n (pf1 : n <> 0)(pf2: (S n) <> 0), lognat pf2 = lognat pf1 \/ lognat pf2 = S (lognat pf1).
Lemma logn_ge_1 : forall n (pf : n <> 0), n > 1 -> lognat pf >= 1.