import Mathlib
import Analysis.Section_2_1
import Analysis.Tags.Section_2_1

namespace Chapter2

-- <CONTEXT>
inductive Nat where
| zero : Nat
| succ : Nat → Nat
deriving Repr, DecidableEq

instance Nat.instZero : Zero Nat := ⟨ zero ⟩

postfix:100 "++" => Nat.succ

instance Nat.instOfNat {n:_root_.Nat} : OfNat Nat n where
  ofNat := _root_.Nat.rec 0 (fun _ n ↦ n++) n

instance Nat.instOne : One Nat := ⟨ 1 ⟩

lemma Nat.zero_succ : 0++ = 1 := by
  sorry

lemma Nat.one_succ : 1++ = 2 := by
  sorry

lemma Nat.two_succ : 2++ = 3 := by
  sorry

theorem Nat.succ_ne (n:Nat) : n++ ≠ 0 := by
  sorry

theorem Nat.four_ne : (4:Nat) ≠ 0 := by
  sorry

theorem Nat.succ_cancel {n m:Nat} (hnm: n++ = m++) : n = m := by
  sorry

theorem Nat.succ_ne_succ (n m:Nat) : n ≠ m → n++ ≠ m++ := by
  sorry

theorem Nat.six_ne_two : (6:Nat) ≠ 2 := by
  sorry

theorem Nat.six_ne_two' : (6:Nat) ≠ 2 := by
  sorry

theorem Nat.induction (P : Nat → Prop) (hbase : P 0) (hind : ∀ n, P n → P (n++)) :
    ∀ n, P n := by
  sorry

abbrev Nat.recurse (f: Nat → Nat → Nat) (c: Nat) : Nat → Nat := fun n ↦ match n with
| 0 => c
| n++ => f n (recurse f c n)

theorem Nat.recurse_zero (f: Nat → Nat → Nat) (c: Nat) : Nat.recurse f c 0 = c := by
  sorry

theorem Nat.recurse_succ (f: Nat → Nat → Nat) (c: Nat) (n: Nat) :
    recurse f c (n++) = f n (recurse f c n) := by
  sorry

theorem Nat.eq_recurse (f: Nat → Nat → Nat) (c: Nat) (a: Nat → Nat) :
    (a 0 = c ∧ ∀ n, a (n++) = f n (a n)) ↔ a = recurse f c := by
  sorry

theorem Nat.recurse_uniq (f: Nat → Nat → Nat) (c: Nat) :
    ∃! (a: Nat → Nat), a 0 = c ∧ ∀ n, a (n++) = f n (a n) := by
  sorry

abbrev Nat.add (n m : Nat) : Nat := Nat.recurse (fun _ sum ↦ sum++) m n

instance Nat.instAdd : Add Nat where
  add := add

@[simp]
theorem Nat.zero_add (m: Nat) : 0 + m = m := by
  sorry

theorem Nat.succ_add (n m: Nat) : n++ + m = (n+m)++ := by
  sorry

theorem Nat.one_add (m:Nat) : 1 + m = m++ := by
  sorry

theorem Nat.two_add (m:Nat) : 2 + m = (m++)++ := by
  sorry

@[simp]
lemma Nat.add_zero (n:Nat) : n + 0 = n := by
  sorry

lemma Nat.add_succ (n m:Nat) : n + (m++) = (n + m)++ := by
  sorry

theorem Nat.succ_eq_add_one (n:Nat) : n++ = n + 1 := by
  sorry

theorem Nat.add_comm (n m:Nat) : n + m = m + n := by
  sorry

theorem Nat.add_assoc (a b c:Nat) : (a + b) + c = a + (b + c) := by
  sorry

theorem Nat.add_left_cancel (a b c:Nat) (habc: a + b = a + c) : b = c := by
  sorry

instance Nat.addCommMonoid : AddCommMonoid Nat where
  add_assoc := add_assoc
  add_comm := add_comm
  zero_add := zero_add
  add_zero := add_zero
  nsmul := nsmulRec

def Nat.IsPos (n:Nat) : Prop := n ≠ 0

theorem Nat.isPos_iff (n:Nat) : n.IsPos ↔ n ≠ 0 := by
  sorry

theorem Nat.add_pos_left {a:Nat} (b:Nat) (ha: a.IsPos) : (a + b).IsPos := by
  sorry

theorem Nat.add_pos_right {a:Nat} (b:Nat) (ha: a.IsPos) : (b + a).IsPos := by
  sorry

theorem Nat.add_eq_zero (a b:Nat) (hab: a + b = 0) : a = 0 ∧ b = 0 := by
  sorry

instance Nat.instLE : LE Nat where
  le n m := ∃ a:Nat, m = n + a

instance Nat.instLT : LT Nat where
  lt n m := n ≤ m ∧ n ≠ m

lemma Nat.le_iff (n m:Nat) : n ≤ m ↔ ∃ a:Nat, m = n + a := by
  sorry

lemma Nat.lt_iff (n m:Nat) : n < m ↔ (∃ a:Nat, m = n + a) ∧ n ≠ m := by
  sorry

@[symm]
lemma Nat.ge_iff_le (n m:Nat) : n ≥ m ↔ m ≤ n := by
  sorry

@[symm]
lemma Nat.gt_iff_lt (n m:Nat) : n > m ↔ m < n := by
  sorry

lemma Nat.le_of_lt {n m:Nat} (hnm: n < m) : n ≤ m := by
  sorry

lemma Nat.le_iff_lt_or_eq (n m:Nat) : n ≤ m ↔ n < m ∨ n = m := by
  sorry

theorem Nat.succ_gt_self (n:Nat) : n++ > n := by
  sorry
-- </CONTEXT>
-- <TARGET_THEOREM>
theorem Nat.ge_refl (a:Nat) : a ≥ a := by
-- </TARGET_THEOREM>

end Chapter2