File: Mathlib/Tactic/NormNum/BigOperators.lean

full_name: Mathlib.Meta.Nat.UnifyZeroOrSuccResult.succ
code: /-- This represents the result of trying to determine whether the given expression `n : Q(ℕ)`
is either `zero` or `succ`. -/
inductive Nat.UnifyZeroOrSuccResult (n : Q(ℕ))
  /-- `n` unifies with `0` -/
  | zero (pf : $n =Q 0)
  /-- `n` unifies with `succ n'` for this specific `n'` -/
  | succ (n' : Q(ℕ)) (pf : $n =Q Nat.succ $n')
goal: Mathlib.Meta.Nat.UnifyZeroOrSuccResult n

full_name: Mathlib.Meta.Nat.UnifyZeroOrSuccResult
code: /-- This represents the result of trying to determine whether the given expression `n : Q(ℕ)`
is either `zero` or `succ`. -/
inductive Nat.UnifyZeroOrSuccResult (n : Q(ℕ))
  /-- `n` unifies with `0` -/
  | zero (pf : $n =Q 0)
  /-- `n` unifies with `succ n'` for this specific `n'` -/
  | succ (n' : Q(ℕ)) (pf : $n =Q Nat.succ $n')
goal: Type

full_name: Mathlib.Meta.Nat.UnifyZeroOrSuccResult.zero
code: /-- This represents the result of trying to determine whether the given expression `n : Q(ℕ)`
is either `zero` or `succ`. -/
inductive Nat.UnifyZeroOrSuccResult (n : Q(ℕ))
  /-- `n` unifies with `0` -/
  | zero (pf : $n =Q 0)
  /-- `n` unifies with `succ n'` for this specific `n'` -/
  | succ (n' : Q(ℕ)) (pf : $n =Q Nat.succ $n')
goal: Mathlib.Meta.Nat.UnifyZeroOrSuccResult n

full_name: Mathlib.Meta.Nat.unifyZeroOrSucc
code: /-- Determine whether the expression `n : Q(ℕ)` unifies with `0` or `Nat.succ n'`.

We do not use `norm_num` functionality because we want definitional equality,
not propositional equality, for use in dependent types.

Fails if neither of the options succeed.
-/
def Nat.unifyZeroOrSucc (n : Q(ℕ)) : MetaM (Nat.UnifyZeroOrSuccResult n) 
goal: Lean.MetaM (Mathlib.Meta.Nat.UnifyZeroOrSuccResult n)

full_name: Mathlib.Meta.List.ProveNilOrConsResult.nil
code: /-- This represents the result of trying to determine whether the given expression
`s : Q(List $α)` is either empty or consists of an element inserted into a strict subset. -/
inductive List.ProveNilOrConsResult {α : Q(Type u)} (s : Q(List $α))
  /-- The set is Nil. -/
  | nil (pf : Q($s = []))
  /-- The set equals `a` inserted into the strict subset `s'`. -/
  | cons (a : Q($α)) (s' : Q(List $α)) (pf : Q($s = List.cons $a $s'))
goal: Mathlib.Meta.List.ProveNilOrConsResult s

full_name: Mathlib.Meta.List.ProveNilOrConsResult
code: /-- This represents the result of trying to determine whether the given expression
`s : Q(List $α)` is either empty or consists of an element inserted into a strict subset. -/
inductive List.ProveNilOrConsResult {α : Q(Type u)} (s : Q(List $α))
  /-- The set is Nil. -/
  | nil (pf : Q($s = []))
  /-- The set equals `a` inserted into the strict subset `s'`. -/
  | cons (a : Q($α)) (s' : Q(List $α)) (pf : Q($s = List.cons $a $s'))
goal: Type

full_name: Mathlib.Meta.List.ProveNilOrConsResult.cons
code: /-- This represents the result of trying to determine whether the given expression
`s : Q(List $α)` is either empty or consists of an element inserted into a strict subset. -/
inductive List.ProveNilOrConsResult {α : Q(Type u)} (s : Q(List $α))
  /-- The set is Nil. -/
  | nil (pf : Q($s = []))
  /-- The set equals `a` inserted into the strict subset `s'`. -/
  | cons (a : Q($α)) (s' : Q(List $α)) (pf : Q($s = List.cons $a $s'))
goal: Mathlib.Meta.List.ProveNilOrConsResult s

full_name: Mathlib.Meta.List.ProveNilOrConsResult.uncheckedCast
code: /-- If `s` unifies with `t`, convert a result for `s` to a result for `t`.

If `s` does not unify with `t`, this results in a type-incorrect proof.
-/
def List.ProveNilOrConsResult.uncheckedCast {α : Q(Type u)} {β : Q(Type v)}
    (s : Q(List $α)) (t : Q(List $β)) :
    List.ProveNilOrConsResult s → List.ProveNilOrConsResult t
  
goal: Mathlib.Meta.List.ProveNilOrConsResult s → Mathlib.Meta.List.ProveNilOrConsResult t

full_name: Mathlib.Meta.List.ProveNilOrConsResult.eq_trans
code: /-- If `s = t` and we can get the result for `t`, then we can get the result for `s`.
-/
def List.ProveNilOrConsResult.eq_trans {α : Q(Type u)} {s t : Q(List $α)}
    (eq : Q($s = $t)) :
    List.ProveNilOrConsResult t → List.ProveNilOrConsResult s
  
goal: Mathlib.Meta.List.ProveNilOrConsResult t → Mathlib.Meta.List.ProveNilOrConsResult s

full_name: Mathlib.Meta.List.range_zero'
code: lemma List.range_zero' {n : ℕ} (pn : NormNum.IsNat n 0) :
    List.range n = [] 
goal: List.range n = []

full_name: Mathlib.Meta.List.range_succ_eq_map'
code: lemma List.range_succ_eq_map' {n nn n' : ℕ} (pn : NormNum.IsNat n nn) (pn' : nn = Nat.succ n') :
    List.range n = 0 :: List.map Nat.succ (List.range n') 
goal: List.range n = 0 :: List.map Nat.succ (List.range n')

full_name: Mathlib.Meta.List.proveNilOrCons
code: /-- Either show the expression `s : Q(List α)` is Nil, or remove one element from it.

Fails if we cannot determine which of the alternatives apply to the expression.
-/
partial def List.proveNilOrCons {u : Level} {α : Q(Type u)} (s : Q(List $α)) :
    MetaM (List.ProveNilOrConsResult s) 
goal: Lean.MetaM (Mathlib.Meta.List.ProveNilOrConsResult s)

full_name: Mathlib.Meta.Multiset.ProveZeroOrConsResult.cons
code: /-- This represents the result of trying to determine whether the given expression
`s : Q(Multiset $α)` is either empty or consists of an element inserted into a strict subset. -/
inductive Multiset.ProveZeroOrConsResult {α : Q(Type u)} (s : Q(Multiset $α))
  /-- The set is zero. -/
  | zero (pf : Q($s = 0))
  /-- The set equals `a` inserted into the strict subset `s'`. -/
  | cons (a : Q($α)) (s' : Q(Multiset $α)) (pf : Q($s = Multiset.cons $a $s'))
goal: Mathlib.Meta.Multiset.ProveZeroOrConsResult s

full_name: Mathlib.Meta.Multiset.ProveZeroOrConsResult
code: /-- This represents the result of trying to determine whether the given expression
`s : Q(Multiset $α)` is either empty or consists of an element inserted into a strict subset. -/
inductive Multiset.ProveZeroOrConsResult {α : Q(Type u)} (s : Q(Multiset $α))
  /-- The set is zero. -/
  | zero (pf : Q($s = 0))
  /-- The set equals `a` inserted into the strict subset `s'`. -/
  | cons (a : Q($α)) (s' : Q(Multiset $α)) (pf : Q($s = Multiset.cons $a $s'))
goal: Type

full_name: Mathlib.Meta.Multiset.ProveZeroOrConsResult.zero
code: /-- This represents the result of trying to determine whether the given expression
`s : Q(Multiset $α)` is either empty or consists of an element inserted into a strict subset. -/
inductive Multiset.ProveZeroOrConsResult {α : Q(Type u)} (s : Q(Multiset $α))
  /-- The set is zero. -/
  | zero (pf : Q($s = 0))
  /-- The set equals `a` inserted into the strict subset `s'`. -/
  | cons (a : Q($α)) (s' : Q(Multiset $α)) (pf : Q($s = Multiset.cons $a $s'))
goal: Mathlib.Meta.Multiset.ProveZeroOrConsResult s

full_name: Mathlib.Meta.Multiset.ProveZeroOrConsResult.uncheckedCast
code: /-- If `s` unifies with `t`, convert a result for `s` to a result for `t`.

If `s` does not unify with `t`, this results in a type-incorrect proof.
-/
def Multiset.ProveZeroOrConsResult.uncheckedCast {α : Q(Type u)} {β : Q(Type v)}
    (s : Q(Multiset $α)) (t : Q(Multiset $β)) :
    Multiset.ProveZeroOrConsResult s → Multiset.ProveZeroOrConsResult t
  
goal: Mathlib.Meta.Multiset.ProveZeroOrConsResult s → Mathlib.Meta.Multiset.ProveZeroOrConsResult t

full_name: Mathlib.Meta.Multiset.ProveZeroOrConsResult.eq_trans
code: /-- If `s = t` and we can get the result for `t`, then we can get the result for `s`.
-/
def Multiset.ProveZeroOrConsResult.eq_trans {α : Q(Type u)} {s t : Q(Multiset $α)}
    (eq : Q($s = $t)) :
    Multiset.ProveZeroOrConsResult t → Multiset.ProveZeroOrConsResult s
  
goal: Mathlib.Meta.Multiset.ProveZeroOrConsResult t → Mathlib.Meta.Multiset.ProveZeroOrConsResult s

full_name: Mathlib.Meta.Multiset.insert_eq_cons
code: lemma Multiset.insert_eq_cons {α : Type*} (a : α) (s : Multiset α) :
    insert a s = Multiset.cons a s 
goal: insert a s = a ::ₘ s

full_name: Mathlib.Meta.Multiset.range_zero'
code: lemma Multiset.range_zero' {n : ℕ} (pn : NormNum.IsNat n 0) :
    Multiset.range n = 0 
goal: Multiset.range n = 0

full_name: Mathlib.Meta.Multiset.range_succ'
code: lemma Multiset.range_succ' {n nn n' : ℕ} (pn : NormNum.IsNat n nn) (pn' : nn = Nat.succ n') :
    Multiset.range n = n' ::ₘ Multiset.range n' 
goal: Multiset.range n = n' ::ₘ Multiset.range n'

full_name: Mathlib.Meta.Multiset.proveZeroOrCons
code: /-- Either show the expression `s : Q(Multiset α)` is Zero, or remove one element from it.

Fails if we cannot determine which of the alternatives apply to the expression.
-/
partial def Multiset.proveZeroOrCons {α : Q(Type u)} (s : Q(Multiset $α)) :
    MetaM (Multiset.ProveZeroOrConsResult s) 
goal: Lean.MetaM (Mathlib.Meta.Multiset.ProveZeroOrConsResult s)

full_name: Mathlib.Meta.Finset.ProveEmptyOrConsResult.cons
code: /-- This represents the result of trying to determine whether the given expression
`s : Q(Finset $α)` is either empty or consists of an element inserted into a strict subset. -/
inductive Finset.ProveEmptyOrConsResult {α : Q(Type u)} (s : Q(Finset $α))
  /-- The set is empty. -/
  | empty (pf : Q($s = ∅))
  /-- The set equals `a` inserted into the strict subset `s'`. -/
  | cons (a : Q($α)) (s' : Q(Finset $α)) (h : Q($a ∉ $s')) (pf : Q($s = Finset.cons $a $s' $h))
goal: Mathlib.Meta.Finset.ProveEmptyOrConsResult s

full_name: Mathlib.Meta.Finset.ProveEmptyOrConsResult.empty
code: /-- This represents the result of trying to determine whether the given expression
`s : Q(Finset $α)` is either empty or consists of an element inserted into a strict subset. -/
inductive Finset.ProveEmptyOrConsResult {α : Q(Type u)} (s : Q(Finset $α))
  /-- The set is empty. -/
  | empty (pf : Q($s = ∅))
  /-- The set equals `a` inserted into the strict subset `s'`. -/
  | cons (a : Q($α)) (s' : Q(Finset $α)) (h : Q($a ∉ $s')) (pf : Q($s = Finset.cons $a $s' $h))
goal: Mathlib.Meta.Finset.ProveEmptyOrConsResult s

full_name: Mathlib.Meta.Finset.ProveEmptyOrConsResult
code: /-- This represents the result of trying to determine whether the given expression
`s : Q(Finset $α)` is either empty or consists of an element inserted into a strict subset. -/
inductive Finset.ProveEmptyOrConsResult {α : Q(Type u)} (s : Q(Finset $α))
  /-- The set is empty. -/
  | empty (pf : Q($s = ∅))
  /-- The set equals `a` inserted into the strict subset `s'`. -/
  | cons (a : Q($α)) (s' : Q(Finset $α)) (h : Q($a ∉ $s')) (pf : Q($s = Finset.cons $a $s' $h))
goal: Type

full_name: Mathlib.Meta.Finset.ProveEmptyOrConsResult.uncheckedCast
code: /-- If `s` unifies with `t`, convert a result for `s` to a result for `t`.

If `s` does not unify with `t`, this results in a type-incorrect proof.
-/
def Finset.ProveEmptyOrConsResult.uncheckedCast {α : Q(Type u)} {β : Q(Type v)}
    (s : Q(Finset $α)) (t : Q(Finset $β)) :
    Finset.ProveEmptyOrConsResult s → Finset.ProveEmptyOrConsResult t
  
goal: Mathlib.Meta.Finset.ProveEmptyOrConsResult s → Mathlib.Meta.Finset.ProveEmptyOrConsResult t

full_name: Mathlib.Meta.Finset.ProveEmptyOrConsResult.eq_trans
code: /-- If `s = t` and we can get the result for `t`, then we can get the result for `s`.
-/
def Finset.ProveEmptyOrConsResult.eq_trans {α : Q(Type u)} {s t : Q(Finset $α)}
    (eq : Q($s = $t)) :
    Finset.ProveEmptyOrConsResult t → Finset.ProveEmptyOrConsResult s
  
goal: Mathlib.Meta.Finset.ProveEmptyOrConsResult t → Mathlib.Meta.Finset.ProveEmptyOrConsResult s

full_name: Mathlib.Meta.Finset.insert_eq_cons
code: lemma Finset.insert_eq_cons {α : Type*} [DecidableEq α] (a : α) (s : Finset α) (h : a ∉ s) :
    insert a s = Finset.cons a s h 
goal: insert a s = Finset.cons a s h

full_name: Mathlib.Meta.Finset.range_zero'
code: lemma Finset.range_zero' {n : ℕ} (pn : NormNum.IsNat n 0) :
    Finset.range n = {} 
goal: Finset.range n = ∅

full_name: Mathlib.Meta.Finset.range_succ'
code: lemma Finset.range_succ' {n nn n' : ℕ} (pn : NormNum.IsNat n nn) (pn' : nn = Nat.succ n') :
    Finset.range n = Finset.cons n' (Finset.range n') Finset.not_mem_range_self 
goal: Finset.range n = Finset.cons n' (Finset.range n') ⋯

full_name: Mathlib.Meta.Finset.univ_eq_elems
code: lemma Finset.univ_eq_elems {α : Type*} [Fintype α] (elems : Finset α)
    (complete : ∀ x : α, x ∈ elems) :
    Finset.univ = elems 
goal: Finset.univ = elems

full_name: Mathlib.Meta.Finset.proveEmptyOrCons
code: /-- Either show the expression `s : Q(Finset α)` is empty, or remove one element from it.

Fails if we cannot determine which of the alternatives apply to the expression.
-/
partial def Finset.proveEmptyOrCons {α : Q(Type u)} (s : Q(Finset $α)) :
    MetaM (ProveEmptyOrConsResult s) 
goal: Lean.MetaM (Mathlib.Meta.Finset.ProveEmptyOrConsResult s)

full_name: Mathlib.Meta.NormNum.Result.eq_trans
code: /-- If `a = b` and we can evaluate `b`, then we can evaluate `a`. -/
def Result.eq_trans {α : Q(Type u)} {a b : Q($α)} (eq : Q($a = $b)) : Result b → Result a
  
goal: Mathlib.Meta.NormNum.Result b → Mathlib.Meta.NormNum.Result a

full_name: Mathlib.Meta.NormNum.Finset.sum_empty
code: protected lemma Finset.sum_empty {β α : Type*} [CommSemiring β] (f : α → β) :
    IsNat (Finset.sum ∅ f) 0 
goal: Mathlib.Meta.NormNum.IsNat (∅.sum f) 0

full_name: Mathlib.Meta.NormNum.Finset.prod_empty
code: protected lemma Finset.prod_empty {β α : Type*} [CommSemiring β] (f : α → β) :
    IsNat (Finset.prod ∅ f) 1 
goal: Mathlib.Meta.NormNum.IsNat (∅.prod f) 1

full_name: Mathlib.Meta.NormNum.evalFinsetBigop
code: /-- Evaluate a big operator applied to a finset by repeating `proveEmptyOrCons` until
we exhaust all elements of the set. -/
partial def evalFinsetBigop {α : Q(Type u)} {β : Q(Type v)}
    (op : Q(Finset $α → ($α → $β) → $β))
    (f : Q($α → $β))
    (res_empty : Result q($op Finset.empty $f))
    (res_cons : {a : Q($α)} -> {s' : Q(Finset $α)} -> {h : Q($a ∉ $s')} ->
      Result (α := β) q($f $a) -> Result (α := β) q($op $s' $f) ->
      MetaM (Result (α := β) q($op (Finset.cons $a $s' $h) $f))) :
    (s : Q(Finset $α)) → MetaM (Result (α := β) q($op $s $f))
  
goal: Lean.MetaM (Mathlib.Meta.NormNum.Result q(«$op» «$s» «$f»))

full_name: Mathlib.Meta.NormNum.evalFinsetProd
code: /-- `norm_num` plugin for evaluating products of finsets.

If your finset is not supported, you can add it to the match in `Finset.proveEmptyOrCons`.
-/
@[norm_num @Finset.prod _ _ _ _ _]
partial def evalFinsetProd : NormNumExt 
goal: Mathlib.Meta.NormNum.NormNumExt

full_name: Mathlib.Meta.NormNum.evalFinsetSum
code: /-- `norm_num` plugin for evaluating sums of finsets.

If your finset is not supported, you can add it to the match in `Finset.proveEmptyOrCons`.
-/
@[norm_num @Finset.sum _ _ _ _ _]
partial def evalFinsetSum : NormNumExt 
goal: Mathlib.Meta.NormNum.NormNumExt