Hints: hint simplify
The hint simplify commands manage user reduction rules used by
simplify, cbv, and tactics that rely on the same simplification
machinery.
Hints can be declared globally in a theory, selected through named databases, and adjusted locally inside a proof.
Global declarations
Global declarations add lemmas to a simplification database.
Syntax
hint simplify [{option}*]? {item} (, {item})* .
Add the listed lemmas to the default simplification database.
Syntax
hint simplify in {db} : [{option}*]? {item} (, {item})* .
Add the listed lemmas to the named database {db}.
Each {item} is a lemma name, or a parenthesised list of lemma names,
optionally followed by a priority:
{lemma}{lemma} @ {n}( {lemma} (, {lemma})* ) @ {n}
Rules are tried in increasing priority order, 0 being the default, so
@ {n} with a larger {n} places a rule after the rules declared without
a priority. The priority of an item applies to every rule it produces.
The optional bracketed {option} list applies to every item of the
command:
reduce– head-normalise the statement of the lemma, unfolding transparent definitions, before compiling it into rules. This lets a lemma stated through an abbreviation-like operator register a rule on the operator the abbreviation unfolds to.eqtrue– accepted for compatibility. A boolean statement that is not an equation is always compiled as a rewrite totrue(see below), so the option currently has no additional effect.
These commands are theory-level declarations: once imported, the corresponding rules are available to simplification.
Rule shape
A lemma is compiled into one or more rewrite rules by decomposing its statement. The statement is first stripped of its leading universal quantifiers, then split as follows:
{c} => {f}– a conditional rule:{c}is recorded as a side condition of every rule produced from{f}. When a rule is applied, each side condition is instantiated and must simplify totruefor the rule to fire.{f1} /{f2}– a conjunction contributes the rules of both conjuncts. Side conditions and binders introduced above the conjunction apply to both sides.forall {x}, {f}– a conjunct may carry its own binders, which are added to those of the enclosing statement.{lhs} = {rhs}and{lhs} <=> {rhs}– a rewrite rule from{lhs}to{rhs}.any other boolean statement
{p}– a rewrite rule from{p}totrue.
Hence a lemma such as
lemma gE : g 0 = 4 /\ g 1 = 6 /\ g 2 = 2.
hint simplify gE.
registers three rules, one per equation, and
lemma hE (x : int) : (0 < x => h x = x + 1) /\ h 0 = 7.
hint simplify hE.
registers a rule for h x guarded by 0 < x and an unconditional rule
for h 0.
The left-hand side of each rule must be a first-order pattern: an application of an operator to patterns, a tuple, a projection, an integer literal, or a variable. Its head must not be a variable, and every bound variable of the rule must occur in it (a binder of the statement that a conjunct does not mention is simply dropped for that conjunct). Lemmas quantifying over memories or modules are rejected.
The hint clause
simplify and cbv accept a single hint clause that controls which
user-reduction rules are used. The clause is introduced by the hint
keyword and is built from an unsigned base database selection followed by
any number of signed items:
Syntax
simplify hint {db}* {item}*
where each {item} is one of:
+ {db}/- {db}— activate / deactivate a database;+[ {op}+ ]/-[ {op}+ ]— head filter: keep only / drop rules headed by the listed operators (at most one filter per clause);{ {lemma}+ }— add lemmas to the default database for this call.
The delimiter disambiguates an item: a bare name is a database, […]
holds operators, {…} holds lemmas. Lemma sets are add-only – a clause
never removes lemmas from a database; use the head filter to restrict
which rules apply. The same clause is accepted by cbv.
The database part of a clause is either an unsigned selection or
signed deltas, never both (mixing them is redundant and rejected). An
unsigned list hint d1 d2 replaces the consulted databases with
exactly {d1, d2}. Signed + {db} / - {db} instead modify the current
set (the proof-local default, else the active set): simplify hint +d2
adds d2 to it, simplify hint -d3 removes d3.
A head filter performs full simplification (like a bare simplify) with
user reduction restricted to the selected operators.
The hint clause is independent of the reduction arguments that
simplify and cbv already accept: a bare simplify performs full
simplification, simplify delta additionally unfolds all transparent
definitions, simplify delta[f g] does the same and also unfolds f and
g even when they are declared [opaque], simplify f g unfolds only
the operators f and g, and a keyword-less list such as beta zeta
performs only the named reductions. A hint clause may follow any of
these (for example simplify delta hint +[f]).
Proof-local commands
Inside a proof, the simplify configuration can be changed without
modifying the theory-level declarations. The hint command takes the
same clause as the simplify/cbv tactics, and each kind of item has a
persistent effect on the proof state:
Syntax
hint {db}* {item}* .
+ {db}/- {db}— activate / deactivate a database (for later baresimplify/cbv);{ {lemma}+ }— add lemmas to the default database;an unsigned database list
{db}+— set the proof-local default databases used by latersimplify/cbvcalls;+[ {op}+ ]/-[ {op}+ ]— set the proof-local default head filter.
As in the tactic clause, the database part is either an unsigned
selection or signed +/- deltas, never both.
Syntax
hint clear {db}? .
Clear the local lemma additions: for the default database when {db} is
omitted, or for the named database {db}. Note that hint clear default
is reserved for the form below, so a database named default cannot be
cleared this way.
Syntax
hint clear default .
Clear the proof-local default database and head filter.
These proof-local changes are part of the proof state and therefore
follow the usual subgoal branching behavior. Explicit arguments on
simplify/cbv take precedence over the proof-local defaults.
Scoped application
A hint command can be used as a scoped wrapper around a tactic, with the
same clause syntax.
Syntax
with hint {clause} ( {tactic} )
For example:
with hint +ring (simplify).
with hint {fooE} (rewrite foo /=).
with hint ring (cbv).
The wrapped tactic runs with the modified hint configuration, but the subgoals produced afterwards are restored to the original configuration.