-- WadrayVerification/Aux.lean

import CorelibVerification.Aux.ZMod

import Aegis.Aux.Bool

import Aegis.Aux.ZMod.DivMod

open Sierra

def Wad : Type := UInt128

namespace Wad

variable (w w' : Wad)

protected def toZMod : UInt128 := w

end Wad

def Ray : Type := UInt128

namespace Ray

def RAY_SCALE : ℕ := 1000000000000000000000000000

variable (r r' : Ray)

protected def toZMod : UInt128 := r

protected def toRat : ℚ := r.toZMod.val / RAY_SCALE

end Ray

namespace SignedWad

variable (w w₁ w₂ : SignedWad)

end SignedWad

def SignedRay := UInt128 × (Unit ⊕ Unit)

namespace SignedRay

variable (w w₁ w₂ : SignedRay)

def toRat : ℚ := if SierraBool.toBool w.2 then -(Ray.toRat w.1) else Ray.toRat w.1

-- Repository definitions used:
content: ...

-- Repository lemmas used:
content: theorem List.getElem_append_left{α : Type u_1} {l₁ l₂ : List α} {i : Nat} (hn : i < l₁.length) :\n(l₁ ++ l₂)[i] = l₁[i]

-- Local definitions used:
content: def Wad : Type := UInt128

content: protected def toZMod : UInt128 := w

content: def Ray : Type := UInt128

content: def RAY_SCALE : ℕ := 1000000000000000000000000000

content: protected def toZMod : UInt128 := r

content: protected def toRat : ℚ := r.toZMod.val / RAY_SCALE

content: def SignedRay := UInt128 × (Unit ⊕ Unit)

content: def toRat : ℚ := if SierraBool.toBool w.2 then -(Ray.toRat w.1) else Ray.toRat w.1

-- Local lemmas used:
content: theorem ZMod.cast_rat_nonneg [NeZero n] (a : ZMod n) : 0 ≤ (a.cast : ℚ)

content: theorem RAY_SCALE_rat_pos : 0 < (RAY_SCALE : ℚ)

content: theorem toRat_lt_toRat_of_val_lt_val (h : @ZMod.val U128_MOD r < @ZMod.val U128_MOD r') :
    r.toRat < r'.toRat

content: theorem toRat_injective : Function.Injective Ray.toRat

content: theorem toRat_nonneg : 0 ≤ r.toRat

content:  @[simp]
theorem toRat_zero : (0 : Ray).toRat = 0

-- Target theorem and proof:
theorem val_eq_of_toRat_eq : w₁.toRat = w₂.toRat → w₁.1 = w₂.1
:= by
  rcases w₁ with ⟨w₁, s₁⟩
  rcases w₂ with ⟨w₂, s₂⟩
  intro h
  cases s₁ <;> cases s₂
  · have := Ray.toRat_injective h
    cases this
    rfl
  · simp only [toRat, SierraBool_toBool_inl, ite_false, SierraBool_toBool_inr, ite_true] at *
    have h' : Ray.toRat w₁ = 0 := by
      apply le_antisymm _ _
      · rw [h, Left.neg_nonpos_iff]
        apply Ray.toRat_nonneg
      · apply Ray.toRat_nonneg
    rw [h', zero_eq_neg, ← Ray.toRat_zero] at h
    have := Ray.toRat_injective h; cases this
    rw [← Ray.toRat_zero] at h'
    have := Ray.toRat_injective h'; cases this
    rfl
  · simp only [toRat, SierraBool_toBool_inr, ite_true, SierraBool_toBool_inl, ite_false] at *
    have h' : Ray.toRat w₂ = 0 := by
      apply le_antisymm _ _
      · rw [← h, Left.neg_nonpos_iff]
        apply Ray.toRat_nonneg
      · apply Ray.toRat_nonneg
    rw [h', eq_comm, zero_eq_neg, ← Ray.toRat_zero] at h
    have := Ray.toRat_injective h; cases this
    rw [← Ray.toRat_zero] at h'
    have := Ray.toRat_injective h'; cases this
    rfl
  · simp only [toRat, SierraBool_toBool_inr, ite_true, neg_inj] at h
    have := Ray.toRat_injective h
    cases this
    rfl