File: Mathlib/Tactic/CancelDenoms/Core.lean

full_name: initFn._@.Mathlib.Tactic.CancelDenoms.Core._hyg.5
code: initialize registerTraceClass `CancelDenoms
goal: IO Unit

full_name: CancelDenoms.mul_subst
code: theorem mul_subst {α} [CommRing α] {n1 n2 k e1 e2 t1 t2 : α}
    (h1 : n1 * e1 = t1) (h2 : n2 * e2 = t2) (h3 : n1 * n2 = k) : k * (e1 * e2) = t1 * t2 
goal: k * (e1 * e2) = t1 * t2

full_name: CancelDenoms.div_subst
code: theorem div_subst {α} [Field α] {n1 n2 k e1 e2 t1 : α}
    (h1 : n1 * e1 = t1) (h2 : n2 / e2 = 1) (h3 : n1 * n2 = k) : k * (e1 / e2) = t1 
goal: k * (e1 / e2) = t1

full_name: CancelDenoms.cancel_factors_eq_div
code: theorem cancel_factors_eq_div {α} [Field α] {n e e' : α}
    (h : n * e = e') (h2 : n ≠ 0) : e = e' / n 
goal: e = e' / n

full_name: CancelDenoms.add_subst
code: theorem add_subst {α} [Ring α] {n e1 e2 t1 t2 : α} (h1 : n * e1 = t1) (h2 : n * e2 = t2) :
    n * (e1 + e2) = t1 + t2 
goal: n * (e1 + e2) = t1 + t2

full_name: CancelDenoms.sub_subst
code: theorem sub_subst {α} [Ring α] {n e1 e2 t1 t2 : α} (h1 : n * e1 = t1) (h2 : n * e2 = t2) :
    n * (e1 - e2) = t1 - t2 
goal: n * (e1 - e2) = t1 - t2

full_name: CancelDenoms.neg_subst
code: theorem neg_subst {α} [Ring α] {n e t : α} (h1 : n * e = t) : n * -e = -t 
goal: n * -e = -t

full_name: CancelDenoms.pow_subst
code: theorem pow_subst {α} [CommRing α] {n e1 t1 k l : α} {e2 : ℕ}
    (h1 : n * e1 = t1) (h2 : l * n ^ e2 = k) : k * (e1 ^ e2) = l * t1 ^ e2 
goal: k * e1 ^ e2 = l * t1 ^ e2

full_name: CancelDenoms.inv_subst
code: theorem inv_subst {α} [Field α] {n k e : α} (h2 : e ≠ 0) (h3 : n * e = k) :
    k * (e ⁻¹) = n 
goal: k * e⁻¹ = n

full_name: CancelDenoms.cancel_factors_lt
code: theorem cancel_factors_lt {α} [LinearOrderedField α] {a b ad bd a' b' gcd : α}
    (ha : ad * a = a') (hb : bd * b = b') (had : 0 < ad) (hbd : 0 < bd) (hgcd : 0 < gcd) :
    (a < b) = (1 / gcd * (bd * a') < 1 / gcd * (ad * b')) 
goal: (a < b) = (1 / gcd * (bd * a') < 1 / gcd * (ad * b'))

full_name: CancelDenoms.cancel_factors_le
code: theorem cancel_factors_le {α} [LinearOrderedField α] {a b ad bd a' b' gcd : α}
    (ha : ad * a = a') (hb : bd * b = b') (had : 0 < ad) (hbd : 0 < bd) (hgcd : 0 < gcd) :
    (a ≤ b) = (1 / gcd * (bd * a') ≤ 1 / gcd * (ad * b')) 
goal: (a ≤ b) = (1 / gcd * (bd * a') ≤ 1 / gcd * (ad * b'))

full_name: CancelDenoms.cancel_factors_eq
code: theorem cancel_factors_eq {α} [Field α] {a b ad bd a' b' gcd : α} (ha : ad * a = a')
    (hb : bd * b = b') (had : ad ≠ 0) (hbd : bd ≠ 0) (hgcd : gcd ≠ 0) :
    (a = b) = (1 / gcd * (bd * a') = 1 / gcd * (ad * b')) 
goal: (a = b) = (1 / gcd * (bd * a') = 1 / gcd * (ad * b'))

full_name: CancelDenoms.cancel_factors_ne
code: theorem cancel_factors_ne {α} [Field α] {a b ad bd a' b' gcd : α} (ha : ad * a = a')
    (hb : bd * b = b') (had : ad ≠ 0) (hbd : bd ≠ 0) (hgcd : gcd ≠ 0) :
    (a ≠ b) = (1 / gcd * (bd * a') ≠ 1 / gcd * (ad * b')) 
goal: (a ≠ b) = (1 / gcd * (bd * a') ≠ 1 / gcd * (ad * b'))

full_name: CancelDenoms.findCancelFactor
code: /--
`findCancelFactor e` produces a natural number `n`, such that multiplying `e` by `n` will
be able to cancel all the numeric denominators in `e`. The returned `Tree` describes how to
distribute the value `n` over products inside `e`.
-/
partial def findCancelFactor (e : Expr) : ℕ × Tree ℕ 
goal: ℕ × Tree ℕ

full_name: CancelDenoms.synthesizeUsingNormNum
code: def synthesizeUsingNormNum (type : Q(Prop)) : MetaM Q($type) 
goal: Lean.MetaM Q(«$type»)

full_name: CancelDenoms.CancelResult.cancelled
code: /-- `CancelResult mα e v'` provies a value for `v * e` where the denominators have been cancelled.
-/
structure CancelResult {u : Level} {α : Q(Type u)} (mα : Q(Mul $α)) (e : Q($α)) (v : Q($α)) where
  /-- An expression with denominators cancelled. -/
  cancelled : Q($α)
  /-- The proof that `cancelled` is valid. -/
  pf : Q($v * $e = $cancelled)
goal: Q(«$α»)

full_name: CancelDenoms.CancelResult
code: /-- `CancelResult mα e v'` provies a value for `v * e` where the denominators have been cancelled.
-/
structure CancelResult {u : Level} {α : Q(Type u)} (mα : Q(Mul $α)) (e : Q($α)) (v : Q($α)) where
  /-- An expression with denominators cancelled. -/
  cancelled : Q($α)
  /-- The proof that `cancelled` is valid. -/
  pf : Q($v * $e = $cancelled)
goal: Type

full_name: CancelDenoms.CancelResult.pf
code: /-- `CancelResult mα e v'` provies a value for `v * e` where the denominators have been cancelled.
-/
structure CancelResult {u : Level} {α : Q(Type u)} (mα : Q(Mul $α)) (e : Q($α)) (v : Q($α)) where
  /-- An expression with denominators cancelled. -/
  cancelled : Q($α)
  /-- The proof that `cancelled` is valid. -/
  pf : Q($v * $e = $cancelled)
goal: Q(«$v» * «$e» = unknown_1)

full_name: CancelDenoms.mkProdPrf
code: /--
`mkProdPrf α sα v v' tr e` produces a proof of `v'*e = e'`, where numeric denominators have been
canceled in `e'`, distributing `v` proportionally according to the tree `tr` computed
by `findCancelFactor`.

The `v'` argument is a numeral expression corresponding to `v`, which we need in order to state
the return type accurately.
-/
partial def mkProdPrf {u : Level} (α : Q(Type u)) (sα : Q(Field $α)) (v : ℕ) (v' : Q($α))
    (t : Tree ℕ) (e : Q($α)) : MetaM (CancelResult q(inferInstance) e v') 
goal: Lean.MetaM (CancelDenoms.CancelResult q(inferInstance) e v')

full_name: CancelDenoms.deriveThms
code: /-- Theorems to get expression into a form that `findCancelFactor` and `mkProdPrf`
can more easily handle. These are important for dividing by rationals and negative integers. -/
def deriveThms : List Name 
goal: List Lean.Name

full_name: CancelDenoms.derive_trans
code: /-- Helper lemma to chain together a `simp` proof and the result of `mkProdPrf`. -/
theorem derive_trans {α} [Mul α] {a b c d : α} (h : a = b) (h' : c * b = d) : c * a = d 
goal: c * a = d

full_name: CancelDenoms.derive
code: /--
Given `e`, a term with rational division, produces a natural number `n` and a proof of `n*e = e'`,
where `e'` has no division. Assumes "well-behaved" division.
-/
def derive (e : Expr) : MetaM (ℕ × Expr) 
goal: Lean.MetaM (ℕ × Lean.Expr)

full_name: CancelDenoms.findCompLemma
code: /--
`findCompLemma e` arranges `e` in the form `lhs R rhs`, where `R ∈ {<, ≤, =, ≠}`, and returns
`lhs`, `rhs`, the `cancel_factors` lemma corresponding to `R`, and a boolean indicating whether
`R` involves the order (i.e. `<` and `≤`) or not (i.e. `=` and `≠`).
In the case of `LT`, `LE`, `GE`, and `GT` an order on the type is needed, in the last case
it is not, the final component of the return value tracks this.
-/
def findCompLemma (e : Expr) : MetaM (Option (Expr × Expr × Name × Bool)) 
goal: Lean.MetaM (Option (Lean.Expr × Lean.Expr × Lean.Name × Bool))

full_name: CancelDenoms.cancelDenominatorsInType
code: /--
`cancelDenominatorsInType h` assumes that `h` is of the form `lhs R rhs`,
where `R ∈ {<, ≤, =, ≠, ≥, >}`.
It produces an Expression `h'` of the form `lhs' R rhs'` and a proof that `h = h'`.
Numeric denominators have been canceled in `lhs'` and `rhs'`.
-/
def cancelDenominatorsInType (h : Expr) : MetaM (Expr × Expr) 
goal: Lean.MetaM (Lean.Expr × Lean.Expr)

full_name: cancelDenoms
code: /--
`cancel_denoms` attempts to remove numerals from the denominators of fractions.
It works on propositions that are field-valued inequalities.

```lean
variable [LinearOrderedField α] (a b c : α)

example (h : a / 5 + b / 4 < c) : 4*a + 5*b < 20*c := by
  cancel_denoms at h
  exact h

example (h : a > 0) : a / 5 > 0 := by
  cancel_denoms
  exact h
```
-/
syntax (name := cancelDenoms) "cancel_denoms" (location)? : tactic
goal: Lean.ParserDescr

full_name: cancelDenominatorsAt
code: def cancelDenominatorsAt (fvar : FVarId) : TacticM Unit 
goal: Lean.Elab.Tactic.TacticM Unit

full_name: cancelDenominatorsTarget
code: def cancelDenominatorsTarget : TacticM Unit 
goal: Lean.Elab.Tactic.TacticM Unit

full_name: cancelDenominators
code: def cancelDenominators (loc : Location) : TacticM Unit 
goal: Lean.Elab.Tactic.TacticM Unit

full_name: tacticCancel_denoms_
code: elab "cancel_denoms" loc?:(location)? : tactic => do
  cancelDenominators (expandOptLocation (Lean.mkOptionalNode loc?))
  Lean.Elab.Tactic.evalTactic (← `(tactic| try norm_num [← mul_assoc] $[$loc?]?))
goal: Lean.ParserDescr

full_name: _aux_Mathlib_Tactic_CancelDenoms_Core___elabRules_tacticCancel_denoms__1
code: elab "cancel_denoms" loc?:(location)? : tactic => do
  cancelDenominators (expandOptLocation (Lean.mkOptionalNode loc?))
  Lean.Elab.Tactic.evalTactic (← `(tactic| try norm_num [← mul_assoc] $[$loc?]?))
goal: Lean.Elab.Tactic.Tactic