Improvable lower bounds. #
The typeclass Estimator a ε
, where a : Thunk α
and ε : Type
,
states that e : ε
carries the data of a lower bound for a.get
,
in the form bound_le : bound a e ≤ a.get
,
along with a mechanism for asking for a better bound improve e : Option ε
,
satisfying
match improve e with
| none => bound e = a.get
| some e' => bound e < bound e'
i.e. it returns none
if the current bound is already optimal,
and otherwise a strictly better bound.
(The value in α
is hidden inside a Thunk
to prevent evaluating it:
the point of this typeclass is to work with cheap-to-compute lower bounds for expensive values.)
An appropriate well-foundedness condition would then ensure that repeated improvements reach the exact value.
Given [EstimatorData a ε]
- a term
e : ε
can be interpreted viabound a e : α
as a lower bound fora
, and - we can ask for an improved lower bound via
improve a e : Option ε
.
The value a
in α
that we are estimating is hidden inside a Thunk
to avoid evaluation.
- bound : ε → α
The value of the bound for
a
representation by a term ofε
. - improve : ε → Option ε
Generate an improved lower bound.
Instances
Given [Estimator a ε]
- we have
bound a e ≤ a.get
, and improve a e
returns none iffbound a e = a.get
, and otherwise it returns a strictly better bound.
- bound : ε → α
- improve : ε → Option ε
- bound_le : ∀ (e : ε), EstimatorData.bound a e ≤ Thunk.get a
The calculated bounds are always lower bounds.
- improve_spec : ∀ (e : ε), match EstimatorData.improve a e with | none => EstimatorData.bound a e = Thunk.get a | some e' => EstimatorData.bound a e < EstimatorData.bound a e'
Calling
improve
either gives a strictly better bound, or a proof that the current bound is exact.
Instances
A trivial estimator, containing the actual value.
Equations
- Estimator.trivial a = { b : α // b = a }
Instances For
Equations
- instBotTrivial = { bot := { val := a, property := ⋯ } }
Equations
- ⋯ = ⋯
Equations
- instEstimatorPureTrivial = Estimator.mk ⋯ ⋯
Implementation of Estimator.improveUntil
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Improve an estimate until it satisfies a predicate, or else return the best available estimate, if any improvement was made.
Equations
- Estimator.improveUntil a p e = Estimator.improveUntilAux a p e false
Instances For
If Estimator.improveUntil a p e
returns some e'
, then bound a e'
satisfies p
.
Otherwise, that value a
must not satisfy p
.
If Estimator.improveUntil a p e
returns some e'
, then bound a e'
satisfies p
.
Otherwise, that value a
must not satisfy p
.
Estimators for sums.
Equations
- One or more equations did not get rendered due to their size.
Estimator for the first component of a pair.
An estimator for (a, b)
can be turned into an estimator for a
,
simply by repeatedly running improve
until the first factor "improves".
The hypothesis that >
is well-founded on { q // q ≤ (a, b) }
ensures this terminates.
- inner : ε
The wrapped bound for a value in
α × β
, which we will use as a bound for the first component.
Instances For
Equations
- ⋯ = ⋯
Equations
- One or more equations did not get rendered due to their size.
Given an estimator for a pair, we can extract an estimator for the first factor.
Equations
- Estimator.fstInst a b i = Estimator.mk ⋯ ⋯