Expand description
Transitive type inference across SCC predicates.
Closes the PR 5 policy gap: where a join-key vertex was anchored
only through SCC-recursive atoms, the typed gate previously left
it untyped under “unknown ≠ unsupported.” This module propagates
types through the rule graph — body atoms type variables, head
atoms back-propagate to head-predicate columns, iterate to
fixpoint — so the typed gate has full type information when it
consults super::analyze_typed.
§Where inference is engaged
Only the group-aware typed entry points engage inference:
super::evaluate_scc_fixpoint_typedruns inference once at entry, then types each rule’s body using the inferred schemas plusbase_relations.super::evaluate_fixpoint_typedtreatstarget_predicateas a single-element rule group and runs the same inference.
The single-rule entry points retain the base-only typing policy because they have no SCC structure to propagate over:
super::evaluate_rule_typedtakes one rule.super::plan_rule/super::plan_rulesplan per-rule.
Callers that want SCC-aware planning should drive
super::evaluate_scc_fixpoint_typed directly or build their
own inference pass via infer_scc_predicate_schemas.
§Conflict layering
Inference detects only back-propagation conflicts: e.g.,
predicate p’s column 0 is U32 from rule A’s head and
Symbol from rule B’s head → InferenceError::ConflictingPredicateColumnType.
Within-rule body conflicts (variable X typed U32 in one body
atom and Symbol in another) stay in the existing
super::typed flow and surface as
super::RefEvalError::ConflictingVariableType. Each conflict
type is detected at exactly one layer.
§Cyclic-only predicates
When an SCC has no base anchor anywhere (e.g., a(X) :- b(X), b(X) :- a(X) with no rule referencing base_relations), every
column converges to None. The typed gate must NOT reject such
rules: the policy narrows from “unknown ≠ unsupported” to
“unknowable-after-inference ≠ unsupported.” Locked by
cyclic_only_predicate_still_passes_typed_gate_locked_policy.
§Strict-correctness behavior change
Fixtures whose base-relation schemas disagreed but whose actual
rows happened to agree at runtime were previously silent (the
typed gate types each body atom independently). They now surface
as InferenceError::ConflictingPredicateColumnType when
back-propagating to a head predicate. That is a strict
correctness win, not a regression — fixtures with internally
contradictory schemas are now caught before evaluation rather
than silently corrupting downstream comparisons.
Enums§
- Inference
Error - Errors surfaced by
infer_scc_predicate_schemas.
Functions§
- infer_
scc_ predicate_ schemas - Infer per-predicate schemas for a rule group via constraint propagation through the rule graph.
Type Aliases§
- Inferred
Schemas - Per-predicate inferred schema.
Veclength equals the head arity; each element isSome(t)if inference established the column’s type, orNoneif the column remains unknowable (e.g., cyclic-only predicate, or a head term whose body atoms don’t type the corresponding variable).