Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues in E-graph matching for parametrized types #142

Open
ChenZhao44 opened this issue Sep 28, 2022 · 6 comments
Open

Issues in E-graph matching for parametrized types #142

ChenZhao44 opened this issue Sep 28, 2022 · 6 comments

Comments

@ChenZhao44
Copy link
Contributor

ChenZhao44 commented Sep 28, 2022

Here is an example.

using Metatheory, TermInterface

struct Foo{A}
    x::A
end

TermInterface.istree(::Foo{T}) where T = true
TermInterface.istree(::Type{Foo{T}}) where T = true
TermInterface.exprhead(::Foo) = :call
TermInterface.operation(::Foo{T}) where T = :(Foo{$T})
TermInterface.arguments(f::Foo) = f.x

function TermInterface.similarterm(::Type{Foo{T}}, f, args; metadata=nothing, exprhead = :call) where T
    return Foo(args...)
end

t = @theory T A begin
    Foo{T}(A) => A
end

f = Foo([:x])
eg = EGraph(f)
saturate!(eg, t)
extract!(eg, astsize) # this returns Foo([:x]) instead of [:x]
@ChenZhao44
Copy link
Contributor Author

I guess I have find where the problem comes from.

The operation of :(Foo{T})(A) is :(Foo{T}) which is another Expr. So when you generate a match pattern in makepattern, op will become another match pattern PatTerm because istree(op) is true.
See:

op = op isa Symbol ? QuoteNode(op) : op

However, it just compare whether the operation of a enode equals to the pattern instead of being matched with the pattern.
See:

checkop = x -> isequal(x, op)

So a parameterized type will never be matched because its operation could never equals PatTerm.

@0x0f0f0f
Copy link
Member

Thanks for reporting! This feature may be added in 2.0 branch https://github.com/JuliaSymbolics/Metatheory.jl/tree/2.0.0-DEV

@0x0f0f0f
Copy link
Member

0x0f0f0f commented Dec 8, 2022

I believe that with the new pattern matcher we can now attack this easily

@willow-ahrens
Copy link
Contributor

willow-ahrens commented May 19, 2023

I think this is also related to #87.

You also can't use enums as head types (as is sometimes recommended when developing custom Julia ASTs), since those get quoted too and won't hit the special case in

function head_matcher(f::Union{Function,DataType,UnionAll})
that tries to undo the quoting.

@0x0f0f0f
Copy link
Member

I think this is also related to #87.

You also can't use enums as head types (as is sometimes recommended when developing custom Julia ASTs), since those get quoted too and won't hit the special case in

function head_matcher(f::Union{Function,DataType,UnionAll})

that tries to undo the quoting.

You can try adding a specialized head_matcher pattern matcher function. LMK if you have any further questions.

@0x0f0f0f 0x0f0f0f mentioned this issue Aug 6, 2024
@olynch
Copy link
Collaborator

olynch commented Aug 16, 2024

It seems like the general problem here is that there isn't support for "curried" functions. That is, we'd also have trouble matching f(a)(b), correct? It's the same problem, because the expression looks like Expr(:call, Expr(:curly, :Foo, :T), :A). If there were support for curried functions, then this could be treated as some kind of curried function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants