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 wrap it in 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.