Skip to content

Exploding egraphs - Troubles defining rule sets working with eq-sat #190

@gkronber

Description

@gkronber

I struggle to define a set of rules that does not lead to exponentially growing egraphs which never saturate for simple expressions (Metatheory v2.0.2).

In the following code I try to fold constants. The rule set is designed to trigger the issue I observe:

    t = @theory a b c begin
        (a + b) + c == a + (b + c)
        a - b --> a + -1.0 * b  # this rule triggers the problem (together with the first rule)
        a::Number + b::Number => a + b
        a::Number * b::Number => a * b
    end

   g = EGraph(:(1 + 1 - 1))
   param = SaturationParams(timeout=20)
   report = saturate!(g, t, param); 
   println(report)

In Iteration two a loop for an e-class is created which is later expanded in each iteration.

┌ Debug: ================ EQSAT ITERATION 4  ================
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:290
┌ Debug: SEARCHING
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:115
┌ Debug: Rule 1: (~a + ~b) + ~c == ~a + (~b + ~c) produced 10 matches
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:129
┌ Debug: Rule 2: ~a - ~b --> ~a + -1.0 * ~b produced 1 matches
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:129
┌ Debug: Rule 3: ~(a::Number) + ~(b::Number) => a + b produced 4 matches
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:129
┌ Debug: Rule 4: ~(a::Number) * ~(b::Number) => a * b produced 1 matches
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:129
┌ Debug: APPLYING 16 matches
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:210
┌ Debug: 1
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:267
┌ Debug: ================ EQSAT ITERATION 5  ================
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:290
┌ Debug: SEARCHING
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:115
┌ Debug: Rule 1: (~a + ~b) + ~c == ~a + (~b + ~c) produced 98 matches
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:129
┌ Debug: Rule 2: ~a - ~b --> ~a + -1.0 * ~b produced 1 matches
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:129
┌ Debug: Rule 3: ~(a::Number) + ~(b::Number) => a + b produced 12 matches
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:129
┌ Debug: Rule 4: ~(a::Number) * ~(b::Number) => a * b produced 1 matches
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:129
┌ Debug: APPLYING 112 matches
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:210
┌ Debug: 1
└ @ Metatheory.EGraphs ~/.julia/dev/Metatheory/src/EGraphs/saturation.jl:267

After two iterations:
image

After three iterations:
image

The default scheduler is the BackoffScheduler and it starts to ban some rules after a few iterations. However, I feel I should be able to solve this without relying on the scheduler.

The problem does not occur for the expression "1+1+1" . What do I miss?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions