Skip to content

Apply a function slot's domain rule once its kind is resolved, not at each merge - #116

Open
dpmills wants to merge 1 commit into
dmills/not-a-valuefrom
dmills/domain-rule-at-coalesce
Open

Apply a function slot's domain rule once its kind is resolved, not at each merge#116
dpmills wants to merge 1 commit into
dmills/not-a-valuefrom
dmills/domain-rule-at-coalesce

Conversation

@dpmills

@dpmills dpmills commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

CompactFun::merge chose how to combine two domains from the slot's KindMerge — union the alternatives for Data, take the contravariant meet otherwise — but a slot's kind is not settled until the last bound has merged, so the choice came from an answer that did not exist yet and a later bound could not undo it. Association therefore decided the outcome: an undetermined pair took the meet, {a} ⊓ {b} is {a, b}, and that deduplicated against a Data bound's own {a, b}, so a join of three collections over {a, b}, {a} and {b} typed as one collection over {a, b} in one association and was rejected in the other. The accepting association is the wrong answer: the kinds join to Data, all three domains are the data, and union_domains states the rule the meet broke — narrowing a data domain drops rows.

A positive join now accumulates the alternatives whatever the kind, and coalesce_compact_go applies the resolved kind's rule once: it meets the alternatives for a Compute reading and for a kind variable nothing pinned, and requires a single survivor for Data. The kind itself joins in the flat semilattice Unknown < {Data, Compute} < Conflict, which is the same operation at both polarities, so merge's four kind branches collapse to one. A negative merge still meets its domains directly — that rule never read the kind.

undetermined_kinds_join_without_deciding_the_domain_rule pins the exhibit in every association, and two_undetermined_kinds_join_to_a_capability_over_the_met_domain pins the join that must keep working: two undetermined-kind bounds over {a} and {b} are a capability over {a, b}, which a rule that merely rejected an undetermined join would have refused. Instrumenting the arm showed no compiled program in the suite reaches a positive undetermined join, and no inferred type changes: the suite passes forward, under DEEP_TYPECHECK=1, and under CAMBRA_REFINEMENT_ORDER=reverse.

@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch from 3e99740 to deda9e9 Compare August 20, 2026 20:51
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch from deda9e9 to 2179abc Compare August 20, 2026 23:24
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch from 2179abc to 500161c Compare August 21, 2026 04:29
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch from 500161c to 873242e Compare August 21, 2026 04:39
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch from 873242e to b1ae9a5 Compare August 21, 2026 04:55
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch from b1ae9a5 to adeb0f5 Compare August 21, 2026 05:47
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch 2 times, most recently from ab5d9d4 to f04d474 Compare August 21, 2026 19:42
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch from f04d474 to 5a72e3f Compare August 21, 2026 20:45
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch from 5a72e3f to b716cf5 Compare August 21, 2026 22:23
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch from b716cf5 to 55f3df8 Compare August 22, 2026 00:08
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch 2 times, most recently from 076ac6c to f34cf64 Compare August 22, 2026 00:35
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch from f34cf64 to 54cbd24 Compare August 22, 2026 00:46
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch from 54cbd24 to e3b0c9c Compare August 22, 2026 01:06
… each merge

`CompactFun::merge` chose how to combine two domains from the slot's `KindMerge` — union the alternatives for `Data`, take the contravariant meet otherwise — but a slot's kind is not settled until the last bound has merged, so the choice came from an answer that did not exist yet and a later bound could not undo it. Association therefore decided the outcome: an undetermined pair took the meet, `{a} ⊓ {b}` is `{a, b}`, and that deduplicated against a `Data` bound's own `{a, b}`, so a join of three collections over `{a, b}`, `{a}` and `{b}` typed as one collection over `{a, b}` in one association and was rejected in the other. The accepting association is the wrong answer: the kinds join to `Data`, all three domains *are* the data, and `union_domains` states the rule the meet broke — narrowing a data domain drops rows.

A positive join now accumulates the alternatives whatever the kind, and `coalesce_compact_go` applies the resolved kind's rule once: it meets the alternatives for a `Compute` reading and for a kind variable nothing pinned, and requires a single survivor for `Data`. The kind itself joins in the flat semilattice `Unknown < {Data, Compute} < Conflict`, which is the same operation at both polarities, so `merge`'s four kind branches collapse to one. A negative merge still meets its domains directly — that rule never read the kind.

`undetermined_kinds_join_without_deciding_the_domain_rule` pins the exhibit in every association, and `two_undetermined_kinds_join_to_a_capability_over_the_met_domain` pins the join that must keep working: two undetermined-kind bounds over `{a}` and `{b}` are a capability over `{a, b}`, which a rule that merely rejected an undetermined join would have refused. Instrumenting the arm showed no compiled program in the suite reaches a positive undetermined join, and no inferred type changes: the suite passes forward, under `DEEP_TYPECHECK=1`, and under `CAMBRA_REFINEMENT_ORDER=reverse`.
@dpmills
dpmills force-pushed the dmills/domain-rule-at-coalesce branch from e3b0c9c to d3f11af Compare August 22, 2026 03:43
@dpmills
dpmills marked this pull request as ready for review August 22, 2026 03:50
@dpmills
dpmills requested a review from a team as a code owner August 22, 2026 03:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant