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ℕ
) - 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.
The normalisation is guided by building a value in the type ExSum
at the meta level,
together with a proof (at the base level) that the original value is equal to
the normalised version.
The outline of the file:
- Define a mutual inductive family of types
ExSum
,ExProd
,ExBase
, which can represent expressions with+
,*
,^
and rational numerals. The mutual induction ensures that associativity and distributivity are applied, by restricting which kinds of subexpressions appear as arguments to the various operators. - Represent addition, multiplication and exponentiation in the
ExSum
type, thus allowing us to map expressions toExSum
(theeval
function drives this). We apply associativity and distributivity of the operators here (helped byEx*
types) and commutativity as well (by sorting the subterms; unfortunately not helped by anything). Any expression not of the above formats is treated as an atom (the same as a variable).
There are some details we glossed over which make the plan more complicated:
- The order on atoms is not initially obvious. We construct a list containing them in order of initial appearance in the expression, then use the index into the list as a key to order on.
- For
pow
, the exponent must be a natural number, while the base can be any semiringα
. We swap out operations for the base ringα
with those for the exponent ringℕ
as soon as we deal with exponents.
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
A shortcut instance for CommSemiring ℕ
used by ring.
Equations
- Mathlib.Tactic.Ring.instCommSemiringNat = inferInstance
Instances For
A typed expression of type CommSemiring ℕ
used when we are working on
ring subexpressions of type ℕ
.
Instances For
Equality test for expressions. This is not a BEq
instance because it is heterogeneous.
Equality test for expressions. This is not a BEq
instance because it is heterogeneous.
Equality test for expressions. This is not a BEq
instance because it is heterogeneous.
A total order on normalized expressions.
This is not an Ord
instance because it is heterogeneous.
A total order on normalized expressions.
This is not an Ord
instance because it is heterogeneous.
A total order on normalized expressions.
This is not an Ord
instance because it is heterogeneous.
Equations
- Mathlib.Tactic.Ring.instInhabitedSigmaQuotedExBase = { default := { fst := default, snd := Mathlib.Tactic.Ring.ExBase.atom 0 } }
Equations
- Mathlib.Tactic.Ring.instInhabitedSigmaQuotedExProd = { default := { fst := default, snd := Mathlib.Tactic.Ring.ExProd.const 0 } }
Converts ExBase sα
to ExBase sβ
, assuming sα
and sβ
are defeq.
Converts ExProd sα
to ExProd sβ
, assuming sα
and sβ
are defeq.
Converts ExSum sα
to ExSum sβ
, assuming sα
and sβ
are defeq.
- k : Q(ℕ)
A raw natural number literal.
- e' : Q(ℕ)
The result of extracting the coefficient is a monic monomial.
- ve' : Mathlib.Tactic.Ring.ExProd Mathlib.Tactic.Ring.sℕ s.e'
e'
is a monomial.
The result of extractCoeff
is a numeral and a proof that the original expression
factors by this numeral.
Instances For
Given a monomial expression va
, splits off the leading coefficient k
and the remainder
e'
, stored in the ExtractCoeff
structure.
Instances For
A precomputed Cache
for ℕ
.
Equations
- Mathlib.Tactic.Ring.Cache.nat = { rα := none, dα := none, czα := some q((_ : CharZero ℕ)) }
Instances For
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
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
Tactic for solving equations of commutative (semi)rings, allowing variables in the exponent.
- This version of
ring
fails if the target is not an equality. - The variant
ring1!
will use 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
Tactic for solving equations of commutative (semi)rings, allowing variables in the exponent.
- This version of
ring
fails if the target is not an equality. - The variant
ring1!
will use 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)