ring tactic #
A tactic for solving equations in commutative (semi)rings, where the exponents can also contain variables. Based on http://www.cs.ru.nl/~freek/courses/tt-2014/read/10.1.1.61.3041.pdf .
More precisely, expressions of the following form are supported:
- constants (non-negative integers)
- variables
- coefficients (any rational number, embedded into the (semi)ring)
- addition of expressions
- multiplication of expressions (
a * b) - scalar multiplication of expressions (
n • a; the multiplier must have typeℕorℤ) - exponentiation of expressions (the exponent must have type
ℕ) - subtraction and negation of expressions (if the base is a full ring)
The extension to exponents means that something like 2 * 2^n * b = b * 2^(n+1) can be proved,
even though it is not strictly speaking an equation in the language of commutative rings.
Implementation notes #
The basic approach to prove equalities is to normalise both sides and check for equality.
We use Mathlib.Tactic.Ring.Common to implement the normal forms and normalization procedure.
This file defines the evaluation of basic operations such as addition and multipication of the
rational coefficients as embedded inside the (semi)ring. This is done using norm_num.
It further implements the core ring1 tactic.
Caveats and future work #
The normalized form of an expression is the one that is useful for the tactic,
but not as nice to read. To remedy this, the user-facing normalization calls ringNFCore.
Subtraction cancels out identical terms, but division does not.
That is: a - a = 0 := by ring solves the goal,
but a / a := 1 by ring doesn't.
Note that 0 / 0 is generally defined to be 0,
so division cancelling out is not true in general.
Multiplication of powers can be simplified a little bit further:
2 ^ n * 2 ^ n = 4 ^ n := by ring could be implemented
in a similar way that 2 * a + 2 * a = 4 * a := by ring already works.
This feature wasn't needed yet, so it's not implemented yet.
Tags #
ring, semiring, exponent, power
ExBase BaseType sα e stores the structure of a normalized expression e, which appears
as the base of an exponent expression e^n. The sum constructor is only used when the exponent
n is not a constant.
Equations
Instances For
ExProd BaseType sα e stores the structure of a normalized monomial expression e.
A monomial here is a product of powers of ExBase expressions, terminated by a (nonzero) constant
coefficient. The data of the constant coefficient is stored in the BaseType.
Equations
Instances For
ExSum BaseType sα e stores the structure of a normalized polynomial expression e, which is
a sum of monomials.
Equations
Instances For
Constructs the expression corresponding to .const n.
(The .const constructor does not check that the expression is correct.)
Instances For
Constructs the expression corresponding to .const (-n).
(The .const constructor does not check that the expression is correct.)
Instances For
Constructs the expression corresponding to .const q h for q = n / d
and h a proof that (d : α) ≠ 0.
(The .const constructor does not check that the expression is correct.)
Equations
- Mathlib.Tactic.Ring.ExProd.mkNNRat sα x✝ q n d h = ⟨q(NNRat.rawCast «$n» «$d»), Mathlib.Tactic.Ring.Common.ExProd.const { value := q, hyp := some h }⟩
Instances For
Constructs the expression corresponding to .const q h for q = -(n / d)
and h a proof that (d : α) ≠ 0.
(The .const constructor does not check that the expression is correct.)
Equations
- Mathlib.Tactic.Ring.ExProd.mkNegNNRat sα x✝ q n d h = ⟨q(Rat.rawCast (Int.negOfNat «$n») «$d»), Mathlib.Tactic.Ring.Common.ExProd.const { value := q, hyp := some h }⟩
Instances For
Converts a proof by norm_num that e is a numeral, into a normalization as a monomial:
e = 0ifnorm_numreturnsIsNat e 0e = Nat.rawCast n + 0ifnorm_numreturnsIsNat e ne = Int.rawCast n + 0ifnorm_numreturnsIsInt e ne = NNRat.rawCast n d + 0ifnorm_numreturnsIsNNRat e n de = Rat.rawCast n d + 0ifnorm_numreturnsIsRat e n d
Instances For
Scalar multiplication by ℕ #
Applies Nat.cast to a nat polynomial to produce a polynomial in α.
- An atom
ecauses↑eto be allocated as a new atom. - A sum delegates to
ExSum.evalNatCast.
Applies Nat.cast to a nat monomial to produce a monomial in α.
↑c = cifcis a numeric literal↑(a ^ n * b) = ↑a ^ n * ↑b
Applies Nat.cast to a nat polynomial to produce a polynomial in α.
↑0 = 0↑(a + b) = ↑a + ↑b
Scalar multiplication by ℤ #
Applies Int.cast to an int polynomial to produce a polynomial in α.
- An atom
ecauses↑eto be allocated as a new atom. - A sum delegates to
ExSum.evalIntCast.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Applies Int.cast to an int monomial to produce a monomial in α.
↑c = cifcis a numeric literal↑(a ^ n * b) = ↑a ^ n * ↑b
Equations
- One or more equations did not get rendered due to their size.
Instances For
Applies Int.cast to an int polynomial to produce a polynomial in α.
↑0 = 0↑(a + b) = ↑a + ↑b
Equations
- One or more equations did not get rendered due to their size.
- Mathlib.Tactic.Ring.ExSum.evalIntCast sα sβ rα Mathlib.Tactic.Ring.Common.ExSum.zero = pure { expr := q(0), val := Mathlib.Tactic.Ring.Common.ExSum.zero, proof := q(⋯) }
Instances For
Converts ExBase sα to ExBase sβ, assuming sα and sβ are defeq.
Equations
- Mathlib.Tactic.Ring.ExBase.cast sα (Mathlib.Tactic.Ring.Common.ExBase.atom i) = ⟨a, Mathlib.Tactic.Ring.Common.ExBase.atom i⟩
- Mathlib.Tactic.Ring.ExBase.cast sα (Mathlib.Tactic.Ring.Common.ExBase.sum a_1) = match Mathlib.Tactic.Ring.ExSum.cast sα a_1 with | ⟨fst, vb⟩ => ⟨fst, Mathlib.Tactic.Ring.Common.ExBase.sum vb⟩
Instances For
Converts ExProd sα to ExProd sβ, assuming sα and sβ are defeq.
Equations
- One or more equations did not get rendered due to their size.
- Mathlib.Tactic.Ring.ExProd.cast sα (Mathlib.Tactic.Ring.Common.ExProd.const { value := i, hyp := h }) = ⟨a, Mathlib.Tactic.Ring.Common.ExProd.const { value := i, hyp := h }⟩
Instances For
Converts ExSum sα to ExSum sβ, assuming sα and sβ are defeq.
Equations
- One or more equations did not get rendered due to their size.
- Mathlib.Tactic.Ring.ExSum.cast sα Mathlib.Tactic.Ring.Common.ExSum.zero = ⟨q(0), Mathlib.Tactic.Ring.Common.ExSum.zero⟩
Instances For
Turn coefficient data into a NormNum.Result.
Equations
- { value := q, hyp := h }.toResult = Mathlib.Meta.NormNum.Result.ofRawRat q a h
Instances For
Turn a NormNum.Result into coefficient data.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Add two rational number expressions. If the result is zero, returns a proof of this fact.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Evaluate the product of two rational number expressions.
Equations
- Mathlib.Tactic.Ring.RingCompute.mul sα za zb = do let res ← za.toResult.mul zb.toResult q(«$sα».toSemiring) let __do_lift ← liftM (Mathlib.Tactic.Ring.RatCoeff.ofResult res) pure __do_lift
Instances For
Cast ℕ and ℤ normalized expressions ExSums into α, used to evaluate scalar multiplications.
Negate rational number expressions.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Raise a rational number expression to the power of a natural number.
Fails if the exponent is not a literal.
Instances For
Evaluate the inverse of a natural number expression.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Try to evaluate an expression as a rational constant using norm_num.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Decide if x is 1 and provide a proof if so.
Equations
Instances For
The comarisons on the basetype used to compare normalized ring expressions.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The data used by the ring tactic to normalize the constant coefficients.
The data used by ring-like tactics to normalize constant coefficients of natural number
expressions.
Equations
Instances For
CSLift α β is a typeclass used by ring for lifting operations from α
(which is not a commutative semiring) into a commutative semiring β by using an injective map
lift : α → β.
- lift : α → β
liftis the "canonical injection" fromαtoβ - inj : Function.Injective lift
liftis an injective function
Instances
CSLiftVal a b means that b = lift a. This is used by ring to construct an expression b
from the input expression a, and then run the usual ring algorithm on b.
The output value
bis equal to the lift ofa. This can be supplied by the default instance which setsb := lift a, butringwill treat this as an atom so it is more useful when there are other instances which distribute addition or multiplication.
Instances
This is a routine which is used to clean up the unsolved subgoal
of a failed ring1 application. It is overridden in Mathlib/Tactic/Ring/RingNF.lean
to apply the ring_nf simp set to the goal.
Frontend of ring1: attempt to close a goal g, assuming it is an equation of semirings.
Equations
- One or more equations did not get rendered due to their size.
Instances For
ring1 solves the goal when it is an equality in commutative (semi)rings,
allowing variables in the exponent.
This version of ring fails if the target is not an equality.
ring1!uses a more aggressive reducibility setting to determine equality of atoms.
Equations
- One or more equations did not get rendered due to their size.
Instances For
ring1 solves the goal when it is an equality in commutative (semi)rings,
allowing variables in the exponent.
This version of ring fails if the target is not an equality.
ring1!uses a more aggressive reducibility setting to determine equality of atoms.
Equations
- Mathlib.Tactic.Ring.tacticRing1! = Lean.ParserDescr.node `Mathlib.Tactic.Ring.tacticRing1! 1024 (Lean.ParserDescr.nonReservedSymbol "ring1!" false)