Instance Wrapping #
Both inferInstanceAs and the default deriving handler wrap instance bodies to ensure
that when deriving or inferring an instance for a semireducible type definition, the
definition's RHS is not leaked when reduced at lower than semireducible transparency.
Algorithm #
Given an instance i : I and expected type I' (where I' must be mvar-free),
wrapInstance constructs a result instance as follows, executing all steps at
instances transparency:
- If
I'is not a class application, returniunchanged. - If
I'is a proposition, wrapiin an auxiliary theorem of typeI'and return it (controlled bybackward.inferInstanceAs.wrap.instances). - Reduce
ito whnf. - If
iis not a constructor application: ifIis already defeq toI', returni; otherwise (ifbackward.inferInstanceAs.wrap.reuseSubInstancesis set) try (recursive) eta-expansion and wrapping ofito see if any sub-instances can be reused; otherwise wrapiin an auxiliary definition of typeI'and return it (controlled bybackward.inferInstanceAs.wrap.instances). - Otherwise, if
iis an application ofctorof classC:- Unify the conclusion of the type of
ctorwithI'to obtain adjusted field typeFᵢ'for each field. - Return a new application
ctor ... : I'where the fields are adjusted as follows:- If the field type is a proposition: assign directly if types are defeq, otherwise wrap in an auxiliary theorem.
- If the field is a parent field (subobject)
p : P: first try to reuse an existing instance that can be synthesized forP(controlled bybackward.inferInstanceAs.wrap.reuseSubInstances) in order to preserve defeqs; if that fails, recurse. - If it is a field of a flattened parent class
C'andbackward.inferInstanceAs.wrap.reuseSubInstancesis true, try synthesizing an instance ofC'forI'and if successful, use the corresponding projection of the found instance in order to preserve defeqs; otherwise, continue.- Specifically, construct the chain of base projections from
CtoC'applied to_ : I'and infer its type to obtain an appropriate application ofC'for the instance search.
- Specifically, construct the chain of base projections from
- Otherwise (non-inherited data field): assign directly if types are defeq, otherwise wrap in an
auxiliary definition to fix the type (controlled by
backward.inferInstanceAs.wrap.data).
- Unify the conclusion of the type of
Options #
backward.inferInstanceAs.wrap: master switch for wrapping in bothinferInstanceAsand the defaultderivinghandlerbackward.inferInstanceAs.wrap.reuseSubInstances: reuse existing instances for sub-instance fields to avoid non-defeq instance diamondsbackward.inferInstanceAs.wrap.instances: wrap non-reducible instances in auxiliary definitionsbackward.inferInstanceAs.wrap.data: wrap data fields in auxiliary definitions
Rebuild a type application with fresh synthetic metavariables for instance-implicit arguments. Non-instance-implicit arguments are assigned from the original application's arguments. If the function is over-applied, extra arguments are preserved.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Wrap an instance value so its type matches the expected type exactly. See the module docstring for the full algorithm specification.
Equations
- One or more equations did not get rendered due to their size.