feat(Tactic): add inferInstanceAs% to fix type leakage#35950
feat(Tactic): add inferInstanceAs% to fix type leakage#35950
Conversation
PR summary ba37a5c6eeImport changes for modified filesNo significant changes to the import graph Import changes for all files
|
| Current number | Change | Type |
|---|---|---|
| 132 | -1 | adaptation notes |
Current commit 4c91a86a72
Reference commit ba37a5c6ee
You can run this locally as
./scripts/reporting/technical-debt-metrics.sh pr_summary
- The
relativevalue is the weighted sum of the differences with weight given by the inverse of the current value of the statistic. - The
absolutevalue is therelativevalue divided by the total sum of the inverses of the current values (i.e. the weighted average of the differences).
|
Should we make an elaborator for |
JovanGerb
left a comment
There was a problem hiding this comment.
I've left some small comments, but I do have one high level criticism. This function will unfold the instance all the way down to its constructors when possible. For some instances this will give some very big terms. It is typically better to use pre-existing instances of sub-structures in place of those sub-structures. This is also what fast_instance% does. So I can imagine that we will see some slowdowns as a result of this.
Using |
|
You're right, and we can use |
I've changed behaviour: when we hit sub-structures, we try to decide if they are "leaky". If so, we emit a (suppresible) warning, hopefully encouraging the user to go fix those first. |
…ed instances `inferInstanceAs%` is a drop-in replacement for `inferInstanceAs` that prevents "type leakage" in synthesized instances. When `inferInstanceAs` synthesizes an instance for a type alias, the resulting expression may contain lambda binder domains referring to unfolded forms of the carrier type rather than the declared alias. This is invisible at `default` transparency but causes `isDefEq` failures at `reducibleAndInstances` transparency — which is the level used by `grind`'s `checkInst`. The fix recursively normalizes the constructor tree: for each class-valued structure, it WHNFs to expose the constructor, patches the carrier type parameter via `isDefEq` matching, recursively processes instance-implicit fields, and replaces lambda binder domains in function fields. This fixes the `grind` failure in `FiniteResidueField` that was previously worked around with an `#adaptation_note` and manual proof. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Refactor the implementation: - Make `unfoldChain` iterative with built-in dedup and `skipHead` param - Extract `addUnfoldings` and `buildReplacements` from inline logic - Split `normalizeInstance` into `getCtorApp?`, `getFieldInfo`, and `normalizeCtorArgs` helpers (mutual block for recursion) Add deeper test hierarchy (TestInv → TestDivInvMonoid → TestField) reproducing the real grind failure pattern, with declarative examples showing defeq at default transparency but not at `instances` transparency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove extra leading spaces on continuation lines of docstrings to match mathlib convention (#8). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ard getAppFn Throw an error when source and expected types fail to unify, and check that the class heads match before comparing arguments pairwise (#1). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All code is `meta`, so `partial` is fine for termination. Remove the unnecessary fuel parameter from `normalizeCtorArgs` and `normalizeInstance`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…add option When `inferInstanceAs%` patches an instance, it now tries to synthesize sub-instances for the target carrier type. If a synthesized sub-instance is not defeq to the patched version at `reducibleAndInstances` transparency, a warning is emitted suggesting the user define it separately. The warning can be disabled with `set_option inferInstanceAsPercent.leakySubInstWarning false`. Also regenerates import files via `lake exe mk_all`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
77c1035 to
4c91a86
Compare
This PR adds
inferInstanceAs%, a drop-in replacement forinferInstanceAsthat prevents "type leakage" in synthesized instances.When
inferInstanceAs (SomeClass A)is used to defineSomeClass B(whereBis a non-reducible alias forA), the synthesized instance may contain lambda binder domains (and other sub-expressions) referring toAor deeper unfoldings instead ofB. This is invisible atdefaulttransparency but causesisDefEqfailures atreducibleAndInstancestransparency — which is the level used bygrind'scheckInst.inferInstanceAs%fixes this by recursively normalizing the constructor tree: it WHNFs to expose the constructor, patches carrier type parameters viaisDefEqmatching against the unfolding chain, recursively processes instance-implicit fields, and replaces lambda binder domains in function fields.As a demonstration, this fixes the
grindfailure inFiniteResidueFieldthat was worked around with#adaptation_noteand a manual proof onnightly-testing.🤖 Prepared with Claude Code