Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6a892ec

Browse files
Merge pull request#382 from egraphs-good/demo
Convert to multisets, facts as actions, and update multiset example
2 parents6daa0ae +e6ad4fa commit6a892ec

File tree

5 files changed

+92
-39
lines changed

5 files changed

+92
-39
lines changed

‎Cargo.lock‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎docs/changelog.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ _This project uses semantic versioning_
44

55
##UNRELEASED
66

7+
- Support using facts as union actions, add conversions to multisets, and update multiset examlpe[#382](https://github.com/egraphs-good/egglog-python/pull/382)
8+
79
##12.0.0 (2025-11-16)
810

911
- Add support for setting report level with`egraph.set_report_level`[#375](https://github.com/egraphs-good/egglog-python/pull/375)

‎python/egglog/builtins.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"Map",
4040
"MapLike",
4141
"MultiSet",
42+
"MultiSetLike",
4243
"Primitive",
4344
"PyObject",
4445
"Rational",
@@ -583,6 +584,17 @@ def __add__(self, other: MultiSet[T]) -> MultiSet[T]: ...
583584
defmap(self,f:Callable[[T],T])->MultiSet[T]: ...
584585

585586

587+
converter(
588+
tuple,
589+
MultiSet,
590+
lambdat:MultiSet[get_type_args()[0]](# type: ignore[misc,operator]
591+
*(convert(x,get_type_args()[0])forxint)
592+
),
593+
)
594+
595+
MultiSetLike:TypeAlias=MultiSet[T]|tuple[TO, ...]
596+
597+
586598
classRational(BuiltinExpr,egg_sort="Rational"):
587599
@method(preserve=True)
588600
@deprecated("use .value")

‎python/egglog/egraph.py‎

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,8 @@ def __replace_expr__(self, new_expr: Self) -> None:
367367
Replace the current expression with the new expression in place.
368368
"""
369369

370+
def__hash__(self)->int: ...# type: ignore[empty-body]
371+
370372

371373
classBuiltinExpr(BaseExpr,metaclass=_ExprMetaclass):
372374
"""
@@ -1933,23 +1935,32 @@ def seq(*schedules: Schedule) -> Schedule:
19331935
returnSchedule(Thunk.fn(Declarations.create,*schedules),SequenceDecl(tuple(s.scheduleforsinschedules)))
19341936

19351937

1936-
ActionLike:TypeAlias=Action|BaseExpr
1937-
1938-
19391938
def_action_likes(action_likes:Iterable[ActionLike])->tuple[Action, ...]:
19401939
returntuple(map(_action_like,action_likes))
19411940

19421941

19431942
def_action_like(action_like:ActionLike)->Action:
19441943
ifisinstance(action_like,Action):
19451944
returnaction_like
1945+
ifisinstance(action_like,Fact):
1946+
matchaction_like.fact:
1947+
caseEqDecl(tp,left,right):
1948+
returnAction(
1949+
action_like.__egg_decls__,
1950+
UnionDecl(tp,left,right),
1951+
)
1952+
caseExprFactDecl(expr):
1953+
returnAction(
1954+
action_like.__egg_decls__,
1955+
ExprActionDecl(expr),
1956+
)
1957+
case _:
1958+
assert_never(action_like.fact)
19461959
returnexpr_action(action_like)
19471960

19481961

19491962
Command:TypeAlias=Action|RewriteOrRule
19501963

1951-
CommandLike:TypeAlias=ActionLike|RewriteOrRule
1952-
19531964

19541965
def_command_like(command_like:CommandLike)->Command:
19551966
ifisinstance(command_like,RewriteOrRule):
@@ -1976,6 +1987,8 @@ def _rewrite_or_rule_generator(gen: RewriteOrRuleGenerator, frame: FrameType) ->
19761987

19771988

19781989
FactLike=Fact|BaseExpr
1990+
ActionLike:TypeAlias=Action|BaseExpr|Fact
1991+
CommandLike:TypeAlias=ActionLike|RewriteOrRule
19791992

19801993

19811994
def_fact_likes(fact_likes:Iterable[FactLike])->tuple[Fact, ...]:

‎python/egglog/examples/multiset.py‎

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,55 +6,81 @@
66

77
from __future__importannotations
88

9-
fromcollectionsimportCounter
10-
119
fromegglogimport*
1210

1311

1412
classMath(Expr):
1513
def__init__(self,x:i64Like)->None: ...
14+
def__add__(self,other:MathLike)->Math: ...
15+
def__radd__(self,other:MathLike)->Math: ...
16+
def__mul__(self,other:MathLike)->Math: ...
17+
def__rmul__(self,other:MathLike)->Math: ...
1618

1719

18-
@function
19-
defsquare(x:Math)->Math: ...
20-
21-
22-
@ruleset
23-
defmath_ruleset(i:i64):
24-
yieldrewrite(square(Math(i))).to(Math(i*i))
25-
20+
MathLike=Math|i64Like
21+
converter(i64,Math,Math)
2622

27-
egraph=EGraph()
2823

29-
xs=MultiSet(Math(1),Math(2),Math(3))
30-
egraph.register(xs)
24+
@function
25+
defsum(xs:MultiSetLike[Math,MathLike])->Math: ...
3126

32-
egraph.check(xs==MultiSet(Math(1),Math(3),Math(2)))
33-
egraph.check_fail(xs==MultiSet(Math(1),Math(1),Math(2),Math(3)))
3427

35-
assertCounter(egraph.extract(xs).value)==Counter({Math(1):1,Math(2):1,Math(3):1})
28+
@function
29+
defproduct(xs:MultiSetLike[Math,MathLike])->Math: ...
3630

3731

38-
inserted=MultiSet(Math(1),Math(2),Math(3),Math(4))
39-
egraph.register(inserted)
40-
egraph.check(xs.insert(Math(4))==inserted)
41-
egraph.check(xs.contains(Math(1)))
42-
egraph.check(xs.not_contains(Math(4)))
43-
assertMath(1)inxs
44-
assertMath(4)notinxs
32+
@function
33+
defsquare(x:Math)->Math: ...
4534

46-
egraph.check(xs.remove(Math(1))==MultiSet(Math(2),Math(3)))
4735

48-
assertegraph.extract(xs.length()).value==3
49-
assertlen(xs)==3
36+
x=constant("x",Math)
37+
expr1=2* (x+3)
38+
expr2=6+2*x
5039

51-
egraph.check(MultiSet(Math(1),Math(1)).length()==i64(2))
5240

53-
egraph.check(MultiSet(Math(1)).pick()==Math(1))
41+
@ruleset
42+
defmath_ruleset(a:Math,b:Math,c:Math,i:i64,j:i64,xs:MultiSet[Math],ys:MultiSet[Math],zs:MultiSet[Math]):
43+
yieldrewrite(a+b).to(sum(MultiSet(a,b)))
44+
yieldrewrite(a*b).to(product(MultiSet(a,b)))
45+
# 0 or 1 elements sums/products also can be extracted back to numbers
46+
yieldrule(a==sum(xs),xs.length()==i64(1)).then(a==xs.pick())
47+
yieldrule(a==product(xs),xs.length()==i64(1)).then(a==xs.pick())
48+
yieldrewrite(sum(MultiSet[Math]())).to(Math(0))
49+
yieldrewrite(product(MultiSet[Math]())).to(Math(1))
50+
# distributive rule (a * (b + c) = a*b + a*c)
51+
yieldrule(
52+
b==product(ys),
53+
a==sum(xs),
54+
ys.contains(a),
55+
ys.length()>1,
56+
zs==ys.remove(a),
57+
).then(
58+
b==sum(xs.map(lambdax:product(zs.insert(x)))),
59+
)
60+
# constants
61+
yieldrule(
62+
a==sum(xs),
63+
b==Math(i),
64+
xs.contains(b),
65+
ys==xs.remove(b),
66+
c==Math(j),
67+
ys.contains(c),
68+
).then(
69+
a==sum(ys.remove(c).insert(Math(i+j))),
70+
)
71+
yieldrule(
72+
a==product(xs),
73+
b==Math(i),
74+
xs.contains(b),
75+
ys==xs.remove(b),
76+
c==Math(j),
77+
ys.contains(c),
78+
).then(
79+
a==product(ys.remove(c).insert(Math(i*j))),
80+
)
5481

55-
mapped=xs.map(square)
56-
egraph.register(mapped)
57-
egraph.run(math_ruleset)
58-
egraph.check(mapped==MultiSet(Math(1),Math(4),Math(9)))
5982

60-
egraph.check(xs+xs==MultiSet(Math(1),Math(2),Math(3),Math(1),Math(2),Math(3)))
83+
egraph=EGraph()
84+
egraph.register(expr1,expr2)
85+
egraph.run(math_ruleset.saturate())
86+
egraph.check(expr1==expr2)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp