File: Mathlib/Tactic/ModCases.lean

full_name: Mathlib.Tactic.ModCases.IntMod.OnModCases
code: /--
`OnModCases n a lb p` represents a partial proof by cases that
there exists `0 ≤ z < n` such that `a ≡ z (mod n)`.
It asserts that if `∃ z, lb ≤ z < n ∧ a ≡ z (mod n)` holds, then `p`
(where `p` is the current goal).
-/
def OnModCases (n : ℕ) (a : ℤ) (lb : ℕ) (p : Sort*) 
goal: Sort (imax 1 u_1)

full_name: Mathlib.Tactic.ModCases.IntMod.onModCases_start
code: /--
The first theorem we apply says that `∃ z, 0 ≤ z < n ∧ a ≡ z (mod n)`.
The actual mathematical content of the proof is here.
-/
@[inline] def onModCases_start (p : Sort*) (a : ℤ) (n : ℕ) (hn : Nat.ble 1 n = true)
    (H : OnModCases n a (nat_lit 0) p) : p 
goal: p

full_name: Mathlib.Tactic.ModCases.IntMod.onModCases_stop
code: /--
The end point is that once we have reduced to `∃ z, n ≤ z < n ∧ a ≡ z (mod n)`
there are no more cases to consider.
-/
@[inline] def onModCases_stop (p : Sort*) (n : ℕ) (a : ℤ) : OnModCases n a n p 
goal: Mathlib.Tactic.ModCases.IntMod.OnModCases n a n p

full_name: Mathlib.Tactic.ModCases.IntMod.onModCases_succ
code: /--
The successor case decomposes `∃ z, b ≤ z < n ∧ a ≡ z (mod n)` into
`a ≡ b (mod n) ∨ ∃ z, b+1 ≤ z < n ∧ a ≡ z (mod n)`,
and the `a ≡ b (mod n) → p` case becomes a subgoal.
-/
@[inline] def onModCases_succ {p : Sort*} {n : ℕ} {a : ℤ} (b : ℕ)
    (h : a ≡ OfNat.ofNat b [ZMOD OfNat.ofNat n] → p) (H : OnModCases n a (Nat.add b 1) p) :
    OnModCases n a b p 
goal: Mathlib.Tactic.ModCases.IntMod.OnModCases n a b p

full_name: Mathlib.Tactic.ModCases.IntMod.proveOnModCases
code: /--
Proves an expression of the form `OnModCases n a b p` where `n` and `b` are raw nat literals
and `b ≤ n`. Returns the list of subgoals `?gi : a ≡ i [ZMOD n] → p`.
-/
partial def proveOnModCases {u : Level} (n : Q(ℕ)) (a : Q(ℤ)) (b : Q(ℕ)) (p : Q(Sort u)) :
    MetaM (Q(OnModCases $n $a $b $p) × List MVarId) 
goal: Lean.MetaM (Q(Mathlib.Tactic.ModCases.IntMod.OnModCases «$n» «$a» «$b» «$p») × List Lean.MVarId)

full_name: Mathlib.Tactic.ModCases.IntMod.modCases
code: /--
Int case of `mod_cases h : e % n`.
-/
def modCases (h : TSyntax `Lean.binderIdent) (e : Q(ℤ)) (n : ℕ) : TacticM Unit 
goal: Lean.Elab.Tactic.TacticM Unit

full_name: Mathlib.Tactic.ModCases.NatMod.OnModCases
code: /--
`OnModCases n a lb p` represents a partial proof by cases that
there exists `0 ≤ m < n` such that `a ≡ m (mod n)`.
It asserts that if `∃ m, lb ≤ m < n ∧ a ≡ m (mod n)` holds, then `p`
(where `p` is the current goal).
-/
def OnModCases (n : ℕ) (a : ℕ) (lb : ℕ) (p : Sort _) 
goal: Sort (imax 1 u_1)

full_name: Mathlib.Tactic.ModCases.NatMod.onModCases_start
code: /--
The first theorem we apply says that `∃ m, 0 ≤ m < n ∧ a ≡ m (mod n)`.
The actual mathematical content of the proof is here.
-/
@[inline] def onModCases_start (p : Sort _) (a : ℕ) (n : ℕ) (hn : Nat.ble 1 n = true)
    (H : OnModCases n a (nat_lit 0) p) : p 
goal: p

full_name: Mathlib.Tactic.ModCases.NatMod.onModCases_stop
code: /--
The end point is that once we have reduced to `∃ m, n ≤ m < n ∧ a ≡ m (mod n)`
there are no more cases to consider.
-/
@[inline] def onModCases_stop (p : Sort _) (n : ℕ) (a : ℕ) : OnModCases n a n p 
goal: Mathlib.Tactic.ModCases.NatMod.OnModCases n a n p

full_name: Mathlib.Tactic.ModCases.NatMod.onModCases_succ
code: /--
The successor case decomposes `∃ m, b ≤ m < n ∧ a ≡ m (mod n)` into
`a ≡ b (mod n) ∨ ∃ m, b+1 ≤ m < n ∧ a ≡ m (mod n)`,
and the `a ≡ b (mod n) → p` case becomes a subgoal.
-/
@[inline] def onModCases_succ {p : Sort _} {n : ℕ} {a : ℕ} (b : ℕ)
    (h : a ≡ b [MOD n] → p) (H : OnModCases n a (Nat.add b 1) p) :
    OnModCases n a b p 
goal: Mathlib.Tactic.ModCases.NatMod.OnModCases n a b p

full_name: Mathlib.Tactic.ModCases.NatMod.proveOnModCases
code: /--
Proves an expression of the form `OnModCases n a b p` where `n` and `b` are raw nat literals
and `b ≤ n`. Returns the list of subgoals `?gi : a ≡ i [MOD n] → p`.
-/
partial def proveOnModCases {u : Level} (n : Q(ℕ)) (a : Q(ℕ)) (b : Q(ℕ)) (p : Q(Sort u)) :
    MetaM (Q(OnModCases $n $a $b $p) × List MVarId) 
goal: Lean.MetaM (Q(Mathlib.Tactic.ModCases.NatMod.OnModCases «$n» «$a» «$b» «$p») × List Lean.MVarId)

full_name: Mathlib.Tactic.ModCases.NatMod.modCases
code: /--
Nat case of `mod_cases h : e % n`.
-/
def modCases (h : TSyntax `Lean.binderIdent) (e : Q(ℕ)) (n : ℕ) : TacticM Unit 
goal: Lean.Elab.Tactic.TacticM Unit

full_name: Mathlib.Tactic.ModCases.«tacticMod_cases_:_%_»
code: /--
* The tactic `mod_cases h : e % 3` will perform a case disjunction on `e`.
  If `e : ℤ`, then it will yield subgoals containing the assumptions
  `h : e ≡ 0 [ZMOD 3]`, `h : e ≡ 1 [ZMOD 3]`, `h : e ≡ 2 [ZMOD 3]`
  respectively. If `e : ℕ` instead, then it works similarly, except with
  `[MOD 3]` instead of `[ZMOD 3]`.
* In general, `mod_cases h : e % n` works
  when `n` is a positive numeral and `e` is an expression of type `ℕ` or `ℤ`.
* If `h` is omitted as in `mod_cases e % n`, it will be default-named `H`.
-/
syntax "mod_cases " (atomic(binderIdent ":"))? term:71 " % " num : tactic
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.ModCases.«_aux_Mathlib_Tactic_ModCases___elabRules_Mathlib_Tactic_ModCases_tacticMod_cases_:_%__1»
code: elab_rules : tactic
  | `(tactic| mod_cases $[$h :]? $e % $n) => do
    let n := n.getNat
    if n == 0 then Elab.throwUnsupportedSyntax
    let h := h.getD (← `(binderIdent| _))
    withMainContext do
    let e ← Tactic.elabTerm e none
    let α : Q(Type) ← inferType e
    match α with
    | ~q(ℤ) => IntMod.modCases h e n
    | ~q(ℕ) => NatMod.modCases h e n
    | _ => throwError "mod_cases only works with Int and Nat"
goal: Lean.Elab.Tactic.Tactic