Chapter 4 Part 1: Fully Typing a Scalar Function with If-Else Branch¶

This chapter extends the type inference system to handle control-flow constructs, specifically the if-else branch. We show how to implement complete type inference for scalar functions with conditional logic.

The chapter covers:

  • How to implement type inference for if-else constructs
  • How to handle type unification across branches
  • How to extend the compiler pipeline for type inference

Imports and Setup¶

In [1]:
from __future__ import annotations
In [2]:
import ctypes
from contextlib import contextmanager
from dataclasses import dataclass
from functools import partial
from traceback import print_exception
from typing import Any, Callable, Sequence, TypedDict
In [3]:
from egglog import (
    EGraph,
    Expr,
    Ruleset,
    String,
    StringLike,
    Unit,
    Vec,
    birewrite,
    eq,
    f64,
    function,
    i64,
    i64Like,
    join,
    method,
    ne,
    rewrite,
    rule,
    ruleset,
    set_,
    union,
    vars_,
)
from llvmlite import binding as llvm
from llvmlite import ir
from sealir import ase, grammar, rvsdg
from sealir.eqsat.py_eqsat import (
    Py_AddIO,
    Py_Call,
    Py_DivIO,
    Py_GtIO,
    Py_LoadGlobal,
    Py_LtIO,
    Py_SubIO,
)
from sealir.eqsat.rvsdg_eqsat import (
    GraphRoot,
    InPorts,
    Port,
    PortList,
    Region,
    Term,
    TermList,
    wildcard,
)
from sealir.eqsat.rvsdg_extract import (
    CostModel,
    EGraphToRVSDG,
    ExtractionError,
    egraph_extraction,
)
from sealir.rvsdg import grammar as rg
In [4]:
from ch02_egraph_basic import (
    EGraphExtractionOutput,
)
from ch03_egraph_program_rewrites import (
    EGraphOutput,
)
from ch03_egraph_program_rewrites import (
    compiler_pipeline as _ch03_compiler_pipeline,
)
from ch03_egraph_program_rewrites import (
    egraph_saturation as _ch03_egraph_saturation,
)
from ch03_egraph_program_rewrites import (
    run_test,
)
from ch04_0_typeinfer_prelude import (
    basic_ruleset,
)
from utils import IN_NOTEBOOK, Pipeline, Report, display
In [5]:
_wc = wildcard

Defining Types¶

First we'll define the Type and TypeVar in the EGraph.

Type¶

Type is the actual type. A simple type will just be identified by its name. The only operation that it has is | for unifying two types. For simplicity, we will actually forbid unifying types so that will not be any implicit casting.

In [6]:
class Type(Expr):
    @classmethod
    def simple(self, name: StringLike) -> Type:
        "Construct a Type with name"
        ...

    def __or__(self, other: Type) -> Type:
        "Unify with other Type"
        ...
In [7]:
TypeInt64 = Type.simple("Int64")
TypeBool = Type.simple("Bool")
TypeFloat64 = Type.simple("Float64")
In [8]:
if __name__ == "__main__":
    print("Valid types:")
    print(TypeInt64)
    print(TypeBool)
    print(TypeFloat64)
    print("The following will not be allowed:")
    print(TypeInt64 | TypeFloat64)
    print(TypeInt64 | TypeFloat64 | TypeInt64)
Valid types:
Type.simple("Int64")
Type.simple("Bool")
Type.simple("Float64")
The following will not be allowed:
Type.simple("Int64") | Type.simple("Float64")
(Type.simple("Int64") | Type.simple("Float64")) | Type.simple("Int64")

Let's define some rules that will establish what is disallowed:

In [9]:
@function
def failed_to_unify(ty: Type) -> Unit: ...
In [10]:
@ruleset
def ruleset_type_basic(
    ta: Type,
    tb: Type,
    tc: Type,
    name: String,
    ty: Type,
):
    # If ta == tb. then ta
    yield rewrite(ta | tb, subsume=True).to(ta, ta == tb)
    # Simplify
    yield rewrite(ta | tb).to(tb | ta)
    yield birewrite((ta | tb) | tc).to(ta | (tb | tc))

    # Identify errors
    yield rule(
        # If both sides are valid types and not equal, then fail
        ty == ta | tb,
        ne(ta).to(tb),  # ta != tb
    ).then(failed_to_unify(ty))
In [11]:
if __name__ == "__main__":
    eg = EGraph()
    eg.register(TypeInt64)
    eg.register(TypeBool)
    eg.register(TypeFloat64)
    eg.register(TypeInt64 | TypeFloat64)
    eg.register(TypeInt64 | TypeFloat64 | TypeInt64)

    print("First run")
    eg.run(ruleset_type_basic)
    if IN_NOTEBOOK:
        eg.display(graphviz=True)
    print("Second run")
    eg.run(ruleset_type_basic)
    if IN_NOTEBOOK:
        eg.display(graphviz=True)
    print("Fully saturated")
    eg.run(ruleset_type_basic.saturate())
    if IN_NOTEBOOK:
        eg.display(graphviz=True)
First run
No description has been provided for this image
Second run
No description has been provided for this image
Fully saturated
No description has been provided for this image

TypeVar¶

A type variable for associating program terms and their type. Later on, we will merge type variables that are associating with different terms. This is needed for the unification of values after a conditional branch (if-else).

In [12]:
class TypeVar(Expr):
    def __init__(self, term: Term):
        "Create a TypeVar for a Term"
        ...

    @method(merge=lambda x, y: x | y)
    def getType(self) -> Type:
        """Get the type for this TypeVar.

        Multiple definitions will be merged by Type.__or__, causing a
        unification.
        """
        ...

Example use of TypeVar showing what happens when type-variables with conflicting types are merged:

In [13]:
if __name__ == "__main__":
    eg = EGraph()
    tv_x = TypeVar(Term.LiteralStr("x"))
    tv_y = TypeVar(Term.LiteralStr("y"))
    eg.register(
        set_(tv_x.getType()).to(TypeInt64),
        set_(tv_y.getType()).to(TypeFloat64),
    )
    eg.run(ruleset_type_basic.saturate())
    if IN_NOTEBOOK:
        eg.display(graphviz=True)
No description has been provided for this image

Merging the two type variables will also merge the type that points to:

In [14]:
if __name__ == "__main__":
    eg.register(union(tv_x).with_(tv_y))
    eg.run(ruleset_type_basic.saturate())
    if IN_NOTEBOOK:
        eg.display(graphviz=True)
No description has been provided for this image

Handling type inference errors¶

Type inference can fail, so we must provide a mechanism for reporting errors.

ErrorMsg¶

We'll define a ErrorMsg class in the egraph to capture all the error message. The compilation will always start with ErrorMsg.root() in the EGraph. When type inference encounters an error, That root node will be merged with ErroMsg.fail() nodes.

In [15]:
class ErrorMsg(Expr):
    @classmethod
    def root(cls) -> ErrorMsg:
        "The empty root"
        ...

    @classmethod
    def fail(cls, msg: String) -> ErrorMsg:
        "A node for failure message"
        ...

    @method(preserve=True)
    def eval(self) -> tuple[str, tuple]:
        """
        This is for converting the information in the EGraph back to
        Python. This will parse the EGraph node to extract the message string.
        """
        from egglog.builtins import ClassMethodRef, _extract_call

        call = _extract_call(self)
        if isinstance(call.callable, ClassMethodRef):
            assert call.callable.class_name == "ErrorMsg"
            args = [self.__with_expr__(x).eval() for x in call.args]
            return call.callable.method_name, tuple(args)
        raise TypeError

Helpers to process the error message

In [16]:
def get_error_message(err_info: tuple[str, tuple]) -> str:
    "Helper to process the result of ErrorMsg.eval()"
    match err_info:
        case "fail", (msg,):
            return msg
        case _:
            raise NotImplementedError

For example

In [17]:
if __name__ == "__main__":
    root = ErrorMsg.root()
    eg = EGraph()
    eg.register(
        union(root).with_(ErrorMsg.fail("I failed")),
        union(root).with_(ErrorMsg.fail("Failed again")),
    )
    if IN_NOTEBOOK:
        eg.display(graphviz=True)
    msgs = eg.extract_multiple(root, n=3)
    print(msgs)
    for msg in msgs:
        print(msg.eval())
        try:
            print(get_error_message(msg.eval()))
        except NotImplementedError:
            print("no msg")
No description has been provided for this image
[ErrorMsg.root(), ErrorMsg.fail("I failed"), ErrorMsg.fail("Failed again")]
('root', ())
no msg
('fail', ('I failed',))
I failed
('fail', ('Failed again',))
Failed again

Typing addition¶

Given a function:

In [18]:
def example_0(a, b):
    return a + b

To implement the addition, we define the operation as an egraph functions:

Int64 + Int64 -> Int64

In [19]:
@function
def Nb_Add_Int64(lhs: Term, rhs: Term) -> Term: ...

Float64 + Float64 -> Float64

In [20]:
@function
def Nb_Add_Float64(lhs: Term, rhs: Term) -> Term: ...

Helper for binary operations

In [21]:
def make_rules_for_binop(binop, lhs_type, rhs_type, typedop, res_type):
    io, lhs, rhs, op = vars_("io lhs rhs op", Term)
    yield rule(
        op == binop(io, lhs, rhs),
        TypeVar(lhs).getType() == lhs_type,
        TypeVar(rhs).getType() == rhs_type,
    ).then(
        # convert to a typed operation
        union(op.getPort(1)).with_(typedop(lhs, rhs)),
        # shortcut io
        union(op.getPort(0)).with_(io),
    )

    yield rule(op == typedop(lhs, rhs)).then(
        # output type
        set_(TypeVar(op).getType()).to(res_type),
    )

Define addition

In [22]:
@ruleset
def ruleset_type_infer_add():
    # Int64 + Int64 -> Int64
    yield from make_rules_for_binop(
        Py_AddIO, TypeInt64, TypeInt64, Nb_Add_Int64, TypeInt64
    )
    # Float64 + Float64 -> Float64
    yield from make_rules_for_binop(
        Py_AddIO, TypeFloat64, TypeFloat64, Nb_Add_Float64, TypeFloat64
    )

Define argument types and their propagations:

In [23]:
def setup_argtypes(*argtypes):
    def rule_gen(region):
        return [
            set_(TypedIns(region).arg(i).getType()).to(ty)
            for i, ty in enumerate(argtypes, start=1)
        ]

    @ruleset
    def arg_rules(
        outports: Vec[Port],
        func_uid: String,
        reg_uid: String,
        fname: String,
        region: Region,
    ):
        yield rule(
            # This match the function at graph root
            GraphRoot(
                Term.Func(
                    body=Term.RegionEnd(
                        region=region, ports=PortList(outports)
                    ),
                    uid=func_uid,
                    fname=fname,
                )
            ),
            region == Region(uid=reg_uid, inports=_wc(InPorts)),
        ).then(*rule_gen(region))

    return arg_rules

Associate type variables to region inputs/outputs.

In [24]:
class TypedIns(Expr):
    def __init__(self, region: Region): ...

    def arg(self, idx: i64Like) -> TypeVar: ...
In [25]:
class TypedOuts(Expr):
    def __init__(self, region: Region): ...

    def at(self, idx: i64Like) -> TypeVar: ...
In [26]:
@ruleset
def ruleset_region_types(
    region: Region,
    idx: i64,
    typ: TypeVar,
    term: Term,
    portlist: PortList,
):
    # Propagate region types
    yield rule(
        # Inputs
        typ == TypedIns(region).arg(idx),
        term == region.get(idx),
    ).then(
        union(TypeVar(term)).with_(typ),
    )

    yield rule(
        # Outputs
        term == Term.RegionEnd(region=region, ports=portlist),
        pv := portlist.getValue(idx),
    ).then(
        union(TypedOuts(region).at(idx)).with_(TypeVar(pv)),
    )
In [27]:
if __name__ == "__main__":
    display(_ch03_compiler_pipeline.visualize())
    rules = (
        basic_ruleset
        | ruleset_region_types
        | ruleset_type_basic
        | ruleset_type_infer_add
        | setup_argtypes(TypeInt64, TypeInt64)
    )
    report = Report("Compiler Pipeline", default_expanded=True)
    try:
        # this should raise a NotImplementedError because we haven't implemented
        # the conversions of `Nb_Add_Int64` back into RVSDG.
        cres = _ch03_compiler_pipeline(
            fn=example_0, ruleset=rules, pipeline_report=report
        )
    except NotImplementedError as e:
        # Expect the error to be raised because we haven't implemented the
        # conversions of `Nb_Add_Int64` back into RVSDG.

        # check __notes__ of the exception
        for note in e.__notes__:
            if "Nb_Add_Int64" in str(note):
                print("Error note:")
                print(note)
                break
        else:
            assert False, "should not reach here"
    else:
        # an error should have been raised
        assert False, "should not reach here"
    finally:
        report.display()
Pipeline-pipeline_backend cluster_legend Legend input_fn fn Any stage_1 Stage 1 pipeline_frontend → FrontendOutput input_fn->stage_1 fn input_ruleset ruleset Ruleset stage_3 Stage 3 egraph_saturation → EGraphOutput input_ruleset->stage_3 ruleset input_pipeline_report pipeline_report Any = DummyReport() input_pipeline_report->stage_1 pipeline_report stage_2 Stage 2 pipeline_egraph_conversion → EGraphOutput input_pipeline_report->stage_2 pipeline_report input_pipeline_report->stage_3 pipeline_report stage_4 Stage 4 pipeline_egraph_extraction → EGraphExtractionOutput input_pipeline_report->stage_4 pipeline_report stage_5 Stage 5 pipeline_backend → BackendOutput input_pipeline_report->stage_5 pipeline_report stage_1->stage_2 rvsdg_expr stage_1->stage_4 rvsdg_expr out_dbginfo dbginfo object stage_1->out_dbginfo dbginfo out_rvsdg_expr rvsdg_expr object stage_1->out_rvsdg_expr rvsdg_expr stage_2->stage_3 egraph stage_2->stage_3 egraph_root stage_3->stage_4 egraph out_egraph egraph EGraph stage_3->out_egraph egraph out_egraph_root egraph_root GraphRoot stage_3->out_egraph_root egraph_root stage_4->stage_5 extracted out_cost cost float stage_4->out_cost cost out_extracted extracted Any stage_4->out_extracted extracted out_jit_func jit_func Any stage_5->out_jit_func jit_func out_llmod llmod Any stage_5->out_llmod llmod legend_input Required Input legend_optional Optional Input legend_input->legend_optional legend_stage Processing Stage legend_optional->legend_stage legend_output Output legend_stage->legend_output
Error note:
Extracting: function-0-Nb_Add_Int64, {'lhs': 'function-1-Region_get', 'rhs': 'function-2-Region_get'}

Compiler Pipeline

1. Frontend ▶
Frontend
Debug Info on RVSDG ▶
--------------------------------original source---------------------------------
   1|def example_0(a, b):
   2|    return a + b
----------------------------------inter source----------------------------------
   1|def transformed_example_0(a, b):
   2|    """#file: /tmp/ipykernel_3564/2077635562.py"""
   3|    '#loc: 2:8-2:20'
   4|    return a + b
RVSDG ▶
transformed_example_0 = Func (Args (ArgSpec 'a' (PyNone)) (ArgSpec 'b' (PyNone)))
$0 = Region[239] <- !io a b
{
  $1 = PyBinOp + $0[0] $0[1], $0[2]
} [314] -> !io=$1[0] !ret=$1[1]
2. EGraph Conversion ▶
EGraph Conversion
EGraph ▶
outer_cluster_InPorts-0 cluster_InPorts-0 outer_cluster_Port-7 cluster_Port-7 outer_cluster_Port-9 cluster_Port-9 outer_cluster_PortList-10 cluster_PortList-10 outer_cluster_Region-1 cluster_Region-1 outer_cluster_Term-6 cluster_Term-6 outer_cluster_Term-4 cluster_Term-4 outer_cluster_Term-12 cluster_Term-12 outer_cluster_Term-2 cluster_Term-2 outer_cluster_Term-13 cluster_Term-13 outer_cluster_Term-5 cluster_Term-5 outer_cluster_Term-3 cluster_Term-3 outer_cluster_Term-11 cluster_Term-11 outer_cluster_Term-8 cluster_Term-8 outer_cluster_Vec_Port-0 cluster_Vec_Port-0 outer_cluster_Vec_String-0 cluster_Vec_String-0 function-0-InPorts___init__:s->primitive-Vec_String-0 function-0-Port___init__:s->function-0-Term_getPort function-0-Term_getPort:s->function-0-Py_AddIO function-1-Port___init__:s->function-1-Term_getPort function-1-Term_getPort:s->function-0-Py_AddIO function-0-PortList___init__:s->primitive-Vec_Port-0 primitive-Vec_Port-0:s->function-0-Port___init__ primitive-Vec_Port-0:s->function-1-Port___init__ function-0-Region___init__:s->function-0-InPorts___init__ function-0-Py_AddIO:s->function-2-Region_get function-0-Py_AddIO:s->function-0-Region_get function-0-Py_AddIO:s->function-1-Region_get function-2-Region_get:s->function-0-Region___init__ function-0-Term_Func:s->function-0-Term_RegionEnd function-0-Term_RegionEnd:s->function-0-PortList___init__ function-0-Term_RegionEnd:s->function-0-Region___init__ function-0-Region_get:s->function-0-Region___init__ function-0-GraphRoot:s->function-0-Term_Func function-1-Region_get:s->function-0-Region___init__ function-0-InPorts___init__ InPorts primitive-Vec_String-0 Vec("!io", "a", "b") function-0-Port___init__ Port("!io", ·) function-0-Term_getPort ·.getPort(·, 0) function-1-Port___init__ Port("!ret", ·) function-1-Term_getPort ·.getPort(·, 1) function-0-PortList___init__ PortList primitive-Vec_Port-0 Vec function-0-Region___init__ Region("239", ·) function-0-Py_AddIO Py_AddIO function-2-Region_get ·.get(·, 2) function-0-Term_Func Term.Func("320", "transformed_example_0", ·) function-0-Term_RegionEnd Term.RegionEnd function-0-Region_get ·.get(·, 0) function-0-GraphRoot GraphRoot function-1-Region_get ·.get(·, 1)
3. EGraph Saturated ▶
outer_cluster_InPorts-0 cluster_InPorts-0 outer_cluster_Port-35 cluster_Port-35 outer_cluster_Port-26 cluster_Port-26 outer_cluster_PortList-10 cluster_PortList-10 outer_cluster_Region-1 cluster_Region-1 outer_cluster_String-20 cluster_String-20 outer_cluster_String-2684354583 cluster_String-2684354583 outer_cluster_Term-28 cluster_Term-28 outer_cluster_Term-41 cluster_Term-41 outer_cluster_Term-13 cluster_Term-13 outer_cluster_Term-3 cluster_Term-3 outer_cluster_Term-40 cluster_Term-40 outer_cluster_Term-4 cluster_Term-4 outer_cluster_Term-12 cluster_Term-12 outer_cluster_Term-5 cluster_Term-5 outer_cluster_Term-21 cluster_Term-21 outer_cluster_Term-11 cluster_Term-11 outer_cluster_Type-19 cluster_Type-19 outer_cluster_TypeVar-32 cluster_TypeVar-32 outer_cluster_TypeVar-24 cluster_TypeVar-24 outer_cluster_TypeVar-37 cluster_TypeVar-37 outer_cluster_TypeVar-25 cluster_TypeVar-25 outer_cluster_TypedIns-17 cluster_TypedIns-17 outer_cluster_TypedOuts-31 cluster_TypedOuts-31 outer_cluster_Vec_Port-2 cluster_Vec_Port-2 outer_cluster_Vec_String-0 cluster_Vec_String-0 function-0-InPorts___init__:s->primitive-Vec_String-0 function-1-Port___init__:s->function-1-Port_value function-1-Port_value:s->function-1-Port___init__ function-1-PortList___getitem__:s->function-0-PortList___init__ function-0-PortList___init__:s->primitive-Vec_Port-2 function-0-Port___init__:s->function-0-PortList_getValue function-0-PortList_getValue:s->function-0-PortList___init__ function-0-PortList___getitem__:s->function-0-PortList___init__ primitive-Vec_Port-2:s->function-1-PortList___getitem__ primitive-Vec_Port-2:s->function-0-PortList___getitem__ function-0-Region___init__:s->function-0-InPorts___init__ function-2-Port_name:s->function-0-PortList___getitem__ function-3-Port_name:s->function-1-PortList___getitem__ function-0-Nb_Add_Int64:s->function-1-Region_get function-0-Nb_Add_Int64:s->function-2-Region_get function-1-Region_get:s->function-0-Region___init__ function-2-Region_get:s->function-0-Region___init__ function-4-Term_getPort:s->function-0-Py_AddIO function-0-Py_AddIO:s->function-1-Region_get function-0-Py_AddIO:s->function-2-Region_get function-0-Py_AddIO:s->function-3-Term_getPort function-1-PortList_getValue:s->function-0-PortList___init__ function-6-Term_getPort:s->function-0-Term_RegionEnd function-0-Term_RegionEnd:s->function-0-PortList___init__ function-0-Term_RegionEnd:s->function-0-Region___init__ function-0-GraphRoot:s->function-0-Term_Func function-0-Term_Func:s->function-0-Term_RegionEnd function-5-Term_getPort:s->function-0-Term_RegionEnd function-3-Term_getPort:s->function-0-Py_AddIO function-4-Region_get:s->function-0-Region___init__ function-0-Port_value:s->function-0-Port___init__ function-2-TypeVar_getType:s->function-2-TypedIns_arg function-2-TypedIns_arg:s->function-0-TypedIns___init__ function-3-TypeVar_getType:s->function-3-TypedIns_arg function-3-TypedIns_arg:s->function-0-TypedIns___init__ function-5-TypeVar_getType:s->function-1-TypedOuts_at function-1-TypedOuts_at:s->function-0-TypedOuts___init__ function-0-TypedOuts_at:s->function-0-TypedOuts___init__ function-0-TypedOuts___init__:s->function-0-Region___init__ function-3-TypeVar___init__:s->function-0-PortList_getValue function-0-TypeVar___init__:s->function-1-Region_get function-0-TypedIns___init__:s->function-0-Region___init__ function-6-TypeVar___init__:s->function-1-Port_value function-1-TypeVar___init__:s->function-2-Region_get function-0-InPorts___init__ InPorts primitive-Vec_String-0 Vec("!io", "a", "b") function-1-Port___init__ Port("!ret", ·) function-1-Port_value ·.value function-1-PortList___getitem__ ·[1] function-0-PortList___init__ PortList function-0-Port___init__ Port("!io", ·) function-0-PortList_getValue ·.getValue(·, 0) function-0-PortList___getitem__ ·[0] primitive-Vec_Port-2 Vec function-0-Region___init__ Region("239", ·) function-2-Port_name ·.name primitive-String-20 "!io" function-3-Port_name ·.name primitive-String-2684354583 "!ret" function-0-Nb_Add_Int64 Nb_Add_Int64 function-1-Region_get ·.get(·, 1) function-2-Region_get ·.get(·, 2) function-4-Term_getPort ·.getPort(·, 1) function-0-Py_AddIO Py_AddIO function-1-PortList_getValue ·.getValue(·, 1) function-6-Term_getPort ·.getPort(·, 1) function-0-Term_RegionEnd Term.RegionEnd function-0-GraphRoot GraphRoot function-0-Term_Func Term.Func("320", "transformed_example_0", ·) function-5-Term_getPort ·.getPort(·, 0) function-3-Term_getPort ·.getPort(·, 0) function-4-Region_get ·.get(·, 0) function-0-Port_value ·.value function-2-TypeVar_getType ·.getType function-2-TypedIns_arg ·.arg(·, 1) function-3-TypeVar_getType ·.getType function-3-TypedIns_arg ·.arg(·, 2) function-5-TypeVar_getType ·.getType function-1-TypedOuts_at ·.at(·, 1) function-0-Type_simple Type.simple("Int64") function-0-TypedOuts_at ·.at(·, 0) function-0-TypedOuts___init__ TypedOuts function-3-TypeVar___init__ TypeVar function-0-TypeVar___init__ TypeVar function-0-TypedIns___init__ TypedIns function-6-TypeVar___init__ TypeVar function-1-TypeVar___init__ TypeVar
4. EGraph Extraction ▶
EGraph Extraction

The above compilation have to stop early because we haven't implemented the conversions of Nb_Add_Int64 back into RVSDG.

Observe in the egraph:

  • Typedouts, TypedIns, Type.simple("Int64")

Extend the rest of the compiler¶

A more extensible compiler pipeline¶

We'll need a more extensible compiler pipeline so capability can be added later. The new pipeline also gained error checking base on whether there is ErrorMsg in the egraph.

In [28]:
class CompilationError(Exception):
    pass
In [29]:
def egraph_saturation_with_error_checking(
    egraph: EGraph,
    egraph_root: GraphRoot,
    ruleset: Ruleset,
    pipeline_debug: bool = False,
    pipeline_report=Report.Sink(),
) -> EGraphOutput:
    with pipeline_report.nest("Egraph Saturation") as report:
        # Define graph root that points to the function

        # Define the empty root node for the error messages
        errors = ErrorMsg.root()
        egraph.let("errors", errors)
        if pipeline_debug:
            report.append("[debug] initial egraph", egraph)

        # Run all the rules until saturation
        egraph.run(ruleset.saturate())

        if pipeline_debug:
            report.append("[debug] saturated egraph", egraph)
            report.append(
                "[debug] egglog.extract", egraph.extract(egraph_root)
            )

        # Use egglog's default extractor to get the error messages
        errmsgs = map(
            lambda x: x.eval(), egraph.extract_multiple(errors, n=10)
        )
        errmsgs_filtered = [
            get_error_message((meth, args))
            for meth, args in errmsgs
            if meth != "root"
        ]
        if errmsgs_filtered:
            # Raise CompilationError if there are compiler errors
            raise CompilationError("\n".join(errmsgs_filtered))

        return dict(egraph=egraph, egraph_root=egraph_root)
In [30]:
def pipeline_egraph_extraction(
    egraph,
    rvsdg_expr,
    converter_class,
    cost_model,
    pipeline_report=Report.Sink(),
) -> EGraphExtractionOutput:
    with pipeline_report.nest(
        "EGraph Extraction", default_expanded=True
    ) as report:
        try:
            # This is the same as ch4.1
            cost, extracted = egraph_extraction(
                egraph,
                rvsdg_expr,
                converter_class=converter_class,
                cost_model=cost_model,
            )
        except ExtractionError as e:
            raise CompilationError("extraction failed") from e

        report.append("Extracted RVSDG", format_rvsdg(extracted))
        report.append("Extracted cost", cost)

    return dict(cost=cost, extracted=extracted)
In [31]:
pipeline_middle_end = (
    _ch03_compiler_pipeline.trunc("egraph_saturation")
    .extend(egraph_saturation_with_error_checking)
    .extend(pipeline_egraph_extraction)
)
In [32]:
if __name__ == "__main__":
    display(pipeline_middle_end.visualize())
Pipeline-pipeline_egraph_extraction cluster_legend Legend input_converter_class converter_class Any stage_4 Stage 4 pipeline_egraph_extraction → EGraphExtractionOutput input_converter_class->stage_4 converter_class input_cost_model cost_model Any input_cost_model->stage_4 cost_model input_fn fn Any stage_1 Stage 1 pipeline_frontend → FrontendOutput input_fn->stage_1 fn input_ruleset ruleset Ruleset stage_3 Stage 3 egraph_saturation_with_error_checking → EGraphOutput input_ruleset->stage_3 ruleset input_pipeline_debug pipeline_debug bool = False input_pipeline_debug->stage_3 pipeline_debug input_pipeline_report pipeline_report Any = DummyReport() input_pipeline_report->stage_1 pipeline_report stage_2 Stage 2 pipeline_egraph_conversion → EGraphOutput input_pipeline_report->stage_2 pipeline_report input_pipeline_report->stage_3 pipeline_report input_pipeline_report->stage_4 pipeline_report stage_1->stage_2 rvsdg_expr stage_1->stage_4 rvsdg_expr out_dbginfo dbginfo object stage_1->out_dbginfo dbginfo out_rvsdg_expr rvsdg_expr object stage_1->out_rvsdg_expr rvsdg_expr stage_2->stage_3 egraph stage_2->stage_3 egraph_root stage_3->stage_4 egraph out_egraph egraph EGraph stage_3->out_egraph egraph out_egraph_root egraph_root GraphRoot stage_3->out_egraph_root egraph_root out_cost cost float stage_4->out_cost cost out_extracted extracted Any stage_4->out_extracted extracted legend_input Required Input legend_optional Optional Input legend_input->legend_optional legend_stage Processing Stage legend_optional->legend_stage legend_output Output legend_stage->legend_output
In [33]:
class BackendOutput(TypedDict):
    module: Any
In [34]:
@pipeline_middle_end.extend
def pipeline_backend(
    extracted, argtypes, backend, pipeline_report=Report.Sink()
) -> BackendOutput:
    with pipeline_report.nest("Backend") as report:
        module = backend.lower(extracted, argtypes)
        report.append("Lowered module", module)
        return dict(module=module)
In [35]:
class JitCompilerOutput(TypedDict):
    jit_func: Any
In [36]:
@pipeline_backend.extend
def jit_compiler(
    module, extracted, backend, export_func_name="func"
) -> JitCompilerOutput:
    jit_func = backend.jit_compile(module, extracted, export_func_name)
    return dict(jit_func=jit_func)
In [37]:
if __name__ == "__main__":
    display(pipeline_backend.visualize())
Pipeline-pipeline_backend cluster_legend Legend input_argtypes argtypes Any stage_5 Stage 5 pipeline_backend → BackendOutput input_argtypes->stage_5 argtypes input_backend backend Any input_backend->stage_5 backend input_converter_class converter_class Any stage_4 Stage 4 pipeline_egraph_extraction → EGraphExtractionOutput input_converter_class->stage_4 converter_class input_cost_model cost_model Any input_cost_model->stage_4 cost_model input_fn fn Any stage_1 Stage 1 pipeline_frontend → FrontendOutput input_fn->stage_1 fn input_ruleset ruleset Ruleset stage_3 Stage 3 egraph_saturation_with_error_checking → EGraphOutput input_ruleset->stage_3 ruleset input_pipeline_debug pipeline_debug bool = False input_pipeline_debug->stage_3 pipeline_debug input_pipeline_report pipeline_report Any = DummyReport() input_pipeline_report->stage_1 pipeline_report stage_2 Stage 2 pipeline_egraph_conversion → EGraphOutput input_pipeline_report->stage_2 pipeline_report input_pipeline_report->stage_3 pipeline_report input_pipeline_report->stage_4 pipeline_report input_pipeline_report->stage_5 pipeline_report stage_1->stage_2 rvsdg_expr stage_1->stage_4 rvsdg_expr out_dbginfo dbginfo object stage_1->out_dbginfo dbginfo out_rvsdg_expr rvsdg_expr object stage_1->out_rvsdg_expr rvsdg_expr stage_2->stage_3 egraph stage_2->stage_3 egraph_root stage_3->stage_4 egraph out_egraph egraph EGraph stage_3->out_egraph egraph out_egraph_root egraph_root GraphRoot stage_3->out_egraph_root egraph_root stage_4->stage_5 extracted out_cost cost float stage_4->out_cost cost out_extracted extracted Any stage_4->out_extracted extracted out_module module Any stage_5->out_module module legend_input Required Input legend_optional Optional Input legend_input->legend_optional legend_stage Processing Stage legend_optional->legend_stage legend_output Output legend_stage->legend_output

Define EGraph functions for new operations:¶

In [38]:
@function
def Nb_Gt_Int64(lhs: Term, rhs: Term) -> Term: ...
@function
def Nb_Lt_Int64(lhs: Term, rhs: Term) -> Term: ...
@function
def Nb_Sub_Int64(lhs: Term, rhs: Term) -> Term: ...
@function
def Nb_Sub_Float64(lhs: Term, rhs: Term) -> Term: ...
@function
def Nb_Div_Int64(lhs: Term, rhs: Term) -> Term: ...
@function
def Nb_CastI64ToF64(operand: Term) -> Term: ...
@function
def Nb_CastToFloat(arg: Term) -> Term: ...

Define rules for the operations:¶

In [39]:
@ruleset
def ruleset_type_infer_gt(io: Term, x: Term, y: Term, op: Term):
    yield from make_rules_for_binop(
        Py_GtIO, TypeInt64, TypeInt64, Nb_Gt_Int64, TypeBool
    )
In [40]:
@ruleset
def ruleset_type_infer_lt(io: Term, x: Term, y: Term, op: Term):
    yield from make_rules_for_binop(
        Py_LtIO, TypeInt64, TypeInt64, Nb_Lt_Int64, TypeBool
    )
In [41]:
@ruleset
def ruleset_type_infer_sub(io: Term, x: Term, y: Term, op: Term):
    yield from make_rules_for_binop(
        Py_SubIO, TypeInt64, TypeInt64, Nb_Sub_Int64, TypeInt64
    )

    yield from make_rules_for_binop(
        Py_SubIO, TypeFloat64, TypeFloat64, Nb_Sub_Float64, TypeFloat64
    )
In [42]:
## This works but not needed
# @ruleset
# def ruleset_type_infer_sub_promote(io: Term, x: Term, y: Term, op: Term):
#     # # Promote to float if one side is float
#     yield rule(
#         op == Py_SubIO(io, x, y),
#         TypeVar(x).getType() == TypeInt64,
#         TypeVar(y).getType() == TypeFloat64,
#     ).then(
#         union(op).with_(Py_SubIO(io, Nb_CastI64ToF64(x), y)),
#     )
#
#     yield rule(
#         op == Py_SubIO(io, x, y),
#         TypeVar(x).getType() == TypeFloat64,
#         TypeVar(y).getType() == TypeInt64,
#     ).then(
#         union(op).with_(Py_SubIO(io, x, Nb_CastI64ToF64(y))),
#         subsume(Py_SubIO(io, x, y)),
#     )
@ruleset
def ruleset_type_infer_literals(op: Term, ival: i64, fval: f64):
    yield rule(op == Term.LiteralI64(ival)).then(
        set_(TypeVar(op).getType()).to(TypeInt64)
    )
    yield rule(op == Term.LiteralF64(fval)).then(
        set_(TypeVar(op).getType()).to(TypeFloat64)
    )
In [43]:
@ruleset
def ruleset_typeinfer_cast(op: Term, val: Term):
    yield rule(
        op == Nb_CastI64ToF64(val),
        TypeVar(val).getType() == TypeInt64,
    ).then(
        set_(TypeVar(op).getType()).to(TypeFloat64),
    )
In [44]:
@ruleset
def ruleset_type_infer_div(io: Term, x: Term, y: Term, op: Term):
    yield from make_rules_for_binop(
        Py_DivIO, TypeInt64, TypeInt64, Nb_Div_Int64, TypeFloat64
    )

Rules for type-inference on if-else¶

Most of the logic is just propagation. The key is merging the type-variables of all outputs.

In [45]:
@ruleset
def ruleset_propagate_typeof_ifelse(
    then_region: Region,
    else_region: Region,
    idx: i64,
    stop: i64,
    ifelse: Term,
    then_ports: PortList,
    else_ports: PortList,
    operands: Vec[Term],
    ta: Type,
    tb: Type,
    ty: Type,
    vecports: Vec[Port],
):

    yield rule(
        # Propagate operand types into the contained regions
        Term.IfElse(
            cond=_wc(Term),
            then=Term.RegionEnd(region=then_region, ports=_wc(PortList)),
            orelse=Term.RegionEnd(region=else_region, ports=_wc(PortList)),
            operands=TermList(operands),
        ),
        then_region.get(idx),
    ).then(
        union(TypeVar(operands[idx])).with_(TypedIns(then_region).arg(idx)),
        union(TypeVar(operands[idx])).with_(TypedIns(else_region).arg(idx)),
    )

    @function
    def propagate_ifelse_outs(
        idx: i64Like,
        stop: i64Like,
        then_ports: PortList,
        else_ports: PortList,
        ifelse: Term,
    ) -> Unit: ...

    yield rule(
        # Propagate output types from the contained regions
        ifelse
        == Term.IfElse(
            cond=_wc(Term),
            then=Term.RegionEnd(region=_wc(Region), ports=then_ports),
            orelse=Term.RegionEnd(region=_wc(Region), ports=else_ports),
            operands=TermList(operands),
        ),
        then_ports == PortList(vecports),
    ).then(
        propagate_ifelse_outs(
            0, vecports.length(), then_ports, else_ports, ifelse
        )
    )

    yield rule(
        # Step forward
        propagate_ifelse_outs(idx, stop, then_ports, else_ports, ifelse),
        idx < stop,
    ).then(
        propagate_ifelse_outs(idx + 1, stop, then_ports, else_ports, ifelse),
    )

    yield rule(
        propagate_ifelse_outs(idx, stop, then_ports, else_ports, ifelse),
    ).then(
        # TypeVars of then ports are else ports
        union(TypeVar(then_ports.getValue(idx))).with_(
            TypeVar(else_ports.getValue(idx))
        ),
        # TypeVars of ifelse outputs are else ports
        union(TypeVar(ifelse.getPort(idx))).with_(
            TypeVar(else_ports.getValue(idx))
        ),
    )
In [46]:
SExpr = rvsdg.grammar.SExpr

Extend RVSDG Grammar for the new operations¶

In [47]:
class NbOp_Base(grammar.Rule):
    pass


class NbOp_Type(NbOp_Base):
    name: str


class NbOp_InTypeAttr(NbOp_Base):
    idx: int
    type: NbOp_Type


class NbOp_OutTypeAttr(NbOp_Base):
    idx: int
    type: NbOp_Type


class NbOp_Gt_Int64(NbOp_Base):
    lhs: SExpr
    rhs: SExpr


class NbOp_Lt_Int64(NbOp_Base):
    lhs: SExpr
    rhs: SExpr


class NbOp_Add_Int64(NbOp_Base):
    lhs: SExpr
    rhs: SExpr


class NbOp_Add_Float64(NbOp_Base):
    lhs: SExpr
    rhs: SExpr


class NbOp_Sub_Int64(NbOp_Base):
    lhs: SExpr
    rhs: SExpr


class NbOp_Sub_Float64(NbOp_Base):
    lhs: SExpr
    rhs: SExpr


class NbOp_Div_Int64(NbOp_Base):
    lhs: SExpr
    rhs: SExpr


class NbOp_CastI64ToF64(NbOp_Base):
    operand: SExpr


class Grammar(grammar.Grammar):
    start = rvsdg.Grammar.start | NbOp_Base

Define attribute formating

In [48]:
def my_attr_format(attrs: rg.Attrs) -> str:
    ins = {}
    outs = {}
    others = []
    for attr in attrs.attrs:
        match attr:
            case NbOp_InTypeAttr(idx=int(idx), type=NbOp_Type(name=str(name))):
                ins[idx] = name
            case NbOp_OutTypeAttr(
                idx=int(idx), type=NbOp_Type(name=str(name))
            ):
                outs[idx] = name
            case _:
                others.append(attr)

    def format(dct):
        if len(dct):
            hi = max(dct.keys())
            out = ", ".join(dct.get(i, "_") for i in range(hi + 1))
            return f"({out})"
        else:
            return "()"

    outbuf = []
    if ins or outs:
        outbuf.append(format(ins) + "->" + format(outs))
    for other in others:
        outbuf.append(ase.pretty_str(other))
    return ", ".join(outbuf)
In [49]:
format_rvsdg = partial(rvsdg.format_rvsdg, format_attrs=my_attr_format)

Extend EGraph to RVSDG¶

In [50]:
class ExtendEGraphToRVSDG(EGraphToRVSDG):
    grammar = Grammar

    def handle_region_attributes(self, key: str, grm: Grammar):

        def search_equiv_calls(self_key: str):
            nodes = self.gdct["nodes"]
            ecl = nodes[self_key]["eclass"]
            for k, v in nodes.items():
                children = v["children"]
                if children and nodes[children[0]]["eclass"] == ecl:
                    yield k, v

        def get_types(key_arg):
            typs = []
            for k, v in search_equiv_calls(key_arg):
                for j in self.search_eclass_siblings(k):
                    op = self.gdct["nodes"][j]["op"]
                    if op.startswith("Type."):
                        typ = self.dispatch(j, grm)
                        typs.append(typ)
            return typs

        attrs = []
        typedargs = list(self.search_calls(key, "TypedIns"))
        if typedargs:
            [typedarg] = typedargs
            for key_arg in self.search_method_calls(typedarg, "arg"):
                _k_self, k_idx = self.get_children(key_arg)
                # get the idx in `.arg(idx)`
                idx = self.dispatch(k_idx, grm)
                typs = get_types(key_arg)

                if len(typs) == 1:
                    typ = typs[0]
                    attrs.append(grm.write(NbOp_InTypeAttr(idx=idx, type=typ)))
                else:
                    resolved = list(map(ase.pretty_str, typs))
                    assert len(typs) == 0, f"multiple types: {resolved}"

        typedouts = list(self.search_calls(key, "TypedOuts"))
        if typedouts:
            [typedout] = typedouts
            for key_at in self.search_method_calls(typedout, "at"):
                _k_self, k_idx = self.get_children(key_at)
                idx = self.dispatch(k_idx, grm)

                typs = get_types(key_at)
                if len(typs) == 1:
                    typ = typs[0]
                    attrs.append(
                        grm.write(NbOp_OutTypeAttr(idx=idx, type=typ))
                    )
                else:
                    assert len(typs) == 0, "multiple types"

        return grm.write(rg.Attrs(tuple(attrs)))

    def handle_Type(
        self, key: str, op: str, children: dict | list, grm: Grammar
    ):
        assert op == "Type.simple"
        match children:
            case {"name": name}:
                return grm.write(NbOp_Type(name))
        raise NotImplementedError

    def handle_Term(self, op: str, children: dict | list, grm: Grammar):
        match op, children:
            case "Nb_Gt_Int64", {"lhs": lhs, "rhs": rhs}:
                return grm.write(NbOp_Gt_Int64(lhs=lhs, rhs=rhs))
            case "Nb_Lt_Int64", {"lhs": lhs, "rhs": rhs}:
                return grm.write(NbOp_Lt_Int64(lhs=lhs, rhs=rhs))
            case "Nb_Add_Int64", {"lhs": lhs, "rhs": rhs}:
                return grm.write(NbOp_Add_Int64(lhs=lhs, rhs=rhs))
            case "Nb_Add_Float64", {"lhs": lhs, "rhs": rhs}:
                return grm.write(NbOp_Add_Float64(lhs=lhs, rhs=rhs))
            case "Nb_Sub_Int64", {"lhs": lhs, "rhs": rhs}:
                return grm.write(NbOp_Sub_Int64(lhs=lhs, rhs=rhs))
            case "Nb_Sub_Float64", {"lhs": lhs, "rhs": rhs}:
                return grm.write(NbOp_Sub_Float64(lhs=lhs, rhs=rhs))
            case "Nb_Div_Int64", {"lhs": lhs, "rhs": rhs}:
                return grm.write(NbOp_Div_Int64(lhs=lhs, rhs=rhs))
            case "Nb_CastI64ToF64", {"operand": operand}:
                return grm.write(NbOp_CastI64ToF64(operand=operand))
            case _:
                # Use parent's implementation for other terms.
                return super().handle_Term(op, children, grm)

Define cost model¶

penalize Python operations (Py_ prefix)

In [51]:
class MyCostModel(CostModel):
    def get_cost_function(self, nodename, op, ty, cost, children):
        if "Term.Literal" in op:
            # Literals has very low cost
            return self.get_simple(1)
        elif op.startswith("Py_"):
            # Penalize Python operations
            return self.get_simple(float("inf"))
        elif op.startswith("Nb_"):
            return self.get_simple(cost)
        # Fallthrough to parent's cost function
        return super().get_cost_function(nodename, op, ty, cost, children)

Define Attributes¶

In [52]:
def get_port_by_name(ports: Sequence[rg.Port], name: str):
    for i, p in enumerate(ports):
        if p.name == name:
            return i, p
    raise ValueError(f"{name!r} not found")


class Attributes:
    _typedins: dict[int, NbOp_InTypeAttr]
    _typedouts: dict[int, NbOp_OutTypeAttr]

    def __init__(self, attrs: rg.Attrs):

        ins = {}
        outs = {}
        for attr in attrs.attrs:
            match attr:
                case NbOp_InTypeAttr(idx=idx):
                    ins[idx] = attr
                case NbOp_OutTypeAttr(idx=idx):
                    outs[idx] = attr
                case _:
                    raise ValueError(attr)

        self._typedins = ins
        self._typedouts = outs

    def get_output_attribute(self, idx: int) -> NbOp_OutTypeAttr | None:
        return self._typedouts.get(idx)

    def get_output_type(self, idx: int) -> NbOp_Type | None:
        at = self._typedouts.get(idx)
        if at is not None:
            return at.type
        return None

    def get_return_type(self, regionend: rg.RegionEnd):
        i, p = get_port_by_name(regionend.ports, rvsdg.internal_prefix("ret"))
        if attr := self.get_output_attribute(i):
            return attr.type
        raise CompilationError("Missing return type")

    def num_input_types(self):
        return len(self._typedins)

    def num_output_types(self):
        return len(self._typedouts)

    def input_types(self):
        for idx in range(1, self.num_input_types() + 1):
            yield self._typedins[idx].type

Extend LLVM Backend for the new operations¶

In [53]:
@dataclass(frozen=True)
class LowerStates(ase.TraverseState):
    builder: ir.IRBuilder
    push: Callable
    tos: Callable


class Backend:
    def __init__(self):
        self.initialize_llvm()

    def initialize_llvm(self):
        llvm.initialize()
        llvm.initialize_native_target()
        llvm.initialize_native_asmprinter()

    def lower_type(self, ty: NbOp_Type):
        match ty:
            case NbOp_Type("Int64"):
                return ir.IntType(64)
            case NbOp_Type("Float64"):
                return ir.DoubleType()
            case NbOp_Type("Bool"):
                return ir.IntType(1)
        raise NotImplementedError(f"unknown type: {ty}")

    def lower_io_type(self):
        # IO type is an empty struct
        return ir.LiteralStructType(())

    def get_result_type(self, ta: NbOp_Type, tb: NbOp_Type) -> NbOp_Type:
        match (ta, tb):
            case (NbOp_Type("Int64"), NbOp_Type("Float64")) | (
                NbOp_Type("Float64"),
                NbOp_Type("Int64"),
            ):
                return NbOp_Type("Float64")
            case _:
                raise NotImplementedError(f"unsupported cast: {ta} {tb}")

    def lower_cast(self, builder, value, fromty, toty):
        match fromty, toty:
            case (NbOp_Type("Int64"), NbOp_Type("Float64")):
                return builder.sitofp(value, self.lower_type(toty))
            case _:
                raise NotImplementedError(
                    f"unsupported lower_cast: {fromty} -> {toty}"
                )

    def lower(self, root: rg.Func, argtypes):
        mod = ir.Module()
        llargtypes = [*map(self.lower_type, argtypes)]

        fname = root.fname
        retty = Attributes(root.body.begin.attrs).get_return_type(root.body)
        llrettype = self.lower_type(retty)

        fnty = ir.FunctionType(llrettype, llargtypes)
        fn = ir.Function(mod, fnty, name=fname)
        # init entry block and builder
        builder = ir.IRBuilder(fn.append_basic_block("entry"))
        iostate = ir.LiteralStructType(())(ir.Undefined)

        # Emit the function body
        reg_args_stack = []

        @contextmanager
        def push(*regionargs):
            reg_args_stack.append(regionargs)
            yield
            reg_args_stack.pop()

        def tos():
            return reg_args_stack[-1]

        try:
            with push(iostate, *fn.args):
                memo = ase.traverse(
                    root.body,
                    self.lower_expr,
                    state=LowerStates(builder=builder, push=push, tos=tos),
                )
        except:
            print(mod)
            raise

        func_region_outs = memo[root.body]

        i, p = get_port_by_name(root.body.ports, rvsdg.internal_prefix("ret"))
        builder.ret(func_region_outs[i])

        return mod

    def lower_expr(self, expr: SExpr, state: LowerStates):
        builder = state.builder
        match expr:
            case rg.RegionBegin(inports=inports):
                values = state.tos()
                assert len(values) == len(inports)
                return values
            case rg.RegionEnd(begin=begin, ports=ports):
                yield begin
                portvalues = []
                for p in ports:
                    pv = yield p.value
                    portvalues.append(pv)
                return portvalues

            case rg.IfElse(
                cond=cond, body=body, orelse=orelse, operands=operands
            ):
                condval = yield cond

                # process operands
                ops = []
                for op in operands:
                    ops.append((yield op))

                # unpack pybool
                match condval.type:
                    case ir.IntType() if condval.type.width == 1:
                        condbit = condval
                    case _:
                        raise NotImplementedError(
                            f"unhandled if-cond type: {condval.type}"
                        )

                bb_then = builder.append_basic_block("then")
                bb_else = builder.append_basic_block("else")
                bb_endif = builder.append_basic_block("endif")

                builder.cbranch(condbit, bb_then, bb_else)

                # Then
                with builder.goto_block(bb_then):
                    with state.push(*ops):
                        value_then = yield body

                    builder.branch(bb_endif)
                    bb_then_end = builder.basic_block
                # Else
                with builder.goto_block(bb_else):
                    with state.push(*ops):
                        value_else = yield orelse

                    builder.branch(bb_endif)
                    bb_else_end = builder.basic_block
                # EndIf
                builder.position_at_end(bb_endif)
                phis = []
                paired = zip(value_then, value_else, strict=True)
                for i, (left, right) in enumerate(paired):
                    assert (
                        left.type == right.type
                    ), f"{left.type} != {right.type}"
                    phi = builder.phi(left.type, name=f"ifelse_{i}")
                    phi.add_incoming(left, bb_then_end)
                    phi.add_incoming(right, bb_else_end)
                    phis.append(phi)
                return phis

            case rg.Unpack(val=source, idx=int(idx)):
                return (yield source)[idx]

            case NbOp_Gt_Int64(lhs, rhs):
                lhs = yield lhs
                rhs = yield rhs
                return builder.icmp_signed(">", lhs, rhs)

            case NbOp_Lt_Int64(lhs, rhs):
                lhs = yield lhs
                rhs = yield rhs
                return builder.icmp_signed("<", lhs, rhs)

            case NbOp_Add_Int64(lhs, rhs):
                lhs = yield lhs
                rhs = yield rhs
                return builder.add(lhs, rhs)

            case NbOp_Add_Float64(lhs, rhs):
                lhs = yield lhs
                rhs = yield rhs
                return builder.fadd(lhs, rhs)

            case NbOp_Sub_Int64(lhs, rhs):
                lhs = yield lhs
                rhs = yield rhs
                return builder.sub(lhs, rhs)

            case NbOp_Sub_Float64(lhs, rhs):
                lhs = yield lhs
                rhs = yield rhs
                return builder.fsub(lhs, rhs)

            case NbOp_Div_Int64(lhs, rhs):
                lhs = yield lhs
                rhs = yield rhs
                x = builder.sitofp(lhs, ir.DoubleType())
                y = builder.sitofp(rhs, ir.DoubleType())
                return builder.fdiv(x, y)

            case NbOp_CastI64ToF64(operand):
                val = yield operand
                return builder.sitofp(val, ir.DoubleType())

            ##### more

            case rg.PyBool(val):
                return ir.IntType(1)(val)

            case rg.PyInt(val):
                return ir.IntType(64)(val)

        raise NotImplementedError(expr)

    def jit_compile(self, llmod: ir.Module, func_node: rg.Func, func_name):
        sym = func_node.fname
        # Create JIT
        lljit = llvm.create_lljit_compiler()
        rt = (
            llvm.JITLibraryBuilder()
            .add_ir(str(llmod))
            .export_symbol(sym)
            .add_current_process()
            .link(lljit, sym)
        )
        ptr = rt[sym]

        fnty = llmod.get_global(sym).type.pointee
        ct_args = list(map(self.get_ctype, fnty.args))
        ct_ret = self.get_ctype(fnty.return_type)

        return JitCallable.from_pointer(rt, ptr, ct_args, ct_ret)

    def get_ctype(self, lltype: ir.Type):
        match lltype:
            case ir.IntType():
                match lltype.width:
                    case 64:
                        return ctypes.c_int64
            case ir.DoubleType():
                return ctypes.c_double
        raise NotImplementedError(lltype)

    def run_passes(self, module, passes):
        pass

Define a new JitCallable with control of the argument

In [54]:
@dataclass(frozen=True)
class JitCallable:
    rt: llvm.ResourceTracker
    pyfunc: Callable

    @classmethod
    def from_pointer(cls, rt: llvm.ResourceTracker, ptr: int, argtys, retty):
        pyfunc = ctypes.PYFUNCTYPE(retty, *argtys)(ptr)
        return cls(rt=rt, pyfunc=pyfunc)

    def __call__(self, *args: Any) -> Any:
        return self.pyfunc(*args)
In [55]:
Int64 = NbOp_Type("Int64")
In [56]:
base_ruleset = (
    basic_ruleset
    | ruleset_propagate_typeof_ifelse
    | ruleset_type_basic
    | ruleset_type_infer_literals
    | ruleset_typeinfer_cast
    | ruleset_type_infer_gt
    | ruleset_type_infer_lt
    | ruleset_type_infer_add
    | ruleset_type_infer_sub
    | ruleset_type_infer_div
    | ruleset_region_types
)

Example 1: simple if-else¶

In [57]:
def example_1(a, b):
    if a > b:
        z = a - b
    else:
        z = b - a
    return z + a
In [58]:
if __name__ == "__main__":
    pipeline_report = Report(
        "Pipeline execution report", enable_nested_metadata=True
    )
    jit_func = jit_compiler(
        fn=example_1,
        argtypes=(Int64, Int64),
        ruleset=(base_ruleset | setup_argtypes(TypeInt64, TypeInt64)),
        converter_class=ExtendEGraphToRVSDG,
        backend=Backend(),
        cost_model=MyCostModel(),
        pipeline_debug=True,
        pipeline_report=pipeline_report,
    ).jit_func
    pipeline_report.display()

    args = (10, 33)
    run_test(example_1, jit_func, args, verbose=True)
    args = (7, 3)
    run_test(example_1, jit_func, args, verbose=True)

Pipeline execution report

1. Frontend (7.33ms) ▶
Frontend
Debug Info on RVSDG ▶
--------------------------------original source---------------------------------
   1|def example_1(a, b):
   2|    if a > b:
   3|        z = a - b
   4|    else:
   5|        z = b - a
   6|    return z + a
----------------------------------inter source----------------------------------
   1|def transformed_example_1(a, b):
   2|    """#file: /tmp/ipykernel_3564/3239589072.py"""
   3|    '#loc: 2:8-5:21'
   4|    if a > b:
   5|        '#loc: 3:12-3:21'
   6|        z = a - b
   7|    else:
   8|        z = b - a
   9|    '#loc: 6:8-6:20'
  10|    return z + a
RVSDG ▶
transformed_example_1 = Func (Args (ArgSpec 'a' (PyNone)) (ArgSpec 'b' (PyNone)))
$0 = Region[512] <- !io a b
{
  $1 = PyBinOp > $0[0] $0[1], $0[2]
  $2 = If $1[1] <- $0[0] $0[1] $0[2]
    $3 = Region[562] <- !io a b
    {
      $4 = PyBinOp - $3[0] $3[1], $3[2]
      $5 = DbgValue 'z' $4[1]
    } [769] -> !io=$4[0] a=$3[1] b=$3[2] z=$5
    Else
    $6 = Region[659] <- !io a b
    {
      $7 = PyBinOp - $6[0] $6[2], $6[1]
      $8 = DbgValue 'z' $7[1]
    } [797] -> !io=$7[0] a=$6[1] b=$6[2] z=$8
  Endif
  $9 = PyBinOp + $2[0] $2[3], $2[1]
} [889] -> !io=$9[0] !ret=$9[1]
[metadata] ▶
time elapsed 7.33ms
timing breakdown:
  5.74ms: Debug Info on RVSDG 
  1.59ms: RVSDG               
2. EGraph Conversion (34.35ms) ▶
EGraph Conversion
EGraph ▶
outer_cluster_InPorts-0 cluster_InPorts-0 outer_cluster_Port-29 cluster_Port-29 outer_cluster_Port-44 cluster_Port-44 outer_cluster_Port-42 cluster_Port-42 outer_cluster_Port-18 cluster_Port-18 outer_cluster_Port-20 cluster_Port-20 outer_cluster_Port-23 cluster_Port-23 outer_cluster_Port-27 cluster_Port-27 outer_cluster_Port-28 cluster_Port-28 outer_cluster_Port-32 cluster_Port-32 outer_cluster_Port-19 cluster_Port-19 outer_cluster_PortList-24 cluster_PortList-24 outer_cluster_PortList-33 cluster_PortList-33 outer_cluster_PortList-45 cluster_PortList-45 outer_cluster_Region-4 cluster_Region-4 outer_cluster_Region-1 cluster_Region-1 outer_cluster_Region-9 cluster_Region-9 outer_cluster_Term-21 cluster_Term-21 outer_cluster_Term-46 cluster_Term-46 outer_cluster_Term-12 cluster_Term-12 outer_cluster_Term-2 cluster_Term-2 outer_cluster_Term-47 cluster_Term-47 outer_cluster_Term-31 cluster_Term-31 outer_cluster_Term-40 cluster_Term-40 outer_cluster_Term-22 cluster_Term-22 outer_cluster_Term-37 cluster_Term-37 outer_cluster_Term-48 cluster_Term-48 outer_cluster_Term-43 cluster_Term-43 outer_cluster_Term-11 cluster_Term-11 outer_cluster_Term-25 cluster_Term-25 outer_cluster_Term-8 cluster_Term-8 outer_cluster_Term-10 cluster_Term-10 outer_cluster_Term-14 cluster_Term-14 outer_cluster_Term-17 cluster_Term-17 outer_cluster_Term-6 cluster_Term-6 outer_cluster_Term-30 cluster_Term-30 outer_cluster_Term-34 cluster_Term-34 outer_cluster_Term-39 cluster_Term-39 outer_cluster_Term-3 cluster_Term-3 outer_cluster_Term-13 cluster_Term-13 outer_cluster_Term-5 cluster_Term-5 outer_cluster_Term-15 cluster_Term-15 outer_cluster_Term-38 cluster_Term-38 outer_cluster_Term-41 cluster_Term-41 outer_cluster_Term-36 cluster_Term-36 outer_cluster_Term-26 cluster_Term-26 outer_cluster_Term-16 cluster_Term-16 outer_cluster_Term-7 cluster_Term-7 outer_cluster_TermList-35 cluster_TermList-35 outer_cluster_Vec_Port-2 cluster_Vec_Port-2 outer_cluster_Vec_Port-0 cluster_Vec_Port-0 outer_cluster_Vec_Port-1 cluster_Vec_Port-1 outer_cluster_Vec_String-0 cluster_Vec_String-0 outer_cluster_Vec_Term-0 cluster_Vec_Term-0 function-0-InPorts___init__:s->primitive-Vec_String-0 function-6-Port___init__:s->function-3-Region_get function-3-Region_get:s->function-1-Region___init__ function-9-Port___init__:s->function-9-Term_getPort function-9-Term_getPort:s->function-0-Py_AddIO function-8-Port___init__:s->function-8-Term_getPort function-8-Term_getPort:s->function-0-Py_AddIO function-0-Port___init__:s->function-1-Term_getPort function-1-Term_getPort:s->function-1-Py_SubIO function-2-Port___init__:s->function-1-Region_get function-1-Region_get:s->function-0-Region___init__ function-3-Port___init__:s->function-0-Term_DbgValue function-0-Term_DbgValue:s->function-2-Term_getPort function-4-Port___init__:s->function-3-Term_getPort function-3-Term_getPort:s->function-0-Py_SubIO function-5-Port___init__:s->function-4-Region_get function-4-Region_get:s->function-1-Region___init__ function-7-Port___init__:s->function-1-Term_DbgValue function-1-Term_DbgValue:s->function-4-Term_getPort function-1-Port___init__:s->function-0-Region_get function-0-Region_get:s->function-0-Region___init__ function-0-PortList___init__:s->primitive-Vec_Port-0 primitive-Vec_Port-0:s->function-0-Port___init__ primitive-Vec_Port-0:s->function-2-Port___init__ primitive-Vec_Port-0:s->function-3-Port___init__ primitive-Vec_Port-0:s->function-1-Port___init__ function-1-PortList___init__:s->primitive-Vec_Port-1 primitive-Vec_Port-1:s->function-6-Port___init__ primitive-Vec_Port-1:s->function-4-Port___init__ primitive-Vec_Port-1:s->function-5-Port___init__ primitive-Vec_Port-1:s->function-7-Port___init__ function-2-PortList___init__:s->primitive-Vec_Port-2 primitive-Vec_Port-2:s->function-9-Port___init__ primitive-Vec_Port-2:s->function-8-Port___init__ function-1-Region___init__:s->function-0-InPorts___init__ function-0-Region___init__:s->function-0-InPorts___init__ function-2-Region___init__:s->function-0-InPorts___init__ function-2-Term_getPort:s->function-1-Py_SubIO function-1-Py_SubIO:s->function-1-Region_get function-1-Py_SubIO:s->function-0-Region_get function-1-Py_SubIO:s->function-5-Region_get function-2-Term_RegionEnd:s->function-2-PortList___init__ function-2-Term_RegionEnd:s->function-2-Region___init__ function-6-Region_get:s->function-2-Region___init__ function-0-Term_Func:s->function-2-Term_RegionEnd function-4-Term_getPort:s->function-0-Py_SubIO function-0-Py_AddIO:s->function-5-Term_getPort function-0-Py_AddIO:s->function-6-Term_getPort function-0-Py_AddIO:s->function-7-Term_getPort function-5-Term_getPort:s->function-0-Term_IfElse function-6-Term_getPort:s->function-0-Term_IfElse function-7-Term_getPort:s->function-0-Term_IfElse function-0-Term_IfElse:s->function-0-Term_RegionEnd function-0-Term_IfElse:s->function-1-Term_RegionEnd function-0-Term_IfElse:s->function-0-Term_getPort function-0-Term_IfElse:s->function-0-TermList___init__ function-0-GraphRoot:s->function-0-Term_Func function-5-Region_get:s->function-0-Region___init__ function-0-Term_RegionEnd:s->function-0-PortList___init__ function-0-Term_RegionEnd:s->function-0-Region___init__ function-0-Py_SubIO:s->function-3-Region_get function-0-Py_SubIO:s->function-4-Region_get function-0-Py_SubIO:s->function-2-Region_get function-2-Region_get:s->function-1-Region___init__ function-8-Region_get:s->function-2-Region___init__ function-1-Term_RegionEnd:s->function-1-PortList___init__ function-1-Term_RegionEnd:s->function-1-Region___init__ function-7-Region_get:s->function-2-Region___init__ function-0-Py_GtIO:s->function-6-Region_get function-0-Py_GtIO:s->function-8-Region_get function-0-Py_GtIO:s->function-7-Region_get function-0-Term_getPort:s->function-0-Py_GtIO function-0-TermList___init__:s->primitive-Vec_Term-0 primitive-Vec_Term-0:s->function-6-Region_get primitive-Vec_Term-0:s->function-8-Region_get primitive-Vec_Term-0:s->function-7-Region_get function-0-InPorts___init__ InPorts primitive-Vec_String-0 Vec("!io", "a", "b") function-6-Port___init__ Port("b", ·) function-3-Region_get ·.get(·, 2) function-9-Port___init__ Port("!ret", ·) function-9-Term_getPort ·.getPort(·, 1) function-8-Port___init__ Port("!io", ·) function-8-Term_getPort ·.getPort(·, 0) function-0-Port___init__ Port("!io", ·) function-1-Term_getPort ·.getPort(·, 0) function-2-Port___init__ Port("b", ·) function-1-Region_get ·.get(·, 2) function-3-Port___init__ Port("z", ·) function-0-Term_DbgValue Term.DbgValue("z", ·) function-4-Port___init__ Port("!io", ·) function-3-Term_getPort ·.getPort(·, 0) function-5-Port___init__ Port("a", ·) function-4-Region_get ·.get(·, 1) function-7-Port___init__ Port("z", ·) function-1-Term_DbgValue Term.DbgValue("z", ·) function-1-Port___init__ Port("a", ·) function-0-Region_get ·.get(·, 1) function-0-PortList___init__ PortList primitive-Vec_Port-0 Vec function-1-PortList___init__ PortList primitive-Vec_Port-1 Vec function-2-PortList___init__ PortList primitive-Vec_Port-2 Vec function-1-Region___init__ Region("659", ·) function-0-Region___init__ Region("562", ·) function-2-Region___init__ Region("512", ·) function-2-Term_getPort ·.getPort(·, 1) function-1-Py_SubIO Py_SubIO function-2-Term_RegionEnd Term.RegionEnd function-6-Region_get ·.get(·, 2) function-0-Term_Func Term.Func("895", "transformed_example_1", ·) function-4-Term_getPort ·.getPort(·, 1) function-0-Py_AddIO Py_AddIO function-5-Term_getPort ·.getPort(·, 0) function-6-Term_getPort ·.getPort(·, 3) function-7-Term_getPort ·.getPort(·, 1) function-0-Term_IfElse Term.IfElse function-0-GraphRoot GraphRoot function-5-Region_get ·.get(·, 0) function-0-Term_RegionEnd Term.RegionEnd function-0-Py_SubIO Py_SubIO function-2-Region_get ·.get(·, 0) function-8-Region_get ·.get(·, 0) function-1-Term_RegionEnd Term.RegionEnd function-7-Region_get ·.get(·, 1) function-0-Py_GtIO Py_GtIO function-0-Term_getPort ·.getPort(·, 1) function-0-TermList___init__ TermList primitive-Vec_Term-0 Vec
[metadata] ▶
time elapsed 34.35ms
timing breakdown:
  34.35ms: EGraph              
3. Egraph Saturation (138.23ms) ▶
Egraph Saturation
[debug] initial egraph ▶
outer_cluster_ErrorMsg-49 cluster_ErrorMsg-49 outer_cluster_InPorts-0 cluster_InPorts-0 outer_cluster_Port-44 cluster_Port-44 outer_cluster_Port-23 cluster_Port-23 outer_cluster_Port-29 cluster_Port-29 outer_cluster_Port-19 cluster_Port-19 outer_cluster_Port-18 cluster_Port-18 outer_cluster_Port-28 cluster_Port-28 outer_cluster_Port-42 cluster_Port-42 outer_cluster_Port-20 cluster_Port-20 outer_cluster_Port-27 cluster_Port-27 outer_cluster_Port-32 cluster_Port-32 outer_cluster_PortList-33 cluster_PortList-33 outer_cluster_PortList-45 cluster_PortList-45 outer_cluster_PortList-24 cluster_PortList-24 outer_cluster_Region-4 cluster_Region-4 outer_cluster_Region-9 cluster_Region-9 outer_cluster_Region-1 cluster_Region-1 outer_cluster_Term-46 cluster_Term-46 outer_cluster_Term-31 cluster_Term-31 outer_cluster_Term-16 cluster_Term-16 outer_cluster_Term-8 cluster_Term-8 outer_cluster_Term-21 cluster_Term-21 outer_cluster_Term-39 cluster_Term-39 outer_cluster_Term-7 cluster_Term-7 outer_cluster_Term-38 cluster_Term-38 outer_cluster_Term-41 cluster_Term-41 outer_cluster_Term-2 cluster_Term-2 outer_cluster_Term-10 cluster_Term-10 outer_cluster_Term-13 cluster_Term-13 outer_cluster_Term-47 cluster_Term-47 outer_cluster_Term-43 cluster_Term-43 outer_cluster_Term-36 cluster_Term-36 outer_cluster_Term-40 cluster_Term-40 outer_cluster_Term-17 cluster_Term-17 outer_cluster_Term-6 cluster_Term-6 outer_cluster_Term-48 cluster_Term-48 outer_cluster_Term-22 cluster_Term-22 outer_cluster_Term-30 cluster_Term-30 outer_cluster_Term-5 cluster_Term-5 outer_cluster_Term-12 cluster_Term-12 outer_cluster_Term-26 cluster_Term-26 outer_cluster_Term-25 cluster_Term-25 outer_cluster_Term-11 cluster_Term-11 outer_cluster_Term-14 cluster_Term-14 outer_cluster_Term-3 cluster_Term-3 outer_cluster_Term-15 cluster_Term-15 outer_cluster_Term-37 cluster_Term-37 outer_cluster_Term-34 cluster_Term-34 outer_cluster_TermList-35 cluster_TermList-35 outer_cluster_Vec_Port-1 cluster_Vec_Port-1 outer_cluster_Vec_Port-2 cluster_Vec_Port-2 outer_cluster_Vec_Port-0 cluster_Vec_Port-0 outer_cluster_Vec_String-0 cluster_Vec_String-0 outer_cluster_Vec_Term-0 cluster_Vec_Term-0 function-0-InPorts___init__:s->primitive-Vec_String-0 function-9-Port___init__:s->function-9-Term_getPort function-9-Term_getPort:s->function-0-Py_AddIO function-3-Port___init__:s->function-0-Term_DbgValue function-0-Term_DbgValue:s->function-2-Term_getPort function-6-Port___init__:s->function-3-Region_get function-3-Region_get:s->function-1-Region___init__ function-1-Port___init__:s->function-0-Region_get function-0-Region_get:s->function-0-Region___init__ function-0-Port___init__:s->function-1-Term_getPort function-1-Term_getPort:s->function-1-Py_SubIO function-5-Port___init__:s->function-4-Region_get function-4-Region_get:s->function-1-Region___init__ function-8-Port___init__:s->function-8-Term_getPort function-8-Term_getPort:s->function-0-Py_AddIO function-2-Port___init__:s->function-1-Region_get function-1-Region_get:s->function-0-Region___init__ function-4-Port___init__:s->function-3-Term_getPort function-3-Term_getPort:s->function-0-Py_SubIO function-7-Port___init__:s->function-1-Term_DbgValue function-1-Term_DbgValue:s->function-4-Term_getPort function-1-PortList___init__:s->primitive-Vec_Port-1 primitive-Vec_Port-1:s->function-6-Port___init__ primitive-Vec_Port-1:s->function-5-Port___init__ primitive-Vec_Port-1:s->function-4-Port___init__ primitive-Vec_Port-1:s->function-7-Port___init__ function-2-PortList___init__:s->primitive-Vec_Port-2 primitive-Vec_Port-2:s->function-9-Port___init__ primitive-Vec_Port-2:s->function-8-Port___init__ function-0-PortList___init__:s->primitive-Vec_Port-0 primitive-Vec_Port-0:s->function-3-Port___init__ primitive-Vec_Port-0:s->function-1-Port___init__ primitive-Vec_Port-0:s->function-0-Port___init__ primitive-Vec_Port-0:s->function-2-Port___init__ function-1-Region___init__:s->function-0-InPorts___init__ function-2-Region___init__:s->function-0-InPorts___init__ function-0-Region___init__:s->function-0-InPorts___init__ function-2-Term_RegionEnd:s->function-2-PortList___init__ function-2-Term_RegionEnd:s->function-2-Region___init__ function-4-Term_getPort:s->function-0-Py_SubIO function-0-Term_getPort:s->function-0-Py_GtIO function-0-Py_GtIO:s->function-7-Region_get function-0-Py_GtIO:s->function-6-Region_get function-0-Py_GtIO:s->function-8-Region_get function-0-Py_SubIO:s->function-3-Region_get function-0-Py_SubIO:s->function-4-Region_get function-0-Py_SubIO:s->function-2-Region_get function-2-Region_get:s->function-1-Region___init__ function-2-Term_getPort:s->function-1-Py_SubIO function-1-Py_SubIO:s->function-0-Region_get function-1-Py_SubIO:s->function-1-Region_get function-1-Py_SubIO:s->function-5-Region_get function-7-Term_getPort:s->function-0-Term_IfElse function-0-Term_IfElse:s->function-0-Term_getPort function-0-Term_IfElse:s->function-0-Term_RegionEnd function-0-Term_IfElse:s->function-1-Term_RegionEnd function-0-Term_IfElse:s->function-0-TermList___init__ function-6-Term_getPort:s->function-0-Term_IfElse function-0-Py_AddIO:s->function-7-Term_getPort function-0-Py_AddIO:s->function-6-Term_getPort function-0-Py_AddIO:s->function-5-Term_getPort function-5-Region_get:s->function-0-Region___init__ function-7-Region_get:s->function-2-Region___init__ function-0-Term_Func:s->function-2-Term_RegionEnd function-0-Term_RegionEnd:s->function-0-PortList___init__ function-0-Term_RegionEnd:s->function-0-Region___init__ function-1-Term_RegionEnd:s->function-1-PortList___init__ function-1-Term_RegionEnd:s->function-1-Region___init__ function-0-TermList___init__:s->primitive-Vec_Term-0 function-5-Term_getPort:s->function-0-Term_IfElse function-0-GraphRoot:s->function-0-Term_Func function-6-Region_get:s->function-2-Region___init__ function-8-Region_get:s->function-2-Region___init__ primitive-Vec_Term-0:s->function-7-Region_get primitive-Vec_Term-0:s->function-6-Region_get primitive-Vec_Term-0:s->function-8-Region_get function-0-ErrorMsg_root ErrorMsg.root function-0-InPorts___init__ InPorts primitive-Vec_String-0 Vec("!io", "a", "b") function-9-Port___init__ Port("!ret", ·) function-9-Term_getPort ·.getPort(·, 1) function-3-Port___init__ Port("z", ·) function-0-Term_DbgValue Term.DbgValue("z", ·) function-6-Port___init__ Port("b", ·) function-3-Region_get ·.get(·, 2) function-1-Port___init__ Port("a", ·) function-0-Region_get ·.get(·, 1) function-0-Port___init__ Port("!io", ·) function-1-Term_getPort ·.getPort(·, 0) function-5-Port___init__ Port("a", ·) function-4-Region_get ·.get(·, 1) function-8-Port___init__ Port("!io", ·) function-8-Term_getPort ·.getPort(·, 0) function-2-Port___init__ Port("b", ·) function-1-Region_get ·.get(·, 2) function-4-Port___init__ Port("!io", ·) function-3-Term_getPort ·.getPort(·, 0) function-7-Port___init__ Port("z", ·) function-1-Term_DbgValue Term.DbgValue("z", ·) function-1-PortList___init__ PortList primitive-Vec_Port-1 Vec function-2-PortList___init__ PortList primitive-Vec_Port-2 Vec function-0-PortList___init__ PortList primitive-Vec_Port-0 Vec function-1-Region___init__ Region("659", ·) function-2-Region___init__ Region("512", ·) function-0-Region___init__ Region("562", ·) function-2-Term_RegionEnd Term.RegionEnd function-4-Term_getPort ·.getPort(·, 1) function-0-Term_getPort ·.getPort(·, 1) function-0-Py_GtIO Py_GtIO function-0-Py_SubIO Py_SubIO function-2-Region_get ·.get(·, 0) function-2-Term_getPort ·.getPort(·, 1) function-1-Py_SubIO Py_SubIO function-7-Term_getPort ·.getPort(·, 1) function-0-Term_IfElse Term.IfElse function-6-Term_getPort ·.getPort(·, 3) function-0-Py_AddIO Py_AddIO function-5-Region_get ·.get(·, 0) function-7-Region_get ·.get(·, 1) function-0-Term_Func Term.Func("895", "transformed_example_1", ·) function-0-Term_RegionEnd Term.RegionEnd function-1-Term_RegionEnd Term.RegionEnd function-0-TermList___init__ TermList function-5-Term_getPort ·.getPort(·, 0) function-0-GraphRoot GraphRoot function-6-Region_get ·.get(·, 2) function-8-Region_get ·.get(·, 0) primitive-Vec_Term-0 Vec
[debug] saturated egraph ▶
outer_cluster_ErrorMsg-49 cluster_ErrorMsg-49 outer_cluster_InPorts-0 cluster_InPorts-0 outer_cluster_Port-159 cluster_Port-159 outer_cluster_Port-84 cluster_Port-84 outer_cluster_Port-143 cluster_Port-143 outer_cluster_Port-161 cluster_Port-161 outer_cluster_Port-88 cluster_Port-88 outer_cluster_Port-82 cluster_Port-82 outer_cluster_Port-118 cluster_Port-118 outer_cluster_Port-86 cluster_Port-86 outer_cluster_Port-92 cluster_Port-92 outer_cluster_Port-90 cluster_Port-90 outer_cluster_Port-131 cluster_Port-131 outer_cluster_Port-145 cluster_Port-145 outer_cluster_PortList-45 cluster_PortList-45 outer_cluster_PortList-33 cluster_PortList-33 outer_cluster_PortList-24 cluster_PortList-24 outer_cluster_Region-1 cluster_Region-1 outer_cluster_Region-4 cluster_Region-4 outer_cluster_Region-9 cluster_Region-9 outer_cluster_String-1879048210 cluster_String-1879048210 outer_cluster_split-0-primitive-String-20 cluster_split-0-primitive-String-20 outer_cluster_String-20 cluster_String-20 outer_cluster_split-1-primitive-String-20 cluster_split-1-primitive-String-20 outer_cluster_split-0-primitive-String-3758096426 cluster_split-0-primitive-String-3758096426 outer_cluster_String-3758096426 cluster_String-3758096426 outer_cluster_split-0-primitive-String-1879048210 cluster_split-0-primitive-String-1879048210 outer_cluster_String-2684354583 cluster_String-2684354583 outer_cluster_split-0-primitive-String-2952790038 cluster_split-0-primitive-String-2952790038 outer_cluster_String-2952790038 cluster_String-2952790038 outer_cluster_Term-152 cluster_Term-152 outer_cluster_Term-46 cluster_Term-46 outer_cluster_Term-15 cluster_Term-15 outer_cluster_Term-147 cluster_Term-147 outer_cluster_Term-16 cluster_Term-16 outer_cluster_Term-125 cluster_Term-125 outer_cluster_Term-133 cluster_Term-133 outer_cluster_Term-48 cluster_Term-48 outer_cluster_Term-137 cluster_Term-137 outer_cluster_Term-134 cluster_Term-134 outer_cluster_Term-12 cluster_Term-12 outer_cluster_Term-156 cluster_Term-156 outer_cluster_Term-154 cluster_Term-154 outer_cluster_Term-34 cluster_Term-34 outer_cluster_Term-65 cluster_Term-65 outer_cluster_Term-40 cluster_Term-40 outer_cluster_Term-38 cluster_Term-38 outer_cluster_Term-120 cluster_Term-120 outer_cluster_Term-61 cluster_Term-61 outer_cluster_Term-8 cluster_Term-8 outer_cluster_Term-11 cluster_Term-11 outer_cluster_Term-13 cluster_Term-13 outer_cluster_Term-151 cluster_Term-151 outer_cluster_Term-62 cluster_Term-62 outer_cluster_Term-47 cluster_Term-47 outer_cluster_Term-94 cluster_Term-94 outer_cluster_Term-25 cluster_Term-25 outer_cluster_Term-63 cluster_Term-63 outer_cluster_Term-64 cluster_Term-64 outer_cluster_Term-60 cluster_Term-60 outer_cluster_Term-36 cluster_Term-36 outer_cluster_Term-39 cluster_Term-39 outer_cluster_TermList-35 cluster_TermList-35 outer_cluster_Type-140 cluster_Type-140 outer_cluster_Type-80 cluster_Type-80 outer_cluster_TypeVar-150 cluster_TypeVar-150 outer_cluster_TypeVar-165 cluster_TypeVar-165 outer_cluster_TypeVar-123 cluster_TypeVar-123 outer_cluster_TypeVar-129 cluster_TypeVar-129 outer_cluster_TypeVar-139 cluster_TypeVar-139 outer_cluster_TypeVar-141 cluster_TypeVar-141 outer_cluster_TypeVar-148 cluster_TypeVar-148 outer_cluster_TypedIns-70 cluster_TypedIns-70 outer_cluster_TypedIns-78 cluster_TypedIns-78 outer_cluster_TypedIns-68 cluster_TypedIns-68 outer_cluster_TypedOuts-112 cluster_TypedOuts-112 outer_cluster_TypedOuts-106 cluster_TypedOuts-106 outer_cluster_TypedOuts-128 cluster_TypedOuts-128 outer_cluster_split-1-primitive-Unit-0 cluster_split-1-primitive-Unit-0 outer_cluster_split-2-primitive-Unit-0 cluster_split-2-primitive-Unit-0 outer_cluster_Unit-0 cluster_Unit-0 outer_cluster_split-0-primitive-Unit-0 cluster_split-0-primitive-Unit-0 outer_cluster_split-3-primitive-Unit-0 cluster_split-3-primitive-Unit-0 outer_cluster_Vec_Port-7 cluster_Vec_Port-7 outer_cluster_Vec_Port-8 cluster_Vec_Port-8 outer_cluster_Vec_Port-6 cluster_Vec_Port-6 outer_cluster_Vec_String-0 cluster_Vec_String-0 outer_cluster_Vec_Term-1 cluster_Vec_Term-1 function-0-InPorts___init__:s->primitive-Vec_String-0 function-10-PortList___getitem__:s->function-3-PortList___init__ function-3-PortList___init__:s->primitive-Vec_Port-7 function-3-Port___init__:s->function-6-Region_get function-6-Region_get:s->function-1-Region___init__ function-1-PortList___getitem__:s->function-4-PortList___init__ function-4-PortList___init__:s->primitive-Vec_Port-8 function-10-Port___init__:s->function-9-Region_get function-9-Region_get:s->function-0-Region___init__ function-8-PortList___getitem__:s->function-3-PortList___init__ function-11-PortList___getitem__:s->function-4-PortList___init__ function-5-Port___init__:s->function-7-Port_value function-7-Port_value:s->function-5-Port___init__ function-3-PortList___getitem__:s->function-4-PortList___init__ function-0-Port___init__:s->function-5-Region_get function-5-Region_get:s->function-0-Region___init__ function-0-PortList___getitem__:s->function-3-PortList___init__ function-6-Port___init__:s->function-6-PortList_getValue function-6-PortList_getValue:s->function-2-PortList___init__ function-6-PortList___getitem__:s->function-2-PortList___init__ function-2-PortList___init__:s->primitive-Vec_Port-6 function-2-Port___init__:s->function-6-Port_value function-6-Port_value:s->function-2-Port___init__ function-2-PortList___getitem__:s->function-3-PortList___init__ function-4-Port___init__:s->function-8-Region_get function-8-Region_get:s->function-1-Region___init__ function-5-PortList___getitem__:s->function-4-PortList___init__ function-1-Port___init__:s->function-7-Region_get function-7-Region_get:s->function-0-Region___init__ function-4-PortList___getitem__:s->function-3-PortList___init__ function-7-Port___init__:s->function-7-PortList_getValue function-7-PortList_getValue:s->function-2-PortList___init__ function-7-PortList___getitem__:s->function-2-PortList___init__ function-11-Port___init__:s->function-10-Region_get function-10-Region_get:s->function-1-Region___init__ function-9-PortList___getitem__:s->function-4-PortList___init__ primitive-Vec_Port-6:s->function-6-PortList___getitem__ primitive-Vec_Port-6:s->function-7-PortList___getitem__ primitive-Vec_Port-8:s->function-1-PortList___getitem__ primitive-Vec_Port-8:s->function-3-PortList___getitem__ primitive-Vec_Port-8:s->function-5-PortList___getitem__ primitive-Vec_Port-8:s->function-9-PortList___getitem__ primitive-Vec_Port-7:s->function-8-PortList___getitem__ primitive-Vec_Port-7:s->function-0-PortList___getitem__ primitive-Vec_Port-7:s->function-2-PortList___getitem__ primitive-Vec_Port-7:s->function-4-PortList___getitem__ function-0-Region___init__:s->function-0-InPorts___init__ function-1-Region___init__:s->function-0-InPorts___init__ function-2-Region___init__:s->function-0-InPorts___init__ function-18-Port_name:s->function-8-PortList___getitem__ function-11-Port_name:s->function-1-PortList___getitem__ function-10-Port_name:s->function-0-PortList___getitem__ function-16-Port_name:s->function-6-PortList___getitem__ function-15-Port_name:s->function-3-PortList___getitem__ function-14-Port_name:s->function-2-PortList___getitem__ function-19-Port_name:s->function-9-PortList___getitem__ function-17-Port_name:s->function-7-PortList___getitem__ function-13-Port_name:s->function-5-PortList___getitem__ function-12-Port_name:s->function-4-PortList___getitem__ function-19-Port_value:s->function-10-PortList___getitem__ function-10-PortList_getValue:s->function-3-PortList___init__ function-2-Term_RegionEnd:s->function-2-PortList___init__ function-2-Term_RegionEnd:s->function-2-Region___init__ function-1-Py_GtIO:s->function-3-Term_getPort function-1-Py_GtIO:s->function-1-Region_get function-1-Py_GtIO:s->function-0-Region_get function-3-Term_getPort:s->function-1-Py_GtIO function-1-Region_get:s->function-2-Region___init__ function-0-Region_get:s->function-2-Region___init__ function-13-Term_getPort:s->function-2-Term_RegionEnd function-0-Term_getPort:s->function-1-Py_GtIO function-1-Nb_Gt_Int64:s->function-1-Region_get function-1-Nb_Gt_Int64:s->function-0-Region_get function-4-Region_get:s->function-2-Region___init__ function-15-Port_value:s->function-10-Port___init__ function-8-PortList_getValue:s->function-3-PortList___init__ function-0-GraphRoot:s->function-0-Term_Func function-0-Term_Func:s->function-2-Term_RegionEnd function-9-Term_getPort:s->function-0-Term_IfElse function-0-Term_IfElse:s->function-1-Nb_Gt_Int64 function-0-Term_IfElse:s->function-1-Term_RegionEnd function-0-Term_IfElse:s->function-0-Term_RegionEnd function-0-Term_IfElse:s->function-1-TermList___init__ function-16-Port_value:s->function-11-Port___init__ function-9-PortList_getValue:s->function-4-PortList___init__ function-12-Term_getPort:s->function-0-Term_IfElse function-20-Port_value:s->function-11-PortList___getitem__ function-11-PortList_getValue:s->function-4-PortList___init__ function-1-Term_RegionEnd:s->function-4-PortList___init__ function-1-Term_RegionEnd:s->function-1-Region___init__ function-9-Port_value:s->function-4-Port___init__ function-5-PortList_getValue:s->function-4-PortList___init__ function-1-Py_AddIO:s->function-10-Term_getPort function-1-Py_AddIO:s->function-1-Term_getPort function-1-Py_AddIO:s->function-2-Term_getPort function-10-Term_getPort:s->function-1-Py_AddIO function-1-Term_getPort:s->function-0-Term_IfElse function-2-Term_getPort:s->function-0-Term_IfElse function-11-Term_getPort:s->function-1-Py_AddIO function-12-Port_value:s->function-7-Port___init__ function-1-Nb_Add_Int64:s->function-1-Term_getPort function-1-Nb_Add_Int64:s->function-2-Term_getPort function-6-Term_getPort:s->function-0-Py_SubIO function-0-Py_SubIO:s->function-9-PortList_getValue function-0-Py_SubIO:s->function-5-PortList_getValue function-0-Py_SubIO:s->function-5-Port_value function-5-Port_value:s->function-3-Port___init__ function-1-PortList_getValue:s->function-4-PortList___init__ function-1-Py_SubIO:s->function-8-PortList_getValue function-1-Py_SubIO:s->function-4-Port_value function-1-Py_SubIO:s->function-4-PortList_getValue function-4-Port_value:s->function-0-Port___init__ function-4-PortList_getValue:s->function-3-PortList___init__ function-15-Term_getPort:s->function-2-Term_RegionEnd function-7-Term_getPort:s->function-1-Py_SubIO function-0-Term_DbgValue:s->function-0-Nb_Sub_Int64 function-0-Nb_Sub_Int64:s->function-15-Port_value function-0-Nb_Sub_Int64:s->function-8-Port_value function-2-PortList_getValue:s->function-3-PortList___init__ function-8-Port_value:s->function-1-Port___init__ function-14-Term_getPort:s->function-0-Term_IfElse function-10-Port_value:s->function-6-Port___init__ function-0-Term_RegionEnd:s->function-3-PortList___init__ function-0-Term_RegionEnd:s->function-0-Region___init__ function-8-Term_getPort:s->function-0-Py_SubIO function-1-Term_DbgValue:s->function-1-Nb_Sub_Int64 function-1-Nb_Sub_Int64:s->function-16-Port_value function-1-Nb_Sub_Int64:s->function-9-Port_value function-3-PortList_getValue:s->function-4-PortList___init__ function-5-Term_getPort:s->function-1-Py_SubIO function-0-PortList_getValue:s->function-3-PortList___init__ function-1-TermList___init__:s->primitive-Vec_Term-1 primitive-Vec_Term-1:s->function-1-Region_get primitive-Vec_Term-1:s->function-0-Region_get primitive-Vec_Term-1:s->function-4-Region_get function-2-TypeVar_getType:s->function-5-TypeVar___init__ function-5-TypeVar___init__:s->function-1-Nb_Gt_Int64 function-1-TypeVar_getType:s->function-9-TypedOuts_at function-9-TypedOuts_at:s->function-0-TypedOuts___init__ function-5-TypeVar_getType:s->function-14-TypedOuts_at function-14-TypedOuts_at:s->function-0-TypedOuts___init__ function-6-TypeVar_getType:s->function-15-TypedOuts_at function-15-TypedOuts_at:s->function-0-TypedOuts___init__ function-7-TypeVar_getType:s->function-6-TypeVar___init__ function-6-TypeVar___init__:s->function-12-Port_value function-10-TypeVar___init__:s->function-9-Term_getPort function-11-TypeVar___init__:s->function-10-Region_get function-12-TypeVar___init__:s->function-9-Region_get function-19-TypeVar___init__:s->function-0-Region_get function-5-TypedIns_arg:s->function-2-TypedIns___init__ function-2-TypedIns___init__:s->function-2-Region___init__ function-6-TypedIns_arg:s->function-0-TypedIns___init__ function-0-TypedIns___init__:s->function-0-Region___init__ function-7-TypedIns_arg:s->function-1-TypedIns___init__ function-1-TypedIns___init__:s->function-1-Region___init__ function-12-TypedOuts_at:s->function-1-TypedOuts___init__ function-1-TypedOuts___init__:s->function-1-Region___init__ function-0-TypedOuts___init__:s->function-0-Region___init__ function-20-TypeVar___init__:s->function-12-Term_getPort function-21-TypeVar___init__:s->function-11-PortList_getValue function-22-TypeVar___init__:s->function-10-PortList_getValue function-19-TypedOuts_at:s->function-1-TypedOuts___init__ function-20-TypedOuts_at:s->function-0-TypedOuts___init__ function-0-TypeVar___init__:s->function-2-Term_getPort function-1-TypeVar___init__:s->function-8-Region_get function-2-TypeVar___init__:s->function-7-Region_get function-4-TypeVar___init__:s->function-1-Region_get function-0-TypedIns_arg:s->function-2-TypedIns___init__ function-1-TypedIns_arg:s->function-0-TypedIns___init__ function-2-TypedIns_arg:s->function-1-TypedIns___init__ function-8-TypedOuts_at:s->function-1-TypedOuts___init__ function-3-TypeVar___init__:s->function-6-PortList_getValue function-16-TypeVar___init__:s->function-0-PortList_getValue function-17-TypeVar___init__:s->function-1-PortList_getValue function-18-TypeVar___init__:s->function-3-Term_getPort function-3-TypedIns_arg:s->function-0-TypedIns___init__ function-4-TypedIns_arg:s->function-1-TypedIns___init__ function-7-TypedOuts_at:s->function-2-TypedOuts___init__ function-2-TypedOuts___init__:s->function-2-Region___init__ function-16-TypedOuts_at:s->function-1-TypedOuts___init__ function-17-TypedOuts_at:s->function-0-TypedOuts___init__ function-10-TypedOuts_at:s->function-2-TypedOuts___init__ function-7-TypeVar___init__:s->function-1-Term_getPort function-8-TypeVar___init__:s->function-7-Port_value function-9-TypeVar___init__:s->function-6-Port_value function-13-TypedOuts_at:s->function-1-TypedOuts___init__ function-2-propagate_ifelse_outs:s->function-3-PortList___init__ function-2-propagate_ifelse_outs:s->function-4-PortList___init__ function-2-propagate_ifelse_outs:s->function-0-Term_IfElse function-3-propagate_ifelse_outs:s->function-3-PortList___init__ function-3-propagate_ifelse_outs:s->function-4-PortList___init__ function-3-propagate_ifelse_outs:s->function-0-Term_IfElse function-0-propagate_ifelse_outs:s->function-3-PortList___init__ function-0-propagate_ifelse_outs:s->function-4-PortList___init__ function-0-propagate_ifelse_outs:s->function-0-Term_IfElse function-1-propagate_ifelse_outs:s->function-3-PortList___init__ function-1-propagate_ifelse_outs:s->function-4-PortList___init__ function-1-propagate_ifelse_outs:s->function-0-Term_IfElse function-4-propagate_ifelse_outs:s->function-3-PortList___init__ function-4-propagate_ifelse_outs:s->function-4-PortList___init__ function-4-propagate_ifelse_outs:s->function-0-Term_IfElse function-0-ErrorMsg_root ErrorMsg.root function-0-InPorts___init__ InPorts primitive-Vec_String-0 Vec("!io", "a", "b") function-10-PortList___getitem__ ·[4] function-3-PortList___init__ PortList function-3-Port___init__ Port("!io", ·) function-6-Region_get ·.get(·, 0) function-1-PortList___getitem__ ·[0] function-4-PortList___init__ PortList function-10-Port___init__ Port("b", ·) function-9-Region_get ·.get(·, 2) function-8-PortList___getitem__ ·[2] function-11-PortList___getitem__ ·[4] function-5-Port___init__ Port("z", ·) function-7-Port_value ·.value function-3-PortList___getitem__ ·[3] function-0-Port___init__ Port("!io", ·) function-5-Region_get ·.get(·, 0) function-0-PortList___getitem__ ·[0] function-6-Port___init__ Port("!io", ·) function-6-PortList_getValue ·.getValue(·, 0) function-6-PortList___getitem__ ·[0] function-2-PortList___init__ PortList function-2-Port___init__ Port("z", ·) function-6-Port_value ·.value function-2-PortList___getitem__ ·[3] function-4-Port___init__ Port("a", ·) function-8-Region_get ·.get(·, 1) function-5-PortList___getitem__ ·[1] function-1-Port___init__ Port("a", ·) function-7-Region_get ·.get(·, 1) function-4-PortList___getitem__ ·[1] function-7-Port___init__ Port("!ret", ·) function-7-PortList_getValue ·.getValue(·, 1) function-7-PortList___getitem__ ·[1] function-11-Port___init__ Port("b", ·) function-10-Region_get ·.get(·, 2) function-9-PortList___getitem__ ·[2] primitive-Vec_Port-6 Vec primitive-Vec_Port-8 Vec primitive-Vec_Port-7 Vec function-0-Region___init__ Region("562", ·) function-1-Region___init__ Region("659", ·) function-2-Region___init__ Region("512", ·) function-18-Port_name ·.name primitive-String-1879048210 "b" function-11-Port_name ·.name split-0-primitive-String-20 "!io" function-10-Port_name ·.name primitive-String-20 "!io" function-16-Port_name ·.name split-1-primitive-String-20 "!io" function-15-Port_name ·.name split-0-primitive-String-3758096426 "z" function-14-Port_name ·.name primitive-String-3758096426 "z" function-19-Port_name ·.name split-0-primitive-String-1879048210 "b" function-17-Port_name ·.name primitive-String-2684354583 "!ret" function-13-Port_name ·.name split-0-primitive-String-2952790038 "a" function-12-Port_name ·.name primitive-String-2952790038 "a" function-19-Port_value ·.value function-10-PortList_getValue ·.getValue(·, 4) function-2-Term_RegionEnd Term.RegionEnd function-1-Py_GtIO Py_GtIO function-3-Term_getPort ·.getPort(·, 0) function-1-Region_get ·.get(·, 1) function-0-Region_get ·.get(·, 2) function-13-Term_getPort ·.getPort(·, 0) function-0-Term_getPort ·.getPort(·, 1) function-1-Nb_Gt_Int64 Nb_Gt_Int64 function-4-Region_get ·.get(·, 0) function-15-Port_value ·.value function-8-PortList_getValue ·.getValue(·, 2) function-0-GraphRoot GraphRoot function-0-Term_Func Term.Func("895", "transformed_example_1", ·) function-9-Term_getPort ·.getPort(·, 2) function-0-Term_IfElse Term.IfElse function-16-Port_value ·.value function-9-PortList_getValue ·.getValue(·, 2) function-12-Term_getPort ·.getPort(·, 4) function-20-Port_value ·.value function-11-PortList_getValue ·.getValue(·, 4) function-1-Term_RegionEnd Term.RegionEnd function-9-Port_value ·.value function-5-PortList_getValue ·.getValue(·, 1) function-1-Py_AddIO Py_AddIO function-10-Term_getPort ·.getPort(·, 0) function-1-Term_getPort ·.getPort(·, 3) function-2-Term_getPort ·.getPort(·, 1) function-11-Term_getPort ·.getPort(·, 1) function-12-Port_value ·.value function-1-Nb_Add_Int64 Nb_Add_Int64 function-6-Term_getPort ·.getPort(·, 0) function-0-Py_SubIO Py_SubIO function-5-Port_value ·.value function-1-PortList_getValue ·.getValue(·, 0) function-1-Py_SubIO Py_SubIO function-4-Port_value ·.value function-4-PortList_getValue ·.getValue(·, 1) function-15-Term_getPort ·.getPort(·, 1) function-7-Term_getPort ·.getPort(·, 1) function-0-Term_DbgValue Term.DbgValue("z", ·) function-0-Nb_Sub_Int64 Nb_Sub_Int64 function-2-PortList_getValue ·.getValue(·, 3) function-8-Port_value ·.value function-14-Term_getPort ·.getPort(·, 0) function-10-Port_value ·.value function-0-Term_RegionEnd Term.RegionEnd function-8-Term_getPort ·.getPort(·, 1) function-1-Term_DbgValue Term.DbgValue("z", ·) function-1-Nb_Sub_Int64 Nb_Sub_Int64 function-3-PortList_getValue ·.getValue(·, 3) function-5-Term_getPort ·.getPort(·, 0) function-0-PortList_getValue ·.getValue(·, 0) function-1-TermList___init__ TermList primitive-Vec_Term-1 Vec function-2-TypeVar_getType ·.getType function-5-TypeVar___init__ TypeVar function-1-Type_simple Type.simple("Bool") function-1-TypeVar_getType ·.getType function-9-TypedOuts_at ·.at(·, 1) function-5-TypeVar_getType ·.getType function-14-TypedOuts_at ·.at(·, 3) function-6-TypeVar_getType ·.getType function-15-TypedOuts_at ·.at(·, 2) function-7-TypeVar_getType ·.getType function-6-TypeVar___init__ TypeVar function-0-Type_simple Type.simple("Int64") function-10-TypeVar___init__ TypeVar function-11-TypeVar___init__ TypeVar function-12-TypeVar___init__ TypeVar function-19-TypeVar___init__ TypeVar function-5-TypedIns_arg ·.arg(·, 2) function-2-TypedIns___init__ TypedIns function-6-TypedIns_arg ·.arg(·, 2) function-0-TypedIns___init__ TypedIns function-7-TypedIns_arg ·.arg(·, 2) function-1-TypedIns___init__ TypedIns function-12-TypedOuts_at ·.at(·, 2) function-1-TypedOuts___init__ TypedOuts function-0-TypedOuts___init__ TypedOuts function-20-TypeVar___init__ TypeVar function-21-TypeVar___init__ TypeVar function-22-TypeVar___init__ TypeVar function-19-TypedOuts_at ·.at(·, 4) function-20-TypedOuts_at ·.at(·, 4) function-0-TypeVar___init__ TypeVar function-1-TypeVar___init__ TypeVar function-2-TypeVar___init__ TypeVar function-4-TypeVar___init__ TypeVar function-0-TypedIns_arg ·.arg(·, 1) function-1-TypedIns_arg ·.arg(·, 1) function-2-TypedIns_arg ·.arg(·, 1) function-8-TypedOuts_at ·.at(·, 1) function-3-TypeVar___init__ TypeVar function-16-TypeVar___init__ TypeVar function-17-TypeVar___init__ TypeVar function-18-TypeVar___init__ TypeVar function-3-TypedIns_arg ·.arg(·, 0) function-4-TypedIns_arg ·.arg(·, 0) function-7-TypedOuts_at ·.at(·, 0) function-2-TypedOuts___init__ TypedOuts function-16-TypedOuts_at ·.at(·, 0) function-17-TypedOuts_at ·.at(·, 0) function-10-TypedOuts_at ·.at(·, 1) function-7-TypeVar___init__ TypeVar function-8-TypeVar___init__ TypeVar function-9-TypeVar___init__ TypeVar function-13-TypedOuts_at ·.at(·, 3) function-2-propagate_ifelse_outs propagate_ifelse_outs(2, 4, ·, ·, ·) split-1-primitive-Unit-0 () function-3-propagate_ifelse_outs propagate_ifelse_outs(3, 4, ·, ·, ·) split-2-primitive-Unit-0 () function-0-propagate_ifelse_outs propagate_ifelse_outs(0, 4, ·, ·, ·) primitive-Unit-0 () function-1-propagate_ifelse_outs propagate_ifelse_outs(1, 4, ·, ·, ·) split-0-primitive-Unit-0 () function-4-propagate_ifelse_outs propagate_ifelse_outs(4, 4, ·, ·, ·) split-3-primitive-Unit-0 ()
[debug] egglog.extract ▶
_Region_1 = Region("512", InPorts(Vec[String]("!io", "a", "b")))
_Region_2 = Region("562", InPorts(Vec[String]("!io", "a", "b")))
_Region_3 = Region("659", InPorts(Vec[String]("!io", "a", "b")))
_Term_1 = Term.IfElse(
    Nb_Gt_Int64(_Region_1.get(1), _Region_1.get(2)),
    Term.RegionEnd(
        _Region_2,
        PortList(Vec[Port](Port("!io", _Region_2.get(0)), Port("a", _Region_2.get(1)), Port("b", _Region_2.get(2)), Port("z", Nb_Sub_Int64(_Region_2.get(1), _Region_2.get(2))))),
    ),
    Term.RegionEnd(
        _Region_3,
        PortList(Vec[Port](Port("!io", _Region_3.get(0)), Port("a", _Region_3.get(1)), Port("b", _Region_3.get(2)), Port("z", Nb_Sub_Int64(_Region_3.get(2), _Region_3.get(1))))),
    ),
    TermList(Vec[Term](_Region_1.get(0), _Region_1.get(1), _Region_1.get(2))),
)
GraphRoot(
    Term.Func(
        "895",
        "transformed_example_1",
        Term.RegionEnd(_Region_1, PortList(Vec[Port](Port("!io", _Term_1.getPort(0)), Port("!ret", Nb_Add_Int64(_Term_1.getPort(3), _Term_1.getPort(1)))))),
    )
)
[metadata] ▶
time elapsed 138.23ms
timing breakdown:
  24.54ms: [debug] initial egraph
  80.58ms: [debug] saturated egraph
  33.11ms: [debug] egglog.extract
4. EGraph Extraction (15.25ms) ▶
EGraph Extraction
Extracted RVSDG ▶
transformed_example_1 = Func (Args (ArgSpec 'a' (PyNone)) (ArgSpec 'b' (PyNone)))
$0 = Region[1076] <- !io a b; #attrs (_, Int64, Int64)->(_, Int64)
{
  $1 = NbOp_Gt_Int64 $0[1] $0[2]
  $2 = If $1 <- $0[0] $0[1] $0[2]
    $3 = Region[1131] <- !io a b; #attrs (_, Int64, Int64)->(_, Int64, Int64, Int64)
    {
      $4 = NbOp_Sub_Int64 $3[1] $3[2]
    } [1178] -> !io=$3[0] a=$3[1] b=$3[2] z=$4
    Else
    $5 = Region[1219] <- !io a b; #attrs (_, Int64, Int64)->(_, Int64, Int64, Int64)
    {
      $6 = NbOp_Sub_Int64 $5[2] $5[1]
    } [1266] -> !io=$5[0] a=$5[1] b=$5[2] z=$6
  Endif
  $7 = NbOp_Add_Int64 $2[3] $2[1]
} [1318] -> !io=$2[0] !ret=$7
Extracted cost ▶
5841595.0
[metadata] ▶
time elapsed 15.25ms
timing breakdown:
  15.24ms: Extracted RVSDG     
  0.01ms: Extracted cost      
5. Backend (0.73ms) ▶
Backend
Lowered module ▶
; ModuleID = ""
target triple = "unknown-unknown-unknown"
target datalayout = ""

define i64 @"transformed_example_1"(i64 %".1", i64 %".2")
{
entry:
  %".4" = icmp sgt i64 %".1", %".2"
  br i1 %".4", label %"then", label %"else"
then:
  %".6" = sub i64 %".1", %".2"
  br label %"endif"
else:
  %".8" = sub i64 %".2", %".1"
  br label %"endif"
endif:
  %"ifelse_0" = phi  {} [undef, %"then"], [undef, %"else"]
  %"ifelse_1" = phi  i64 [%".1", %"then"], [%".1", %"else"]
  %"ifelse_2" = phi  i64 [%".2", %"then"], [%".2", %"else"]
  %"ifelse_3" = phi  i64 [%".6", %"then"], [%".8", %"else"]
  %".10" = add i64 %"ifelse_3", %"ifelse_1"
  ret i64 %".10"
}
[metadata] ▶
time elapsed 0.73ms
timing breakdown:
  0.73ms: Lowered module      

Testing report

1. Args ▶
(10, 33)
2. JIT output ▶
33
3. Expected output ▶
33

Testing report

1. Args ▶
(7, 3)
2. JIT output ▶
11
3. Expected output ▶
11

Example 2: add float()¶

In [59]:
def example_2(a, b):
    if a > b:
        z = float(a - b)
    else:
        z = float(b) - 1 / a
    return z - float(a)

Add rules for float()

In [60]:
@ruleset
def ruleset_type_infer_float(
    io: Term, loadglb: Term, callstmt: Term, args: Vec[Term], arg: Term
):
    yield rule(
        # Convert Python float(arg)
        loadglb == Py_LoadGlobal(io=_wc(Term), name="float"),
        callstmt == Py_Call(io=io, func=loadglb, args=TermList(args)),
        eq(args.length()).to(i64(1)),
    ).then(
        union(callstmt.getPort(1)).with_(Nb_CastToFloat(args[0])),
        union(callstmt.getPort(0)).with_(io),
    )
    # Type check and specialize
    yield rewrite(
        Nb_CastToFloat(arg),
        subsume=True,
    ).to(
        Nb_CastI64ToF64(arg),
        # given
        TypeVar(arg).getType() == TypeInt64,
    )
In [61]:
if __name__ == "__main__":
    report = Report("Pipeline execution report")
    cres = jit_compiler(
        fn=example_2,
        argtypes=(Int64, Int64),
        ruleset=(
            base_ruleset
            | setup_argtypes(TypeInt64, TypeInt64)
            | ruleset_type_infer_float  # < --- added for float()
        ),
        converter_class=ExtendEGraphToRVSDG,
        backend=Backend(),
        cost_model=MyCostModel(),
        pipeline_debug=True,
        pipeline_report=report,
    )
    jit_func = cres.jit_func
    args = (10, 33)
    run_test(example_2, jit_func, args, verbose=True)
    args = (7, 3)
    run_test(example_2, jit_func, args, verbose=True)

Testing report

1. Args ▶
(10, 33)
2. JIT output ▶
22.9
3. Expected output ▶
22.9

Testing report

1. Args ▶
(7, 3)
2. JIT output ▶
-3.0
3. Expected output ▶
-3.0

Example 3: unify mismatching type¶

What if type of z does not match across the branch?

In [62]:
def example_3(a, b):
    if a > b:
        z = a - b  # this as int
    else:
        z = float(b) - 1 / a  # this is float
    return z - float(a)

Add rules to signal error

In [63]:
@ruleset
def ruleset_failed_to_unify(ty: Type):
    yield rule(
        failed_to_unify(ty),
    ).then(
        union(ErrorMsg.root()).with_(ErrorMsg.fail("fail to unify")),
    )
In [64]:
if __name__ == "__main__":
    report = Report("Pipeline execution report")
    try:
        jit_compiler(
            fn=example_3,
            argtypes=(Int64, Int64),
            ruleset=(
                base_ruleset
                | setup_argtypes(TypeInt64, TypeInt64)
                | ruleset_type_infer_float
                | ruleset_failed_to_unify
            ),
            converter_class=ExtendEGraphToRVSDG,
            backend=Backend(),
            cost_model=MyCostModel(),
            pipeline_debug=True,
            pipeline_report=report,
        )
    except CompilationError as e:
        # Compilation failed because the return type cannot be determined.
        # This indicates that the type inference is incomplete
        print_exception(e)
        assert "fail to unify" in str(e)
    finally:
        report.display()
Traceback (most recent call last):
  File "/tmp/ipykernel_3564/3463894060.py", line 4, in <module>
    jit_compiler(
  File "/home/runner/work/numba-prototypes/numba-prototypes/sealir-tutorials/utils/pipeline.py", line 235, in __call__
    result = func(**filtered_kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/ipykernel_3564/571815991.py", line 37, in egraph_saturation_with_error_checking
    raise CompilationError("\n".join(errmsgs_filtered))
CompilationError: fail to unify

Pipeline execution report

1. Frontend ▶
Frontend
Debug Info on RVSDG ▶
--------------------------------original source---------------------------------
   1|def example_3(a, b):
   2|    if a > b:
   3|        z = a - b  # this as int
   4|    else:
   5|        z = float(b) - 1 / a  # this is float
   6|    return z - float(a)
----------------------------------inter source----------------------------------
   1|def transformed_example_3(a, b):
   2|    """#file: /tmp/ipykernel_3564/2268966838.py"""
   3|    '#loc: 2:8-5:32'
   4|    if a > b:
   5|        '#loc: 3:12-3:21'
   6|        z = a - b
   7|    else:
   8|        z = float(b) - 1 / a
   9|    '#loc: 6:8-6:27'
  10|    return z - float(a)
RVSDG ▶
transformed_example_3 = Func (Args (ArgSpec 'a' (PyNone)) (ArgSpec 'b' (PyNone)))
$0 = Region[598] <- !io a b
{
  $1 = PyBinOp > $0[0] $0[1], $0[2]
  $2 = If $1[1] <- $0[0] $0[1] $0[2]
    $3 = Region[648] <- !io a b
    {
      $4 = PyBinOp - $3[0] $3[1], $3[2]
      $5 = DbgValue 'z' $4[1]
    } [897] -> !io=$4[0] a=$3[1] b=$3[2] z=$5
    Else
    $6 = Region[745] <- !io a b
    {
      $7 = PyLoadGlobal $6[0] 'float'
      $8 = PyCall $7 $6[0] $6[2]
      $9 = PyInt 1
      $10 = PyBinOp / $8[0] $9, $6[1]
      $11 = PyBinOp - $10[0] $8[1], $10[1]
      $12 = DbgValue 'z' $11[1]
    } [925] -> !io=$11[0] a=$6[1] b=$6[2] z=$12
  Endif
  $13 = PyLoadGlobal $2[0] 'float'
  $14 = PyCall $13 $2[0] $2[1]
  $15 = PyBinOp - $14[0] $2[3], $14[1]
} [1038] -> !io=$15[0] !ret=$15[1]
2. EGraph Conversion ▶
EGraph Conversion
EGraph ▶
outer_cluster_InPorts-0 cluster_InPorts-0 outer_cluster_Port-22 cluster_Port-22 outer_cluster_Port-38 cluster_Port-38 outer_cluster_Port-56 cluster_Port-56 outer_cluster_Port-20 cluster_Port-20 outer_cluster_Port-21 cluster_Port-21 outer_cluster_Port-25 cluster_Port-25 outer_cluster_Port-37 cluster_Port-37 outer_cluster_Port-41 cluster_Port-41 outer_cluster_Port-36 cluster_Port-36 outer_cluster_Port-58 cluster_Port-58 outer_cluster_PortList-59 cluster_PortList-59 outer_cluster_PortList-26 cluster_PortList-26 outer_cluster_PortList-42 cluster_PortList-42 outer_cluster_Region-1 cluster_Region-1 outer_cluster_Region-8 cluster_Region-8 outer_cluster_Region-13 cluster_Region-13 outer_cluster_Term-14 cluster_Term-14 outer_cluster_Term-47 cluster_Term-47 outer_cluster_Term-6 cluster_Term-6 outer_cluster_Term-24 cluster_Term-24 outer_cluster_Term-17 cluster_Term-17 outer_cluster_Term-33 cluster_Term-33 outer_cluster_Term-15 cluster_Term-15 outer_cluster_Term-34 cluster_Term-34 outer_cluster_Term-54 cluster_Term-54 outer_cluster_Term-11 cluster_Term-11 outer_cluster_Term-51 cluster_Term-51 outer_cluster_Term-53 cluster_Term-53 outer_cluster_Term-19 cluster_Term-19 outer_cluster_Term-61 cluster_Term-61 outer_cluster_Term-45 cluster_Term-45 outer_cluster_Term-57 cluster_Term-57 outer_cluster_Term-43 cluster_Term-43 outer_cluster_Term-30 cluster_Term-30 outer_cluster_Term-7 cluster_Term-7 outer_cluster_Term-3 cluster_Term-3 outer_cluster_Term-46 cluster_Term-46 outer_cluster_Term-55 cluster_Term-55 outer_cluster_Term-62 cluster_Term-62 outer_cluster_Term-12 cluster_Term-12 outer_cluster_Term-28 cluster_Term-28 outer_cluster_Term-60 cluster_Term-60 outer_cluster_Term-23 cluster_Term-23 outer_cluster_Term-48 cluster_Term-48 outer_cluster_Term-52 cluster_Term-52 outer_cluster_Term-31 cluster_Term-31 outer_cluster_Term-16 cluster_Term-16 outer_cluster_Term-32 cluster_Term-32 outer_cluster_Term-9 cluster_Term-9 outer_cluster_Term-2 cluster_Term-2 outer_cluster_Term-35 cluster_Term-35 outer_cluster_Term-4 cluster_Term-4 outer_cluster_Term-50 cluster_Term-50 outer_cluster_Term-39 cluster_Term-39 outer_cluster_Term-40 cluster_Term-40 outer_cluster_Term-27 cluster_Term-27 outer_cluster_Term-18 cluster_Term-18 outer_cluster_Term-10 cluster_Term-10 outer_cluster_Term-29 cluster_Term-29 outer_cluster_TermList-44 cluster_TermList-44 outer_cluster_TermList-49 cluster_TermList-49 outer_cluster_TermList-5 cluster_TermList-5 outer_cluster_Vec_Port-2 cluster_Vec_Port-2 outer_cluster_Vec_Port-0 cluster_Vec_Port-0 outer_cluster_Vec_Port-1 cluster_Vec_Port-1 outer_cluster_Vec_String-0 cluster_Vec_String-0 outer_cluster_Vec_Term-0 cluster_Vec_Term-0 outer_cluster_Vec_Term-2 cluster_Vec_Term-2 outer_cluster_Vec_Term-1 cluster_Vec_Term-1 function-0-InPorts___init__:s->primitive-Vec_String-0 function-2-Port___init__:s->function-4-Region_get function-4-Region_get:s->function-1-Region___init__ function-6-Port___init__:s->function-1-Region_get function-1-Region_get:s->function-0-Region___init__ function-8-Port___init__:s->function-14-Term_getPort function-14-Term_getPort:s->function-2-Py_SubIO function-0-Port___init__:s->function-1-Term_getPort function-1-Term_getPort:s->function-0-Py_SubIO function-1-Port___init__:s->function-3-Region_get function-3-Region_get:s->function-1-Region___init__ function-3-Port___init__:s->function-0-Term_DbgValue function-0-Term_DbgValue:s->function-2-Term_getPort function-5-Port___init__:s->function-2-Region_get function-2-Region_get:s->function-0-Region___init__ function-7-Port___init__:s->function-1-Term_DbgValue function-1-Term_DbgValue:s->function-8-Term_getPort function-4-Port___init__:s->function-7-Term_getPort function-7-Term_getPort:s->function-1-Py_SubIO function-9-Port___init__:s->function-15-Term_getPort function-15-Term_getPort:s->function-2-Py_SubIO function-2-PortList___init__:s->primitive-Vec_Port-2 primitive-Vec_Port-2:s->function-8-Port___init__ primitive-Vec_Port-2:s->function-9-Port___init__ function-0-PortList___init__:s->primitive-Vec_Port-0 primitive-Vec_Port-0:s->function-2-Port___init__ primitive-Vec_Port-0:s->function-0-Port___init__ primitive-Vec_Port-0:s->function-1-Port___init__ primitive-Vec_Port-0:s->function-3-Port___init__ function-1-PortList___init__:s->primitive-Vec_Port-1 primitive-Vec_Port-1:s->function-6-Port___init__ primitive-Vec_Port-1:s->function-5-Port___init__ primitive-Vec_Port-1:s->function-7-Port___init__ primitive-Vec_Port-1:s->function-4-Port___init__ function-0-Region___init__:s->function-0-InPorts___init__ function-1-Region___init__:s->function-0-InPorts___init__ function-2-Region___init__:s->function-0-InPorts___init__ function-6-Region_get:s->function-2-Region___init__ function-1-Py_LoadGlobal:s->function-9-Term_getPort function-9-Term_getPort:s->function-0-Term_IfElse function-0-Py_Call:s->function-0-Py_LoadGlobal function-0-Py_Call:s->function-0-Region_get function-0-Py_Call:s->function-0-TermList___init__ function-0-Py_LoadGlobal:s->function-0-Region_get function-0-Region_get:s->function-0-Region___init__ function-0-TermList___init__:s->primitive-Vec_Term-0 function-2-Term_getPort:s->function-0-Py_SubIO function-0-Py_GtIO:s->function-6-Region_get function-0-Py_GtIO:s->function-8-Region_get function-0-Py_GtIO:s->function-7-Region_get function-8-Region_get:s->function-2-Region___init__ function-7-Region_get:s->function-2-Region___init__ function-6-Term_getPort:s->function-0-Py_DivIO function-0-Py_DivIO:s->function-2-Region_get function-0-Py_DivIO:s->function-3-Term_getPort function-0-Py_DivIO:s->function-0-Term_LiteralI64 function-1-Py_SubIO:s->function-6-Term_getPort function-1-Py_SubIO:s->function-4-Term_getPort function-1-Py_SubIO:s->function-5-Term_getPort function-4-Term_getPort:s->function-0-Py_DivIO function-5-Term_getPort:s->function-0-Py_Call function-2-Py_SubIO:s->function-11-Term_getPort function-2-Py_SubIO:s->function-12-Term_getPort function-2-Py_SubIO:s->function-13-Term_getPort function-11-Term_getPort:s->function-1-Py_Call function-12-Term_getPort:s->function-0-Term_IfElse function-13-Term_getPort:s->function-1-Py_Call function-5-Region_get:s->function-1-Region___init__ function-1-Py_Call:s->function-1-Py_LoadGlobal function-1-Py_Call:s->function-9-Term_getPort function-1-Py_Call:s->function-2-TermList___init__ function-0-Py_SubIO:s->function-4-Region_get function-0-Py_SubIO:s->function-3-Region_get function-0-Py_SubIO:s->function-5-Region_get function-0-Term_Func:s->function-2-Term_RegionEnd function-2-Term_RegionEnd:s->function-2-PortList___init__ function-2-Term_RegionEnd:s->function-2-Region___init__ function-0-Term_IfElse:s->function-0-Term_getPort function-0-Term_IfElse:s->function-0-Term_RegionEnd function-0-Term_IfElse:s->function-1-Term_RegionEnd function-0-Term_IfElse:s->function-1-TermList___init__ function-0-Term_getPort:s->function-0-Py_GtIO function-0-Term_RegionEnd:s->function-0-PortList___init__ function-0-Term_RegionEnd:s->function-1-Region___init__ function-1-Term_RegionEnd:s->function-1-PortList___init__ function-1-Term_RegionEnd:s->function-0-Region___init__ function-1-TermList___init__:s->primitive-Vec_Term-1 function-3-Term_getPort:s->function-0-Py_Call function-0-GraphRoot:s->function-0-Term_Func function-10-Term_getPort:s->function-0-Term_IfElse function-2-TermList___init__:s->primitive-Vec_Term-2 function-8-Term_getPort:s->function-1-Py_SubIO primitive-Vec_Term-1:s->function-6-Region_get primitive-Vec_Term-1:s->function-8-Region_get primitive-Vec_Term-1:s->function-7-Region_get primitive-Vec_Term-2:s->function-10-Term_getPort primitive-Vec_Term-0:s->function-1-Region_get function-0-InPorts___init__ InPorts primitive-Vec_String-0 Vec("!io", "a", "b") function-2-Port___init__ Port("b", ·) function-4-Region_get ·.get(·, 2) function-6-Port___init__ Port("b", ·) function-1-Region_get ·.get(·, 2) function-8-Port___init__ Port("!io", ·) function-14-Term_getPort ·.getPort(·, 0) function-0-Port___init__ Port("!io", ·) function-1-Term_getPort ·.getPort(·, 0) function-1-Port___init__ Port("a", ·) function-3-Region_get ·.get(·, 1) function-3-Port___init__ Port("z", ·) function-0-Term_DbgValue Term.DbgValue("z", ·) function-5-Port___init__ Port("a", ·) function-2-Region_get ·.get(·, 1) function-7-Port___init__ Port("z", ·) function-1-Term_DbgValue Term.DbgValue("z", ·) function-4-Port___init__ Port("!io", ·) function-7-Term_getPort ·.getPort(·, 0) function-9-Port___init__ Port("!ret", ·) function-15-Term_getPort ·.getPort(·, 1) function-2-PortList___init__ PortList primitive-Vec_Port-2 Vec function-0-PortList___init__ PortList primitive-Vec_Port-0 Vec function-1-PortList___init__ PortList primitive-Vec_Port-1 Vec function-0-Region___init__ Region("745", ·) function-1-Region___init__ Region("648", ·) function-2-Region___init__ Region("598", ·) function-6-Region_get ·.get(·, 1) function-1-Py_LoadGlobal Py_LoadGlobal(·, "float") function-9-Term_getPort ·.getPort(·, 0) function-0-Py_Call Py_Call function-0-Py_LoadGlobal Py_LoadGlobal(·, "float") function-0-Region_get ·.get(·, 0) function-0-TermList___init__ TermList function-2-Term_getPort ·.getPort(·, 1) function-0-Py_GtIO Py_GtIO function-8-Region_get ·.get(·, 0) function-7-Region_get ·.get(·, 2) function-6-Term_getPort ·.getPort(·, 1) function-0-Py_DivIO Py_DivIO function-1-Py_SubIO Py_SubIO function-4-Term_getPort ·.getPort(·, 0) function-5-Term_getPort ·.getPort(·, 1) function-2-Py_SubIO Py_SubIO function-11-Term_getPort ·.getPort(·, 0) function-12-Term_getPort ·.getPort(·, 3) function-13-Term_getPort ·.getPort(·, 1) function-5-Region_get ·.get(·, 0) function-1-Py_Call Py_Call function-0-Py_SubIO Py_SubIO function-0-Term_Func Term.Func("1044", "transformed_example_3", ·) function-2-Term_RegionEnd Term.RegionEnd function-0-Term_IfElse Term.IfElse function-0-Term_getPort ·.getPort(·, 1) function-0-Term_RegionEnd Term.RegionEnd function-1-Term_RegionEnd Term.RegionEnd function-1-TermList___init__ TermList function-3-Term_getPort ·.getPort(·, 0) function-0-Term_LiteralI64 Term.LiteralI64(1) function-0-GraphRoot GraphRoot function-10-Term_getPort ·.getPort(·, 1) function-2-TermList___init__ TermList function-8-Term_getPort ·.getPort(·, 1) primitive-Vec_Term-1 Vec primitive-Vec_Term-2 Vec primitive-Vec_Term-0 Vec
3. Egraph Saturation ▶
Egraph Saturation
[debug] initial egraph ▶
outer_cluster_ErrorMsg-63 cluster_ErrorMsg-63 outer_cluster_InPorts-0 cluster_InPorts-0 outer_cluster_Port-56 cluster_Port-56 outer_cluster_Port-41 cluster_Port-41 outer_cluster_Port-21 cluster_Port-21 outer_cluster_Port-36 cluster_Port-36 outer_cluster_Port-20 cluster_Port-20 outer_cluster_Port-22 cluster_Port-22 outer_cluster_Port-38 cluster_Port-38 outer_cluster_Port-25 cluster_Port-25 outer_cluster_Port-58 cluster_Port-58 outer_cluster_Port-37 cluster_Port-37 outer_cluster_PortList-42 cluster_PortList-42 outer_cluster_PortList-59 cluster_PortList-59 outer_cluster_PortList-26 cluster_PortList-26 outer_cluster_Region-1 cluster_Region-1 outer_cluster_Region-13 cluster_Region-13 outer_cluster_Region-8 cluster_Region-8 outer_cluster_Term-57 cluster_Term-57 outer_cluster_Term-60 cluster_Term-60 outer_cluster_Term-39 cluster_Term-39 outer_cluster_Term-43 cluster_Term-43 outer_cluster_Term-14 cluster_Term-14 outer_cluster_Term-30 cluster_Term-30 outer_cluster_Term-18 cluster_Term-18 outer_cluster_Term-4 cluster_Term-4 outer_cluster_Term-9 cluster_Term-9 outer_cluster_Term-50 cluster_Term-50 outer_cluster_Term-46 cluster_Term-46 outer_cluster_Term-2 cluster_Term-2 outer_cluster_Term-29 cluster_Term-29 outer_cluster_Term-31 cluster_Term-31 outer_cluster_Term-11 cluster_Term-11 outer_cluster_Term-35 cluster_Term-35 outer_cluster_Term-48 cluster_Term-48 outer_cluster_Term-6 cluster_Term-6 outer_cluster_Term-17 cluster_Term-17 outer_cluster_Term-3 cluster_Term-3 outer_cluster_Term-19 cluster_Term-19 outer_cluster_Term-15 cluster_Term-15 outer_cluster_Term-47 cluster_Term-47 outer_cluster_Term-23 cluster_Term-23 outer_cluster_Term-12 cluster_Term-12 outer_cluster_Term-54 cluster_Term-54 outer_cluster_Term-24 cluster_Term-24 outer_cluster_Term-33 cluster_Term-33 outer_cluster_Term-55 cluster_Term-55 outer_cluster_Term-7 cluster_Term-7 outer_cluster_Term-51 cluster_Term-51 outer_cluster_Term-40 cluster_Term-40 outer_cluster_Term-34 cluster_Term-34 outer_cluster_Term-27 cluster_Term-27 outer_cluster_Term-62 cluster_Term-62 outer_cluster_Term-10 cluster_Term-10 outer_cluster_Term-16 cluster_Term-16 outer_cluster_Term-28 cluster_Term-28 outer_cluster_Term-61 cluster_Term-61 outer_cluster_Term-45 cluster_Term-45 outer_cluster_Term-52 cluster_Term-52 outer_cluster_Term-32 cluster_Term-32 outer_cluster_Term-53 cluster_Term-53 outer_cluster_TermList-49 cluster_TermList-49 outer_cluster_TermList-44 cluster_TermList-44 outer_cluster_TermList-5 cluster_TermList-5 outer_cluster_Vec_Port-0 cluster_Vec_Port-0 outer_cluster_Vec_Port-1 cluster_Vec_Port-1 outer_cluster_Vec_Port-2 cluster_Vec_Port-2 outer_cluster_Vec_String-0 cluster_Vec_String-0 outer_cluster_Vec_Term-2 cluster_Vec_Term-2 outer_cluster_Vec_Term-1 cluster_Vec_Term-1 outer_cluster_Vec_Term-0 cluster_Vec_Term-0 function-0-InPorts___init__:s->primitive-Vec_String-0 function-8-Port___init__:s->function-14-Term_getPort function-14-Term_getPort:s->function-2-Py_SubIO function-7-Port___init__:s->function-1-Term_DbgValue function-1-Term_DbgValue:s->function-8-Term_getPort function-1-Port___init__:s->function-3-Region_get function-3-Region_get:s->function-1-Region___init__ function-4-Port___init__:s->function-7-Term_getPort function-7-Term_getPort:s->function-1-Py_SubIO function-0-Port___init__:s->function-1-Term_getPort function-1-Term_getPort:s->function-0-Py_SubIO function-2-Port___init__:s->function-4-Region_get function-4-Region_get:s->function-1-Region___init__ function-6-Port___init__:s->function-1-Region_get function-1-Region_get:s->function-0-Region___init__ function-3-Port___init__:s->function-0-Term_DbgValue function-0-Term_DbgValue:s->function-2-Term_getPort function-9-Port___init__:s->function-15-Term_getPort function-15-Term_getPort:s->function-2-Py_SubIO function-5-Port___init__:s->function-2-Region_get function-2-Region_get:s->function-0-Region___init__ function-1-PortList___init__:s->primitive-Vec_Port-1 primitive-Vec_Port-1:s->function-7-Port___init__ primitive-Vec_Port-1:s->function-4-Port___init__ primitive-Vec_Port-1:s->function-6-Port___init__ primitive-Vec_Port-1:s->function-5-Port___init__ function-2-PortList___init__:s->primitive-Vec_Port-2 primitive-Vec_Port-2:s->function-8-Port___init__ primitive-Vec_Port-2:s->function-9-Port___init__ function-0-PortList___init__:s->primitive-Vec_Port-0 primitive-Vec_Port-0:s->function-1-Port___init__ primitive-Vec_Port-0:s->function-0-Port___init__ primitive-Vec_Port-0:s->function-2-Port___init__ primitive-Vec_Port-0:s->function-3-Port___init__ function-0-Region___init__:s->function-0-InPorts___init__ function-2-Region___init__:s->function-0-InPorts___init__ function-1-Region___init__:s->function-0-InPorts___init__ function-2-Py_SubIO:s->function-11-Term_getPort function-2-Py_SubIO:s->function-12-Term_getPort function-2-Py_SubIO:s->function-13-Term_getPort function-2-Term_RegionEnd:s->function-2-PortList___init__ function-2-Term_RegionEnd:s->function-2-Region___init__ function-8-Term_getPort:s->function-1-Py_SubIO function-1-Py_SubIO:s->function-4-Term_getPort function-1-Py_SubIO:s->function-6-Term_getPort function-1-Py_SubIO:s->function-5-Term_getPort function-1-Term_RegionEnd:s->function-1-PortList___init__ function-1-Term_RegionEnd:s->function-0-Region___init__ function-6-Region_get:s->function-2-Region___init__ function-0-Py_DivIO:s->function-2-Region_get function-0-Py_DivIO:s->function-3-Term_getPort function-0-Py_DivIO:s->function-0-Term_LiteralI64 function-3-Term_getPort:s->function-0-Py_Call function-0-Term_getPort:s->function-0-Py_GtIO function-0-Py_GtIO:s->function-6-Region_get function-0-Py_GtIO:s->function-8-Region_get function-0-Py_GtIO:s->function-7-Region_get function-1-Py_Call:s->function-1-Py_LoadGlobal function-1-Py_Call:s->function-9-Term_getPort function-1-Py_Call:s->function-2-TermList___init__ function-1-Py_LoadGlobal:s->function-9-Term_getPort function-9-Term_getPort:s->function-0-Term_IfElse function-2-TermList___init__:s->primitive-Vec_Term-2 function-0-Term_IfElse:s->function-1-Term_RegionEnd function-0-Term_IfElse:s->function-0-Term_getPort function-0-Term_IfElse:s->function-0-Term_RegionEnd function-0-Term_IfElse:s->function-1-TermList___init__ function-0-Region_get:s->function-0-Region___init__ function-4-Term_getPort:s->function-0-Py_DivIO function-5-Region_get:s->function-1-Region___init__ function-10-Term_getPort:s->function-0-Term_IfElse function-0-Py_Call:s->function-0-Region_get function-0-Py_Call:s->function-0-Py_LoadGlobal function-0-Py_Call:s->function-0-TermList___init__ function-0-Py_LoadGlobal:s->function-0-Region_get function-0-TermList___init__:s->primitive-Vec_Term-0 function-8-Region_get:s->function-2-Region___init__ function-7-Region_get:s->function-2-Region___init__ function-0-Py_SubIO:s->function-3-Region_get function-0-Py_SubIO:s->function-4-Region_get function-0-Py_SubIO:s->function-5-Region_get function-2-Term_getPort:s->function-0-Py_SubIO function-11-Term_getPort:s->function-1-Py_Call function-12-Term_getPort:s->function-0-Term_IfElse function-13-Term_getPort:s->function-1-Py_Call function-6-Term_getPort:s->function-0-Py_DivIO function-5-Term_getPort:s->function-0-Py_Call function-0-Term_RegionEnd:s->function-0-PortList___init__ function-0-Term_RegionEnd:s->function-1-Region___init__ function-0-GraphRoot:s->function-0-Term_Func function-0-Term_Func:s->function-2-Term_RegionEnd function-1-TermList___init__:s->primitive-Vec_Term-1 primitive-Vec_Term-2:s->function-10-Term_getPort primitive-Vec_Term-1:s->function-6-Region_get primitive-Vec_Term-1:s->function-8-Region_get primitive-Vec_Term-1:s->function-7-Region_get primitive-Vec_Term-0:s->function-1-Region_get function-0-ErrorMsg_root ErrorMsg.root function-0-InPorts___init__ InPorts primitive-Vec_String-0 Vec("!io", "a", "b") function-8-Port___init__ Port("!io", ·) function-14-Term_getPort ·.getPort(·, 0) function-7-Port___init__ Port("z", ·) function-1-Term_DbgValue Term.DbgValue("z", ·) function-1-Port___init__ Port("a", ·) function-3-Region_get ·.get(·, 1) function-4-Port___init__ Port("!io", ·) function-7-Term_getPort ·.getPort(·, 0) function-0-Port___init__ Port("!io", ·) function-1-Term_getPort ·.getPort(·, 0) function-2-Port___init__ Port("b", ·) function-4-Region_get ·.get(·, 2) function-6-Port___init__ Port("b", ·) function-1-Region_get ·.get(·, 2) function-3-Port___init__ Port("z", ·) function-0-Term_DbgValue Term.DbgValue("z", ·) function-9-Port___init__ Port("!ret", ·) function-15-Term_getPort ·.getPort(·, 1) function-5-Port___init__ Port("a", ·) function-2-Region_get ·.get(·, 1) function-1-PortList___init__ PortList primitive-Vec_Port-1 Vec function-2-PortList___init__ PortList primitive-Vec_Port-2 Vec function-0-PortList___init__ PortList primitive-Vec_Port-0 Vec function-0-Region___init__ Region("745", ·) function-2-Region___init__ Region("598", ·) function-1-Region___init__ Region("648", ·) function-2-Py_SubIO Py_SubIO function-2-Term_RegionEnd Term.RegionEnd function-8-Term_getPort ·.getPort(·, 1) function-1-Py_SubIO Py_SubIO function-1-Term_RegionEnd Term.RegionEnd function-6-Region_get ·.get(·, 1) function-0-Py_DivIO Py_DivIO function-3-Term_getPort ·.getPort(·, 0) function-0-Term_LiteralI64 Term.LiteralI64(1) function-0-Term_getPort ·.getPort(·, 1) function-0-Py_GtIO Py_GtIO function-1-Py_Call Py_Call function-1-Py_LoadGlobal Py_LoadGlobal(·, "float") function-9-Term_getPort ·.getPort(·, 0) function-2-TermList___init__ TermList function-0-Term_IfElse Term.IfElse function-0-Region_get ·.get(·, 0) function-4-Term_getPort ·.getPort(·, 0) function-5-Region_get ·.get(·, 0) function-10-Term_getPort ·.getPort(·, 1) function-0-Py_Call Py_Call function-0-Py_LoadGlobal Py_LoadGlobal(·, "float") function-0-TermList___init__ TermList function-8-Region_get ·.get(·, 0) function-7-Region_get ·.get(·, 2) function-0-Py_SubIO Py_SubIO function-2-Term_getPort ·.getPort(·, 1) function-11-Term_getPort ·.getPort(·, 0) function-12-Term_getPort ·.getPort(·, 3) function-13-Term_getPort ·.getPort(·, 1) function-6-Term_getPort ·.getPort(·, 1) function-5-Term_getPort ·.getPort(·, 1) function-0-Term_RegionEnd Term.RegionEnd function-0-GraphRoot GraphRoot function-0-Term_Func Term.Func("1044", "transformed_example_3", ·) function-1-TermList___init__ TermList primitive-Vec_Term-2 Vec primitive-Vec_Term-1 Vec primitive-Vec_Term-0 Vec
[debug] saturated egraph ▶
outer_cluster_ErrorMsg-63 cluster_ErrorMsg-63 outer_cluster_InPorts-0 cluster_InPorts-0 outer_cluster_Port-109 cluster_Port-109 outer_cluster_Port-107 cluster_Port-107 outer_cluster_Port-183 cluster_Port-183 outer_cluster_Port-185 cluster_Port-185 outer_cluster_Port-99 cluster_Port-99 outer_cluster_Port-135 cluster_Port-135 outer_cluster_Port-165 cluster_Port-165 outer_cluster_Port-101 cluster_Port-101 outer_cluster_Port-103 cluster_Port-103 outer_cluster_Port-167 cluster_Port-167 outer_cluster_Port-105 cluster_Port-105 outer_cluster_Port-149 cluster_Port-149 outer_cluster_PortList-26 cluster_PortList-26 outer_cluster_PortList-42 cluster_PortList-42 outer_cluster_PortList-59 cluster_PortList-59 outer_cluster_Region-13 cluster_Region-13 outer_cluster_Region-1 cluster_Region-1 outer_cluster_Region-8 cluster_Region-8 outer_cluster_split-0-primitive-String-2952790038 cluster_split-0-primitive-String-2952790038 outer_cluster_split-0-primitive-String-1879048210 cluster_split-0-primitive-String-1879048210 outer_cluster_String-20 cluster_String-20 outer_cluster_String-2952790038 cluster_String-2952790038 outer_cluster_String-1879048210 cluster_String-1879048210 outer_cluster_split-0-primitive-String-20 cluster_split-0-primitive-String-20 outer_cluster_split-0-primitive-String-3758096426 cluster_split-0-primitive-String-3758096426 outer_cluster_split-1-primitive-String-20 cluster_split-1-primitive-String-20 outer_cluster_String-2684354583 cluster_String-2684354583 outer_cluster_String-3758096426 cluster_String-3758096426 outer_cluster_Term-77 cluster_Term-77 outer_cluster_Term-111 cluster_Term-111 outer_cluster_Term-175 cluster_Term-175 outer_cluster_Term-34 cluster_Term-34 outer_cluster_Term-48 cluster_Term-48 outer_cluster_Term-176 cluster_Term-176 outer_cluster_Term-6 cluster_Term-6 outer_cluster_Term-15 cluster_Term-15 outer_cluster_Term-60 cluster_Term-60 outer_cluster_Term-180 cluster_Term-180 outer_cluster_Term-29 cluster_Term-29 outer_cluster_Term-62 cluster_Term-62 outer_cluster_Term-142 cluster_Term-142 outer_cluster_Term-43 cluster_Term-43 outer_cluster_Term-45 cluster_Term-45 outer_cluster_Term-61 cluster_Term-61 outer_cluster_Term-50 cluster_Term-50 outer_cluster_Term-14 cluster_Term-14 outer_cluster_Term-54 cluster_Term-54 outer_cluster_Term-12 cluster_Term-12 outer_cluster_Term-47 cluster_Term-47 outer_cluster_Term-52 cluster_Term-52 outer_cluster_Term-137 cluster_Term-137 outer_cluster_Term-17 cluster_Term-17 outer_cluster_Term-151 cluster_Term-151 outer_cluster_Term-27 cluster_Term-27 outer_cluster_Term-53 cluster_Term-53 outer_cluster_Term-152 cluster_Term-152 outer_cluster_Term-51 cluster_Term-51 outer_cluster_Term-79 cluster_Term-79 outer_cluster_Term-169 cluster_Term-169 outer_cluster_Term-178 cluster_Term-178 outer_cluster_Term-30 cluster_Term-30 outer_cluster_Term-155 cluster_Term-155 outer_cluster_Term-74 cluster_Term-74 outer_cluster_Term-18 cluster_Term-18 outer_cluster_Term-78 cluster_Term-78 outer_cluster_Term-76 cluster_Term-76 outer_cluster_Term-33 cluster_Term-33 outer_cluster_Term-32 cluster_Term-32 outer_cluster_Term-3 cluster_Term-3 outer_cluster_Term-75 cluster_Term-75 outer_cluster_TermList-44 cluster_TermList-44 outer_cluster_TermList-49 cluster_TermList-49 outer_cluster_TermList-5 cluster_TermList-5 outer_cluster_Type-158 cluster_Type-158 outer_cluster_Type-189 cluster_Type-189 outer_cluster_Type-193 cluster_Type-193 outer_cluster_Type-160 cluster_Type-160 outer_cluster_TypeVar-146 cluster_TypeVar-146 outer_cluster_TypeVar-140 cluster_TypeVar-140 outer_cluster_TypeVar-159 cluster_TypeVar-159 outer_cluster_TypeVar-162 cluster_TypeVar-162 outer_cluster_TypeVar-171 cluster_TypeVar-171 outer_cluster_TypeVar-174 cluster_TypeVar-174 outer_cluster_TypeVar-170 cluster_TypeVar-170 outer_cluster_TypeVar-157 cluster_TypeVar-157 outer_cluster_TypeVar-191 cluster_TypeVar-191 outer_cluster_TypeVar-92 cluster_TypeVar-92 outer_cluster_TypeVar-130 cluster_TypeVar-130 outer_cluster_TypeVar-161 cluster_TypeVar-161 outer_cluster_TypedIns-94 cluster_TypedIns-94 outer_cluster_TypedIns-82 cluster_TypedIns-82 outer_cluster_TypedIns-84 cluster_TypedIns-84 outer_cluster_TypedOuts-129 cluster_TypedOuts-129 outer_cluster_TypedOuts-123 cluster_TypedOuts-123 outer_cluster_TypedOuts-145 cluster_TypedOuts-145 outer_cluster_split-5-primitive-Unit-0 cluster_split-5-primitive-Unit-0 outer_cluster_split-4-primitive-Unit-0 cluster_split-4-primitive-Unit-0 outer_cluster_split-3-primitive-Unit-0 cluster_split-3-primitive-Unit-0 outer_cluster_Unit-0 cluster_Unit-0 outer_cluster_split-0-primitive-Unit-0 cluster_split-0-primitive-Unit-0 outer_cluster_split-1-primitive-Unit-0 cluster_split-1-primitive-Unit-0 outer_cluster_split-2-primitive-Unit-0 cluster_split-2-primitive-Unit-0 outer_cluster_Vec_Port-6 cluster_Vec_Port-6 outer_cluster_Vec_Port-7 cluster_Vec_Port-7 outer_cluster_Vec_Port-8 cluster_Vec_Port-8 outer_cluster_Vec_String-0 cluster_Vec_String-0 outer_cluster_Vec_Term-2 cluster_Vec_Term-2 outer_cluster_Vec_Term-4 cluster_Vec_Term-4 outer_cluster_Vec_Term-5 cluster_Vec_Term-5 function-0-InPorts___init__:s->primitive-Vec_String-0 function-5-Port___init__:s->function-9-Port_value function-9-Port_value:s->function-5-Port___init__ function-5-PortList___getitem__:s->function-4-PortList___init__ function-4-PortList___init__:s->primitive-Vec_Port-8 function-2-Port___init__:s->function-8-Port_value function-8-Port_value:s->function-2-Port___init__ function-4-PortList___getitem__:s->function-3-PortList___init__ function-3-PortList___init__:s->primitive-Vec_Port-7 function-10-PortList___getitem__:s->function-3-PortList___init__ function-11-PortList___getitem__:s->function-4-PortList___init__ function-0-Port___init__:s->function-6-Region_get function-6-Region_get:s->function-1-Region___init__ function-0-PortList___getitem__:s->function-3-PortList___init__ function-6-Port___init__:s->function-6-PortList_getValue function-6-PortList_getValue:s->function-2-PortList___init__ function-6-PortList___getitem__:s->function-2-PortList___init__ function-2-PortList___init__:s->primitive-Vec_Port-6 function-10-Port___init__:s->function-10-Region_get function-10-Region_get:s->function-1-Region___init__ function-8-PortList___getitem__:s->function-3-PortList___init__ function-3-Port___init__:s->function-35-Term_getPort function-35-Term_getPort:s->function-0-Py_DivIO function-1-PortList___getitem__:s->function-4-PortList___init__ function-1-Port___init__:s->function-7-Region_get function-7-Region_get:s->function-1-Region___init__ function-2-PortList___getitem__:s->function-3-PortList___init__ function-11-Port___init__:s->function-11-Region_get function-11-Region_get:s->function-0-Region___init__ function-9-PortList___getitem__:s->function-4-PortList___init__ function-4-Port___init__:s->function-3-PortList_getValue function-3-PortList_getValue:s->function-4-PortList___init__ function-3-PortList___getitem__:s->function-4-PortList___init__ function-7-Port___init__:s->function-7-PortList_getValue function-7-PortList_getValue:s->function-2-PortList___init__ function-7-PortList___getitem__:s->function-2-PortList___init__ primitive-Vec_Port-7:s->function-4-PortList___getitem__ primitive-Vec_Port-7:s->function-0-PortList___getitem__ primitive-Vec_Port-7:s->function-8-PortList___getitem__ primitive-Vec_Port-7:s->function-2-PortList___getitem__ primitive-Vec_Port-8:s->function-5-PortList___getitem__ primitive-Vec_Port-8:s->function-1-PortList___getitem__ primitive-Vec_Port-8:s->function-9-PortList___getitem__ primitive-Vec_Port-8:s->function-3-PortList___getitem__ primitive-Vec_Port-6:s->function-6-PortList___getitem__ primitive-Vec_Port-6:s->function-7-PortList___getitem__ function-2-Region___init__:s->function-0-InPorts___init__ function-0-Region___init__:s->function-0-InPorts___init__ function-1-Region___init__:s->function-0-InPorts___init__ function-14-Port_name:s->function-3-PortList___getitem__ function-19-Port_name:s->function-9-PortList___getitem__ function-10-Port_name:s->function-0-PortList___getitem__ function-11-Port_name:s->function-2-PortList___getitem__ function-18-Port_name:s->function-8-PortList___getitem__ function-13-Port_name:s->function-1-PortList___getitem__ function-15-Port_name:s->function-5-PortList___getitem__ function-16-Port_name:s->function-6-PortList___getitem__ function-17-Port_name:s->function-7-PortList___getitem__ function-12-Port_name:s->function-4-PortList___getitem__ function-8-Region_get:s->function-0-Region___init__ function-7-Port_value:s->function-4-Port___init__ function-34-Term_getPort:s->function-0-Py_SubIO function-0-Py_SubIO:s->function-20-Term_getPort function-0-Py_SubIO:s->function-12-Term_getPort function-0-Py_SubIO:s->function-0-Nb_CastI64ToF64 function-10-Port_value:s->function-6-Port___init__ function-40-Term_getPort:s->function-2-Term_RegionEnd function-2-Term_RegionEnd:s->function-2-PortList___init__ function-2-Term_RegionEnd:s->function-2-Region___init__ function-2-Py_SubIO:s->function-5-Port_value function-2-Py_SubIO:s->function-1-Nb_CastI64ToF64 function-2-Py_SubIO:s->function-1-Nb_Div_Int64 function-5-Port_value:s->function-3-Port___init__ function-1-Nb_CastI64ToF64:s->function-16-Port_value function-1-Nb_Div_Int64:s->function-7-Port_value function-1-Nb_Div_Int64:s->function-0-Term_LiteralI64 function-10-Term_getPort:s->function-0-Term_IfElse function-0-Term_IfElse:s->function-1-Term_RegionEnd function-0-Term_IfElse:s->function-1-Nb_Gt_Int64 function-0-Term_IfElse:s->function-0-Term_RegionEnd function-0-Term_IfElse:s->function-4-TermList___init__ function-19-Port_value:s->function-10-PortList___getitem__ function-10-PortList_getValue:s->function-3-PortList___init__ function-2-Py_Call:s->function-35-Term_getPort function-2-Py_Call:s->function-2-Py_LoadGlobal function-2-Py_Call:s->function-5-TermList___init__ function-2-Py_LoadGlobal:s->function-36-Term_getPort function-5-TermList___init__:s->primitive-Vec_Term-5 function-1-Region_get:s->function-2-Region___init__ function-38-Term_getPort:s->function-0-Term_IfElse function-0-GraphRoot:s->function-0-Term_Func function-0-Term_Func:s->function-2-Term_RegionEnd function-4-Region_get:s->function-2-Region___init__ function-26-Term_getPort:s->function-1-Py_GtIO function-1-Py_GtIO:s->function-1-Region_get function-1-Py_GtIO:s->function-4-Region_get function-1-Py_GtIO:s->function-0-Region_get function-1-Term_RegionEnd:s->function-4-PortList___init__ function-1-Term_RegionEnd:s->function-0-Region___init__ function-1-Nb_Gt_Int64:s->function-1-Region_get function-1-Nb_Gt_Int64:s->function-0-Region_get function-0-Term_RegionEnd:s->function-3-PortList___init__ function-0-Term_RegionEnd:s->function-1-Region___init__ function-4-TermList___init__:s->primitive-Vec_Term-4 function-0-Py_Call:s->function-0-Py_LoadGlobal function-0-Py_Call:s->function-20-Term_getPort function-0-Py_Call:s->function-2-TermList___init__ function-0-Py_LoadGlobal:s->function-11-Term_getPort function-20-Term_getPort:s->function-0-Term_IfElse function-2-TermList___init__:s->primitive-Vec_Term-2 function-0-Region_get:s->function-2-Region___init__ function-12-Term_getPort:s->function-0-Term_IfElse function-0-Nb_CastI64ToF64:s->function-10-Term_getPort function-3-Py_SubIO:s->function-4-Port_value function-3-Py_SubIO:s->function-2-PortList_getValue function-3-Py_SubIO:s->function-8-PortList_getValue function-4-Port_value:s->function-0-Port___init__ function-2-PortList_getValue:s->function-3-PortList___init__ function-8-PortList_getValue:s->function-3-PortList___init__ function-11-Term_getPort:s->function-0-Py_Call function-37-Term_getPort:s->function-0-Py_SubIO function-12-Port_value:s->function-7-Port___init__ function-15-Port_value:s->function-10-Port___init__ function-2-Nb_CastToFloat:s->function-10-Term_getPort function-13-Term_getPort:s->function-0-Py_Call function-16-Port_value:s->function-11-Port___init__ function-9-PortList_getValue:s->function-4-PortList___init__ function-32-Term_getPort:s->function-2-Py_SubIO function-1-Term_DbgValue:s->function-1-Nb_Sub_Float64 function-1-Nb_Sub_Float64:s->function-3-Nb_CastToFloat function-1-Nb_Sub_Float64:s->function-6-Term_getPort function-5-PortList_getValue:s->function-4-PortList___init__ function-3-Nb_CastToFloat:s->function-9-PortList_getValue function-6-Term_getPort:s->function-0-Py_DivIO function-39-Term_getPort:s->function-2-Term_RegionEnd function-20-Port_value:s->function-11-PortList___getitem__ function-11-PortList_getValue:s->function-4-PortList___init__ function-0-Py_DivIO:s->function-8-Region_get function-0-Py_DivIO:s->function-0-Term_LiteralI64 function-0-Py_DivIO:s->function-36-Term_getPort function-36-Term_getPort:s->function-2-Py_Call function-33-Term_getPort:s->function-0-Term_IfElse function-29-Term_getPort:s->function-3-Py_SubIO function-0-PortList_getValue:s->function-3-PortList___init__ function-0-Term_getPort:s->function-1-Py_GtIO function-30-Term_getPort:s->function-3-Py_SubIO function-0-Term_DbgValue:s->function-0-Nb_Sub_Int64 function-0-Nb_Sub_Int64:s->function-15-Port_value function-0-Nb_Sub_Int64:s->function-6-Port_value function-4-PortList_getValue:s->function-3-PortList___init__ function-6-Port_value:s->function-1-Port___init__ function-5-Term_getPort:s->function-2-Py_Call function-9-Region_get:s->function-0-Region___init__ function-31-Term_getPort:s->function-2-Py_SubIO function-1-PortList_getValue:s->function-4-PortList___init__ primitive-Vec_Term-4:s->function-1-Region_get primitive-Vec_Term-4:s->function-4-Region_get primitive-Vec_Term-4:s->function-0-Region_get primitive-Vec_Term-2:s->function-10-Term_getPort primitive-Vec_Term-5:s->function-9-PortList_getValue function-0-TypeVar_getType:s->function-23-TypeVar___init__ function-23-TypeVar___init__:s->function-5-Term_getPort function-2-TypeVar_getType:s->function-25-TypeVar___init__ function-25-TypeVar___init__:s->function-1-Nb_Div_Int64 function-3-TypeVar_getType:s->function-31-TypeVar___init__ function-31-TypeVar___init__:s->function-13-Term_getPort function-0-Type___or__:s->function-2-TypeVar_getType function-0-Type___or__:s->function-5-TypeVar_getType function-5-TypeVar_getType:s->function-0-TypeVar___init__ function-1-Type___or__:s->function-3-TypeVar_getType function-1-Type___or__:s->function-6-TypeVar_getType function-6-TypeVar_getType:s->function-9-TypedOuts_at function-2-Type___or__:s->function-7-TypeVar_getType function-2-Type___or__:s->function-4-TypeVar_getType function-7-TypeVar_getType:s->function-15-TypedOuts_at function-4-TypeVar_getType:s->function-14-TypedOuts_at function-4-Type___or__:s->function-1-Type___or__ function-4-Type___or__:s->function-6-TypeVar_getType function-14-TypedOuts_at:s->function-0-TypedOuts___init__ function-3-Type___or__:s->function-5-TypeVar_getType function-3-Type___or__:s->function-3-Type___or__ function-0-TypeVar___init__:s->function-0-Term_LiteralI64 function-9-TypedOuts_at:s->function-0-TypedOuts___init__ function-15-TypedOuts_at:s->function-0-TypedOuts___init__ function-1-TypeVar_getType:s->function-24-TypeVar___init__ function-24-TypeVar___init__:s->function-1-Nb_Gt_Int64 function-17-TypeVar___init__:s->function-6-PortList_getValue function-7-TypedOuts_at:s->function-2-TypedOuts___init__ function-2-TypedOuts___init__:s->function-2-Region___init__ function-12-TypeVar___init__:s->function-10-Term_getPort function-15-TypeVar___init__:s->function-8-Region_get function-16-TypeVar___init__:s->function-7-Region_get function-19-TypeVar___init__:s->function-0-Region_get function-10-TypedIns_arg:s->function-2-TypedIns___init__ function-2-TypedIns___init__:s->function-2-Region___init__ function-11-TypedIns_arg:s->function-0-TypedIns___init__ function-0-TypedIns___init__:s->function-1-Region___init__ function-12-TypedIns_arg:s->function-1-TypedIns___init__ function-1-TypedIns___init__:s->function-0-Region___init__ function-8-TypedOuts_at:s->function-1-TypedOuts___init__ function-1-TypedOuts___init__:s->function-0-Region___init__ function-0-TypedOuts___init__:s->function-1-Region___init__ function-29-TypeVar___init__:s->function-7-PortList_getValue function-10-TypedOuts_at:s->function-2-TypedOuts___init__ function-34-TypeVar___init__:s->function-33-Term_getPort function-35-TypeVar___init__:s->function-11-Region_get function-36-TypeVar___init__:s->function-10-Region_get function-42-TypeVar___init__:s->function-1-Region_get function-13-TypedIns_arg:s->function-2-TypedIns___init__ function-14-TypedIns_arg:s->function-0-TypedIns___init__ function-15-TypedIns_arg:s->function-1-TypedIns___init__ function-12-TypedOuts_at:s->function-1-TypedOuts___init__ function-30-TypeVar___init__:s->function-12-Term_getPort function-32-TypeVar___init__:s->function-9-Port_value function-33-TypeVar___init__:s->function-8-Port_value function-13-TypedOuts_at:s->function-1-TypedOuts___init__ function-43-TypeVar___init__:s->function-38-Term_getPort function-44-TypeVar___init__:s->function-11-PortList_getValue function-45-TypeVar___init__:s->function-10-PortList_getValue function-17-TypedOuts_at:s->function-1-TypedOuts___init__ function-18-TypedOuts_at:s->function-0-TypedOuts___init__ function-5-TypeVar___init__:s->function-0-PortList_getValue function-6-TypeVar___init__:s->function-9-Region_get function-7-TypeVar___init__:s->function-11-Term_getPort function-18-TypeVar___init__:s->function-26-Term_getPort function-8-TypedIns_arg:s->function-0-TypedIns___init__ function-9-TypedIns_arg:s->function-1-TypedIns___init__ function-3-TypedOuts_at:s->function-1-TypedOuts___init__ function-6-TypedOuts_at:s->function-0-TypedOuts___init__ function-1-failed_to_unify:s->function-2-Type___or__ function-4-propagate_ifelse_outs:s->function-4-PortList___init__ function-4-propagate_ifelse_outs:s->function-3-PortList___init__ function-4-propagate_ifelse_outs:s->function-0-Term_IfElse function-3-propagate_ifelse_outs:s->function-4-PortList___init__ function-3-propagate_ifelse_outs:s->function-3-PortList___init__ function-3-propagate_ifelse_outs:s->function-0-Term_IfElse function-0-IsConstantTrue:s->function-0-Term_LiteralI64 function-0-propagate_ifelse_outs:s->function-4-PortList___init__ function-0-propagate_ifelse_outs:s->function-3-PortList___init__ function-0-propagate_ifelse_outs:s->function-0-Term_IfElse function-1-propagate_ifelse_outs:s->function-4-PortList___init__ function-1-propagate_ifelse_outs:s->function-3-PortList___init__ function-1-propagate_ifelse_outs:s->function-0-Term_IfElse function-2-propagate_ifelse_outs:s->function-4-PortList___init__ function-2-propagate_ifelse_outs:s->function-3-PortList___init__ function-2-propagate_ifelse_outs:s->function-0-Term_IfElse function-1-ErrorMsg_fail ErrorMsg.fail("fail to unify") function-0-ErrorMsg_root ErrorMsg.root function-0-InPorts___init__ InPorts primitive-Vec_String-0 Vec("!io", "a", "b") function-5-Port___init__ Port("z", ·) function-9-Port_value ·.value function-5-PortList___getitem__ ·[3] function-4-PortList___init__ PortList function-2-Port___init__ Port("z", ·) function-8-Port_value ·.value function-4-PortList___getitem__ ·[3] function-3-PortList___init__ PortList function-10-PortList___getitem__ ·[4] function-11-PortList___getitem__ ·[4] function-0-Port___init__ Port("!io", ·) function-6-Region_get ·.get(·, 0) function-0-PortList___getitem__ ·[0] function-6-Port___init__ Port("!io", ·) function-6-PortList_getValue ·.getValue(·, 0) function-6-PortList___getitem__ ·[0] function-2-PortList___init__ PortList function-10-Port___init__ Port("b", ·) function-10-Region_get ·.get(·, 2) function-8-PortList___getitem__ ·[2] function-3-Port___init__ Port("!io", ·) function-35-Term_getPort ·.getPort(·, 0) function-1-PortList___getitem__ ·[0] function-1-Port___init__ Port("a", ·) function-7-Region_get ·.get(·, 1) function-2-PortList___getitem__ ·[1] function-11-Port___init__ Port("b", ·) function-11-Region_get ·.get(·, 2) function-9-PortList___getitem__ ·[2] function-4-Port___init__ Port("a", ·) function-3-PortList_getValue ·.getValue(·, 1) function-3-PortList___getitem__ ·[1] function-7-Port___init__ Port("!ret", ·) function-7-PortList_getValue ·.getValue(·, 1) function-7-PortList___getitem__ ·[1] primitive-Vec_Port-7 Vec primitive-Vec_Port-8 Vec primitive-Vec_Port-6 Vec function-2-Region___init__ Region("598", ·) function-0-Region___init__ Region("745", ·) function-1-Region___init__ Region("648", ·) function-14-Port_name ·.name split-0-primitive-String-2952790038 "a" function-19-Port_name ·.name split-0-primitive-String-1879048210 "b" function-10-Port_name ·.name primitive-String-20 "!io" function-11-Port_name ·.name primitive-String-2952790038 "a" function-18-Port_name ·.name primitive-String-1879048210 "b" function-13-Port_name ·.name split-0-primitive-String-20 "!io" function-15-Port_name ·.name split-0-primitive-String-3758096426 "z" function-16-Port_name ·.name split-1-primitive-String-20 "!io" function-17-Port_name ·.name primitive-String-2684354583 "!ret" function-12-Port_name ·.name primitive-String-3758096426 "z" function-8-Region_get ·.get(·, 1) function-7-Port_value ·.value function-34-Term_getPort ·.getPort(·, 0) function-0-Py_SubIO Py_SubIO function-10-Port_value ·.value function-40-Term_getPort ·.getPort(·, 1) function-2-Term_RegionEnd Term.RegionEnd function-2-Py_SubIO Py_SubIO function-5-Port_value ·.value function-1-Nb_CastI64ToF64 Nb_CastI64ToF64 function-1-Nb_Div_Int64 Nb_Div_Int64 function-10-Term_getPort ·.getPort(·, 1) function-0-Term_IfElse Term.IfElse function-19-Port_value ·.value function-10-PortList_getValue ·.getValue(·, 4) function-2-Py_Call Py_Call function-2-Py_LoadGlobal Py_LoadGlobal(·, "float") function-5-TermList___init__ TermList function-1-Region_get ·.get(·, 2) function-38-Term_getPort ·.getPort(·, 4) function-0-Term_LiteralI64 Term.LiteralI64(1) function-0-GraphRoot GraphRoot function-0-Term_Func Term.Func("1044", "transformed_example_3", ·) function-4-Region_get ·.get(·, 0) function-26-Term_getPort ·.getPort(·, 0) function-1-Py_GtIO Py_GtIO function-1-Term_RegionEnd Term.RegionEnd function-1-Nb_Gt_Int64 Nb_Gt_Int64 function-0-Term_RegionEnd Term.RegionEnd function-4-TermList___init__ TermList function-0-Py_Call Py_Call function-0-Py_LoadGlobal Py_LoadGlobal(·, "float") function-20-Term_getPort ·.getPort(·, 0) function-2-TermList___init__ TermList function-0-Region_get ·.get(·, 1) function-12-Term_getPort ·.getPort(·, 3) function-0-Nb_CastI64ToF64 Nb_CastI64ToF64 function-3-Py_SubIO Py_SubIO function-4-Port_value ·.value function-2-PortList_getValue ·.getValue(·, 1) function-8-PortList_getValue ·.getValue(·, 2) function-11-Term_getPort ·.getPort(·, 0) function-37-Term_getPort ·.getPort(·, 1) function-12-Port_value ·.value function-15-Port_value ·.value function-2-Nb_CastToFloat Nb_CastToFloat function-13-Term_getPort ·.getPort(·, 1) function-16-Port_value ·.value function-9-PortList_getValue ·.getValue(·, 2) function-32-Term_getPort ·.getPort(·, 1) function-1-Term_DbgValue Term.DbgValue("z", ·) function-1-Nb_Sub_Float64 Nb_Sub_Float64 function-5-PortList_getValue ·.getValue(·, 3) function-3-Nb_CastToFloat Nb_CastToFloat function-6-Term_getPort ·.getPort(·, 1) function-39-Term_getPort ·.getPort(·, 0) function-20-Port_value ·.value function-11-PortList_getValue ·.getValue(·, 4) function-0-Py_DivIO Py_DivIO function-36-Term_getPort ·.getPort(·, 0) function-33-Term_getPort ·.getPort(·, 2) function-29-Term_getPort ·.getPort(·, 0) function-0-PortList_getValue ·.getValue(·, 0) function-0-Term_getPort ·.getPort(·, 1) function-30-Term_getPort ·.getPort(·, 1) function-0-Term_DbgValue Term.DbgValue("z", ·) function-0-Nb_Sub_Int64 Nb_Sub_Int64 function-4-PortList_getValue ·.getValue(·, 3) function-6-Port_value ·.value function-5-Term_getPort ·.getPort(·, 1) function-9-Region_get ·.get(·, 0) function-31-Term_getPort ·.getPort(·, 0) function-1-PortList_getValue ·.getValue(·, 0) primitive-Vec_Term-4 Vec primitive-Vec_Term-2 Vec primitive-Vec_Term-5 Vec function-0-TypeVar_getType ·.getType function-23-TypeVar___init__ TypeVar function-2-TypeVar_getType ·.getType function-25-TypeVar___init__ TypeVar function-3-TypeVar_getType ·.getType function-31-TypeVar___init__ TypeVar function-1-Type_simple Type.simple("Float64") function-0-Type___or__ · | · function-5-TypeVar_getType ·.getType function-1-Type___or__ · | · function-6-TypeVar_getType ·.getType function-2-Type___or__ · | · function-7-TypeVar_getType ·.getType function-4-TypeVar_getType ·.getType function-4-Type___or__ · | · function-14-TypedOuts_at ·.at(·, 3) function-3-Type___or__ · | · function-0-TypeVar___init__ TypeVar function-9-TypedOuts_at ·.at(·, 1) function-15-TypedOuts_at ·.at(·, 2) function-3-Type_simple Type.simple("Int64") function-1-TypeVar_getType ·.getType function-24-TypeVar___init__ TypeVar function-2-Type_simple Type.simple("Bool") function-17-TypeVar___init__ TypeVar function-7-TypedOuts_at ·.at(·, 0) function-2-TypedOuts___init__ TypedOuts function-12-TypeVar___init__ TypeVar function-15-TypeVar___init__ TypeVar function-16-TypeVar___init__ TypeVar function-19-TypeVar___init__ TypeVar function-10-TypedIns_arg ·.arg(·, 1) function-2-TypedIns___init__ TypedIns function-11-TypedIns_arg ·.arg(·, 1) function-0-TypedIns___init__ TypedIns function-12-TypedIns_arg ·.arg(·, 1) function-1-TypedIns___init__ TypedIns function-8-TypedOuts_at ·.at(·, 1) function-1-TypedOuts___init__ TypedOuts function-0-TypedOuts___init__ TypedOuts function-29-TypeVar___init__ TypeVar function-10-TypedOuts_at ·.at(·, 1) function-34-TypeVar___init__ TypeVar function-35-TypeVar___init__ TypeVar function-36-TypeVar___init__ TypeVar function-42-TypeVar___init__ TypeVar function-13-TypedIns_arg ·.arg(·, 2) function-14-TypedIns_arg ·.arg(·, 2) function-15-TypedIns_arg ·.arg(·, 2) function-12-TypedOuts_at ·.at(·, 2) function-30-TypeVar___init__ TypeVar function-32-TypeVar___init__ TypeVar function-33-TypeVar___init__ TypeVar function-13-TypedOuts_at ·.at(·, 3) function-43-TypeVar___init__ TypeVar function-44-TypeVar___init__ TypeVar function-45-TypeVar___init__ TypeVar function-17-TypedOuts_at ·.at(·, 4) function-18-TypedOuts_at ·.at(·, 4) function-5-TypeVar___init__ TypeVar function-6-TypeVar___init__ TypeVar function-7-TypeVar___init__ TypeVar function-18-TypeVar___init__ TypeVar function-8-TypedIns_arg ·.arg(·, 0) function-9-TypedIns_arg ·.arg(·, 0) function-3-TypedOuts_at ·.at(·, 0) function-6-TypedOuts_at ·.at(·, 0) function-1-failed_to_unify failed_to_unify split-5-primitive-Unit-0 () function-4-propagate_ifelse_outs propagate_ifelse_outs(4, 4, ·, ·, ·) split-4-primitive-Unit-0 () function-3-propagate_ifelse_outs propagate_ifelse_outs(3, 4, ·, ·, ·) split-3-primitive-Unit-0 () function-0-IsConstantTrue IsConstantTrue primitive-Unit-0 () function-0-propagate_ifelse_outs propagate_ifelse_outs(0, 4, ·, ·, ·) split-0-primitive-Unit-0 () function-1-propagate_ifelse_outs propagate_ifelse_outs(1, 4, ·, ·, ·) split-1-primitive-Unit-0 () function-2-propagate_ifelse_outs propagate_ifelse_outs(2, 4, ·, ·, ·) split-2-primitive-Unit-0 ()
[debug] egglog.extract ▶
_Region_1 = Region("598", InPorts(Vec[String]("!io", "a", "b")))
_Region_2 = Region("648", InPorts(Vec[String]("!io", "a", "b")))
_Region_3 = Region("745", InPorts(Vec[String]("!io", "a", "b")))
_Term_1 = Term.IfElse(
    Nb_Gt_Int64(_Region_1.get(1), _Region_1.get(2)),
    Term.RegionEnd(
        _Region_2,
        PortList(Vec[Port](Port("!io", _Region_2.get(0)), Port("a", _Region_2.get(1)), Port("b", _Region_2.get(2)), Port("z", Nb_Sub_Int64(_Region_2.get(1), _Region_2.get(2))))),
    ),
    Term.RegionEnd(
        _Region_3,
        PortList(
            Vec[Port](
                Port("!io", _Region_3.get(0)),
                Port("a", _Region_3.get(1)),
                Port("b", _Region_3.get(2)),
                Port("z", Nb_Sub_Float64(Nb_CastI64ToF64(_Region_3.get(2)), Nb_Div_Int64(Term.LiteralI64(1), _Region_3.get(1)))),
            )
        ),
    ),
    TermList(Vec[Term](_Region_1.get(0), _Region_1.get(1), _Region_1.get(2))),
)
_Term_2 = Py_SubIO(_Term_1.getPort(0), _Term_1.getPort(3), Nb_CastI64ToF64(_Term_1.getPort(1)))
GraphRoot(Term.Func("1044", "transformed_example_3", Term.RegionEnd(_Region_1, PortList(Vec[Port](Port("!io", _Term_2.getPort(0)), Port("!ret", _Term_2.getPort(1)))))))

Example 4: Improve error reporting¶

Add logics to report error early

In [65]:
@ruleset
def ruleset_type_infer_failure_report(
    ifelse: Term,
    ty: Type,
    idx: i64,
    name: String,
    then_region: Region,
    else_region: Region,
    then_ports: PortList,
    else_ports: PortList,
):
    yield rule(
        ifelse
        == Term.IfElse(
            cond=_wc(Term),
            then=Term.RegionEnd(then_region, ports=then_ports),
            orelse=Term.RegionEnd(else_region, ports=else_ports),
            operands=_wc(TermList),
        ),
        ty == TypeVar(ifelse.getPort(idx)).getType(),
        failed_to_unify(ty),
        name == then_ports[idx].name,
    ).then(
        union(ErrorMsg.root()).with_(
            ErrorMsg.fail(
                join("Failed to unify if-else outgoing variables: ", name)
            )
        ),
    )
In [66]:
if __name__ == "__main__":
    report = Report("Pipeline execution report")
    try:
        jit_compiler(
            fn=example_3,
            argtypes=(Int64, Int64),
            ruleset=(
                base_ruleset
                | setup_argtypes(TypeInt64, TypeInt64)
                | ruleset_type_infer_float
                | ruleset_failed_to_unify
                | ruleset_type_infer_failure_report
            ),
            converter_class=ExtendEGraphToRVSDG,
            backend=Backend(),
            cost_model=MyCostModel(),
            pipeline_debug=True,
            pipeline_report=report,
        )

    except CompilationError as e:
        print_exception(e)
        assert "Failed to unify if-else outgoing variables: z" in str(e)
    finally:
        report.display()
Traceback (most recent call last):
  File "/tmp/ipykernel_3564/3518016275.py", line 4, in <module>
    jit_compiler(
  File "/home/runner/work/numba-prototypes/numba-prototypes/sealir-tutorials/utils/pipeline.py", line 235, in __call__
    result = func(**filtered_kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/ipykernel_3564/571815991.py", line 37, in egraph_saturation_with_error_checking
    raise CompilationError("\n".join(errmsgs_filtered))
CompilationError: fail to unify
Failed to unify if-else outgoing variables: z

Pipeline execution report

1. Frontend ▶
Frontend
Debug Info on RVSDG ▶
--------------------------------original source---------------------------------
   1|def example_3(a, b):
   2|    if a > b:
   3|        z = a - b  # this as int
   4|    else:
   5|        z = float(b) - 1 / a  # this is float
   6|    return z - float(a)
----------------------------------inter source----------------------------------
   1|def transformed_example_3(a, b):
   2|    """#file: /tmp/ipykernel_3564/2268966838.py"""
   3|    '#loc: 2:8-5:32'
   4|    if a > b:
   5|        '#loc: 3:12-3:21'
   6|        z = a - b
   7|    else:
   8|        z = float(b) - 1 / a
   9|    '#loc: 6:8-6:27'
  10|    return z - float(a)
RVSDG ▶
transformed_example_3 = Func (Args (ArgSpec 'a' (PyNone)) (ArgSpec 'b' (PyNone)))
$0 = Region[598] <- !io a b
{
  $1 = PyBinOp > $0[0] $0[1], $0[2]
  $2 = If $1[1] <- $0[0] $0[1] $0[2]
    $3 = Region[648] <- !io a b
    {
      $4 = PyBinOp - $3[0] $3[1], $3[2]
      $5 = DbgValue 'z' $4[1]
    } [897] -> !io=$4[0] a=$3[1] b=$3[2] z=$5
    Else
    $6 = Region[745] <- !io a b
    {
      $7 = PyLoadGlobal $6[0] 'float'
      $8 = PyCall $7 $6[0] $6[2]
      $9 = PyInt 1
      $10 = PyBinOp / $8[0] $9, $6[1]
      $11 = PyBinOp - $10[0] $8[1], $10[1]
      $12 = DbgValue 'z' $11[1]
    } [925] -> !io=$11[0] a=$6[1] b=$6[2] z=$12
  Endif
  $13 = PyLoadGlobal $2[0] 'float'
  $14 = PyCall $13 $2[0] $2[1]
  $15 = PyBinOp - $14[0] $2[3], $14[1]
} [1038] -> !io=$15[0] !ret=$15[1]
2. EGraph Conversion ▶
EGraph Conversion
EGraph ▶
outer_cluster_InPorts-0 cluster_InPorts-0 outer_cluster_Port-41 cluster_Port-41 outer_cluster_Port-25 cluster_Port-25 outer_cluster_Port-37 cluster_Port-37 outer_cluster_Port-22 cluster_Port-22 outer_cluster_Port-58 cluster_Port-58 outer_cluster_Port-21 cluster_Port-21 outer_cluster_Port-38 cluster_Port-38 outer_cluster_Port-36 cluster_Port-36 outer_cluster_Port-20 cluster_Port-20 outer_cluster_Port-56 cluster_Port-56 outer_cluster_PortList-42 cluster_PortList-42 outer_cluster_PortList-26 cluster_PortList-26 outer_cluster_PortList-59 cluster_PortList-59 outer_cluster_Region-1 cluster_Region-1 outer_cluster_Region-8 cluster_Region-8 outer_cluster_Region-13 cluster_Region-13 outer_cluster_Term-28 cluster_Term-28 outer_cluster_Term-35 cluster_Term-35 outer_cluster_Term-9 cluster_Term-9 outer_cluster_Term-3 cluster_Term-3 outer_cluster_Term-18 cluster_Term-18 outer_cluster_Term-23 cluster_Term-23 outer_cluster_Term-33 cluster_Term-33 outer_cluster_Term-10 cluster_Term-10 outer_cluster_Term-60 cluster_Term-60 outer_cluster_Term-32 cluster_Term-32 outer_cluster_Term-51 cluster_Term-51 outer_cluster_Term-52 cluster_Term-52 outer_cluster_Term-27 cluster_Term-27 outer_cluster_Term-34 cluster_Term-34 outer_cluster_Term-14 cluster_Term-14 outer_cluster_Term-24 cluster_Term-24 outer_cluster_Term-46 cluster_Term-46 outer_cluster_Term-40 cluster_Term-40 outer_cluster_Term-62 cluster_Term-62 outer_cluster_Term-30 cluster_Term-30 outer_cluster_Term-12 cluster_Term-12 outer_cluster_Term-55 cluster_Term-55 outer_cluster_Term-39 cluster_Term-39 outer_cluster_Term-2 cluster_Term-2 outer_cluster_Term-47 cluster_Term-47 outer_cluster_Term-29 cluster_Term-29 outer_cluster_Term-4 cluster_Term-4 outer_cluster_Term-31 cluster_Term-31 outer_cluster_Term-16 cluster_Term-16 outer_cluster_Term-19 cluster_Term-19 outer_cluster_Term-48 cluster_Term-48 outer_cluster_Term-57 cluster_Term-57 outer_cluster_Term-17 cluster_Term-17 outer_cluster_Term-43 cluster_Term-43 outer_cluster_Term-15 cluster_Term-15 outer_cluster_Term-11 cluster_Term-11 outer_cluster_Term-50 cluster_Term-50 outer_cluster_Term-6 cluster_Term-6 outer_cluster_Term-54 cluster_Term-54 outer_cluster_Term-61 cluster_Term-61 outer_cluster_Term-45 cluster_Term-45 outer_cluster_Term-53 cluster_Term-53 outer_cluster_Term-7 cluster_Term-7 outer_cluster_TermList-5 cluster_TermList-5 outer_cluster_TermList-44 cluster_TermList-44 outer_cluster_TermList-49 cluster_TermList-49 outer_cluster_Vec_Port-2 cluster_Vec_Port-2 outer_cluster_Vec_Port-0 cluster_Vec_Port-0 outer_cluster_Vec_Port-1 cluster_Vec_Port-1 outer_cluster_Vec_String-0 cluster_Vec_String-0 outer_cluster_Vec_Term-0 cluster_Vec_Term-0 outer_cluster_Vec_Term-1 cluster_Vec_Term-1 outer_cluster_Vec_Term-2 cluster_Vec_Term-2 function-0-InPorts___init__:s->primitive-Vec_String-0 function-7-Port___init__:s->function-1-Term_DbgValue function-1-Term_DbgValue:s->function-8-Term_getPort function-3-Port___init__:s->function-0-Term_DbgValue function-0-Term_DbgValue:s->function-2-Term_getPort function-5-Port___init__:s->function-2-Region_get function-2-Region_get:s->function-0-Region___init__ function-2-Port___init__:s->function-4-Region_get function-4-Region_get:s->function-1-Region___init__ function-9-Port___init__:s->function-15-Term_getPort function-15-Term_getPort:s->function-2-Py_SubIO function-1-Port___init__:s->function-3-Region_get function-3-Region_get:s->function-1-Region___init__ function-6-Port___init__:s->function-1-Region_get function-1-Region_get:s->function-0-Region___init__ function-4-Port___init__:s->function-7-Term_getPort function-7-Term_getPort:s->function-1-Py_SubIO function-0-Port___init__:s->function-1-Term_getPort function-1-Term_getPort:s->function-0-Py_SubIO function-8-Port___init__:s->function-14-Term_getPort function-14-Term_getPort:s->function-2-Py_SubIO function-1-PortList___init__:s->primitive-Vec_Port-1 primitive-Vec_Port-1:s->function-7-Port___init__ primitive-Vec_Port-1:s->function-5-Port___init__ primitive-Vec_Port-1:s->function-6-Port___init__ primitive-Vec_Port-1:s->function-4-Port___init__ function-0-PortList___init__:s->primitive-Vec_Port-0 primitive-Vec_Port-0:s->function-3-Port___init__ primitive-Vec_Port-0:s->function-2-Port___init__ primitive-Vec_Port-0:s->function-1-Port___init__ primitive-Vec_Port-0:s->function-0-Port___init__ function-2-PortList___init__:s->primitive-Vec_Port-2 primitive-Vec_Port-2:s->function-9-Port___init__ primitive-Vec_Port-2:s->function-8-Port___init__ function-0-Region___init__:s->function-0-InPorts___init__ function-1-Region___init__:s->function-0-InPorts___init__ function-2-Region___init__:s->function-0-InPorts___init__ function-3-Term_getPort:s->function-0-Py_Call function-0-Py_Call:s->function-0-Py_LoadGlobal function-0-Py_Call:s->function-0-Region_get function-0-Py_Call:s->function-0-TermList___init__ function-1-Py_SubIO:s->function-6-Term_getPort function-1-Py_SubIO:s->function-5-Term_getPort function-1-Py_SubIO:s->function-4-Term_getPort function-0-Py_LoadGlobal:s->function-0-Region_get function-0-Region_get:s->function-0-Region___init__ function-0-Term_getPort:s->function-0-Py_GtIO function-0-Py_GtIO:s->function-6-Region_get function-0-Py_GtIO:s->function-8-Region_get function-0-Py_GtIO:s->function-7-Region_get function-2-Term_getPort:s->function-0-Py_SubIO function-0-Py_SubIO:s->function-4-Region_get function-0-Py_SubIO:s->function-3-Region_get function-0-Py_SubIO:s->function-5-Region_get function-6-Term_getPort:s->function-0-Py_DivIO function-0-Py_DivIO:s->function-2-Region_get function-0-Py_DivIO:s->function-3-Term_getPort function-0-Py_DivIO:s->function-0-Term_LiteralI64 function-2-Term_RegionEnd:s->function-2-PortList___init__ function-2-Term_RegionEnd:s->function-2-Region___init__ function-5-Term_getPort:s->function-0-Py_Call function-11-Term_getPort:s->function-1-Py_Call function-1-Py_Call:s->function-9-Term_getPort function-1-Py_Call:s->function-1-Py_LoadGlobal function-1-Py_Call:s->function-2-TermList___init__ function-12-Term_getPort:s->function-0-Term_IfElse function-0-Term_IfElse:s->function-0-Term_getPort function-0-Term_IfElse:s->function-0-Term_RegionEnd function-0-Term_IfElse:s->function-1-Term_RegionEnd function-0-Term_IfElse:s->function-1-TermList___init__ function-0-Term_RegionEnd:s->function-0-PortList___init__ function-0-Term_RegionEnd:s->function-1-Region___init__ function-4-Term_getPort:s->function-0-Py_DivIO function-6-Region_get:s->function-2-Region___init__ function-9-Term_getPort:s->function-0-Term_IfElse function-8-Term_getPort:s->function-1-Py_SubIO function-0-GraphRoot:s->function-0-Term_Func function-0-Term_Func:s->function-2-Term_RegionEnd function-5-Region_get:s->function-1-Region___init__ function-2-Py_SubIO:s->function-11-Term_getPort function-2-Py_SubIO:s->function-12-Term_getPort function-2-Py_SubIO:s->function-13-Term_getPort function-1-Py_LoadGlobal:s->function-9-Term_getPort function-8-Region_get:s->function-2-Region___init__ function-10-Term_getPort:s->function-0-Term_IfElse function-7-Region_get:s->function-2-Region___init__ function-1-Term_RegionEnd:s->function-1-PortList___init__ function-1-Term_RegionEnd:s->function-0-Region___init__ function-2-TermList___init__:s->primitive-Vec_Term-2 function-0-TermList___init__:s->primitive-Vec_Term-0 function-13-Term_getPort:s->function-1-Py_Call function-1-TermList___init__:s->primitive-Vec_Term-1 primitive-Vec_Term-0:s->function-1-Region_get primitive-Vec_Term-1:s->function-6-Region_get primitive-Vec_Term-1:s->function-8-Region_get primitive-Vec_Term-1:s->function-7-Region_get primitive-Vec_Term-2:s->function-10-Term_getPort function-0-InPorts___init__ InPorts primitive-Vec_String-0 Vec("!io", "a", "b") function-7-Port___init__ Port("z", ·) function-1-Term_DbgValue Term.DbgValue("z", ·) function-3-Port___init__ Port("z", ·) function-0-Term_DbgValue Term.DbgValue("z", ·) function-5-Port___init__ Port("a", ·) function-2-Region_get ·.get(·, 1) function-2-Port___init__ Port("b", ·) function-4-Region_get ·.get(·, 2) function-9-Port___init__ Port("!ret", ·) function-15-Term_getPort ·.getPort(·, 1) function-1-Port___init__ Port("a", ·) function-3-Region_get ·.get(·, 1) function-6-Port___init__ Port("b", ·) function-1-Region_get ·.get(·, 2) function-4-Port___init__ Port("!io", ·) function-7-Term_getPort ·.getPort(·, 0) function-0-Port___init__ Port("!io", ·) function-1-Term_getPort ·.getPort(·, 0) function-8-Port___init__ Port("!io", ·) function-14-Term_getPort ·.getPort(·, 0) function-1-PortList___init__ PortList primitive-Vec_Port-1 Vec function-0-PortList___init__ PortList primitive-Vec_Port-0 Vec function-2-PortList___init__ PortList primitive-Vec_Port-2 Vec function-0-Region___init__ Region("745", ·) function-1-Region___init__ Region("648", ·) function-2-Region___init__ Region("598", ·) function-3-Term_getPort ·.getPort(·, 0) function-0-Py_Call Py_Call function-1-Py_SubIO Py_SubIO function-0-Py_LoadGlobal Py_LoadGlobal(·, "float") function-0-Region_get ·.get(·, 0) function-0-Term_getPort ·.getPort(·, 1) function-0-Py_GtIO Py_GtIO function-2-Term_getPort ·.getPort(·, 1) function-0-Py_SubIO Py_SubIO function-6-Term_getPort ·.getPort(·, 1) function-0-Py_DivIO Py_DivIO function-2-Term_RegionEnd Term.RegionEnd function-5-Term_getPort ·.getPort(·, 1) function-11-Term_getPort ·.getPort(·, 0) function-1-Py_Call Py_Call function-12-Term_getPort ·.getPort(·, 3) function-0-Term_IfElse Term.IfElse function-0-Term_RegionEnd Term.RegionEnd function-4-Term_getPort ·.getPort(·, 0) function-6-Region_get ·.get(·, 1) function-9-Term_getPort ·.getPort(·, 0) function-8-Term_getPort ·.getPort(·, 1) function-0-GraphRoot GraphRoot function-0-Term_Func Term.Func("1044", "transformed_example_3", ·) function-0-Term_LiteralI64 Term.LiteralI64(1) function-5-Region_get ·.get(·, 0) function-2-Py_SubIO Py_SubIO function-1-Py_LoadGlobal Py_LoadGlobal(·, "float") function-8-Region_get ·.get(·, 0) function-10-Term_getPort ·.getPort(·, 1) function-7-Region_get ·.get(·, 2) function-1-Term_RegionEnd Term.RegionEnd function-2-TermList___init__ TermList function-0-TermList___init__ TermList function-13-Term_getPort ·.getPort(·, 1) function-1-TermList___init__ TermList primitive-Vec_Term-0 Vec primitive-Vec_Term-1 Vec primitive-Vec_Term-2 Vec
3. Egraph Saturation ▶
Egraph Saturation
[debug] initial egraph ▶
outer_cluster_ErrorMsg-63 cluster_ErrorMsg-63 outer_cluster_InPorts-0 cluster_InPorts-0 outer_cluster_Port-20 cluster_Port-20 outer_cluster_Port-25 cluster_Port-25 outer_cluster_Port-56 cluster_Port-56 outer_cluster_Port-21 cluster_Port-21 outer_cluster_Port-37 cluster_Port-37 outer_cluster_Port-38 cluster_Port-38 outer_cluster_Port-58 cluster_Port-58 outer_cluster_Port-36 cluster_Port-36 outer_cluster_Port-41 cluster_Port-41 outer_cluster_Port-22 cluster_Port-22 outer_cluster_PortList-59 cluster_PortList-59 outer_cluster_PortList-26 cluster_PortList-26 outer_cluster_PortList-42 cluster_PortList-42 outer_cluster_Region-1 cluster_Region-1 outer_cluster_Region-8 cluster_Region-8 outer_cluster_Region-13 cluster_Region-13 outer_cluster_Term-23 cluster_Term-23 outer_cluster_Term-19 cluster_Term-19 outer_cluster_Term-35 cluster_Term-35 outer_cluster_Term-27 cluster_Term-27 outer_cluster_Term-45 cluster_Term-45 outer_cluster_Term-29 cluster_Term-29 outer_cluster_Term-16 cluster_Term-16 outer_cluster_Term-34 cluster_Term-34 outer_cluster_Term-14 cluster_Term-14 outer_cluster_Term-50 cluster_Term-50 outer_cluster_Term-28 cluster_Term-28 outer_cluster_Term-55 cluster_Term-55 outer_cluster_Term-7 cluster_Term-7 outer_cluster_Term-11 cluster_Term-11 outer_cluster_Term-18 cluster_Term-18 outer_cluster_Term-33 cluster_Term-33 outer_cluster_Term-53 cluster_Term-53 outer_cluster_Term-10 cluster_Term-10 outer_cluster_Term-6 cluster_Term-6 outer_cluster_Term-54 cluster_Term-54 outer_cluster_Term-60 cluster_Term-60 outer_cluster_Term-9 cluster_Term-9 outer_cluster_Term-31 cluster_Term-31 outer_cluster_Term-30 cluster_Term-30 outer_cluster_Term-2 cluster_Term-2 outer_cluster_Term-24 cluster_Term-24 outer_cluster_Term-62 cluster_Term-62 outer_cluster_Term-39 cluster_Term-39 outer_cluster_Term-48 cluster_Term-48 outer_cluster_Term-15 cluster_Term-15 outer_cluster_Term-4 cluster_Term-4 outer_cluster_Term-3 cluster_Term-3 outer_cluster_Term-12 cluster_Term-12 outer_cluster_Term-57 cluster_Term-57 outer_cluster_Term-32 cluster_Term-32 outer_cluster_Term-51 cluster_Term-51 outer_cluster_Term-43 cluster_Term-43 outer_cluster_Term-40 cluster_Term-40 outer_cluster_Term-61 cluster_Term-61 outer_cluster_Term-47 cluster_Term-47 outer_cluster_Term-46 cluster_Term-46 outer_cluster_Term-17 cluster_Term-17 outer_cluster_Term-52 cluster_Term-52 outer_cluster_TermList-44 cluster_TermList-44 outer_cluster_TermList-5 cluster_TermList-5 outer_cluster_TermList-49 cluster_TermList-49 outer_cluster_Vec_Port-2 cluster_Vec_Port-2 outer_cluster_Vec_Port-0 cluster_Vec_Port-0 outer_cluster_Vec_Port-1 cluster_Vec_Port-1 outer_cluster_Vec_String-0 cluster_Vec_String-0 outer_cluster_Vec_Term-1 cluster_Vec_Term-1 outer_cluster_Vec_Term-2 cluster_Vec_Term-2 outer_cluster_Vec_Term-0 cluster_Vec_Term-0 function-0-InPorts___init__:s->primitive-Vec_String-0 function-0-Port___init__:s->function-1-Term_getPort function-1-Term_getPort:s->function-0-Py_SubIO function-3-Port___init__:s->function-0-Term_DbgValue function-0-Term_DbgValue:s->function-2-Term_getPort function-8-Port___init__:s->function-14-Term_getPort function-14-Term_getPort:s->function-2-Py_SubIO function-1-Port___init__:s->function-3-Region_get function-3-Region_get:s->function-1-Region___init__ function-5-Port___init__:s->function-2-Region_get function-2-Region_get:s->function-0-Region___init__ function-6-Port___init__:s->function-1-Region_get function-1-Region_get:s->function-0-Region___init__ function-9-Port___init__:s->function-15-Term_getPort function-15-Term_getPort:s->function-2-Py_SubIO function-4-Port___init__:s->function-7-Term_getPort function-7-Term_getPort:s->function-1-Py_SubIO function-7-Port___init__:s->function-1-Term_DbgValue function-1-Term_DbgValue:s->function-8-Term_getPort function-2-Port___init__:s->function-4-Region_get function-4-Region_get:s->function-1-Region___init__ function-2-PortList___init__:s->primitive-Vec_Port-2 primitive-Vec_Port-2:s->function-8-Port___init__ primitive-Vec_Port-2:s->function-9-Port___init__ function-0-PortList___init__:s->primitive-Vec_Port-0 primitive-Vec_Port-0:s->function-0-Port___init__ primitive-Vec_Port-0:s->function-3-Port___init__ primitive-Vec_Port-0:s->function-1-Port___init__ primitive-Vec_Port-0:s->function-2-Port___init__ function-1-PortList___init__:s->primitive-Vec_Port-1 primitive-Vec_Port-1:s->function-5-Port___init__ primitive-Vec_Port-1:s->function-6-Port___init__ primitive-Vec_Port-1:s->function-4-Port___init__ primitive-Vec_Port-1:s->function-7-Port___init__ function-0-Region___init__:s->function-0-InPorts___init__ function-1-Region___init__:s->function-0-InPorts___init__ function-2-Region___init__:s->function-0-InPorts___init__ function-2-Term_getPort:s->function-0-Py_SubIO function-0-Py_SubIO:s->function-3-Region_get function-0-Py_SubIO:s->function-4-Region_get function-0-Py_SubIO:s->function-5-Region_get function-1-Py_SubIO:s->function-4-Term_getPort function-1-Py_SubIO:s->function-5-Term_getPort function-1-Py_SubIO:s->function-6-Term_getPort function-0-Term_RegionEnd:s->function-0-PortList___init__ function-0-Term_RegionEnd:s->function-1-Region___init__ function-0-Term_IfElse:s->function-0-Term_RegionEnd function-0-Term_IfElse:s->function-0-Term_getPort function-0-Term_IfElse:s->function-1-Term_RegionEnd function-0-Term_IfElse:s->function-1-TermList___init__ function-0-Term_getPort:s->function-0-Py_GtIO function-1-Term_RegionEnd:s->function-1-PortList___init__ function-1-Term_RegionEnd:s->function-0-Region___init__ function-1-TermList___init__:s->primitive-Vec_Term-1 function-8-Region_get:s->function-2-Region___init__ function-4-Term_getPort:s->function-0-Py_DivIO function-5-Term_getPort:s->function-0-Py_Call function-6-Term_getPort:s->function-0-Py_DivIO function-6-Region_get:s->function-2-Region___init__ function-1-Py_Call:s->function-1-Py_LoadGlobal function-1-Py_Call:s->function-9-Term_getPort function-1-Py_Call:s->function-2-TermList___init__ function-1-Py_LoadGlobal:s->function-9-Term_getPort function-9-Term_getPort:s->function-0-Term_IfElse function-2-TermList___init__:s->primitive-Vec_Term-2 function-3-Term_getPort:s->function-0-Py_Call function-0-Py_Call:s->function-0-Py_LoadGlobal function-0-Py_Call:s->function-0-Region_get function-0-Py_Call:s->function-0-TermList___init__ function-2-Py_SubIO:s->function-13-Term_getPort function-2-Py_SubIO:s->function-11-Term_getPort function-2-Py_SubIO:s->function-12-Term_getPort function-5-Region_get:s->function-1-Region___init__ function-0-Py_GtIO:s->function-8-Region_get function-0-Py_GtIO:s->function-6-Region_get function-0-Py_GtIO:s->function-7-Region_get function-0-Py_DivIO:s->function-2-Region_get function-0-Py_DivIO:s->function-0-Term_LiteralI64 function-0-Py_DivIO:s->function-3-Term_getPort function-13-Term_getPort:s->function-1-Py_Call function-0-Py_LoadGlobal:s->function-0-Region_get function-0-Region_get:s->function-0-Region___init__ function-0-TermList___init__:s->primitive-Vec_Term-0 function-11-Term_getPort:s->function-1-Py_Call function-12-Term_getPort:s->function-0-Term_IfElse function-2-Term_RegionEnd:s->function-2-PortList___init__ function-2-Term_RegionEnd:s->function-2-Region___init__ function-0-GraphRoot:s->function-0-Term_Func function-0-Term_Func:s->function-2-Term_RegionEnd function-8-Term_getPort:s->function-1-Py_SubIO function-10-Term_getPort:s->function-0-Term_IfElse function-7-Region_get:s->function-2-Region___init__ primitive-Vec_Term-1:s->function-8-Region_get primitive-Vec_Term-1:s->function-6-Region_get primitive-Vec_Term-1:s->function-7-Region_get primitive-Vec_Term-0:s->function-1-Region_get primitive-Vec_Term-2:s->function-10-Term_getPort function-0-ErrorMsg_root ErrorMsg.root function-0-InPorts___init__ InPorts primitive-Vec_String-0 Vec("!io", "a", "b") function-0-Port___init__ Port("!io", ·) function-1-Term_getPort ·.getPort(·, 0) function-3-Port___init__ Port("z", ·) function-0-Term_DbgValue Term.DbgValue("z", ·) function-8-Port___init__ Port("!io", ·) function-14-Term_getPort ·.getPort(·, 0) function-1-Port___init__ Port("a", ·) function-3-Region_get ·.get(·, 1) function-5-Port___init__ Port("a", ·) function-2-Region_get ·.get(·, 1) function-6-Port___init__ Port("b", ·) function-1-Region_get ·.get(·, 2) function-9-Port___init__ Port("!ret", ·) function-15-Term_getPort ·.getPort(·, 1) function-4-Port___init__ Port("!io", ·) function-7-Term_getPort ·.getPort(·, 0) function-7-Port___init__ Port("z", ·) function-1-Term_DbgValue Term.DbgValue("z", ·) function-2-Port___init__ Port("b", ·) function-4-Region_get ·.get(·, 2) function-2-PortList___init__ PortList primitive-Vec_Port-2 Vec function-0-PortList___init__ PortList primitive-Vec_Port-0 Vec function-1-PortList___init__ PortList primitive-Vec_Port-1 Vec function-0-Region___init__ Region("745", ·) function-1-Region___init__ Region("648", ·) function-2-Region___init__ Region("598", ·) function-2-Term_getPort ·.getPort(·, 1) function-0-Py_SubIO Py_SubIO function-1-Py_SubIO Py_SubIO function-0-Term_RegionEnd Term.RegionEnd function-0-Term_IfElse Term.IfElse function-0-Term_getPort ·.getPort(·, 1) function-1-Term_RegionEnd Term.RegionEnd function-1-TermList___init__ TermList function-0-Term_LiteralI64 Term.LiteralI64(1) function-8-Region_get ·.get(·, 0) function-4-Term_getPort ·.getPort(·, 0) function-5-Term_getPort ·.getPort(·, 1) function-6-Term_getPort ·.getPort(·, 1) function-6-Region_get ·.get(·, 1) function-1-Py_Call Py_Call function-1-Py_LoadGlobal Py_LoadGlobal(·, "float") function-9-Term_getPort ·.getPort(·, 0) function-2-TermList___init__ TermList function-3-Term_getPort ·.getPort(·, 0) function-0-Py_Call Py_Call function-2-Py_SubIO Py_SubIO function-5-Region_get ·.get(·, 0) function-0-Py_GtIO Py_GtIO function-0-Py_DivIO Py_DivIO function-13-Term_getPort ·.getPort(·, 1) function-0-Py_LoadGlobal Py_LoadGlobal(·, "float") function-0-Region_get ·.get(·, 0) function-0-TermList___init__ TermList function-11-Term_getPort ·.getPort(·, 0) function-12-Term_getPort ·.getPort(·, 3) function-2-Term_RegionEnd Term.RegionEnd function-0-GraphRoot GraphRoot function-0-Term_Func Term.Func("1044", "transformed_example_3", ·) function-8-Term_getPort ·.getPort(·, 1) function-10-Term_getPort ·.getPort(·, 1) function-7-Region_get ·.get(·, 2) primitive-Vec_Term-1 Vec primitive-Vec_Term-0 Vec primitive-Vec_Term-2 Vec
[debug] saturated egraph ▶
outer_cluster_ErrorMsg-63 cluster_ErrorMsg-63 outer_cluster_InPorts-0 cluster_InPorts-0 outer_cluster_Port-185 cluster_Port-185 outer_cluster_Port-99 cluster_Port-99 outer_cluster_Port-107 cluster_Port-107 outer_cluster_Port-135 cluster_Port-135 outer_cluster_Port-167 cluster_Port-167 outer_cluster_Port-183 cluster_Port-183 outer_cluster_Port-105 cluster_Port-105 outer_cluster_Port-165 cluster_Port-165 outer_cluster_Port-101 cluster_Port-101 outer_cluster_Port-149 cluster_Port-149 outer_cluster_Port-103 cluster_Port-103 outer_cluster_Port-109 cluster_Port-109 outer_cluster_PortList-42 cluster_PortList-42 outer_cluster_PortList-26 cluster_PortList-26 outer_cluster_PortList-59 cluster_PortList-59 outer_cluster_Region-1 cluster_Region-1 outer_cluster_Region-8 cluster_Region-8 outer_cluster_Region-13 cluster_Region-13 outer_cluster_String-3758096426 cluster_String-3758096426 outer_cluster_split-0-primitive-String-3758096426 cluster_split-0-primitive-String-3758096426 outer_cluster_String-2684354583 cluster_String-2684354583 outer_cluster_split-0-primitive-String-20 cluster_split-0-primitive-String-20 outer_cluster_String-20 cluster_String-20 outer_cluster_String-2952790038 cluster_String-2952790038 outer_cluster_split-0-primitive-String-2952790038 cluster_split-0-primitive-String-2952790038 outer_cluster_split-0-primitive-String-1879048210 cluster_split-0-primitive-String-1879048210 outer_cluster_String-1879048210 cluster_String-1879048210 outer_cluster_split-1-primitive-String-20 cluster_split-1-primitive-String-20 outer_cluster_Term-17 cluster_Term-17 outer_cluster_Term-78 cluster_Term-78 outer_cluster_Term-61 cluster_Term-61 outer_cluster_Term-169 cluster_Term-169 outer_cluster_Term-74 cluster_Term-74 outer_cluster_Term-178 cluster_Term-178 outer_cluster_Term-142 cluster_Term-142 outer_cluster_Term-54 cluster_Term-54 outer_cluster_Term-27 cluster_Term-27 outer_cluster_Term-176 cluster_Term-176 outer_cluster_Term-43 cluster_Term-43 outer_cluster_Term-47 cluster_Term-47 outer_cluster_Term-180 cluster_Term-180 outer_cluster_Term-111 cluster_Term-111 outer_cluster_Term-18 cluster_Term-18 outer_cluster_Term-48 cluster_Term-48 outer_cluster_Term-151 cluster_Term-151 outer_cluster_Term-14 cluster_Term-14 outer_cluster_Term-15 cluster_Term-15 outer_cluster_Term-76 cluster_Term-76 outer_cluster_Term-34 cluster_Term-34 outer_cluster_Term-155 cluster_Term-155 outer_cluster_Term-3 cluster_Term-3 outer_cluster_Term-29 cluster_Term-29 outer_cluster_Term-52 cluster_Term-52 outer_cluster_Term-77 cluster_Term-77 outer_cluster_Term-45 cluster_Term-45 outer_cluster_Term-50 cluster_Term-50 outer_cluster_Term-33 cluster_Term-33 outer_cluster_Term-62 cluster_Term-62 outer_cluster_Term-30 cluster_Term-30 outer_cluster_Term-152 cluster_Term-152 outer_cluster_Term-175 cluster_Term-175 outer_cluster_Term-75 cluster_Term-75 outer_cluster_Term-32 cluster_Term-32 outer_cluster_Term-79 cluster_Term-79 outer_cluster_Term-137 cluster_Term-137 outer_cluster_Term-6 cluster_Term-6 outer_cluster_Term-51 cluster_Term-51 outer_cluster_Term-60 cluster_Term-60 outer_cluster_Term-12 cluster_Term-12 outer_cluster_Term-53 cluster_Term-53 outer_cluster_TermList-49 cluster_TermList-49 outer_cluster_TermList-44 cluster_TermList-44 outer_cluster_TermList-5 cluster_TermList-5 outer_cluster_Type-158 cluster_Type-158 outer_cluster_Type-193 cluster_Type-193 outer_cluster_Type-160 cluster_Type-160 outer_cluster_Type-189 cluster_Type-189 outer_cluster_TypeVar-161 cluster_TypeVar-161 outer_cluster_TypeVar-130 cluster_TypeVar-130 outer_cluster_TypeVar-157 cluster_TypeVar-157 outer_cluster_TypeVar-140 cluster_TypeVar-140 outer_cluster_TypeVar-162 cluster_TypeVar-162 outer_cluster_TypeVar-170 cluster_TypeVar-170 outer_cluster_TypeVar-92 cluster_TypeVar-92 outer_cluster_TypeVar-171 cluster_TypeVar-171 outer_cluster_TypeVar-159 cluster_TypeVar-159 outer_cluster_TypeVar-174 cluster_TypeVar-174 outer_cluster_TypeVar-146 cluster_TypeVar-146 outer_cluster_TypeVar-191 cluster_TypeVar-191 outer_cluster_TypedIns-82 cluster_TypedIns-82 outer_cluster_TypedIns-84 cluster_TypedIns-84 outer_cluster_TypedIns-94 cluster_TypedIns-94 outer_cluster_TypedOuts-129 cluster_TypedOuts-129 outer_cluster_TypedOuts-123 cluster_TypedOuts-123 outer_cluster_TypedOuts-145 cluster_TypedOuts-145 outer_cluster_Unit-0 cluster_Unit-0 outer_cluster_split-1-primitive-Unit-0 cluster_split-1-primitive-Unit-0 outer_cluster_split-0-primitive-Unit-0 cluster_split-0-primitive-Unit-0 outer_cluster_split-5-primitive-Unit-0 cluster_split-5-primitive-Unit-0 outer_cluster_split-2-primitive-Unit-0 cluster_split-2-primitive-Unit-0 outer_cluster_split-3-primitive-Unit-0 cluster_split-3-primitive-Unit-0 outer_cluster_split-4-primitive-Unit-0 cluster_split-4-primitive-Unit-0 outer_cluster_Vec_Port-6 cluster_Vec_Port-6 outer_cluster_Vec_Port-8 cluster_Vec_Port-8 outer_cluster_Vec_Port-7 cluster_Vec_Port-7 outer_cluster_Vec_String-0 cluster_Vec_String-0 outer_cluster_Vec_Term-4 cluster_Vec_Term-4 outer_cluster_Vec_Term-2 cluster_Vec_Term-2 outer_cluster_Vec_Term-5 cluster_Vec_Term-5 function-0-InPorts___init__:s->primitive-Vec_String-0 function-11-PortList___getitem__:s->function-4-PortList___init__ function-4-PortList___init__:s->primitive-Vec_Port-8 function-0-Port___init__:s->function-6-Region_get function-6-Region_get:s->function-1-Region___init__ function-0-PortList___getitem__:s->function-3-PortList___init__ function-3-PortList___init__:s->primitive-Vec_Port-7 function-2-Port___init__:s->function-8-Port_value function-8-Port_value:s->function-2-Port___init__ function-4-PortList___getitem__:s->function-3-PortList___init__ function-6-Port___init__:s->function-6-PortList_getValue function-6-PortList_getValue:s->function-2-PortList___init__ function-6-PortList___getitem__:s->function-2-PortList___init__ function-2-PortList___init__:s->primitive-Vec_Port-6 function-11-Port___init__:s->function-11-Region_get function-11-Region_get:s->function-0-Region___init__ function-9-PortList___getitem__:s->function-4-PortList___init__ function-10-PortList___getitem__:s->function-3-PortList___init__ function-4-Port___init__:s->function-3-PortList_getValue function-3-PortList_getValue:s->function-4-PortList___init__ function-3-PortList___getitem__:s->function-4-PortList___init__ function-10-Port___init__:s->function-10-Region_get function-10-Region_get:s->function-1-Region___init__ function-8-PortList___getitem__:s->function-3-PortList___init__ function-3-Port___init__:s->function-35-Term_getPort function-35-Term_getPort:s->function-0-Py_DivIO function-1-PortList___getitem__:s->function-4-PortList___init__ function-7-Port___init__:s->function-7-PortList_getValue function-7-PortList_getValue:s->function-2-PortList___init__ function-7-PortList___getitem__:s->function-2-PortList___init__ function-1-Port___init__:s->function-7-Region_get function-7-Region_get:s->function-1-Region___init__ function-2-PortList___getitem__:s->function-3-PortList___init__ function-5-Port___init__:s->function-9-Port_value function-9-Port_value:s->function-5-Port___init__ function-5-PortList___getitem__:s->function-4-PortList___init__ primitive-Vec_Port-8:s->function-9-PortList___getitem__ primitive-Vec_Port-8:s->function-3-PortList___getitem__ primitive-Vec_Port-8:s->function-1-PortList___getitem__ primitive-Vec_Port-8:s->function-5-PortList___getitem__ primitive-Vec_Port-7:s->function-0-PortList___getitem__ primitive-Vec_Port-7:s->function-4-PortList___getitem__ primitive-Vec_Port-7:s->function-8-PortList___getitem__ primitive-Vec_Port-7:s->function-2-PortList___getitem__ primitive-Vec_Port-6:s->function-6-PortList___getitem__ primitive-Vec_Port-6:s->function-7-PortList___getitem__ function-0-Region___init__:s->function-0-InPorts___init__ function-1-Region___init__:s->function-0-InPorts___init__ function-2-Region___init__:s->function-0-InPorts___init__ function-12-Port_name:s->function-4-PortList___getitem__ function-15-Port_name:s->function-5-PortList___getitem__ function-17-Port_name:s->function-7-PortList___getitem__ function-13-Port_name:s->function-1-PortList___getitem__ function-10-Port_name:s->function-0-PortList___getitem__ function-11-Port_name:s->function-2-PortList___getitem__ function-14-Port_name:s->function-3-PortList___getitem__ function-19-Port_name:s->function-9-PortList___getitem__ function-18-Port_name:s->function-8-PortList___getitem__ function-16-Port_name:s->function-6-PortList___getitem__ function-1-Py_GtIO:s->function-4-Region_get function-1-Py_GtIO:s->function-0-Region_get function-1-Py_GtIO:s->function-1-Region_get function-4-Region_get:s->function-2-Region___init__ function-0-Region_get:s->function-2-Region___init__ function-1-Region_get:s->function-2-Region___init__ function-30-Term_getPort:s->function-3-Py_SubIO function-3-Py_SubIO:s->function-4-Port_value function-3-Py_SubIO:s->function-8-PortList_getValue function-3-Py_SubIO:s->function-2-PortList_getValue function-0-Term_DbgValue:s->function-0-Nb_Sub_Int64 function-0-Nb_Sub_Int64:s->function-6-Port_value function-0-Nb_Sub_Int64:s->function-15-Port_value function-4-PortList_getValue:s->function-3-PortList___init__ function-6-Port_value:s->function-1-Port___init__ function-15-Port_value:s->function-10-Port___init__ function-0-Term_Func:s->function-2-Term_RegionEnd function-2-Term_RegionEnd:s->function-2-PortList___init__ function-2-Term_RegionEnd:s->function-2-Region___init__ function-39-Term_getPort:s->function-2-Term_RegionEnd function-29-Term_getPort:s->function-3-Py_SubIO function-4-Port_value:s->function-0-Port___init__ function-0-PortList_getValue:s->function-3-PortList___init__ function-20-Port_value:s->function-11-PortList___getitem__ function-11-PortList_getValue:s->function-4-PortList___init__ function-26-Term_getPort:s->function-1-Py_GtIO function-0-Py_SubIO:s->function-20-Term_getPort function-0-Py_SubIO:s->function-12-Term_getPort function-0-Py_SubIO:s->function-0-Nb_CastI64ToF64 function-20-Term_getPort:s->function-0-Term_IfElse function-12-Term_getPort:s->function-0-Term_IfElse function-0-Nb_CastI64ToF64:s->function-10-Term_getPort function-0-Term_RegionEnd:s->function-3-PortList___init__ function-0-Term_RegionEnd:s->function-1-Region___init__ function-19-Port_value:s->function-10-PortList___getitem__ function-10-PortList_getValue:s->function-3-PortList___init__ function-1-Term_RegionEnd:s->function-4-PortList___init__ function-1-Term_RegionEnd:s->function-0-Region___init__ function-0-Py_LoadGlobal:s->function-11-Term_getPort function-11-Term_getPort:s->function-0-Py_Call function-38-Term_getPort:s->function-0-Term_IfElse function-0-Term_IfElse:s->function-0-Term_RegionEnd function-0-Term_IfElse:s->function-1-Term_RegionEnd function-0-Term_IfElse:s->function-1-Nb_Gt_Int64 function-0-Term_IfElse:s->function-4-TermList___init__ function-34-Term_getPort:s->function-0-Py_SubIO function-10-Port_value:s->function-6-Port___init__ function-0-Term_getPort:s->function-1-Py_GtIO function-1-Nb_Gt_Int64:s->function-0-Region_get function-1-Nb_Gt_Int64:s->function-1-Region_get function-10-Term_getPort:s->function-0-Term_IfElse function-8-PortList_getValue:s->function-3-PortList___init__ function-2-PortList_getValue:s->function-3-PortList___init__ function-2-Py_SubIO:s->function-5-Port_value function-2-Py_SubIO:s->function-1-Nb_CastI64ToF64 function-2-Py_SubIO:s->function-1-Nb_Div_Int64 function-5-Port_value:s->function-3-Port___init__ function-1-Nb_CastI64ToF64:s->function-16-Port_value function-1-Nb_Div_Int64:s->function-0-Term_LiteralI64 function-1-Nb_Div_Int64:s->function-7-Port_value function-33-Term_getPort:s->function-0-Term_IfElse function-2-Py_LoadGlobal:s->function-36-Term_getPort function-36-Term_getPort:s->function-2-Py_Call function-8-Region_get:s->function-0-Region___init__ function-7-Port_value:s->function-4-Port___init__ function-4-TermList___init__:s->primitive-Vec_Term-4 function-0-Py_Call:s->function-20-Term_getPort function-0-Py_Call:s->function-0-Py_LoadGlobal function-0-Py_Call:s->function-2-TermList___init__ function-2-TermList___init__:s->primitive-Vec_Term-2 function-6-Term_getPort:s->function-0-Py_DivIO function-0-Py_DivIO:s->function-36-Term_getPort function-0-Py_DivIO:s->function-0-Term_LiteralI64 function-0-Py_DivIO:s->function-8-Region_get function-0-GraphRoot:s->function-0-Term_Func function-16-Port_value:s->function-11-Port___init__ function-9-PortList_getValue:s->function-4-PortList___init__ function-40-Term_getPort:s->function-2-Term_RegionEnd function-9-Region_get:s->function-0-Region___init__ function-31-Term_getPort:s->function-2-Py_SubIO function-2-Py_Call:s->function-35-Term_getPort function-2-Py_Call:s->function-2-Py_LoadGlobal function-2-Py_Call:s->function-5-TermList___init__ function-1-PortList_getValue:s->function-4-PortList___init__ function-3-Nb_CastToFloat:s->function-9-PortList_getValue function-5-Term_getPort:s->function-2-Py_Call function-32-Term_getPort:s->function-2-Py_SubIO function-1-Term_DbgValue:s->function-1-Nb_Sub_Float64 function-1-Nb_Sub_Float64:s->function-6-Term_getPort function-1-Nb_Sub_Float64:s->function-3-Nb_CastToFloat function-5-PortList_getValue:s->function-4-PortList___init__ function-37-Term_getPort:s->function-0-Py_SubIO function-12-Port_value:s->function-7-Port___init__ function-5-TermList___init__:s->primitive-Vec_Term-5 function-13-Term_getPort:s->function-0-Py_Call function-2-Nb_CastToFloat:s->function-10-Term_getPort primitive-Vec_Term-2:s->function-10-Term_getPort primitive-Vec_Term-4:s->function-4-Region_get primitive-Vec_Term-4:s->function-0-Region_get primitive-Vec_Term-4:s->function-1-Region_get primitive-Vec_Term-5:s->function-9-PortList_getValue function-0-TypeVar_getType:s->function-23-TypeVar___init__ function-23-TypeVar___init__:s->function-5-Term_getPort function-2-TypeVar_getType:s->function-25-TypeVar___init__ function-25-TypeVar___init__:s->function-1-Nb_Div_Int64 function-3-TypeVar_getType:s->function-31-TypeVar___init__ function-31-TypeVar___init__:s->function-13-Term_getPort function-3-Type___or__:s->function-3-Type___or__ function-3-Type___or__:s->function-5-TypeVar_getType function-5-TypeVar_getType:s->function-0-TypeVar___init__ function-0-TypeVar___init__:s->function-0-Term_LiteralI64 function-6-TypeVar_getType:s->function-9-TypedOuts_at function-9-TypedOuts_at:s->function-0-TypedOuts___init__ function-7-TypeVar_getType:s->function-15-TypedOuts_at function-15-TypedOuts_at:s->function-0-TypedOuts___init__ function-1-TypeVar_getType:s->function-24-TypeVar___init__ function-24-TypeVar___init__:s->function-1-Nb_Gt_Int64 function-0-Type___or__:s->function-2-TypeVar_getType function-0-Type___or__:s->function-5-TypeVar_getType function-1-Type___or__:s->function-3-TypeVar_getType function-1-Type___or__:s->function-6-TypeVar_getType function-2-Type___or__:s->function-7-TypeVar_getType function-2-Type___or__:s->function-4-TypeVar_getType function-4-TypeVar_getType:s->function-14-TypedOuts_at function-4-Type___or__:s->function-6-TypeVar_getType function-4-Type___or__:s->function-1-Type___or__ function-14-TypedOuts_at:s->function-0-TypedOuts___init__ function-5-TypeVar___init__:s->function-0-PortList_getValue function-6-TypeVar___init__:s->function-9-Region_get function-7-TypeVar___init__:s->function-11-Term_getPort function-18-TypeVar___init__:s->function-26-Term_getPort function-8-TypedIns_arg:s->function-0-TypedIns___init__ function-0-TypedIns___init__:s->function-1-Region___init__ function-9-TypedIns_arg:s->function-1-TypedIns___init__ function-1-TypedIns___init__:s->function-0-Region___init__ function-3-TypedOuts_at:s->function-1-TypedOuts___init__ function-1-TypedOuts___init__:s->function-0-Region___init__ function-6-TypedOuts_at:s->function-0-TypedOuts___init__ function-0-TypedOuts___init__:s->function-1-Region___init__ function-12-TypeVar___init__:s->function-10-Term_getPort function-15-TypeVar___init__:s->function-8-Region_get function-16-TypeVar___init__:s->function-7-Region_get function-19-TypeVar___init__:s->function-0-Region_get function-10-TypedIns_arg:s->function-2-TypedIns___init__ function-2-TypedIns___init__:s->function-2-Region___init__ function-11-TypedIns_arg:s->function-0-TypedIns___init__ function-12-TypedIns_arg:s->function-1-TypedIns___init__ function-8-TypedOuts_at:s->function-1-TypedOuts___init__ function-29-TypeVar___init__:s->function-7-PortList_getValue function-10-TypedOuts_at:s->function-2-TypedOuts___init__ function-2-TypedOuts___init__:s->function-2-Region___init__ function-30-TypeVar___init__:s->function-12-Term_getPort function-32-TypeVar___init__:s->function-9-Port_value function-33-TypeVar___init__:s->function-8-Port_value function-13-TypedOuts_at:s->function-1-TypedOuts___init__ function-34-TypeVar___init__:s->function-33-Term_getPort function-35-TypeVar___init__:s->function-11-Region_get function-36-TypeVar___init__:s->function-10-Region_get function-42-TypeVar___init__:s->function-1-Region_get function-13-TypedIns_arg:s->function-2-TypedIns___init__ function-14-TypedIns_arg:s->function-0-TypedIns___init__ function-15-TypedIns_arg:s->function-1-TypedIns___init__ function-12-TypedOuts_at:s->function-1-TypedOuts___init__ function-17-TypeVar___init__:s->function-6-PortList_getValue function-7-TypedOuts_at:s->function-2-TypedOuts___init__ function-43-TypeVar___init__:s->function-38-Term_getPort function-44-TypeVar___init__:s->function-11-PortList_getValue function-45-TypeVar___init__:s->function-10-PortList_getValue function-17-TypedOuts_at:s->function-1-TypedOuts___init__ function-18-TypedOuts_at:s->function-0-TypedOuts___init__ function-0-IsConstantTrue:s->function-0-Term_LiteralI64 function-1-propagate_ifelse_outs:s->function-4-PortList___init__ function-1-propagate_ifelse_outs:s->function-3-PortList___init__ function-1-propagate_ifelse_outs:s->function-0-Term_IfElse function-0-propagate_ifelse_outs:s->function-4-PortList___init__ function-0-propagate_ifelse_outs:s->function-3-PortList___init__ function-0-propagate_ifelse_outs:s->function-0-Term_IfElse function-1-failed_to_unify:s->function-2-Type___or__ function-2-propagate_ifelse_outs:s->function-4-PortList___init__ function-2-propagate_ifelse_outs:s->function-3-PortList___init__ function-2-propagate_ifelse_outs:s->function-0-Term_IfElse function-3-propagate_ifelse_outs:s->function-4-PortList___init__ function-3-propagate_ifelse_outs:s->function-3-PortList___init__ function-3-propagate_ifelse_outs:s->function-0-Term_IfElse function-4-propagate_ifelse_outs:s->function-4-PortList___init__ function-4-propagate_ifelse_outs:s->function-3-PortList___init__ function-4-propagate_ifelse_outs:s->function-0-Term_IfElse function-1-ErrorMsg_fail ErrorMsg.fail("fail to unify") function-3-ErrorMsg_fail ErrorMsg.fail("Failed to unify if-else outgoing variables: z") function-0-ErrorMsg_root ErrorMsg.root function-0-InPorts___init__ InPorts primitive-Vec_String-0 Vec("!io", "a", "b") function-11-PortList___getitem__ ·[4] function-4-PortList___init__ PortList function-0-Port___init__ Port("!io", ·) function-6-Region_get ·.get(·, 0) function-0-PortList___getitem__ ·[0] function-3-PortList___init__ PortList function-2-Port___init__ Port("z", ·) function-8-Port_value ·.value function-4-PortList___getitem__ ·[3] function-6-Port___init__ Port("!io", ·) function-6-PortList_getValue ·.getValue(·, 0) function-6-PortList___getitem__ ·[0] function-2-PortList___init__ PortList function-11-Port___init__ Port("b", ·) function-11-Region_get ·.get(·, 2) function-9-PortList___getitem__ ·[2] function-10-PortList___getitem__ ·[4] function-4-Port___init__ Port("a", ·) function-3-PortList_getValue ·.getValue(·, 1) function-3-PortList___getitem__ ·[1] function-10-Port___init__ Port("b", ·) function-10-Region_get ·.get(·, 2) function-8-PortList___getitem__ ·[2] function-3-Port___init__ Port("!io", ·) function-35-Term_getPort ·.getPort(·, 0) function-1-PortList___getitem__ ·[0] function-7-Port___init__ Port("!ret", ·) function-7-PortList_getValue ·.getValue(·, 1) function-7-PortList___getitem__ ·[1] function-1-Port___init__ Port("a", ·) function-7-Region_get ·.get(·, 1) function-2-PortList___getitem__ ·[1] function-5-Port___init__ Port("z", ·) function-9-Port_value ·.value function-5-PortList___getitem__ ·[3] primitive-Vec_Port-8 Vec primitive-Vec_Port-7 Vec primitive-Vec_Port-6 Vec function-0-Region___init__ Region("745", ·) function-1-Region___init__ Region("648", ·) function-2-Region___init__ Region("598", ·) function-12-Port_name ·.name primitive-String-3758096426 "z" function-15-Port_name ·.name split-0-primitive-String-3758096426 "z" function-17-Port_name ·.name primitive-String-2684354583 "!ret" function-13-Port_name ·.name split-0-primitive-String-20 "!io" function-10-Port_name ·.name primitive-String-20 "!io" function-11-Port_name ·.name primitive-String-2952790038 "a" function-14-Port_name ·.name split-0-primitive-String-2952790038 "a" function-19-Port_name ·.name split-0-primitive-String-1879048210 "b" function-18-Port_name ·.name primitive-String-1879048210 "b" function-16-Port_name ·.name split-1-primitive-String-20 "!io" function-1-Py_GtIO Py_GtIO function-4-Region_get ·.get(·, 0) function-0-Region_get ·.get(·, 1) function-1-Region_get ·.get(·, 2) function-30-Term_getPort ·.getPort(·, 1) function-3-Py_SubIO Py_SubIO function-0-Term_DbgValue Term.DbgValue("z", ·) function-0-Nb_Sub_Int64 Nb_Sub_Int64 function-4-PortList_getValue ·.getValue(·, 3) function-6-Port_value ·.value function-15-Port_value ·.value function-0-Term_Func Term.Func("1044", "transformed_example_3", ·) function-2-Term_RegionEnd Term.RegionEnd function-39-Term_getPort ·.getPort(·, 0) function-29-Term_getPort ·.getPort(·, 0) function-4-Port_value ·.value function-0-PortList_getValue ·.getValue(·, 0) function-20-Port_value ·.value function-11-PortList_getValue ·.getValue(·, 4) function-26-Term_getPort ·.getPort(·, 0) function-0-Py_SubIO Py_SubIO function-20-Term_getPort ·.getPort(·, 0) function-12-Term_getPort ·.getPort(·, 3) function-0-Nb_CastI64ToF64 Nb_CastI64ToF64 function-0-Term_RegionEnd Term.RegionEnd function-19-Port_value ·.value function-10-PortList_getValue ·.getValue(·, 4) function-1-Term_RegionEnd Term.RegionEnd function-0-Py_LoadGlobal Py_LoadGlobal(·, "float") function-11-Term_getPort ·.getPort(·, 0) function-38-Term_getPort ·.getPort(·, 4) function-0-Term_IfElse Term.IfElse function-34-Term_getPort ·.getPort(·, 0) function-10-Port_value ·.value function-0-Term_getPort ·.getPort(·, 1) function-1-Nb_Gt_Int64 Nb_Gt_Int64 function-10-Term_getPort ·.getPort(·, 1) function-8-PortList_getValue ·.getValue(·, 2) function-2-PortList_getValue ·.getValue(·, 1) function-2-Py_SubIO Py_SubIO function-5-Port_value ·.value function-1-Nb_CastI64ToF64 Nb_CastI64ToF64 function-1-Nb_Div_Int64 Nb_Div_Int64 function-33-Term_getPort ·.getPort(·, 2) function-2-Py_LoadGlobal Py_LoadGlobal(·, "float") function-36-Term_getPort ·.getPort(·, 0) function-0-Term_LiteralI64 Term.LiteralI64(1) function-8-Region_get ·.get(·, 1) function-7-Port_value ·.value function-4-TermList___init__ TermList function-0-Py_Call Py_Call function-2-TermList___init__ TermList function-6-Term_getPort ·.getPort(·, 1) function-0-Py_DivIO Py_DivIO function-0-GraphRoot GraphRoot function-16-Port_value ·.value function-9-PortList_getValue ·.getValue(·, 2) function-40-Term_getPort ·.getPort(·, 1) function-9-Region_get ·.get(·, 0) function-31-Term_getPort ·.getPort(·, 0) function-2-Py_Call Py_Call function-1-PortList_getValue ·.getValue(·, 0) function-3-Nb_CastToFloat Nb_CastToFloat function-5-Term_getPort ·.getPort(·, 1) function-32-Term_getPort ·.getPort(·, 1) function-1-Term_DbgValue Term.DbgValue("z", ·) function-1-Nb_Sub_Float64 Nb_Sub_Float64 function-5-PortList_getValue ·.getValue(·, 3) function-37-Term_getPort ·.getPort(·, 1) function-12-Port_value ·.value function-5-TermList___init__ TermList function-13-Term_getPort ·.getPort(·, 1) function-2-Nb_CastToFloat Nb_CastToFloat primitive-Vec_Term-2 Vec primitive-Vec_Term-4 Vec primitive-Vec_Term-5 Vec function-0-TypeVar_getType ·.getType function-23-TypeVar___init__ TypeVar function-2-TypeVar_getType ·.getType function-25-TypeVar___init__ TypeVar function-3-TypeVar_getType ·.getType function-31-TypeVar___init__ TypeVar function-1-Type_simple Type.simple("Float64") function-3-Type___or__ · | · function-5-TypeVar_getType ·.getType function-0-TypeVar___init__ TypeVar function-6-TypeVar_getType ·.getType function-9-TypedOuts_at ·.at(·, 1) function-7-TypeVar_getType ·.getType function-15-TypedOuts_at ·.at(·, 2) function-3-Type_simple Type.simple("Int64") function-1-TypeVar_getType ·.getType function-24-TypeVar___init__ TypeVar function-2-Type_simple Type.simple("Bool") function-0-Type___or__ · | · function-1-Type___or__ · | · function-2-Type___or__ · | · function-4-TypeVar_getType ·.getType function-4-Type___or__ · | · function-14-TypedOuts_at ·.at(·, 3) function-5-TypeVar___init__ TypeVar function-6-TypeVar___init__ TypeVar function-7-TypeVar___init__ TypeVar function-18-TypeVar___init__ TypeVar function-8-TypedIns_arg ·.arg(·, 0) function-0-TypedIns___init__ TypedIns function-9-TypedIns_arg ·.arg(·, 0) function-1-TypedIns___init__ TypedIns function-3-TypedOuts_at ·.at(·, 0) function-1-TypedOuts___init__ TypedOuts function-6-TypedOuts_at ·.at(·, 0) function-0-TypedOuts___init__ TypedOuts function-12-TypeVar___init__ TypeVar function-15-TypeVar___init__ TypeVar function-16-TypeVar___init__ TypeVar function-19-TypeVar___init__ TypeVar function-10-TypedIns_arg ·.arg(·, 1) function-2-TypedIns___init__ TypedIns function-11-TypedIns_arg ·.arg(·, 1) function-12-TypedIns_arg ·.arg(·, 1) function-8-TypedOuts_at ·.at(·, 1) function-29-TypeVar___init__ TypeVar function-10-TypedOuts_at ·.at(·, 1) function-2-TypedOuts___init__ TypedOuts function-30-TypeVar___init__ TypeVar function-32-TypeVar___init__ TypeVar function-33-TypeVar___init__ TypeVar function-13-TypedOuts_at ·.at(·, 3) function-34-TypeVar___init__ TypeVar function-35-TypeVar___init__ TypeVar function-36-TypeVar___init__ TypeVar function-42-TypeVar___init__ TypeVar function-13-TypedIns_arg ·.arg(·, 2) function-14-TypedIns_arg ·.arg(·, 2) function-15-TypedIns_arg ·.arg(·, 2) function-12-TypedOuts_at ·.at(·, 2) function-17-TypeVar___init__ TypeVar function-7-TypedOuts_at ·.at(·, 0) function-43-TypeVar___init__ TypeVar function-44-TypeVar___init__ TypeVar function-45-TypeVar___init__ TypeVar function-17-TypedOuts_at ·.at(·, 4) function-18-TypedOuts_at ·.at(·, 4) function-0-IsConstantTrue IsConstantTrue primitive-Unit-0 () function-1-propagate_ifelse_outs propagate_ifelse_outs(1, 4, ·, ·, ·) split-1-primitive-Unit-0 () function-0-propagate_ifelse_outs propagate_ifelse_outs(0, 4, ·, ·, ·) split-0-primitive-Unit-0 () function-1-failed_to_unify failed_to_unify split-5-primitive-Unit-0 () function-2-propagate_ifelse_outs propagate_ifelse_outs(2, 4, ·, ·, ·) split-2-primitive-Unit-0 () function-3-propagate_ifelse_outs propagate_ifelse_outs(3, 4, ·, ·, ·) split-3-primitive-Unit-0 () function-4-propagate_ifelse_outs propagate_ifelse_outs(4, 4, ·, ·, ·) split-4-primitive-Unit-0 ()
[debug] egglog.extract ▶
_Region_1 = Region("598", InPorts(Vec[String]("!io", "a", "b")))
_Region_2 = Region("648", InPorts(Vec[String]("!io", "a", "b")))
_Region_3 = Region("745", InPorts(Vec[String]("!io", "a", "b")))
_Term_1 = Term.IfElse(
    Nb_Gt_Int64(_Region_1.get(1), _Region_1.get(2)),
    Term.RegionEnd(
        _Region_2,
        PortList(Vec[Port](Port("!io", _Region_2.get(0)), Port("a", _Region_2.get(1)), Port("b", _Region_2.get(2)), Port("z", Nb_Sub_Int64(_Region_2.get(1), _Region_2.get(2))))),
    ),
    Term.RegionEnd(
        _Region_3,
        PortList(
            Vec[Port](
                Port("!io", _Region_3.get(0)),
                Port("a", _Region_3.get(1)),
                Port("b", _Region_3.get(2)),
                Port("z", Nb_Sub_Float64(Nb_CastI64ToF64(_Region_3.get(2)), Nb_Div_Int64(Term.LiteralI64(1), _Region_3.get(1)))),
            )
        ),
    ),
    TermList(Vec[Term](_Region_1.get(0), _Region_1.get(1), _Region_1.get(2))),
)
_Term_2 = Py_SubIO(_Term_1.getPort(0), _Term_1.getPort(3), Nb_CastI64ToF64(_Term_1.getPort(1)))
GraphRoot(Term.Func("1044", "transformed_example_3", Term.RegionEnd(_Region_1, PortList(Vec[Port](Port("!io", _Term_2.getPort(0)), Port("!ret", _Term_2.getPort(1)))))))