Metatheory.jl
Metatheory.jl は開始式から E-Graphを作成し, addexpr! で式を追加して, saturate! で書き換えルールを適用した全ての等価式を反映できる.
extract! で式を抽出できる.
using Metatheory.Library
comm_monoid = @commutative_monoid (*) 1
t = @theory a b c begin
a * b == b * a
a * 1 == a
a * (b * c) == (a * b) * c
end
g = EGraph(:((a * b) * (1 * (b + c))));
report = saturate!(g, t);
# access the saturated EGraph
report.egraph
# show some fancy stats
report@areequal some_theory (x+y)*(a+b) ((a*(x+y))+b*(x+y)) ((x*(a+b))+y*(a+b))式の等価性をチェック
using Metatheory
using Metatheory.Library
comm_monoid = @commutative_monoid (*) 1;
t = @theory a b c begin
a + 0 --> a
a + b --> b + a
a + inv(a) --> 0 # inverse
a + (b + c) --> (a + b) + c
a * (b + c) --> (a * b) + (a * c)
(a * b) + (a * c) --> a * (b + c)
a * a --> a^2
a --> a^1
a^b * a^c --> a^(b+c)
log(a^b) --> b * log(a)
log(a * b) --> log(a) + log(b)
log(1) --> 0
log(:e) --> 1
:e^(log(a)) --> a
a::Number + b::Number => a + b
a::Number * b::Number => a * b
end
t = comm_monoid ∪ t ;expr = :((log(e) * log(e)) * (log(a^3 * a^2)))
g = EGraph(expr)
saturate!(g, t)
ex = extract!(g, astsize)
> :(log(a ^ 5))astsize は表現の長さのコスト関数
Custom cost function
# This is a cost function that behaves like `astsize` but increments the cost
# of nodes containing the `^` operation. This results in a tendency to avoid
# extraction of expressions containing '^'.
function cost_function(n::ENodeTerm, g::EGraph, an::Type{<:AbstractAnalysis})
cost = 1 + arity(n)
operation(n) == :^ && (cost += 2)
for id in arguments(n)
eclass = g[id]
# if the child e-class has not yet been analyzed, return +Inf
!hasdata(eclass, an) && (cost += Inf; break)
cost += last(getdata(eclass, an))
end
return cost
end
# All literal expressions (e.g `a`, 123, 0.42, "hello") have cost 1
cost_function(n::ENodeLiteral, g::EGraph, an::Type{<:AbstractAnalysis}) = 1