2014-09-20 00:59:09 +00:00
|
|
|
* Reducible hints
|
|
|
|
|
|
|
|
Lean automation can be configured using different commands and
|
|
|
|
annotations. The =reducible= hint/annotation instructs automation
|
|
|
|
which declarations can be freely unfolded. One of the main components
|
2014-09-20 14:44:48 +00:00
|
|
|
of the Lean elaborator is a procedure for solving simultaneous
|
2014-09-20 00:59:09 +00:00
|
|
|
higher-order unification constraints. Higher-order unification is a
|
|
|
|
undecidable problem. Thus, the procedure implemented in Lean is
|
|
|
|
clearly incomplete, that is, it may fail to find a solution for a set
|
|
|
|
of constraints. One way to guide/help the procedure is to indicate
|
|
|
|
which declarations can be unfolded. We should not confuse the
|
|
|
|
=reducible= hint with whether a declaration is opaque or not. We say
|
|
|
|
_opaqueness_ is part of the Lean logic, and is implemented inside of
|
|
|
|
its trusted kernel. The =reducible= hint is just a way to
|
|
|
|
control/guide Lean automation to fill missing gaps in our proofs and
|
|
|
|
definitions. The Lean kernel ignores this annotation.
|
|
|
|
|
|
|
|
The higher-order unification procedure has to perform case-analysis.
|
|
|
|
The procedure is essentially implementing a backtracking search. This
|
|
|
|
procedure has to decide whether a definition =C= should be unfolded or
|
|
|
|
not. Here, we roughly divide this decision in two groups: _simple_
|
2014-09-20 14:44:48 +00:00
|
|
|
and _complex_. We say an unfolding decision is _simple_ if the
|
2014-09-20 00:59:09 +00:00
|
|
|
procedure does not have to consider an extra case (aka
|
2014-09-20 14:44:48 +00:00
|
|
|
case-split). That is, it does not increase the search space. We say an
|
2014-09-20 00:59:09 +00:00
|
|
|
unfolding decision is _complex_ if it produces at least one extra
|
|
|
|
case, and consequently increases the search space.
|
|
|
|
|
|
|
|
Users can mark whether a definition is =reducible= or =irreducible=.
|
|
|
|
We write =reducible(C)= to denote that =C= was marked as reducible by the user,
|
|
|
|
and =irreducible(C)= to denote that =C= was marked as irreducible by the user.
|
|
|
|
|
|
|
|
Theorems are never unfolded. For a transparent definition =C=, the
|
2014-09-20 14:44:48 +00:00
|
|
|
higher-order unification procedure uses the following decision tree.
|
2014-09-20 00:59:09 +00:00
|
|
|
|
|
|
|
#+BEGIN_SRC
|
|
|
|
if simple unfolding decision then
|
|
|
|
if irreducible(C) then
|
|
|
|
do not unfold
|
|
|
|
else
|
|
|
|
unfold
|
|
|
|
end
|
|
|
|
else -- complex unfolding decision
|
|
|
|
if reducible(C) then
|
|
|
|
unfold
|
|
|
|
else
|
|
|
|
do not unfold
|
|
|
|
end
|
|
|
|
end
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
For an opaque definition =D=, the higher-order unification procedure uses the
|
|
|
|
same decision tree if =D= was declared in the current module. Otherwise, it does
|
|
|
|
not unfold =D=.
|
|
|
|
|
|
|
|
The following command declares a transparent definition =pr= and mark it as reducible.
|
|
|
|
|
|
|
|
#+BEGIN_SRC lean
|
|
|
|
definition pr1 [reducible] (A : Type) (a b : A) : A := a
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
The =reducible= mark is saved in the compiled .olean files. The user
|
|
|
|
can temporarily change the =reducible= and =irreducible= marks using
|
|
|
|
the following commands. The temporary modification is effective only in the
|
|
|
|
current file, and is not saved in the produced .olean file.
|
|
|
|
|
|
|
|
#+BEGIN_SRC lean
|
|
|
|
definition id (A : Type) (a : A) : A := a
|
|
|
|
definition pr2 (A : Type) (a b : A) : A := b
|
|
|
|
-- mark pr2 as reducible
|
|
|
|
reducible pr2
|
|
|
|
-- ...
|
|
|
|
-- mark id and pr2 as irreducible
|
|
|
|
irreducible id pr2
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
The annotation =[persistent]= can be used to instruct Lean to make the
|
|
|
|
modification permanent, and save it in the .olean file.
|
|
|
|
|
|
|
|
#+BEGIN_SRC lean
|
|
|
|
definition pr2 (A : Type) (a b : A) : A := b
|
|
|
|
-- Mark pr2 as irreducible.
|
|
|
|
-- The modification will affect modules that import this one.
|
|
|
|
irreducible [persistent] pr2
|
|
|
|
#+END_SRC
|
|
|
|
|
2014-09-20 14:44:48 +00:00
|
|
|
The reducible and irreducible annotations can be removed using the modifier =[none]=.
|
2014-09-20 00:59:09 +00:00
|
|
|
|
|
|
|
#+BEGIN_SRC lean
|
|
|
|
definition pr2 (A : Type) (a b : A) : A := b
|
|
|
|
|
|
|
|
-- temporarily remove any reducible and irreducible annotation from pr2
|
|
|
|
reducible [none] pr2
|
|
|
|
|
|
|
|
-- permanently remove any reducible and irreducible annotation from pr2
|
|
|
|
reducible [persistent] [none] pr2
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
Finally, the command =irreducible= is syntax sugar for =reducible [off]=.
|
|
|
|
The commands =reducible= and =reducible [on]= are equivalent.
|