egglog 11.2.0__cp311-cp311-manylinux_2_17_ppc64.manylinux2014_ppc64.whl → 11.3.0__cp311-cp311-manylinux_2_17_ppc64.manylinux2014_ppc64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of egglog might be problematic. Click here for more details.

egglog/builtins.py CHANGED
@@ -103,6 +103,10 @@ class String(BuiltinExpr):
103
103
  @method(egg_fn="replace")
104
104
  def replace(self, old: StringLike, new: StringLike) -> String: ...
105
105
 
106
+ @method(preserve=True)
107
+ def __add__(self, other: StringLike) -> String:
108
+ return join(self, other)
109
+
106
110
 
107
111
  StringLike: TypeAlias = String | str
108
112
 
egglog/declarations.py CHANGED
@@ -9,6 +9,7 @@ from __future__ import annotations
9
9
  from dataclasses import dataclass, field
10
10
  from functools import cached_property
11
11
  from typing import TYPE_CHECKING, ClassVar, Literal, Protocol, TypeAlias, TypeVar, Union, cast, runtime_checkable
12
+ from uuid import UUID
12
13
  from weakref import WeakValueDictionary
13
14
 
14
15
  from typing_extensions import Self, assert_never
@@ -20,6 +21,7 @@ if TYPE_CHECKING:
20
21
  __all__ = [
21
22
  "ActionCommandDecl",
22
23
  "ActionDecl",
24
+ "BackOffDecl",
23
25
  "BiRewriteDecl",
24
26
  "CallDecl",
25
27
  "CallableDecl",
@@ -52,6 +54,7 @@ __all__ = [
52
54
  "JustTypeRef",
53
55
  "LetDecl",
54
56
  "LetRefDecl",
57
+ "LetSchedulerDecl",
55
58
  "LitDecl",
56
59
  "LitType",
57
60
  "MethodRef",
@@ -790,9 +793,24 @@ class SequenceDecl:
790
793
  class RunDecl:
791
794
  ruleset: str
792
795
  until: tuple[FactDecl, ...] | None
796
+ scheduler: BackOffDecl | None = None
793
797
 
794
798
 
795
- ScheduleDecl: TypeAlias = SaturateDecl | RepeatDecl | SequenceDecl | RunDecl
799
+ @dataclass(frozen=True)
800
+ class LetSchedulerDecl:
801
+ scheduler: BackOffDecl
802
+ inner: ScheduleDecl
803
+
804
+
805
+ ScheduleDecl: TypeAlias = SaturateDecl | RepeatDecl | SequenceDecl | RunDecl | LetSchedulerDecl
806
+
807
+
808
+ @dataclass(frozen=True)
809
+ class BackOffDecl:
810
+ id: UUID
811
+ match_limit: int | None
812
+ ban_length: int | None
813
+
796
814
 
797
815
  ##
798
816
  # Facts
egglog/egraph.py CHANGED
@@ -23,6 +23,7 @@ from typing import (
23
23
  get_type_hints,
24
24
  overload,
25
25
  )
26
+ from uuid import uuid4
26
27
  from warnings import warn
27
28
 
28
29
  import graphviz
@@ -45,6 +46,7 @@ if TYPE_CHECKING:
45
46
 
46
47
  __all__ = [
47
48
  "Action",
49
+ "BackOff",
48
50
  "BaseExpr",
49
51
  "BuiltinExpr",
50
52
  "Command",
@@ -63,6 +65,7 @@ __all__ = [
63
65
  "_RewriteBuilder",
64
66
  "_SetBuilder",
65
67
  "_UnionBuilder",
68
+ "back_off",
66
69
  "birewrite",
67
70
  "check",
68
71
  "check_eq",
@@ -905,8 +908,8 @@ class EGraph:
905
908
 
906
909
  def _run_schedule(self, schedule: Schedule) -> bindings.RunReport:
907
910
  self._add_decls(schedule)
908
- egg_schedule = self._state.schedule_to_egg(schedule.schedule)
909
- (command_output,) = self._egraph.run_program(bindings.RunSchedule(egg_schedule))
911
+ cmd = self._state.run_schedule_to_egg(schedule.schedule)
912
+ (command_output,) = self._egraph.run_program(cmd)
910
913
  assert isinstance(command_output, bindings.RunScheduleOutput)
911
914
  return command_output.report
912
915
 
@@ -1033,7 +1036,7 @@ class EGraph:
1033
1036
  split_primitive_outputs = kwargs.pop("split_primitive_outputs", True)
1034
1037
  split_functions = kwargs.pop("split_functions", [])
1035
1038
  include_temporary_functions = kwargs.pop("include_temporary_functions", False)
1036
- n_inline_leaves = kwargs.pop("n_inline_leaves", 1)
1039
+ n_inline_leaves = kwargs.pop("n_inline_leaves", 0)
1037
1040
  serialized = self._egraph.serialize(
1038
1041
  [],
1039
1042
  max_functions=max_functions,
@@ -1786,17 +1789,51 @@ def to_runtime_expr(expr: BaseExpr) -> RuntimeExpr:
1786
1789
  return expr
1787
1790
 
1788
1791
 
1789
- def run(ruleset: Ruleset | None = None, *until: FactLike) -> Schedule:
1792
+ def run(ruleset: Ruleset | None = None, *until: FactLike, scheduler: BackOff | None = None) -> Schedule:
1790
1793
  """
1791
1794
  Create a run configuration.
1792
1795
  """
1793
1796
  facts = _fact_likes(until)
1794
1797
  return Schedule(
1795
1798
  Thunk.fn(Declarations.create, ruleset, *facts),
1796
- RunDecl(ruleset.__egg_name__ if ruleset else "", tuple(f.fact for f in facts) or None),
1799
+ RunDecl(
1800
+ ruleset.__egg_name__ if ruleset else "",
1801
+ tuple(f.fact for f in facts) or None,
1802
+ scheduler.scheduler if scheduler else None,
1803
+ ),
1797
1804
  )
1798
1805
 
1799
1806
 
1807
+ def back_off(match_limit: None | int = None, ban_length: None | int = None) -> BackOff:
1808
+ """
1809
+ Create a backoff scheduler configuration.
1810
+
1811
+ ```python
1812
+ schedule = run(analysis_ruleset).saturate() + run(ruleset, scheduler=back_off(match_limit=1000, ban_length=5)) * 10
1813
+ ```
1814
+ This will run the `analysis_ruleset` until saturation, then run `ruleset` 10 times, using a backoff scheduler.
1815
+ """
1816
+ return BackOff(BackOffDecl(id=uuid4(), match_limit=match_limit, ban_length=ban_length))
1817
+
1818
+
1819
+ @dataclass(frozen=True)
1820
+ class BackOff:
1821
+ scheduler: BackOffDecl
1822
+
1823
+ def scope(self, schedule: Schedule) -> Schedule:
1824
+ """
1825
+ Defines the scheduler to be created directly before the inner schedule, instead of the default which is at the
1826
+ most outer scope.
1827
+ """
1828
+ return Schedule(schedule.__egg_decls_thunk__, LetSchedulerDecl(self.scheduler, schedule.schedule))
1829
+
1830
+ def __str__(self) -> str:
1831
+ return pretty_decl(Declarations(), self.scheduler)
1832
+
1833
+ def __repr__(self) -> str:
1834
+ return str(self)
1835
+
1836
+
1800
1837
  def seq(*schedules: Schedule) -> Schedule:
1801
1838
  """
1802
1839
  Run a sequence of schedules.
egglog/egraph_state.py CHANGED
@@ -8,6 +8,7 @@ import re
8
8
  from collections import defaultdict
9
9
  from dataclasses import dataclass, field, replace
10
10
  from typing import TYPE_CHECKING, Literal, overload
11
+ from uuid import UUID
11
12
 
12
13
  from typing_extensions import assert_never
13
14
 
@@ -89,18 +90,140 @@ class EGraphState:
89
90
  cost_callables=self.cost_callables.copy(),
90
91
  )
91
92
 
92
- def schedule_to_egg(self, schedule: ScheduleDecl) -> bindings._Schedule:
93
+ def run_schedule_to_egg(self, schedule: ScheduleDecl) -> bindings._Command:
94
+ """
95
+ Turn a run schedule into an egg command.
96
+
97
+ If there exists any custom schedulers in the schedule, it will be turned into a custom extract command otherwise
98
+ will be a normal run command.
99
+ """
100
+ processed_schedule = self._process_schedule(schedule)
101
+ if processed_schedule is None:
102
+ return bindings.RunSchedule(self._schedule_to_egg(schedule))
103
+ top_level_schedules = self._schedule_with_scheduler_to_egg(processed_schedule, [])
104
+ if len(top_level_schedules) == 1:
105
+ schedule_expr = top_level_schedules[0]
106
+ else:
107
+ schedule_expr = bindings.Call(span(), "seq", top_level_schedules)
108
+ return bindings.UserDefined(span(), "run-schedule", [schedule_expr])
109
+
110
+ def _process_schedule(self, schedule: ScheduleDecl) -> ScheduleDecl | None:
111
+ """
112
+ Processes a schedule to determine if it contains any custom schedulers.
113
+
114
+ If it does, it returns a new schedule with all the required let bindings added to the other scope.
115
+ If not, returns none.
116
+
117
+ Also processes all rulesets in the schedule to make sure they are registered.
118
+ """
119
+ bound_schedulers: list[UUID] = []
120
+ unbound_schedulers: list[BackOffDecl] = []
121
+
122
+ def helper(s: ScheduleDecl) -> None:
123
+ match s:
124
+ case LetSchedulerDecl(scheduler, inner):
125
+ bound_schedulers.append(scheduler.id)
126
+ return helper(inner)
127
+ case RunDecl(ruleset_name, _, scheduler):
128
+ self.ruleset_to_egg(ruleset_name)
129
+ if scheduler and scheduler.id not in bound_schedulers:
130
+ unbound_schedulers.append(scheduler)
131
+ case SaturateDecl(inner) | RepeatDecl(inner, _):
132
+ return helper(inner)
133
+ case SequenceDecl(schedules):
134
+ for sc in schedules:
135
+ helper(sc)
136
+ case _:
137
+ assert_never(s)
138
+ return None
139
+
140
+ helper(schedule)
141
+ if not bound_schedulers and not unbound_schedulers:
142
+ return None
143
+ for scheduler in unbound_schedulers:
144
+ schedule = LetSchedulerDecl(scheduler, schedule)
145
+ return schedule
146
+
147
+ def _schedule_to_egg(self, schedule: ScheduleDecl) -> bindings._Schedule:
148
+ msg = "Should never reach this, let schedulers should be handled by custom scheduler"
93
149
  match schedule:
94
150
  case SaturateDecl(schedule):
95
- return bindings.Saturate(span(), self.schedule_to_egg(schedule))
151
+ return bindings.Saturate(span(), self._schedule_to_egg(schedule))
96
152
  case RepeatDecl(schedule, times):
97
- return bindings.Repeat(span(), times, self.schedule_to_egg(schedule))
153
+ return bindings.Repeat(span(), times, self._schedule_to_egg(schedule))
98
154
  case SequenceDecl(schedules):
99
- return bindings.Sequence(span(), [self.schedule_to_egg(s) for s in schedules])
100
- case RunDecl(ruleset_name, until):
101
- self.ruleset_to_egg(ruleset_name)
155
+ return bindings.Sequence(span(), [self._schedule_to_egg(s) for s in schedules])
156
+ case RunDecl(ruleset_name, until, scheduler):
157
+ if scheduler is not None:
158
+ raise ValueError(msg)
102
159
  config = bindings.RunConfig(ruleset_name, None if not until else list(map(self.fact_to_egg, until)))
103
160
  return bindings.Run(span(), config)
161
+ case LetSchedulerDecl():
162
+ raise ValueError(msg)
163
+ case _:
164
+ assert_never(schedule)
165
+
166
+ def _schedule_with_scheduler_to_egg( # noqa: C901, PLR0912
167
+ self, schedule: ScheduleDecl, bound_schedulers: list[UUID]
168
+ ) -> list[bindings._Expr]:
169
+ """
170
+ Turns a scheduler into an egg expression, to be used with a custom extract command.
171
+
172
+ The bound_schedulers is a list of all the schedulers that have been bound. We can lookup their name as `_scheduler_{index}`.
173
+ """
174
+ match schedule:
175
+ case LetSchedulerDecl(BackOffDecl(id, match_limit, ban_length), inner):
176
+ name = f"_scheduler_{len(bound_schedulers)}"
177
+ bound_schedulers.append(id)
178
+ args: list[bindings._Expr] = []
179
+ if match_limit is not None:
180
+ args.append(bindings.Var(span(), ":match-limit"))
181
+ args.append(bindings.Lit(span(), bindings.Int(match_limit)))
182
+ if ban_length is not None:
183
+ args.append(bindings.Var(span(), ":ban-length"))
184
+ args.append(bindings.Lit(span(), bindings.Int(ban_length)))
185
+ back_off_decl = bindings.Call(span(), "back-off", args)
186
+ let_decl = bindings.Call(span(), "let-scheduler", [bindings.Var(span(), name), back_off_decl])
187
+ return [let_decl, *self._schedule_with_scheduler_to_egg(inner, bound_schedulers)]
188
+ case RunDecl(ruleset_name, until, scheduler):
189
+ args = [bindings.Var(span(), ruleset_name)]
190
+ if scheduler:
191
+ name = "run-with"
192
+ scheduler_name = f"_scheduler_{bound_schedulers.index(scheduler.id)}"
193
+ args.insert(0, bindings.Var(span(), scheduler_name))
194
+ else:
195
+ name = "run"
196
+ if until:
197
+ if len(until) > 1:
198
+ msg = "Can only have one until fact with custom scheduler"
199
+ raise ValueError(msg)
200
+ args.append(bindings.Var(span(), ":until"))
201
+ fact_egg = self.fact_to_egg(until[0])
202
+ if isinstance(fact_egg, bindings.Eq):
203
+ msg = "Cannot use equality fact with custom scheduler"
204
+ raise ValueError(msg)
205
+ args.append(fact_egg.expr)
206
+ return [bindings.Call(span(), name, args)]
207
+ case SaturateDecl(inner):
208
+ return [
209
+ bindings.Call(span(), "saturate", self._schedule_with_scheduler_to_egg(inner, bound_schedulers))
210
+ ]
211
+ case RepeatDecl(inner, times):
212
+ return [
213
+ bindings.Call(
214
+ span(),
215
+ "repeat",
216
+ [
217
+ bindings.Lit(span(), bindings.Int(times)),
218
+ *self._schedule_with_scheduler_to_egg(inner, bound_schedulers),
219
+ ],
220
+ )
221
+ ]
222
+ case SequenceDecl(schedules):
223
+ res = []
224
+ for s in schedules:
225
+ res.extend(self._schedule_with_scheduler_to_egg(s, bound_schedulers))
226
+ return res
104
227
  case _:
105
228
  assert_never(schedule)
106
229
 
@@ -62,6 +62,3 @@ egraph.register(query)
62
62
  egraph.run(1000)
63
63
  print(egraph.extract(query))
64
64
  print(egraph.extract(query.size))
65
-
66
-
67
- egraph
egglog/pretty.py CHANGED
@@ -67,7 +67,9 @@ UNARY_METHODS = {
67
67
  "__invert__": "~",
68
68
  }
69
69
 
70
- AllDecls: TypeAlias = RulesetDecl | CombinedRulesetDecl | CommandDecl | ActionDecl | FactDecl | ExprDecl | ScheduleDecl
70
+ AllDecls: TypeAlias = (
71
+ RulesetDecl | CombinedRulesetDecl | CommandDecl | ActionDecl | FactDecl | ExprDecl | ScheduleDecl | BackOffDecl
72
+ )
71
73
 
72
74
 
73
75
  def pretty_decl(
@@ -188,10 +190,12 @@ class TraverseContext:
188
190
  case _:
189
191
  for e in exprs:
190
192
  self(e.expr)
191
- case RunDecl(_, until):
193
+ case RunDecl(_, until, scheduler):
192
194
  if until:
193
195
  for f in until:
194
196
  self(f)
197
+ if scheduler:
198
+ self(scheduler)
195
199
  case PartialCallDecl(c):
196
200
  self(c)
197
201
  case CombinedRulesetDecl(_):
@@ -201,6 +205,12 @@ class TraverseContext:
201
205
  case SetCostDecl(_, e, c):
202
206
  self(e)
203
207
  self(c)
208
+ case BackOffDecl():
209
+ pass
210
+ case LetSchedulerDecl(scheduler, schedule):
211
+ self(scheduler)
212
+ self(schedule)
213
+
204
214
  case _:
205
215
  assert_never(decl)
206
216
 
@@ -238,7 +248,11 @@ class PrettyContext:
238
248
  # it would take up is > than some constant (~ line length).
239
249
  line_diff: int = len(expr) - LINE_DIFFERENCE
240
250
  n_parents = self.parents[decl]
241
- if n_parents > 1 and n_parents * line_diff > MAX_LINE_LENGTH:
251
+ if n_parents > 1 and (
252
+ n_parents * line_diff > MAX_LINE_LENGTH
253
+ # Schedulers with multiple parents need to be the same object, b/c are created with hidden UUIDs
254
+ or tp_name == "scheduler"
255
+ ):
242
256
  self.names[decl] = expr_name = self._name_expr(tp_name, expr, copy_identifier=False)
243
257
  return expr_name
244
258
  return expr
@@ -318,16 +332,27 @@ class PrettyContext:
318
332
  return f"{self(schedules[0], parens=True)} + {self(schedules[1], parens=True)}", "schedule"
319
333
  args = ", ".join(map(self, schedules))
320
334
  return f"seq({args})", "schedule"
321
- case RunDecl(ruleset_name, until):
335
+ case LetSchedulerDecl(scheduler, schedule):
336
+ return f"{self(scheduler, parens=True)}.scope({self(schedule, parens=True)})", "schedule"
337
+ case RunDecl(ruleset_name, until, scheduler):
322
338
  ruleset = self.decls._rulesets[ruleset_name]
323
339
  ruleset_str = self(ruleset, ruleset_name=ruleset_name)
324
- if not until:
340
+ if not until and not scheduler:
325
341
  return ruleset_str, "schedule"
326
- args = ", ".join(map(self, until))
327
- return f"run({ruleset_str}, {args})", "schedule"
342
+ arg_lst = list(map(self, until or []))
343
+ if scheduler:
344
+ arg_lst.append(f"scheduler={self(scheduler)}")
345
+ return f"run({ruleset_str}, {', '.join(arg_lst)})", "schedule"
328
346
  case DefaultRewriteDecl():
329
347
  msg = "default rewrites should not be pretty printed"
330
348
  raise TypeError(msg)
349
+ case BackOffDecl(_, match_limit, ban_length):
350
+ list_args: list[str] = []
351
+ if match_limit is not None:
352
+ list_args.append(f"match_limit={match_limit}")
353
+ if ban_length is not None:
354
+ list_args.append(f"ban_length={ban_length}")
355
+ return f"back_off({', '.join(list_args)})", "scheduler"
331
356
  assert_never(decl)
332
357
 
333
358
  def _call(
egglog/runtime.py CHANGED
@@ -635,14 +635,22 @@ for name in TYPE_DEFINED_METHODS:
635
635
 
636
636
 
637
637
  for name, r_method in itertools.product(NUMERIC_BINARY_METHODS, (False, True)):
638
+ method_name = f"__r{name[2:]}" if r_method else name
638
639
 
639
- def _numeric_binary_method(self: object, other: object, name: str = name, r_method: bool = r_method) -> object:
640
+ def _numeric_binary_method(
641
+ self: object, other: object, name: str = name, r_method: bool = r_method, method_name: str = method_name
642
+ ) -> object:
640
643
  """
641
644
  Implements numeric binary operations.
642
645
 
643
646
  Tries to find the minimum cost conversion of either the LHS or the RHS, by finding all methods with either
644
647
  the LHS or the RHS as exactly the right type and then upcasting the other to that type.
645
648
  """
649
+ # First check if we have a preserved method for this:
650
+ if isinstance(self, RuntimeExpr) and (
651
+ (preserved_method := self.__egg_class_decl__.preserved_methods.get(method_name)) is not None
652
+ ):
653
+ return preserved_method.__get__(self)(other)
646
654
  # 1. switch if reversed method
647
655
  if r_method:
648
656
  self, other = other, self
@@ -668,7 +676,6 @@ for name, r_method in itertools.product(NUMERIC_BINARY_METHODS, (False, True)):
668
676
  fn = RuntimeFunction(Thunk.value(self.__egg_decls__), Thunk.value(method_ref), self)
669
677
  return fn(other)
670
678
 
671
- method_name = f"__r{name[2:]}" if r_method else name
672
679
  setattr(RuntimeExpr, method_name, _numeric_binary_method)
673
680
 
674
681
 
@@ -688,6 +695,8 @@ def resolve_callable(callable: object) -> tuple[CallableRef, Declarations]:
688
695
  ):
689
696
  raise NotImplementedError(f"Can only turn constants or classvars into callable refs, not {expr}")
690
697
  return expr.callable, decl_thunk()
698
+ case types.MethodWrapperType() if isinstance((slf := callable.__self__), RuntimeClass):
699
+ return MethodRef(slf.__egg_tp__.name, callable.__name__), slf.__egg_decls__
691
700
  case _:
692
701
  raise NotImplementedError(f"Cannot turn {callable} of type {type(callable)} into a callable ref")
693
702
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: egglog
3
- Version: 11.2.0
3
+ Version: 11.3.0
4
4
  Classifier: Environment :: MacOS X
5
5
  Classifier: Environment :: Win32 (MS Windows)
6
6
  Classifier: Intended Audience :: Developers
@@ -51,6 +51,7 @@ Requires-Dist: egglog[array] ; extra == 'docs'
51
51
  Requires-Dist: line-profiler ; extra == 'docs'
52
52
  Requires-Dist: sphinxcontrib-mermaid ; extra == 'docs'
53
53
  Requires-Dist: ablog ; extra == 'docs'
54
+ Requires-Dist: jupytext ; extra == 'docs'
54
55
  Provides-Extra: array
55
56
  Provides-Extra: dev
56
57
  Provides-Extra: test
@@ -72,3 +73,20 @@ Please see the [documentation](https://egglog-python.readthedocs.io/) for more i
72
73
 
73
74
  Come say hello [on the e-graphs Zulip](https://egraphs.zulipchat.com/#narrow/stream/375765-egglog/) or [open an issue](https://github.com/egraphs-good/egglog-python/issues/new/choose)!
74
75
 
76
+ ## How to cite
77
+
78
+ If you use **egglog-python** in academic work, please cite the paper:
79
+
80
+ ```bibtex
81
+ @misc{Shanabrook2023EgglogPython,
82
+ title = {Egglog Python: A Pythonic Library for E-graphs},
83
+ author = {Saul Shanabrook},
84
+ year = {2023},
85
+ eprint = {2305.04311},
86
+ archivePrefix = {arXiv},
87
+ primaryClass = {cs.PL},
88
+ doi = {10.48550/arXiv.2305.04311},
89
+ url = {https://arxiv.org/abs/2305.04311},
90
+ note = {Presented at EGRAPHS@PLDI 2023}
91
+ }
92
+
@@ -1,16 +1,16 @@
1
- egglog-11.2.0.dist-info/METADATA,sha256=10JQyEe0Um6WF78Wz6E6XMAi2zeAF-fT0oAlCVkBh9Q,4009
2
- egglog-11.2.0.dist-info/WHEEL,sha256=I660Wu_bwsa52hoMAbWjHQzRtFseFdfcsevn1BQ9D-0,127
3
- egglog-11.2.0.dist-info/licenses/LICENSE,sha256=w7VlVv5O_FPZRo8Z-4Zb_q7D5ac3YDs8JUkMZ4Gq9CE,1070
1
+ egglog-11.3.0.dist-info/METADATA,sha256=_7z3OUAk7vWdO7bwhHHUwhirFqvbHsguTnkGY9qvidQ,4554
2
+ egglog-11.3.0.dist-info/WHEEL,sha256=I660Wu_bwsa52hoMAbWjHQzRtFseFdfcsevn1BQ9D-0,127
3
+ egglog-11.3.0.dist-info/licenses/LICENSE,sha256=w7VlVv5O_FPZRo8Z-4Zb_q7D5ac3YDs8JUkMZ4Gq9CE,1070
4
4
  egglog/__init__.py,sha256=0r3MzQbU-9U0fSCeAoJ3deVhZ77tI-1tf8A_WFOhbJs,344
5
- egglog/bindings.cpython-311-powerpc64-linux-gnu.so,sha256=yu_rt4acRoicYflIGt5t1MaXvTSX9QHnj9_1CuroZ14,167394984
5
+ egglog/bindings.cpython-311-powerpc64-linux-gnu.so,sha256=PJ4yPRWwIazcstrBfwB2ApAxJ_eIWe7MS4RfuXoBrVA,169628688
6
6
  egglog/bindings.pyi,sha256=Y_YpdAKmVHZ0nIHTTPeg0sigBEPiS8z_U-Z161zKSK4,15330
7
- egglog/builtins.py,sha256=bF3GanSmsrIIutvuMUmr4SnSNF0zAEwjmDYWbPEEayo,30204
7
+ egglog/builtins.py,sha256=qXbBOtT1qwgR9uQu9yb1gUp4dm2L6BgvJIWYU4zCzuw,30317
8
8
  egglog/config.py,sha256=yM3FIcVCKnhWZmHD0pxkzx7ah7t5PxZx3WUqKtA9tjU,168
9
9
  egglog/conversion.py,sha256=DO76lxRbbTqHs6hRo_Lckvtwu0c6LaKoX7k5_B2AfuY,11238
10
- egglog/declarations.py,sha256=vBCcK94EqLDfMPasTwCQA_8EU0nVDSLfJoudboi4MgI,25920
10
+ egglog/declarations.py,sha256=pc2KEYwyKNQXuKndbBCC6iuVROgHkaSKJJf_s9liZi8,26260
11
11
  egglog/deconstruct.py,sha256=CovORrpROMIwOLgERPUw8doqRUDUehj6LJEB5FMbpmI,5635
12
- egglog/egraph.py,sha256=HVpHLHzHfvv1ZX7uxmsblUiEF8ZfJKkNjM-h7Cf8Zb0,64227
13
- egglog/egraph_state.py,sha256=vIa2ACOxXMjrIS4vwA0UkY1I8hDjDUnS9Pq8awFCVfA,30515
12
+ egglog/egraph.py,sha256=zJpAoC6JXXqnRsp24CvQN5M5EZ0PrOj93R9U4w6bqlw,65417
13
+ egglog/egraph_state.py,sha256=3VLwkAsR3oCydHLx_BXmFw4UHXgdZ9jooQdWUcQeUD0,36375
14
14
  egglog/examples/README.rst,sha256=ztTvpofR0eotSqGoCy_C1fPLDPCncjvcqDanXtLHNNU,232
15
15
  egglog/examples/__init__.py,sha256=wm9evUbMPfbtylXIjbDdRTAVMLH4OjT4Z77PCBFyaPU,31
16
16
  egglog/examples/bignum.py,sha256=jfL57XXpQqIqizQQ3sSUCCjTrkdjtB71BmjrQIQorQk,535
@@ -18,7 +18,7 @@ egglog/examples/bool.py,sha256=e0z2YoYJsLlhpSADZK1yRYHzilyxSZWGiYAaM0DQ_Gw,695
18
18
  egglog/examples/eqsat_basic.py,sha256=2xtM81gG9Br72mr58N-2BUeksR7C_UXnZJ4MvzSPplc,869
19
19
  egglog/examples/fib.py,sha256=BOHxKWA7jGx4FURBmfmuZKfLo6xq9-uXAwAXjYid7LU,492
20
20
  egglog/examples/higher_order_functions.py,sha256=DNLIQfPJCX_DOLbHNiaYsfvcFIYCYOsRUqp99r9bpc8,1063
21
- egglog/examples/jointree.py,sha256=60lS8sCgg0V8O6QqBKpN1y7Tz5BRFsvN8L1jM-9mTSE,1723
21
+ egglog/examples/jointree.py,sha256=TLlH7TsQzWfadqDo7qeTprFhLdQmj59AQaGse81RIKk,1714
22
22
  egglog/examples/lambda_.py,sha256=iQvwaXVhp2VNOMS7j1WwceZaiq3dqqilwUkMcW5GFBE,8194
23
23
  egglog/examples/matrix.py,sha256=7_mPcMcgE-t_GJDyf76-nv3xhPIeN2mvFkc_p_Gnr8g,4961
24
24
  egglog/examples/multiset.py,sha256=IBOsB80DkXQ07dYnk1odi27q77LH80Z8zysuLE-Q8F8,1445
@@ -34,13 +34,13 @@ egglog/exp/array_api_program_gen.py,sha256=qnve8iqklRQVyGChllG8ZAjAffRpezmdxc3Id
34
34
  egglog/exp/program_gen.py,sha256=CavsD70x0ERS87V4OU9zkgMvLXswGEpb1ZZFK0WyN_g,13033
35
35
  egglog/exp/siu_examples.py,sha256=yZ-sgH2Y12iTdwBUumP7D2OtCGL83M6pPW7PMobVFXc,719
36
36
  egglog/ipython_magic.py,sha256=2hs3g2cSiyDmbCvE2t1OINmu17Bb8MWV--2DpEWwO7I,1189
37
- egglog/pretty.py,sha256=bX1rZnujgo_oUK0QRveS5ES1hECpR665__qksUxeEKQ,20921
37
+ egglog/pretty.py,sha256=Sv3H9e0CJcZv3-ylijP58ApCQ5w1BOdXl2VDw6Hst4Y,22061
38
38
  egglog/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- egglog/runtime.py,sha256=NJZEE0PJGLfZMeBxhBphKFAuGPq01AaDoHOQxs3k79Y,29160
39
+ egglog/runtime.py,sha256=NUA0O-_urneP54RqXRcPLQIlFzNwPacPKIMxGpwAkus,29672
40
40
  egglog/thunk.py,sha256=MrAlPoGK36VQrUrq8PWSaJFu42sPL0yupwiH18lNips,2271
41
41
  egglog/type_constraint_solver.py,sha256=U2GjLgbebTLv5QY8_TU0As5wMKL5_NxkHLen9rpfMwI,4518
42
42
  egglog/version_compat.py,sha256=EaKRMIOPcatrx9XjCofxZD6Nr5WOooiWNdoapkKleww,3512
43
43
  egglog/visualizer.css,sha256=eL0POoThQRc0P4OYnDT-d808ln9O5Qy6DizH9Z5LgWc,259398
44
44
  egglog/visualizer.js,sha256=2qZZ-9W_INJx4gZMYjnVXl27IjT_JNuQyEeI2dbjWoU,3753315
45
45
  egglog/visualizer_widget.py,sha256=LtVfzOtv2WeKtNuILQQ_9SOHWvRr8YdBYQDKQSgry_s,1319
46
- egglog-11.2.0.dist-info/RECORD,,
46
+ egglog-11.3.0.dist-info/RECORD,,