positivity
tactic #
The positivity
tactic in this file solves goals of the form 0 ≤ x
, 0 < x
and x ≠ 0
. The
tactic works recursively according to the syntax of the expression x
. For example, a goal of the
form 0 ≤ 3 * a ^ 2 + b * c
can be solved either
- by a hypothesis such as
5 ≤ 3 * a ^ 2 + b * c
which directly implies the nonegativity of3 * a ^ 2 + b * c
; or, - by the application of the lemma
add_nonneg
and the success of thepositivity
tactic on the two sub-expressions3 * a ^ 2
andb * c
.
For each supported operation, one must write a small tactic, tagged with the attribute
@[positivity]
, which operates only on goals whose leading function application is that operation.
Typically, this small tactic will run the full positivity
tactic on one or more of the function's
arguments (which is where the recursion comes in), and if successful will combine this with an
appropriate lemma to give positivity of the full expression.
This file contains the core positivity
logic and the small tactics handling the basic operations:
min
, max
, +
, *
, /
, ⁻¹
, raising to natural powers, and taking absolute values. Further
extensions, e.g. to handle real.sqrt
and norms, can be found in the files of the library which
introduce these operations.
Main declarations #
tactic.norm_num.positivity
tries to prove positivity of an expression by runningnorm_num
on it. This is one of the base cases of the recursion.tactic.positivity.compare_hyp
tries to prove positivity of an expression by comparing with a provided hypothesis. If the hypothesis is of the forma ≤ b
or similar, withb
matching the expression whose proof of positivity is desired, then it will check whethera
can be proved positive viatactic.norm_num.positivity
and if so apply a transitivity lemma. This is the other base case of the recursion.tactic.positivity.attr
creates thepositivity
user attribute for tagging the extension tactics handling specific operations, and specifies the behaviour for a single step of the recursiontactic.positivity.core
collects the list of tactics with the@[positivity]
attribute and calls the first recursion step as specified intactic.positivity.attr
. Its input ise : expr
and its output (if it succeeds) is a term of a custom inductive typetactic.positivity.strictness
, containing anexpr
which is a proof of the strict-positivity/nonnegativity ofe
as well as an indication of whether what could be proved was strict-positivity or nonnegativitytactic.positivity.order_rel
is a custom inductive type recording whether the goal is0 ≤ e
/e ≥ 0
,0 < e
/e > 0
,e ≠ 0
or0 ≠ e
.tactic.interactive.positivity
is the user-facing tactic. It parses the goal and, if it is of one of the forms0 ≤ e
,0 < e
,e > 0
,e ≥ 0
,e ≠ 0
,0 ≠ e
, it sendse
totactic.positivity.core
.
TODO #
Implement extensions for other operations (raising to non-numeral powers, log
).
- le : tactic.positivity.order_rel
- lt : tactic.positivity.order_rel
- ne : tactic.positivity.order_rel
- ne' : tactic.positivity.order_rel
Inductive type recording whether the goal positivity
is called on is nonnegativity, positivity
or different from 0
.
Instances for tactic.positivity.order_rel
- tactic.positivity.order_rel.has_sizeof_inst
- tactic.positivity.order_rel.inhabited
- tactic.positivity.order_rel.has_to_format
Core logic of the positivity
tactic #
Tactic solving goals of the form 0 ≤ x
, 0 < x
and x ≠ 0
. The tactic works recursively
according to the syntax of the expression x
, if the atoms composing the expression all have
numeric lower bounds which can be proved positive/nonnegative/nonzero by norm_num
. This tactic
either closes the goal or fails.
Examples:
example {a : ℤ} (ha : 3 < a) : 0 ≤ a ^ 3 + a := by positivity
example {a : ℤ} (ha : 1 < a) : 0 < |(3:ℤ) + a| := by positivity
example {b : ℤ} : 0 ≤ max (-3) (b ^ 2) := by positivity
```
positivity
extensions for particular arithmetic operations #
Alias of the reverse direction of abs_pos
.