ring
Evaluate expressions in the language of commutative (semi)rings. Based on http://www.cs.ru.nl/~freek/courses/tt-2014/read/10.1.1.61.3041.pdf .
The normal form that ring
uses is mediated by the function horner a x n b := a * x ^ n + b
.
The reason we use a definition rather than the (more readable) expression on the right is because
this expression contains a number of typeclass arguments in different positions, while horner
contains only one comm_semiring
instance at the top level. See also horner_expr
for a
description of normal form.
Equations
- tactic.ring.horner a x n b = a * x ^ n + b
- α : expr
- univ : level
- comm_semiring_inst : expr
- red : tactic.transparency
- ic : tactic.ref tactic.instance_cache
- nc : tactic.ref tactic.instance_cache
- atoms : tactic.ref (buffer expr)
This cache contains data required by the ring
tactic during execution.
The monad that ring
works in. This is a reader monad containing a mutable cache (using ref
for mutability), as well as the list of atoms-up-to-defeq encountered thus far, used for atom
sorting.
Get the ring
data from the monad.
Get an already encountered atom by its index.
Get the index corresponding to an atomic expression, if it has already been encountered, or put it in the list of atoms and return the new index, otherwise.
Lift a tactic into the ring_m
monad.
Run a ring_m
tactic in the tactic monad.
Lift an instance cache tactic (probably from norm_num
) to the ring_m
monad. This version
is abstract over the instance cache in question (either the ring α
, or ℕ
for exponents).
Lift an instance cache tactic (probably from norm_num
) to the ring_m
monad. This uses
the instance cache corresponding to the ring α
.
Lift an instance cache tactic (probably from norm_num
) to the ring_m
monad. This uses
the instance cache corresponding to ℕ
, which is used for computations in the exponent.
Apply a theorem that expects a comm_semiring
instance. This is a special case of
ic_lift mk_app
, but it comes up often because horner
and all its theorems have this assumption;
it also does not require the tactic monad which improves access speed a bit.
- const : expr → ℚ → tactic.ring.horner_expr
- xadd : expr → tactic.ring.horner_expr → expr × ℕ → expr × ℕ → tactic.ring.horner_expr → tactic.ring.horner_expr
Every expression in the language of commutative semirings can be viewed as a sum of monomials,
where each monomial is a product of powers of atoms. We fix a global order on atoms (up to
definitional equality), and then separate the terms according to their smallest atom. So the top
level expression is a * x^n + b
where x
is the smallest atom and n > 0
is a numeral, and
n
is maximal (so a
contains at least one monomial not containing an x
), and b
contains no
monomials with an x
(hence all atoms in b
are larger than x
).
If there is no x
satisfying these constraints, then the expression must be a numeral. Even though
we are working over rings, we allow rational constants when these can be interpreted in the ring,
so we can solve problems like x / 3 = 1 / 3 * x
even though these are not technically in the
language of rings.
These constraints ensure that there is a unique normal form for each ring expression, and so the algorithm is simply to calculate the normal form of each side and compare for equality.
To allow us to efficiently pattern match on normal forms, we maintain this inductive type that
holds a normalized expression together with its structure. All the expr
s in this type could be
removed without loss of information, and conversely the horner_expr
structure and the ℕ
and
ℚ
values can be recovered from the top level expr
, but we keep both in order to keep proof
producing normalization functions efficient.
Get the expression corresponding to a horner_expr
. This can be calculated recursively from
the structure, but we cache the exprs in all subterms so that this function can be computed in
constant time.
Is this expr the constant 0
?
Construct a xadd
node, generating the cached expr using the input cache.
Pretty printer for horner_expr
.
Pretty printer for horner_expr
.
Reflexivity conversion for a horner_expr
.
Evaluate horner a n x b
where a
and b
are already in normal form.
Evaluate a + b
where a
and b
are already in normal form.
Evaluate -a
where a
is already in normal form.
Evaluate k * a
where k
is a rational numeral and a
is in normal form.
Evaluate a * b
where a
and b
are in normal form.
Evaluate a ^ n
where a
is in normal form and n
is a natural numeral.
Evaluate a
where a
is an atom.
Evaluate a ring expression e
recursively to normal form, together with a proof of
equality.
Evaluate a ring expression e
recursively to normal form, together with a proof of
equality.
- raw : tactic.ring.normalize_mode
- SOP : tactic.ring.normalize_mode
- horner : tactic.ring.normalize_mode
If ring
fails to close the goal, it falls back on normalizing the expression to a "pretty"
form so that you can see why it failed. This setting adjusts the resulting form:
raw
is the form thatring
actually uses internally, with iterated applications ofhorner
. Not very readable but useful if you don't want any postprocessing. This results in terms likehorner (horner (horner 3 y 1 0) x 2 1) x 1 (horner 1 y 1 0)
.horner
maintains the Horner form structure, but it unfolds thehorner
definition itself, and tries to otherwise minimize parentheses. This results in terms like(3 * x ^ 2 * y + 1) * x + y
.SOP
means sum of products form, expanding everything to monomials. This results in terms like3 * x ^ 3 * y + x + y
.
Equations
A ring
-based normalization simplifier that rewrites ring expressions into the specified mode.
raw
is the form thatring
actually uses internally, with iterated applications ofhorner
. Not very readable but useful if you don't want any postprocessing. This results in terms likehorner (horner (horner 3 y 1 0) x 2 1) x 1 (horner 1 y 1 0)
.horner
maintains the Horner form structure, but it unfolds thehorner
definition itself, and tries to otherwise minimize parentheses. This results in terms like(3 * x ^ 2 * y + 1) * x + y
.SOP
means sum of products form, expanding everything to monomials. This results in terms like3 * x ^ 3 * y + x + y
.
Tactic for solving equations in the language of commutative (semi)rings.
This version of ring
fails if the target is not an equality
that is provable by the axioms of commutative (semi)rings.
Parser for ring
's mode
argument, which can only be the "keywords" raw
, horner
or SOP
.
(Because these are not actually keywords we use a name parser and postprocess the result.)
Tactic for solving equations in the language of commutative (semi)rings.
Attempts to prove the goal outright if there is no at
specifier and the target is an equality, but if this
fails it falls back to rewriting all ring expressions
into a normal form. When writing a normal form,
ring SOP
will use sum-of-products form instead of horner form.
ring!
will use a more aggressive reducibility setting to identify atoms.
Based on Proving Equalities in a Commutative Ring Done Right in Coq by Benjamin Grégoire and Assia Mahboubi.
Normalises expressions in commutative (semi-)rings inside of a conv
block using the tactic ring
.