Skip to content

Hash-cons and simplify descriptor BDDs#15292

Draft
gldubc wants to merge 5 commits intoelixir-lang:mainfrom
gldubc:hash-consing-bdd-simplifications
Draft

Hash-cons and simplify descriptor BDDs#15292
gldubc wants to merge 5 commits intoelixir-lang:mainfrom
gldubc:hash-consing-bdd-simplifications

Conversation

@gldubc
Copy link
Copy Markdown
Member

@gldubc gldubc commented Apr 20, 2026

Summary

  • hash-cons BDD leaves and nodes by storing precomputed hashes
  • route list, map, and tuple unions/intersections/differences through the generic BDD operations and simplify split/negation paths instead of keeping the previous specialized optimizations
  • add bdd simplifications that leverage hash-consing

Keeping hashes on the BDD structure and simplifying through the generic operations reduces repeated structural work and makes equivalent fragments cheaper to compare and reuse.

Validation

  • 109/123 tests passing, 14 assertions failing in Module.Types.DescrTest (leaving this as a draft PR)

@gldubc
Copy link
Copy Markdown
Member Author

gldubc commented Apr 24, 2026

Those are the expected type-checking times for this PR:

| Codebase | LoC | Files | Modules | TC Time |
|---|---:|---:|---:|---:|
| Livebook | 65,218 | 264 | 266 | 0.184 s |
| HexPm | 33,360 | 282 | 301 | 0.158 s |
| Ecto | 32,804 | 56 | 147 | 0.036 s |
| Credo | 29,199 | 262 | 327 | 0.052 s |
| Phoenix | 22,817 | 74 | 110 | 0.026 s |
| OpenApiSpex | 8,613 | 80 | 103 | 0.155 s |
| ExDoc | 7,297 | 30 | 36 | 0.020 s |
| Nerves | 6,024 | 51 | 52 | 0.008 s |
| Spitfire | 4,876 | 5 | 7 | 1.008 s |
| SQL | 3,782 | 18 | 19 | timeout after 10 s |
| AbsintheFederation | 2,158 | 18 | 23 | 0.011 s |

And those are the times with arg == head_arg set to false

| Codebase | LoC | Files | Modules | TC Time |
|---|---:|---:|---:|---:|
| Livebook | 65,218 | 264 | 266 | 0.189 s |
| HexPm | 33,360 | 282 | 301 | 0.172 s |
| Ecto | 32,804 | 56 | 147 | 0.051 s |
| Credo | 29,199 | 262 | 327 | timeout after 10 s |
| Phoenix | 22,817 | 74 | 110 | 0.030 s |
| OpenApiSpex | 8,613 | 80 | 103 | 0.289 s |
| ExDoc | 7,297 | 30 | 36 | 0.017 s |
| Nerves | 6,024 | 51 | 52 | 0.010 s |
| Spitfire | 4,876 | 5 | 7 | timeout after 10 s |
| SQL | 3,782 | 18 | 19 | timeout after 10 s |
| AbsintheFederation | 2,158 | 18 | 23 | timeout after 10 s |

Long times to be solved by caching bdd ops (coming later)

gldubc added 5 commits April 24, 2026 16:35
Store hashes directly on BDD leaves and nodes so equality checks can short-circuit while still normalizing legacy two- and four-tuple forms. Route BDD construction through bdd_leaf_new/2 and bdd_node_new/4 to keep descriptors in the hashed representation.

Centralize node construction through bdd_split/4 and use it from union, difference, intersection, and negation paths. This lets construction immediately discard redundant branches, simplify branches under union assumptions, and preserve normalized hashes after transformations.

When unioning a BDD node with its own literal, put the literal into the union arm instead of replacing the positive branch with top. Then collapse splits whose union arm already covers the split literal, removing redundant negative occurrences such as (t2 \ t1) | t1 into the plain t1 | t2 shape.

Add descriptor coverage for union(difference(t2, t1), t1) over nested list BDDs. The test documents the exact-match normalization invariant: the redundant negation is removed, while leaf-level semantic union may still decide whether t1 | t2 further collapses to t2.
Map unions were taking the map-specific merge path eagerly. In large inferred descriptors that can repeatedly merge field shapes even when preserving the generic BDD union is enough for the hot path.

Route maps through the generic BDD union and keep the fallback equal cases for difference and intersection in split form. This avoids expanding the decision literal back into a union, which reduces repeated normalization and simplification work on large chained refinements.

Add a regression for chained list differences and unions so the rewritten BDD operations keep the expected semantic shape.
@gldubc gldubc force-pushed the hash-consing-bdd-simplifications branch from 0d476f6 to d159d77 Compare April 24, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant