import Mathlib

inductive Color
| Red
| Black
deriving Inhabited, BEq

inductive Node
| Empty : Node
| Tree  (color : Color) (val : Int) (left : Node) (right : Node) : Node
deriving Inhabited

def view (t : Node) : Set Int :=
  match t with
  | Node.Empty => ∅
  | Node.Tree _ v l r => view l ∪ view r ∪ {v}

def is_red (t : Node) : Bool :=
  match t with
  | Node.Tree Color.Red _ _ _ => true
  | _ => false

def is_bst (t : Node) : Prop :=
  match t with
  | Node.Empty => True
  | Node.Tree _ v l r =>
    (∀ x ∈ view l, x < v) ∧
    is_bst l ∧
    (∀ x ∈ view r, x > v) ∧
    is_bst r

-- Black Height: Returns -1 if invalid
def black_height (t : Node) : Int :=
  match t with
  | Node.Empty => 1
  | Node.Tree c _ l r =>
    let lh := black_height l
    let rh := black_height r
    if lh ≠ -1 ∧ rh ≠ -1 ∧ lh = rh then
      if c == Color.Black then lh + 1 else lh
    else
      -1

def satisfies_red_props (t : Node) : Prop :=
  match t with
  | Node.Empty => True
  | Node.Tree _ _ l r =>
    satisfies_red_props l ∧
    satisfies_red_props r ∧
    -- Rule: No Right-Leaning Red
    (¬ is_red r) ∧
    -- Rule: No Double Red on Left (left child red AND left.left child red)
    (match l with
     | Node.Tree Color.Red _ ll _ => ¬ is_red ll
     | _ => True)

-- Main Invariant
def is_llrbt (t : Node) : Prop :=
  is_bst t ∧
  black_height t ≠ -1 ∧
  satisfies_red_props t

-- Precondition definitions
@[reducible, simp]
def delete_precond (t : Node) : Prop :=
  -- !benchmark @start precond
  is_llrbt t
  -- !benchmark @end precond

-- !benchmark @start auxcode
-- !benchmark @end auxcode

-- Main function definition
def delete (t : Node) (v : Int)
    (h_precond : delete_precond t) : Node :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def delete_postcond (t : Node) (v : Int) (result : Node)
    (_ : delete_precond t) : Prop :=
  -- !benchmark @start postcond
  is_llrbt result ∧
  view result = view t \ {v}
  -- !benchmark @end postcond

-- !benchmark @start lemma
-- !benchmark @end lemma

-- Proof content
theorem delete_postcond_satisfied (t : Node) (v : Int)
    (h_precond : delete_precond t) :
    delete_postcond t v (delete t v h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof