feat: implement variable-bound FOL domain resolution for descendants/children

- Extend DomainResolver.resolve() signature to accept optional BindingEnv
  so that parentVar domains can be resolved with runtime variable bindings
- Pass BindingEnv through evaluateForAll/evaluateExists to resolver calls
- Add buildAncestorIndex() to precompute DOM ancestor sets from CDP data
- SelectorDomainResolver now filters descendant domains by the bound parent
  when domain.parentVar is present and ancestor index is available
- Return undefined for parentVar domains when no ancestor index or env
  (prevents silent fallback to global domain resolution)
- Update all test DomainResolver mocks for new resolve interface
- Add 10 unit tests covering ancestor index construction, backward compat,
  descendant filtering, exclusion of non-descendants, empty descendants,
  missing parentVar/env, and no-ancestor-index safety
This commit is contained in:
John Dvorak
2026-05-21 17:05:35 -07:00
parent b7ac0e8f31
commit 19559b658b
9 changed files with 465 additions and 270 deletions
+3 -3
View File
@@ -97,7 +97,7 @@ export interface FormulaResult {
// ---------------------------------------------------------------------------
export interface DomainResolver {
resolve(domain: DomainRef): DomainValue | undefined;
resolve(domain: DomainRef, env?: BindingEnv): DomainValue | undefined;
}
// ---------------------------------------------------------------------------
@@ -262,7 +262,7 @@ function evaluateForAll(
// Resolve domains and build join specs.
const specs: JoinSpec[] = [];
for (const binding of formula.bindings) {
const domain = state.resolver.resolve(binding.domain);
const domain = state.resolver.resolve(binding.domain, env);
if (!domain) {
addDiagnostic(
state,
@@ -403,7 +403,7 @@ function evaluateExists(
// Resolve domains and build join specs.
const specs: JoinSpec[] = [];
for (const binding of formula.bindings) {
const domain = state.resolver.resolve(binding.domain);
const domain = state.resolver.resolve(binding.domain, env);
if (!domain) {
addDiagnostic(
state,