srdatalog.ir.hir.lower¶
HIR -> MIR Lowering (Pass 6). Phase 1+2.
Phase 1 (shipped): single-clause variant case + helpers. Phase 2 (this file): multi-clause lowering (ColumnJoin per join var + one CartesianJoin for the remaining independent vars), negation patterns, and the four maintenance generators (rebuild/merge indices, simple + loop maintenance).
Phase 3 (future): stratum wrapping (ExecutePipeline / Block / FixpointPlan / Program, parallel groups, schema arities, before/after hooks) and a Nim-side tool that emits MIR S-expr so we can do end-to-end byte-diff.
Deliberately NOT ported (no Python DSL equivalent or deferred optimization):
Binary-join / materialized-join dispatch (alternate dialects)
Balanced-scan (balancedRoot / balancedSources pragmas)
Split rule lowering (SplitClause + tempRelName)
IfClause (Filter) / LetClause (ConstantBind) / AggClause handling
InnerPipeline / debug-hook injection
Module Contents¶
Functions¶
Mirror Nim generateColumnSource. Used by Phase 2 ColumnJoin lowering. |
|
Mirror Nim generateInsertInto. Emits to NEW_VER (always) with the stratum’s canonical index for the head relation. |
|
Maintenance at the end of a fixpoint iteration. |
|
Mirror Nim generateScan. Produces the Scan node used as the outer iteration driver when a variant has a single body clause. |
|
Maintenance for a non-recursive (simple) SCC: build canonical NEW, size-check, compute delta, clear NEW, rebuild non-canonical DELTAs, merge every index into FULL. |
|
Top-level lowering entry: HirProgram -> MIR Program. |
|
Assemble per-stratum FixpointPlan + PostStratumReconstructInternCols
steps. Returns the flat |
|
Mirror lowerSplitAbove in lowering.nim. Supports single-positive-clause above-split (Scan + negations + filter/let), which covers the negation- pushdown use case. Returns empty list if multi-positive above-split is encountered (caller falls back to full pipeline). |
|
Mirror lowerSplitBelow: Scan(temp) + CartesianJoin(below sources, prefix = temp vars that they share) + below negations + below filters |
|
Lower a rule variant to an MIR pipeline. |
|
Wrap a pipeline body in an ExecutePipeline node, extracting source specs (flattened through ColumnJoin/CartesianJoin) and dest specs (InsertInto nodes). |
API¶
- srdatalog.ir.hir.lower.generate_column_source(pattern: srdatalog.ir.hir.types.AccessPattern) srdatalog.ir.mir.types.ColumnSource[source]¶
Mirror Nim generateColumnSource. Used by Phase 2 ColumnJoin lowering.
- srdatalog.ir.hir.lower.generate_insert_into(head: srdatalog.dsl.Atom, canonical_index: list[int]) srdatalog.ir.mir.types.InsertInto[source]¶
Mirror Nim generateInsertInto. Emits to NEW_VER (always) with the stratum’s canonical index for the head relation.
- srdatalog.ir.hir.lower.generate_loop_maintenance(rel_name: str, indices: list[list[int]], canonical_index: list[int], arity: int, full_needed: set[tuple[int, ...]] | None = None) list[srdatalog.ir.mir.types.MirNode][source]¶
Maintenance at the end of a fixpoint iteration.
full_neededis the set of (completed) indices whose FULL-version is actually read by joins in this SCC — only those (plus the canonical index) need MergeIndex into FULL. Others just get their DELTA rebuilt.
- srdatalog.ir.hir.lower.generate_merge_indices(rel_name: str, indices: list[list[int]]) list[srdatalog.ir.mir.types.MirNode][source]¶
- srdatalog.ir.hir.lower.generate_rebuild_indices(rel_name: str, indices: list[list[int]], version: srdatalog.ir.hir.types.Version) list[srdatalog.ir.mir.types.MirNode][source]¶
- srdatalog.ir.hir.lower.generate_scan(pattern: srdatalog.ir.hir.types.AccessPattern, bound_vars: list[str]) srdatalog.ir.mir.types.Scan[source]¶
Mirror Nim generateScan. Produces the Scan node used as the outer iteration driver when a variant has a single body clause.
bound_varsis accepted for API parity with Nim; the Nim implementation does not use it either (all binding context comes from the access pattern’s ownaccess_order/prefix_len).
- srdatalog.ir.hir.lower.generate_simple_maintenance(rel_name: str, indices: list[list[int]], canonical_index: list[int], arity: int) list[srdatalog.ir.mir.types.MirNode][source]¶
Maintenance for a non-recursive (simple) SCC: build canonical NEW, size-check, compute delta, clear NEW, rebuild non-canonical DELTAs, merge every index into FULL.
- srdatalog.ir.hir.lower.lower_hir_to_mir(hir: srdatalog.ir.hir.types.HirProgram) srdatalog.ir.mir.types.Program[source]¶
Top-level lowering entry: HirProgram -> MIR Program.
Does NOT run the MIR optimization passes (pre_reconstruct_rebuild, clause_order_reorder, etc.) that Nim’s compileToMir runs afterwards. The Nim-side tool used for golden fixtures also dumps pre-pass MIR, so byte-diff lines up.
- srdatalog.ir.hir.lower.lower_hir_to_mir_steps(hir: srdatalog.ir.hir.types.HirProgram) list[tuple[srdatalog.ir.mir.types.MirNode, bool]][source]¶
Assemble per-stratum FixpointPlan + PostStratumReconstructInternCols steps. Returns the flat
[(node, is_recursive)]sequence consumed bylower_hir_to_mir(which wraps them in a Program).Mirrors lowerHirToMirSteps in lowering.nim. Deliberately not ported from Nim (see module docstring): before/after hooks, split-rule dispatch, InjectCppHook for debug code, balanced scan.
- srdatalog.ir.hir.lower.lower_split_above(variant: srdatalog.ir.hir.types.HirRuleVariant, stratum: srdatalog.ir.hir.types.HirStratum) list[srdatalog.ir.mir.types.MirNode][source]¶
Mirror lowerSplitAbove in lowering.nim. Supports single-positive-clause above-split (Scan + negations + filter/let), which covers the negation- pushdown use case. Returns empty list if multi-positive above-split is encountered (caller falls back to full pipeline).
- srdatalog.ir.hir.lower.lower_split_below(variant: srdatalog.ir.hir.types.HirRuleVariant, stratum: srdatalog.ir.hir.types.HirStratum, temp_version: srdatalog.ir.hir.types.Version = Version.FULL) list[srdatalog.ir.mir.types.MirNode][source]¶
Mirror lowerSplitBelow: Scan(temp) + CartesianJoin(below sources, prefix = temp vars that they share) + below negations + below filters
InsertInto(head).
temp_versionswitches between the non-recursive default (FULL — the temp is merged into FULL by standard maintenance before the Scan) and the recursive inner-loop variant (NEW — temp is repopulated each iteration and consumed directly from NEW).
- srdatalog.ir.hir.lower.lower_variant_to_pipeline(variant: srdatalog.ir.hir.types.HirRuleVariant, stratum: srdatalog.ir.hir.types.HirStratum) list[srdatalog.ir.mir.types.MirNode][source]¶
Lower a rule variant to an MIR pipeline.
For a single-clause variant: Scan (+ Negation*) + InsertInto. For a multi-clause variant: ColumnJoin* + CartesianJoin? + Negation* + InsertInto.
- srdatalog.ir.hir.lower.wrap_in_execute_pipeline(pipeline: list[srdatalog.ir.mir.types.MirNode], clause_order: list[int], rule_name: str, use_fan_out: bool = False, work_stealing: bool = False, block_group: bool = False, count: bool = False, dedup_hash: bool = False) srdatalog.ir.mir.types.ExecutePipeline[source]¶
Wrap a pipeline body in an ExecutePipeline node, extracting source specs (flattened through ColumnJoin/CartesianJoin) and dest specs (InsertInto nodes).