File: .lake/packages/lean4/src/lean/Lean/Meta/Tactic/Simp/BuiltinSimprocs/Nat.lean

full_name: Nat.fromExpr?
code: def fromExpr? (e : Expr) : SimpM (Option Nat) 
goal: Lean.Meta.SimpM (Option Nat)

full_name: Nat.reduceUnary
code: @[inline] def reduceUnary (declName : Name) (arity : Nat) (op : Nat → Nat) (e : Expr) : SimpM DStep 
goal: Lean.Meta.SimpM Lean.Meta.Simp.DStep

full_name: Nat.reduceBin
code: @[inline] def reduceBin (declName : Name) (arity : Nat) (op : Nat → Nat → Nat) (e : Expr) : SimpM DStep 
goal: Lean.Meta.SimpM Lean.Meta.Simp.DStep

full_name: Nat.reduceBinPred
code: @[inline] def reduceBinPred (declName : Name) (arity : Nat) (op : Nat → Nat → Bool) (e : Expr) : SimpM Step 
goal: Lean.Meta.SimpM Lean.Meta.Simp.Step

full_name: Nat.reduceBoolPred
code: @[inline] def reduceBoolPred (declName : Name) (arity : Nat) (op : Nat → Nat → Bool) (e : Expr) : SimpM DStep 
goal: Lean.Meta.SimpM Lean.Meta.Simp.DStep

full_name: Nat.reduceSucc
code: builtin_dsimproc [simp, seval] reduceSucc (Nat.succ _) := reduceUnary ``Nat.succ 1 (· + 1)
goal: Lean.Meta.Simp.DSimproc

full_name: Nat.reduceAdd
code: builtin_dsimproc [simp, seval] reduceAdd ((_ + _ : Nat)) := reduceBin ``HAdd.hAdd 6 (· + ·)
goal: Lean.Meta.Simp.DSimproc

full_name: Nat.reduceMul
code: builtin_dsimproc [simp, seval] reduceMul ((_ * _ : Nat)) := reduceBin ``HMul.hMul 6 (· * ·)
goal: Lean.Meta.Simp.DSimproc

full_name: Nat.reduceSub
code: builtin_dsimproc [simp, seval] reduceSub ((_ - _ : Nat)) := reduceBin ``HSub.hSub 6 (· - ·)
goal: Lean.Meta.Simp.DSimproc

full_name: Nat.reduceDiv
code: builtin_dsimproc [simp, seval] reduceDiv ((_ / _ : Nat)) := reduceBin ``HDiv.hDiv 6 (· / ·)
goal: Lean.Meta.Simp.DSimproc

full_name: Nat.reduceMod
code: builtin_dsimproc [simp, seval] reduceMod ((_ % _ : Nat)) := reduceBin ``HMod.hMod 6 (· % ·)
goal: Lean.Meta.Simp.DSimproc

full_name: Nat.reducePow
code: builtin_dsimproc [simp, seval] reducePow ((_ ^ _ : Nat)) := reduceBin ``HPow.hPow 6 (· ^ ·)
goal: Lean.Meta.Simp.DSimproc

full_name: Nat.reduceGcd
code: builtin_dsimproc [simp, seval] reduceGcd (gcd _ _)       := reduceBin ``gcd 2 gcd
goal: Lean.Meta.Simp.DSimproc

full_name: Nat.reduceLT
code: builtin_simproc [simp, seval] reduceLT  (( _ : Nat) < _)  := reduceBinPred ``LT.lt 4 (. < .)
goal: Lean.Meta.Simp.Simproc

full_name: Nat.reduceGT
code: builtin_simproc [simp, seval] reduceGT  (( _ : Nat) > _)  := reduceBinPred ``GT.gt 4 (. > .)
goal: Lean.Meta.Simp.Simproc

full_name: Nat.reduceBEq
code: builtin_dsimproc [simp, seval] reduceBEq  (( _ : Nat) == _)  := reduceBoolPred ``BEq.beq 4 (. == .)
goal: Lean.Meta.Simp.DSimproc

full_name: Nat.reduceBNe
code: builtin_dsimproc [simp, seval] reduceBNe  (( _ : Nat) != _)  := reduceBoolPred ``bne 4 (. != .)
goal: Lean.Meta.Simp.DSimproc

full_name: Nat.isValue
code: /-- Return `.done` for Nat values. We don't want to unfold in the symbolic evaluator. -/
builtin_dsimproc [seval] isValue ((OfNat.ofNat _ : Nat)) := fun e => do
  let_expr OfNat.ofNat _ _ _ ← e | return .continue
  return .done e
goal: Lean.Meta.Simp.DSimproc

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.NatOffset.offset
code: /-- A literal natural number or a base + offset expression. -/
private inductive NatOffset where
  /- denotes expression definition equal to `n` -/
  | const (n : Nat)
  /-- denotes `e + o` where `o` is expression definitionally equal to `n` -/
  | offset (e o : Expr) (n : Nat)
goal: Nat.NatOffset

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.NatOffset
code: /-- A literal natural number or a base + offset expression. -/
private inductive NatOffset where
  /- denotes expression definition equal to `n` -/
  | const (n : Nat)
  /-- denotes `e + o` where `o` is expression definitionally equal to `n` -/
  | offset (e o : Expr) (n : Nat)
goal: Type

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.NatOffset.const
code: /-- A literal natural number or a base + offset expression. -/
private inductive NatOffset where
  /- denotes expression definition equal to `n` -/
  | const (n : Nat)
  /-- denotes `e + o` where `o` is expression definitionally equal to `n` -/
  | offset (e o : Expr) (n : Nat)
goal: Nat.NatOffset

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.NatOffset.asOffset
code: private partial def NatOffset.asOffset (e : Expr) : Meta.SimpM (Option (Expr × Nat)) 
goal: Lean.Meta.SimpM (Option (Lean.Expr × Nat))

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.NatOffset.fromExprAux
code: private partial def NatOffset.fromExprAux (e : Expr) (inc : Nat) : Meta.SimpM (Option (Expr × Nat)) 
goal: Lean.Meta.SimpM (Option (Lean.Expr × Nat))

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.NatOffset.fromExpr?
code: private def NatOffset.fromExpr? (e : Expr) (inc : Nat := 0) : Meta.SimpM (Option NatOffset) 
goal: Lean.Meta.SimpM (Option Nat.NatOffset)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.mkAddNat
code: private def mkAddNat (x y : Expr) : Expr 
goal: Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.mkSubNat
code: private def mkSubNat (x y : Expr) : Expr 
goal: Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.mkEqNat
code: private def mkEqNat (x y : Expr) : Expr 
goal: Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.mkBeqNat
code: private def mkBeqNat (x y : Expr) : Expr 
goal: Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.mkBneNat
code: private def mkBneNat (x y : Expr) : Expr 
goal: Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.mkLENat
code: private def mkLENat (x y : Expr) : Expr 
goal: Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.mkGENat
code: private def mkGENat (x y : Expr) : Expr 
goal: Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.mkLTNat
code: private def mkLTNat (x y : Expr) : Expr 
goal: Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.mkGTNat
code: private def mkGTNat (x y : Expr) : Expr 
goal: Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat.0.Nat.mkOfDecideEqTrue
code: private def mkOfDecideEqTrue (p : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Nat.applySimprocConst
code: def applySimprocConst (expr : Expr) (nm : Name) (args : Array Expr) : SimpM Step 
goal: Lean.Meta.SimpM Lean.Meta.Simp.Step

full_name: Nat.EqResult.eq
code: inductive EqResult where
| decide (b : Bool) : EqResult
| false (p : Expr) : EqResult
| eq (x y : Expr) (p : Expr) : EqResult
goal: Nat.EqResult

full_name: Nat.EqResult.decide
code: inductive EqResult where
| decide (b : Bool) : EqResult
| false (p : Expr) : EqResult
| eq (x y : Expr) (p : Expr) : EqResult
goal: Nat.EqResult

full_name: Nat.EqResult
code: inductive EqResult where
| decide (b : Bool) : EqResult
| false (p : Expr) : EqResult
| eq (x y : Expr) (p : Expr) : EqResult
goal: Type

full_name: Nat.EqResult.false
code: inductive EqResult where
| decide (b : Bool) : EqResult
| false (p : Expr) : EqResult
| eq (x y : Expr) (p : Expr) : EqResult
goal: Nat.EqResult

full_name: Nat.applyEqLemma
code: def applyEqLemma (e : Expr → EqResult) (lemmaName : Name) (args : Array Expr) : SimpM (Option EqResult) 
goal: Lean.Meta.SimpM (Option Nat.EqResult)

full_name: Nat.reduceNatEqExpr
code: def reduceNatEqExpr (x y : Expr) : SimpM (Option EqResult)
goal: Lean.Meta.SimpM (Option Nat.EqResult)

full_name: Nat.reduceEqDiff
code: builtin_simproc [simp, seval] reduceEqDiff ((_ : Nat) = _) := fun e => do
  unless e.isAppOfArity ``Eq 3 do
    return .continue
  let x := e.appFn!.appArg!
  let y := e.appArg!
  match ← reduceNatEqExpr x y with
  | none =>
    return .continue
  | some (.decide true) =>
    let d ← mkDecide e
    let p := mkAppN (mkConst ``eq_true_of_decide)  #[e, d.appArg!, (← mkEqRefl (mkConst ``true))]
    return .done  { expr := mkConst ``True,  proof? := some p, cache := true }
  | some (.decide false) =>
    let d ← mkDecide e
    let p := mkAppN (mkConst ``eq_false_of_decide) #[e, d.appArg!, (← mkEqRefl (mkConst ``false))]
    return .done  { expr := mkConst ``False, proof? := some p, cache := true }
  | some (.false p)  =>
    return .done  { expr := mkConst ``False, proof? := some p, cache := true }
  | some (.eq x y p) =>
    return .visit { expr := mkEqNat x y,     proof? := some p, cache := true }
goal: Lean.Meta.Simp.Simproc

full_name: Nat.reduceBeqDiff
code: builtin_simproc [simp, seval] reduceBeqDiff ((_ : Nat) == _) := fun e => do
  unless e.isAppOfArity ``BEq.beq 4 do
    return .continue
  let x := e.appFn!.appArg!
  let y := e.appArg!
  match ← reduceNatEqExpr x y with
  | none =>
    return .continue
  | some (.decide b) =>
    return .done { expr := toExpr b }
  | some (.false p) =>
    let q := mkAppN (mkConst ``Nat.Simproc.beqFalseOfEqFalse) #[x, y, p]
    return .done  { expr := mkConst ``false, proof? := some q, cache := true }
  | some (.eq u v p) =>
    let q := mkAppN (mkConst ``Nat.Simproc.beqEqOfEqEq) #[x, y, u, v, p]
    return .visit { expr := mkBeqNat u v, proof? := some q, cache := true }
goal: Lean.Meta.Simp.Simproc

full_name: Nat.reduceBneDiff
code: builtin_simproc [simp, seval] reduceBneDiff ((_ : Nat) != _) := fun e => do
  unless e.isAppOfArity ``bne 4 do
    return .continue
  let x := e.appFn!.appArg!
  let y := e.appArg!
  match ← reduceNatEqExpr x y with
  | none =>
    return .continue
  | some (.decide b) =>
    return .done { expr := toExpr (!b) }
  | some (.false p) =>
    let q := mkAppN (mkConst ``Nat.Simproc.bneTrueOfEqFalse) #[x, y, p]
    return .done  { expr := mkConst ``true, proof? := some q, cache := true }
  | some (.eq u v p) =>
    let q := mkAppN (mkConst ``Nat.Simproc.bneEqOfEqEq) #[x, y, u, v, p]
    return .visit { expr := mkBneNat u v, proof? := some q, cache := true }
goal: Lean.Meta.Simp.Simproc

full_name: Nat.reduceLTLE
code: def reduceLTLE (nm : Name) (arity : Nat) (isLT : Bool) (e : Expr) : SimpM Step 
goal: Lean.Meta.SimpM Lean.Meta.Simp.Step

full_name: Nat.reduceLeDiff
code: builtin_simproc [simp, seval] reduceLeDiff ((_ : Nat) ≤ _) := reduceLTLE ``LE.le 4 false
goal: Lean.Meta.Simp.Simproc

full_name: Nat.reduceSubDiff
code: builtin_simproc [simp, seval] reduceSubDiff ((_ - _ : Nat)) := fun e => do
  unless e.isAppOfArity ``HSub.hSub 6 do
    return .continue
  let p := e.appFn!.appArg!
  let some pno ← NatOffset.fromExpr? p | return .continue
  let q := e.appArg!
  let some qno ← NatOffset.fromExpr? q | return .continue
  match pno, qno with
  | .const pn, .const qn =>
    -- Generate rfl proof  showing (p - q) = pn - qn
    let finExpr := toExpr (pn - qn)
    let finProof ← Meta.mkEqRefl finExpr
    return .done  { expr := finExpr, proof? := finProof, cache := true }
  | .offset pb po pn, .const n => do
    if pn ≤ n then
      let finExpr := if pn = n then pb else mkSubNat pb (toExpr (n - pn))
      let leProof ← mkOfDecideEqTrue (mkLENat po q)
      applySimprocConst finExpr ``Nat.Simproc.add_sub_le  #[pb, po, q, leProof]
    else
      let finExpr := mkAddNat pb (toExpr (pn - n))
      let geProof ← mkOfDecideEqTrue (mkGENat po q)
      applySimprocConst finExpr ``Nat.add_sub_assoc #[po, q, geProof, pb]
  | .const po, .offset nb no nn => do
      let finExpr := mkSubNat (toExpr (po - nn)) nb
      applySimprocConst finExpr ``Nat.Simproc.sub_add_eq_comm #[p, nb, no]
  | .offset pb po pn, .offset nb no nn => do
    if pn ≤ nn then
      let finExpr := mkSubNat pb (if pn = nn then nb else mkAddNat nb (toExpr (nn - pn)))
      let leProof ← mkOfDecideEqTrue (mkLENat po no)
      applySimprocConst finExpr ``Nat.Simproc.add_sub_add_le #[pb, nb, po, no, leProof]
    else
      let finExpr := mkSubNat (mkAddNat pb (toExpr (pn - nn))) nb
      let geProof ← mkOfDecideEqTrue (mkGENat po no)
      applySimprocConst finExpr ``Nat.Simproc.add_sub_add_ge #[pb, nb, po, no, geProof]
goal: Lean.Meta.Simp.Simproc