egglog 11.0.0__cp313-cp313-manylinux_2_17_ppc64.manylinux2014_ppc64.whl → 11.2.0__cp313-cp313-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/bindings.pyi CHANGED
@@ -7,15 +7,16 @@ from typing_extensions import final
7
7
  __all__ = [
8
8
  "ActionCommand",
9
9
  "AddRuleset",
10
- "Best",
11
10
  "BiRewriteCommand",
12
11
  "Bool",
12
+ "CSVPrintFunctionMode",
13
13
  "Call",
14
14
  "Change",
15
15
  "Check",
16
16
  "Constructor",
17
17
  "Datatype",
18
18
  "Datatypes",
19
+ "DefaultPrintFunctionMode",
19
20
  "Delete",
20
21
  "EGraph",
21
22
  "EggSmolError",
@@ -23,10 +24,13 @@ __all__ = [
23
24
  "Eq",
24
25
  "Expr_",
25
26
  "Extract",
27
+ "ExtractBest",
28
+ "ExtractVariants",
26
29
  "Fact",
27
30
  "Fail",
28
31
  "Float",
29
32
  "Function",
33
+ "FunctionCommand",
30
34
  "IdentSort",
31
35
  "Include",
32
36
  "Input",
@@ -35,10 +39,14 @@ __all__ = [
35
39
  "Lit",
36
40
  "NewSort",
37
41
  "Output",
42
+ "OverallStatistics",
38
43
  "Panic",
39
44
  "PanicSpan",
40
45
  "Pop",
46
+ "PrintAllFunctionsSize",
41
47
  "PrintFunction",
48
+ "PrintFunctionOutput",
49
+ "PrintFunctionSize",
42
50
  "PrintOverallStatistics",
43
51
  "PrintSize",
44
52
  "Push",
@@ -53,13 +61,13 @@ __all__ = [
53
61
  "RunConfig",
54
62
  "RunReport",
55
63
  "RunSchedule",
64
+ "RunScheduleOutput",
56
65
  "RustSpan",
57
66
  "Saturate",
58
67
  "Schema",
59
68
  "Sequence",
60
69
  "SerializedEGraph",
61
70
  "Set",
62
- "SetOption",
63
71
  "Sort",
64
72
  "SrcFile",
65
73
  "String",
@@ -73,13 +81,18 @@ __all__ = [
73
81
  "Unit",
74
82
  "UnstableCombinedRuleset",
75
83
  "UserDefined",
84
+ "UserDefinedCommandOutput",
85
+ "UserDefinedOutput",
76
86
  "Var",
77
87
  "Variant",
78
- "Variants",
79
88
  ]
80
89
 
81
90
  @final
82
91
  class SerializedEGraph:
92
+ @property
93
+ def truncated_functions(self) -> list[str]: ...
94
+ @property
95
+ def discarded_functions(self) -> list[str]: ...
83
96
  def inline_leaves(self) -> None: ...
84
97
  def saturate_inline_leaves(self) -> None: ...
85
98
  def to_dot(self) -> str: ...
@@ -106,9 +119,7 @@ class EGraph:
106
119
  ) -> None: ...
107
120
  def parse_program(self, __input: str, /, filename: str | None = None) -> list[_Command]: ...
108
121
  def commands(self) -> str | None: ...
109
- def run_program(self, *commands: _Command) -> list[str]: ...
110
- def extract_report(self) -> _ExtractReport | None: ...
111
- def run_report(self) -> RunReport | None: ...
122
+ def run_program(self, *commands: _Command) -> list[_CommandOutput]: ...
112
123
  def serialize(
113
124
  self,
114
125
  root_eclasses: list[_Expr],
@@ -356,6 +367,13 @@ class IdentSort:
356
367
  sort: str
357
368
  def __init__(self, ident: str, sort: str) -> None: ...
358
369
 
370
+ @final
371
+ class UserDefinedCommandOutput: ...
372
+
373
+ @final
374
+ class Function:
375
+ name: str
376
+
359
377
  @final
360
378
  class RunReport:
361
379
  updated: bool
@@ -375,20 +393,80 @@ class RunReport:
375
393
  rebuild_time_per_ruleset: dict[str, timedelta],
376
394
  ) -> None: ...
377
395
 
396
+ ##
397
+ # Command Outputs
398
+ ##
399
+
400
+ @final
401
+ class PrintFunctionSize:
402
+ size: int
403
+ def __init__(self, size: int) -> None: ...
404
+
405
+ @final
406
+ class PrintAllFunctionsSize:
407
+ sizes: list[tuple[str, int]]
408
+ def __init__(self, sizes: list[tuple[str, int]]) -> None: ...
409
+
378
410
  @final
379
- class Variants:
411
+ class ExtractVariants:
380
412
  termdag: TermDag
381
413
  terms: list[_Term]
382
414
  def __init__(self, termdag: TermDag, terms: list[_Term]) -> None: ...
383
415
 
384
416
  @final
385
- class Best:
417
+ class ExtractBest:
386
418
  termdag: TermDag
387
419
  cost: int
388
420
  term: _Term
389
421
  def __init__(self, termdag: TermDag, cost: int, term: _Term) -> None: ...
390
422
 
391
- _ExtractReport: TypeAlias = Variants | Best
423
+ @final
424
+ class OverallStatistics:
425
+ report: RunReport
426
+ def __init__(self, report: RunReport) -> None: ...
427
+
428
+ @final
429
+ class RunScheduleOutput:
430
+ report: RunReport
431
+ def __init__(self, report: RunReport) -> None: ...
432
+
433
+ @final
434
+ class PrintFunctionOutput:
435
+ function: Function
436
+ termdag: TermDag
437
+ terms: list[tuple[_Term, _Term]]
438
+ mode: _PrintFunctionMode
439
+ def __init__(
440
+ self, function: Function, termdag: TermDag, terms: list[tuple[_Term, _Term]], mode: _PrintFunctionMode
441
+ ) -> None: ...
442
+
443
+ @final
444
+ class UserDefinedOutput:
445
+ output: UserDefinedCommandOutput
446
+ def __init__(self, output: UserDefinedCommandOutput) -> None: ...
447
+
448
+ _CommandOutput: TypeAlias = (
449
+ PrintFunctionSize
450
+ | PrintAllFunctionsSize
451
+ | ExtractVariants
452
+ | ExtractBest
453
+ | OverallStatistics
454
+ | RunScheduleOutput
455
+ | PrintFunctionOutput
456
+ | UserDefinedOutput
457
+ )
458
+
459
+ ##
460
+ # Print Function Modes
461
+ ##
462
+
463
+ @final
464
+ class DefaultPrintFunctionMode: ...
465
+
466
+ @final
467
+ class CSVPrintFunctionMode: ...
468
+
469
+ _PrintFunctionMode: TypeAlias = DefaultPrintFunctionMode | CSVPrintFunctionMode
392
470
 
393
471
  ##
394
472
  # Schedules
@@ -442,12 +520,6 @@ _Subdatatypes: TypeAlias = SubVariants | NewSort
442
520
  # Commands
443
521
  ##
444
522
 
445
- @final
446
- class SetOption:
447
- name: str
448
- value: _Expr
449
- def __init__(self, name: str, value: _Expr) -> None: ...
450
-
451
523
  @final
452
524
  class Datatype:
453
525
  span: _Span
@@ -469,7 +541,7 @@ class Sort:
469
541
  def __init__(self, span: _Span, name: str, presort_and_args: tuple[str, list[_Expr]] | None = None) -> None: ...
470
542
 
471
543
  @final
472
- class Function:
544
+ class FunctionCommand:
473
545
  span: _Span
474
546
  name: str
475
547
  schema: Schema
@@ -531,8 +603,12 @@ class Check:
531
603
  class PrintFunction:
532
604
  span: _Span
533
605
  name: str
534
- length: int
535
- def __init__(self, span: _Span, name: str, length: int) -> None: ...
606
+ length: int | None
607
+ filename: str | None
608
+ mode: _PrintFunctionMode
609
+ def __init__(
610
+ self, span: _Span, name: str, length: int | None, filename: str | None, mode: _PrintFunctionMode
611
+ ) -> None: ...
536
612
 
537
613
  @final
538
614
  class PrintSize:
@@ -613,11 +689,10 @@ class UnstableCombinedRuleset:
613
689
  def __init__(self, span: _Span, name: str, rulesets: list[str]) -> None: ...
614
690
 
615
691
  _Command: TypeAlias = (
616
- SetOption
617
- | Datatype
692
+ Datatype
618
693
  | Datatypes
619
694
  | Sort
620
- | Function
695
+ | FunctionCommand
621
696
  | AddRuleset
622
697
  | RuleCommand
623
698
  | RewriteCommand
egglog/builtins.py CHANGED
@@ -91,7 +91,7 @@ class String(BuiltinExpr):
91
91
  def eval(self) -> str:
92
92
  return self.value
93
93
 
94
- @method(preserve=True) # type: ignore[misc]
94
+ @method(preserve=True) # type: ignore[prop-decorator]
95
95
  @property
96
96
  def value(self) -> str:
97
97
  if (value := get_literal_value(self)) is not None:
@@ -122,7 +122,7 @@ class Bool(BuiltinExpr, egg_sort="bool"):
122
122
  def eval(self) -> bool:
123
123
  return self.value
124
124
 
125
- @method(preserve=True) # type: ignore[misc]
125
+ @method(preserve=True) # type: ignore[prop-decorator]
126
126
  @property
127
127
  def value(self) -> bool:
128
128
  if (value := get_literal_value(self)) is not None:
@@ -165,7 +165,7 @@ class i64(BuiltinExpr): # noqa: N801
165
165
  def eval(self) -> int:
166
166
  return self.value
167
167
 
168
- @method(preserve=True) # type: ignore[misc]
168
+ @method(preserve=True) # type: ignore[prop-decorator]
169
169
  @property
170
170
  def value(self) -> int:
171
171
  if (value := get_literal_value(self)) is not None:
@@ -239,14 +239,14 @@ class i64(BuiltinExpr): # noqa: N801
239
239
  def __invert__(self) -> i64: ...
240
240
 
241
241
  @method(egg_fn="<")
242
- def __lt__(self, other: i64Like) -> Unit: # type: ignore[empty-body,has-type]
242
+ def __lt__(self, other: i64Like) -> Unit: # type: ignore[has-type]
243
243
  ...
244
244
 
245
245
  @method(egg_fn=">")
246
246
  def __gt__(self, other: i64Like) -> Unit: ...
247
247
 
248
248
  @method(egg_fn="<=")
249
- def __le__(self, other: i64Like) -> Unit: # type: ignore[empty-body,has-type]
249
+ def __le__(self, other: i64Like) -> Unit: # type: ignore[has-type]
250
250
  ...
251
251
 
252
252
  @method(egg_fn=">=")
@@ -292,7 +292,7 @@ class f64(BuiltinExpr): # noqa: N801
292
292
  def eval(self) -> float:
293
293
  return self.value
294
294
 
295
- @method(preserve=True) # type: ignore[misc]
295
+ @method(preserve=True) # type: ignore[prop-decorator]
296
296
  @property
297
297
  def value(self) -> float:
298
298
  if (value := get_literal_value(self)) is not None:
@@ -341,14 +341,14 @@ class f64(BuiltinExpr): # noqa: N801
341
341
  def __rmod__(self, other: f64Like) -> f64: ...
342
342
 
343
343
  @method(egg_fn="<")
344
- def __lt__(self, other: f64Like) -> Unit: # type: ignore[empty-body,has-type]
344
+ def __lt__(self, other: f64Like) -> Unit: # type: ignore[has-type]
345
345
  ...
346
346
 
347
347
  @method(egg_fn=">")
348
348
  def __gt__(self, other: f64Like) -> Unit: ...
349
349
 
350
350
  @method(egg_fn="<=")
351
- def __le__(self, other: f64Like) -> Unit: # type: ignore[empty-body,has-type]
351
+ def __le__(self, other: f64Like) -> Unit: # type: ignore[has-type]
352
352
  ...
353
353
 
354
354
  @method(egg_fn=">=")
@@ -387,7 +387,7 @@ class Map(BuiltinExpr, Generic[T, V]):
387
387
  def eval(self) -> dict[T, V]:
388
388
  return self.value
389
389
 
390
- @method(preserve=True) # type: ignore[misc]
390
+ @method(preserve=True) # type: ignore[prop-decorator]
391
391
  @property
392
392
  def value(self) -> dict[T, V]:
393
393
  d = {}
@@ -457,7 +457,7 @@ class Set(BuiltinExpr, Generic[T]):
457
457
  def eval(self) -> set[T]:
458
458
  return self.value
459
459
 
460
- @method(preserve=True) # type: ignore[misc]
460
+ @method(preserve=True) # type: ignore[prop-decorator]
461
461
  @property
462
462
  def value(self) -> set[T]:
463
463
  if (args := get_callable_args(self, Set[T])) is not None:
@@ -527,7 +527,7 @@ class MultiSet(BuiltinExpr, Generic[T]):
527
527
  def eval(self) -> list[T]:
528
528
  return self.value
529
529
 
530
- @method(preserve=True) # type: ignore[misc]
530
+ @method(preserve=True) # type: ignore[prop-decorator]
531
531
  @property
532
532
  def value(self) -> list[T]:
533
533
  if (args := get_callable_args(self, MultiSet[T])) is not None:
@@ -582,7 +582,7 @@ class Rational(BuiltinExpr):
582
582
  def eval(self) -> Fraction:
583
583
  return self.value
584
584
 
585
- @method(preserve=True) # type: ignore[misc]
585
+ @method(preserve=True) # type: ignore[prop-decorator]
586
586
  @property
587
587
  def value(self) -> Fraction:
588
588
  match get_callable_args(self, Rational):
@@ -651,11 +651,11 @@ class Rational(BuiltinExpr):
651
651
  @method(egg_fn="cbrt")
652
652
  def cbrt(self) -> Rational: ...
653
653
 
654
- @method(egg_fn="numer") # type: ignore[misc]
654
+ @method(egg_fn="numer") # type: ignore[prop-decorator]
655
655
  @property
656
656
  def numer(self) -> i64: ...
657
657
 
658
- @method(egg_fn="denom") # type: ignore[misc]
658
+ @method(egg_fn="denom") # type: ignore[prop-decorator]
659
659
  @property
660
660
  def denom(self) -> i64: ...
661
661
 
@@ -666,7 +666,7 @@ class BigInt(BuiltinExpr):
666
666
  def eval(self) -> int:
667
667
  return self.value
668
668
 
669
- @method(preserve=True) # type: ignore[misc]
669
+ @method(preserve=True) # type: ignore[prop-decorator]
670
670
  @property
671
671
  def value(self) -> int:
672
672
  match get_callable_args(self, BigInt.from_string):
@@ -744,14 +744,14 @@ class BigInt(BuiltinExpr):
744
744
  def bits(self) -> BigInt: ...
745
745
 
746
746
  @method(egg_fn="<")
747
- def __lt__(self, other: BigIntLike) -> Unit: # type: ignore[empty-body,has-type]
747
+ def __lt__(self, other: BigIntLike) -> Unit: # type: ignore[has-type]
748
748
  ...
749
749
 
750
750
  @method(egg_fn=">")
751
751
  def __gt__(self, other: BigIntLike) -> Unit: ...
752
752
 
753
753
  @method(egg_fn="<=")
754
- def __le__(self, other: BigIntLike) -> Unit: # type: ignore[empty-body,has-type]
754
+ def __le__(self, other: BigIntLike) -> Unit: # type: ignore[has-type]
755
755
  ...
756
756
 
757
757
  @method(egg_fn=">=")
@@ -793,7 +793,7 @@ class BigRat(BuiltinExpr):
793
793
  def eval(self) -> Fraction:
794
794
  return self.value
795
795
 
796
- @method(preserve=True) # type: ignore[misc]
796
+ @method(preserve=True) # type: ignore[prop-decorator]
797
797
  @property
798
798
  def value(self) -> Fraction:
799
799
  match get_callable_args(self, BigRat):
@@ -862,11 +862,11 @@ class BigRat(BuiltinExpr):
862
862
  @method(egg_fn="cbrt")
863
863
  def cbrt(self) -> BigRat: ...
864
864
 
865
- @method(egg_fn="numer") # type: ignore[misc]
865
+ @method(egg_fn="numer") # type: ignore[prop-decorator]
866
866
  @property
867
867
  def numer(self) -> BigInt: ...
868
868
 
869
- @method(egg_fn="denom") # type: ignore[misc]
869
+ @method(egg_fn="denom") # type: ignore[prop-decorator]
870
870
  @property
871
871
  def denom(self) -> BigInt: ...
872
872
 
@@ -893,7 +893,7 @@ class Vec(BuiltinExpr, Generic[T]):
893
893
  def eval(self) -> tuple[T, ...]:
894
894
  return self.value
895
895
 
896
- @method(preserve=True) # type: ignore[misc]
896
+ @method(preserve=True) # type: ignore[prop-decorator]
897
897
  @property
898
898
  def value(self) -> tuple[T, ...]:
899
899
  if get_callable_args(self, Vec.empty) is not None:
@@ -972,7 +972,7 @@ class PyObject(BuiltinExpr):
972
972
  def eval(self) -> object:
973
973
  return self.value
974
974
 
975
- @method(preserve=True) # type: ignore[misc]
975
+ @method(preserve=True) # type: ignore[prop-decorator]
976
976
  @property
977
977
  def value(self) -> object:
978
978
  expr = cast("RuntimeExpr", self).__egg_typed_expr__.expr
egglog/declarations.py CHANGED
@@ -69,6 +69,7 @@ __all__ = [
69
69
  "SaturateDecl",
70
70
  "ScheduleDecl",
71
71
  "SequenceDecl",
72
+ "SetCostDecl",
72
73
  "SetDecl",
73
74
  "SpecialFunctions",
74
75
  "TypeOrVarRef",
@@ -854,7 +855,14 @@ class PanicDecl:
854
855
  msg: str
855
856
 
856
857
 
857
- ActionDecl: TypeAlias = LetDecl | SetDecl | ExprActionDecl | ChangeDecl | UnionDecl | PanicDecl
858
+ @dataclass(frozen=True)
859
+ class SetCostDecl:
860
+ tp: JustTypeRef
861
+ expr: CallDecl
862
+ cost: ExprDecl
863
+
864
+
865
+ ActionDecl: TypeAlias = LetDecl | SetDecl | ExprActionDecl | ChangeDecl | UnionDecl | PanicDecl | SetCostDecl
858
866
 
859
867
 
860
868
  ##
egglog/egraph.py CHANGED
@@ -23,6 +23,7 @@ from typing import (
23
23
  get_type_hints,
24
24
  overload,
25
25
  )
26
+ from warnings import warn
26
27
 
27
28
  import graphviz
28
29
  from typing_extensions import Never, ParamSpec, Self, Unpack, assert_never
@@ -39,7 +40,7 @@ from .thunk import *
39
40
  from .version_compat import *
40
41
 
41
42
  if TYPE_CHECKING:
42
- from .builtins import String, Unit
43
+ from .builtins import String, Unit, i64Like
43
44
 
44
45
 
45
46
  __all__ = [
@@ -83,6 +84,7 @@ __all__ = [
83
84
  "run",
84
85
  "seq",
85
86
  "set_",
87
+ "set_cost",
86
88
  "subsume",
87
89
  "union",
88
90
  "unstable_combine_rulesets",
@@ -804,7 +806,7 @@ class GraphvizKwargs(TypedDict, total=False):
804
806
  max_calls_per_function: int | None
805
807
  n_inline_leaves: int
806
808
  split_primitive_outputs: bool
807
- split_functions: list[object]
809
+ split_functions: list[ExprCallable]
808
810
  include_temporary_functions: bool
809
811
 
810
812
 
@@ -851,12 +853,12 @@ class EGraph:
851
853
  """
852
854
  Loads a CSV file and sets it as *input, output of the function.
853
855
  """
854
- self._egraph.run_program(bindings.Input(span(1), self._callable_to_egg(fn), path))
856
+ self._egraph.run_program(bindings.Input(span(1), self._callable_to_egg(fn)[1], path))
855
857
 
856
- def _callable_to_egg(self, fn: object) -> str:
858
+ def _callable_to_egg(self, fn: ExprCallable) -> tuple[CallableRef, str]:
857
859
  ref, decls = resolve_callable(fn)
858
860
  self._add_decls(decls)
859
- return self._state.callable_ref_to_egg(ref)[0]
861
+ return ref, self._state.callable_ref_to_egg(ref)[0]
860
862
 
861
863
  # TODO: Change let to be action...
862
864
  def let(self, name: str, expr: BASE_EXPR) -> BASE_EXPR:
@@ -904,12 +906,17 @@ class EGraph:
904
906
  def _run_schedule(self, schedule: Schedule) -> bindings.RunReport:
905
907
  self._add_decls(schedule)
906
908
  egg_schedule = self._state.schedule_to_egg(schedule.schedule)
907
- self._egraph.run_program(bindings.RunSchedule(egg_schedule))
908
- run_report = self._egraph.run_report()
909
- if not run_report:
910
- msg = "No run report saved"
911
- raise ValueError(msg)
912
- return run_report
909
+ (command_output,) = self._egraph.run_program(bindings.RunSchedule(egg_schedule))
910
+ assert isinstance(command_output, bindings.RunScheduleOutput)
911
+ return command_output.report
912
+
913
+ def stats(self) -> bindings.RunReport:
914
+ """
915
+ Returns the overall run report for the egraph.
916
+ """
917
+ (output,) = self._egraph.run_program(bindings.PrintOverallStatistics())
918
+ assert isinstance(output, bindings.OverallStatistics)
919
+ return output.report
913
920
 
914
921
  def check_bool(self, *facts: FactLike) -> bool:
915
922
  """
@@ -954,45 +961,41 @@ class EGraph:
954
961
  """
955
962
  runtime_expr = to_runtime_expr(expr)
956
963
  extract_report = self._run_extract(runtime_expr, 0)
957
-
958
- if not isinstance(extract_report, bindings.Best):
959
- msg = "No extract report saved"
960
- raise ValueError(msg) # noqa: TRY004
961
- (new_typed_expr,) = self._state.exprs_from_egg(
962
- extract_report.termdag, [extract_report.term], runtime_expr.__egg_typed_expr__.tp
963
- )
964
-
965
- res = cast("BASE_EXPR", RuntimeExpr.__from_values__(self.__egg_decls__, new_typed_expr))
964
+ assert isinstance(extract_report, bindings.ExtractBest)
965
+ res = self._from_termdag(extract_report.termdag, extract_report.term, runtime_expr.__egg_typed_expr__.tp)
966
966
  if include_cost:
967
967
  return res, extract_report.cost
968
968
  return res
969
969
 
970
+ def _from_termdag(self, termdag: bindings.TermDag, term: bindings._Term, tp: JustTypeRef) -> Any:
971
+ (new_typed_expr,) = self._state.exprs_from_egg(termdag, [term], tp)
972
+ return RuntimeExpr.__from_values__(self.__egg_decls__, new_typed_expr)
973
+
970
974
  def extract_multiple(self, expr: BASE_EXPR, n: int) -> list[BASE_EXPR]:
971
975
  """
972
976
  Extract multiple expressions from the egraph.
973
977
  """
974
978
  runtime_expr = to_runtime_expr(expr)
975
979
  extract_report = self._run_extract(runtime_expr, n)
976
- if not isinstance(extract_report, bindings.Variants):
977
- msg = "Wrong extract report type"
978
- raise ValueError(msg) # noqa: TRY004
980
+ assert isinstance(extract_report, bindings.ExtractVariants)
979
981
  new_exprs = self._state.exprs_from_egg(
980
982
  extract_report.termdag, extract_report.terms, runtime_expr.__egg_typed_expr__.tp
981
983
  )
982
984
  return [cast("BASE_EXPR", RuntimeExpr.__from_values__(self.__egg_decls__, expr)) for expr in new_exprs]
983
985
 
984
- def _run_extract(self, expr: RuntimeExpr, n: int) -> bindings._ExtractReport:
986
+ def _run_extract(self, expr: RuntimeExpr, n: int) -> bindings._CommandOutput:
985
987
  self._add_decls(expr)
986
988
  expr = self._state.typed_expr_to_egg(expr.__egg_typed_expr__)
989
+ # If we have defined any cost tables use the custom extraction
990
+ args = (expr, bindings.Lit(span(2), bindings.Int(n)))
991
+ if self._state.cost_callables:
992
+ cmd: bindings._Command = bindings.UserDefined(span(2), "extract", list(args))
993
+ else:
994
+ cmd = bindings.Extract(span(2), *args)
987
995
  try:
988
- self._egraph.run_program(bindings.Extract(span(2), expr, bindings.Lit(span(2), bindings.Int(n))))
996
+ return self._egraph.run_program(cmd)[0]
989
997
  except BaseException as e:
990
998
  raise add_note("Extracting: " + str(expr), e) # noqa: B904
991
- extract_report = self._egraph.extract_report()
992
- if not extract_report:
993
- msg = "No extract report saved"
994
- raise ValueError(msg)
995
- return extract_report
996
999
 
997
1000
  def push(self) -> None:
998
1001
  """
@@ -1037,8 +1040,14 @@ class EGraph:
1037
1040
  max_calls_per_function=max_calls_per_function,
1038
1041
  include_temporary_functions=include_temporary_functions,
1039
1042
  )
1043
+ if serialized.discarded_functions:
1044
+ msg = ", ".join(set(self._state.possible_egglog_functions(serialized.discarded_functions)))
1045
+ warn(f"Omitted: {msg}", stacklevel=3)
1046
+ if serialized.truncated_functions:
1047
+ msg = ", ".join(set(self._state.possible_egglog_functions(serialized.truncated_functions)))
1048
+ warn(f"Truncated: {msg}", stacklevel=3)
1040
1049
  if split_primitive_outputs or split_functions:
1041
- additional_ops = set(map(self._callable_to_egg, split_functions))
1050
+ additional_ops = {self._callable_to_egg(f)[1] for f in split_functions}
1042
1051
  serialized.split_classes(self._egraph, additional_ops)
1043
1052
  serialized.map_ops(self._state.op_mapping())
1044
1053
 
@@ -1185,6 +1194,58 @@ class EGraph:
1185
1194
  assert_never(cmd)
1186
1195
  return self._state.command_to_egg(cmd_decl, ruleset_name)
1187
1196
 
1197
+ def function_size(self, fn: ExprCallable) -> int:
1198
+ """
1199
+ Returns the number of rows in a certain function
1200
+ """
1201
+ egg_name = self._callable_to_egg(fn)[1]
1202
+ (output,) = self._egraph.run_program(bindings.PrintSize(span(1), egg_name))
1203
+ assert isinstance(output, bindings.PrintFunctionSize)
1204
+ return output.size
1205
+
1206
+ def all_function_sizes(self) -> list[tuple[ExprCallable, int]]:
1207
+ """
1208
+ Returns a list of all functions and their sizes.
1209
+ """
1210
+ (output,) = self._egraph.run_program(bindings.PrintSize(span(1), None))
1211
+ assert isinstance(output, bindings.PrintAllFunctionsSize)
1212
+ return [
1213
+ (
1214
+ cast(
1215
+ "ExprCallable",
1216
+ create_callable(self._state.__egg_decls__, next(iter(refs))),
1217
+ ),
1218
+ size,
1219
+ )
1220
+ for (name, size) in output.sizes
1221
+ if (refs := self._state.egg_fn_to_callable_refs[name])
1222
+ ]
1223
+
1224
+ def function_values(
1225
+ self, fn: Callable[..., BASE_EXPR] | BASE_EXPR, length: int | None = None
1226
+ ) -> dict[BASE_EXPR, BASE_EXPR]:
1227
+ """
1228
+ Given a callable that is a "function", meaning it returns a primitive or has a merge set,
1229
+ returns a mapping of the function applied with its arguments to its values
1230
+
1231
+ If length is specified, only the first `length` values will be returned.
1232
+ """
1233
+ ref, egg_name = self._callable_to_egg(fn)
1234
+ cmd = bindings.PrintFunction(span(1), egg_name, length, None, bindings.DefaultPrintFunctionMode())
1235
+ (output,) = self._egraph.run_program(cmd)
1236
+ assert isinstance(output, bindings.PrintFunctionOutput)
1237
+ signature = self.__egg_decls__.get_callable_decl(ref).signature
1238
+ assert isinstance(signature, FunctionSignature)
1239
+ tp = signature.semantic_return_type.to_just()
1240
+ return {
1241
+ self._from_termdag(output.termdag, call, tp): self._from_termdag(output.termdag, res, tp)
1242
+ for (call, res) in output.terms
1243
+ }
1244
+
1245
+
1246
+ # Either a constant or a function.
1247
+ ExprCallable: TypeAlias = Callable[..., BaseExpr] | BaseExpr
1248
+
1188
1249
 
1189
1250
  @dataclass(frozen=True)
1190
1251
  class _WrappedMethod:
@@ -1406,10 +1467,13 @@ class Fact:
1406
1467
  """
1407
1468
  Returns True if the two sides of an equality are structurally equal.
1408
1469
  """
1409
- if not isinstance(self.fact, EqDecl):
1410
- msg = "Can only check equality facts"
1411
- raise TypeError(msg)
1412
- return self.fact.left == self.fact.right
1470
+ match self.fact:
1471
+ case EqDecl(_, left, right):
1472
+ return left == right
1473
+ case ExprFactDecl(TypedExprDecl(_, CallDecl(FunctionRef("!="), (left_tp, right_tp)))):
1474
+ return left_tp != right_tp
1475
+ msg = f"Can only check equality for == or != not {self}"
1476
+ raise ValueError(msg)
1413
1477
 
1414
1478
 
1415
1479
  @dataclass
@@ -1457,6 +1521,18 @@ def panic(message: str) -> Action:
1457
1521
  return Action(Declarations(), PanicDecl(message))
1458
1522
 
1459
1523
 
1524
+ def set_cost(expr: BaseExpr, cost: i64Like) -> Action:
1525
+ """Set the cost of the given expression."""
1526
+ from .builtins import i64 # noqa: PLC0415
1527
+
1528
+ expr_runtime = to_runtime_expr(expr)
1529
+ typed_expr_decl = expr_runtime.__egg_typed_expr__
1530
+ expr_decl = typed_expr_decl.expr
1531
+ assert isinstance(expr_decl, CallDecl), "Can only set cost of calls, not literals or vars"
1532
+ cost_decl = to_runtime_expr(convert(cost, i64)).__egg_typed_expr__.expr
1533
+ return Action(expr_runtime.__egg_decls__, SetCostDecl(typed_expr_decl.tp, expr_decl, cost_decl))
1534
+
1535
+
1460
1536
  def let(name: str, expr: BaseExpr) -> Action:
1461
1537
  """Create a let binding."""
1462
1538
  runtime_expr = to_runtime_expr(expr)
@@ -1767,7 +1843,7 @@ def _rewrite_or_rule_generator(gen: RewriteOrRuleGenerator, frame: FrameType) ->
1767
1843
  combined = {**gen.__globals__, **frame.f_locals}
1768
1844
  hints = get_type_hints(gen, combined, combined)
1769
1845
  args = [_var(p.name, hints[p.name], egg_name=None) for p in signature(gen).parameters.values()]
1770
- return list(gen(*args)) # type: ignore[misc]
1846
+ return list(gen(*args))
1771
1847
 
1772
1848
 
1773
1849
  FactLike = Fact | BaseExpr
egglog/egraph_state.py CHANGED
@@ -6,7 +6,7 @@ from __future__ import annotations
6
6
 
7
7
  import re
8
8
  from collections import defaultdict
9
- from dataclasses import dataclass, field
9
+ from dataclasses import dataclass, field, replace
10
10
  from typing import TYPE_CHECKING, Literal, overload
11
11
 
12
12
  from typing_extensions import assert_never
@@ -71,6 +71,9 @@ class EGraphState:
71
71
  # Cache of egg expressions for converting to egg
72
72
  expr_to_egg_cache: dict[ExprDecl, bindings._Expr] = field(default_factory=dict)
73
73
 
74
+ # Callables which have cost tables associated with them
75
+ cost_callables: set[CallableRef] = field(default_factory=set)
76
+
74
77
  def copy(self) -> EGraphState:
75
78
  """
76
79
  Returns a copy of the state. Th egraph reference is kept the same. Used for pushing/popping.
@@ -83,6 +86,7 @@ class EGraphState:
83
86
  callable_ref_to_egg_fn=self.callable_ref_to_egg_fn.copy(),
84
87
  type_ref_to_egg_sort=self.type_ref_to_egg_sort.copy(),
85
88
  expr_to_egg_cache=self.expr_to_egg_cache.copy(),
89
+ cost_callables=self.cost_callables.copy(),
86
90
  )
87
91
 
88
92
  def schedule_to_egg(self, schedule: ScheduleDecl) -> bindings._Schedule:
@@ -212,9 +216,32 @@ class EGraphState:
212
216
  return bindings.Union(span(), self._expr_to_egg(lhs), self._expr_to_egg(rhs))
213
217
  case PanicDecl(name):
214
218
  return bindings.Panic(span(), name)
219
+ case SetCostDecl(tp, expr, cost):
220
+ self.type_ref_to_egg(tp)
221
+ cost_table = self.create_cost_table(expr.callable)
222
+ args_egg = [self.typed_expr_to_egg(x, False) for x in expr.args]
223
+ return bindings.Set(span(), cost_table, args_egg, self._expr_to_egg(cost))
215
224
  case _:
216
225
  assert_never(action)
217
226
 
227
+ def create_cost_table(self, ref: CallableRef) -> str:
228
+ """
229
+ Creates the egg cost table if needed and gets the name of the table.
230
+ """
231
+ name = self.cost_table_name(ref)
232
+ if ref not in self.cost_callables:
233
+ self.cost_callables.add(ref)
234
+ signature = self.__egg_decls__.get_callable_decl(ref).signature
235
+ assert isinstance(signature, FunctionSignature), "Can only add cost tables for functions"
236
+ signature = replace(signature, return_type=TypeRefWithVars("i64"))
237
+ self.egraph.run_program(
238
+ bindings.FunctionCommand(span(), name, self._signature_to_egg_schema(signature), None)
239
+ )
240
+ return name
241
+
242
+ def cost_table_name(self, ref: CallableRef) -> str:
243
+ return f"cost_table_{self.callable_ref_to_egg(ref)[0]}"
244
+
218
245
  def fact_to_egg(self, fact: FactDecl) -> bindings._Fact:
219
246
  match fact:
220
247
  case EqDecl(tp, left, right):
@@ -225,7 +252,7 @@ class EGraphState:
225
252
  case _:
226
253
  assert_never(fact)
227
254
 
228
- def callable_ref_to_egg(self, ref: CallableRef) -> tuple[str, bool]:
255
+ def callable_ref_to_egg(self, ref: CallableRef) -> tuple[str, bool]: # noqa: C901, PLR0912
229
256
  """
230
257
  Returns the egg function name for a callable reference, registering it if it is not already registered.
231
258
 
@@ -245,9 +272,12 @@ class EGraphState:
245
272
  case ConstantDecl(tp, _):
246
273
  # Use constructor decleration instead of constant b/c constants cannot be extracted
247
274
  # https://github.com/egraphs-good/egglog/issues/334
248
- self.egraph.run_program(
249
- bindings.Constructor(span(), egg_name, bindings.Schema([], self.type_ref_to_egg(tp)), None, False)
250
- )
275
+ is_function = self.__egg_decls__._classes[tp.name].builtin
276
+ schema = bindings.Schema([], self.type_ref_to_egg(tp))
277
+ if is_function:
278
+ self.egraph.run_program(bindings.FunctionCommand(span(), egg_name, schema, None))
279
+ else:
280
+ self.egraph.run_program(bindings.Constructor(span(), egg_name, schema, None, False))
251
281
  case FunctionDecl(signature, builtin, _, merge):
252
282
  if isinstance(signature, FunctionSignature):
253
283
  reverse_args = signature.reverse_args
@@ -263,7 +293,7 @@ class EGraphState:
263
293
  self.egraph.run_program(bindings.Relation(span(), egg_name, schema.input))
264
294
  else:
265
295
  self.egraph.run_program(
266
- bindings.Function(
296
+ bindings.FunctionCommand(
267
297
  span(),
268
298
  egg_name,
269
299
  self._signature_to_egg_schema(signature),
@@ -347,13 +377,26 @@ class EGraphState:
347
377
  """
348
378
  Create a mapping of egglog function name to Python function name, for use in the serialized format
349
379
  for better visualization.
380
+
381
+ Includes cost tables
350
382
  """
351
383
  return {
352
384
  k: pretty_callable_ref(self.__egg_decls__, next(iter(v)))
353
385
  for k, v in self.egg_fn_to_callable_refs.items()
354
386
  if len(v) == 1
387
+ } | {
388
+ self.cost_table_name(ref): f"cost({pretty_callable_ref(self.__egg_decls__, ref, include_all_args=True)})"
389
+ for ref in self.cost_callables
355
390
  }
356
391
 
392
+ def possible_egglog_functions(self, names: list[str]) -> Iterable[str]:
393
+ """
394
+ Given a list of egglog functions, returns all the possible Python function strings
395
+ """
396
+ for name in names:
397
+ for c in self.egg_fn_to_callable_refs[name]:
398
+ yield pretty_callable_ref(self.__egg_decls__, c)
399
+
357
400
  def typed_expr_to_egg(self, typed_expr_decl: TypedExprDecl, transform_let: bool = True) -> bindings._Expr:
358
401
  # transform all expressions with multiple parents into a let binding, so that less expressions
359
402
  # are sent to egglog. Only for performance reasons.
@@ -0,0 +1,67 @@
1
+ # mypy: disable-error-code="empty-body"
2
+
3
+ """
4
+ Join Tree (custom costs)
5
+ ========================
6
+
7
+ Example of using custom cost functions for jointree.
8
+
9
+ From https://egraphs.zulipchat.com/#narrow/stream/328972-general/topic/How.20can.20I.20find.20the.20tree.20associated.20with.20an.20extraction.3F
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from egglog import *
15
+
16
+
17
+ class JoinTree(Expr):
18
+ def __init__(self, name: StringLike) -> None: ...
19
+
20
+ def join(self, other: JoinTree) -> JoinTree: ...
21
+
22
+ @method(merge=lambda old, new: old.min(new)) # type:ignore[prop-decorator]
23
+ @property
24
+ def size(self) -> i64: ...
25
+
26
+
27
+ ra = JoinTree("a")
28
+ rb = JoinTree("b")
29
+ rc = JoinTree("c")
30
+ rd = JoinTree("d")
31
+ re = JoinTree("e")
32
+ rf = JoinTree("f")
33
+
34
+ query = ra.join(rb).join(rc).join(rd).join(re).join(rf)
35
+
36
+ egraph = EGraph()
37
+ egraph.register(
38
+ set_(ra.size).to(50),
39
+ set_(rb.size).to(200),
40
+ set_(rc.size).to(10),
41
+ set_(rd.size).to(123),
42
+ set_(re.size).to(10000),
43
+ set_(rf.size).to(1),
44
+ )
45
+
46
+
47
+ @egraph.register
48
+ def _rules(s: String, a: JoinTree, b: JoinTree, c: JoinTree, asize: i64, bsize: i64):
49
+ # cost of relation is its size minus 1, since the string arg will have a cost of 1 as well
50
+ yield rule(JoinTree(s).size == asize).then(set_cost(JoinTree(s), asize - 1))
51
+ # cost/size of join is product of sizes
52
+ yield rule(a.join(b), a.size == asize, b.size == bsize).then(
53
+ set_(a.join(b).size).to(asize * bsize), set_cost(a.join(b), asize * bsize)
54
+ )
55
+ # associativity
56
+ yield rewrite(a.join(b)).to(b.join(a))
57
+ # commutativity
58
+ yield rewrite(a.join(b).join(c)).to(a.join(b.join(c)))
59
+
60
+
61
+ egraph.register(query)
62
+ egraph.run(1000)
63
+ print(egraph.extract(query))
64
+ print(egraph.extract(query.size))
65
+
66
+
67
+ egraph
egglog/exp/array_api.py CHANGED
@@ -729,7 +729,7 @@ int64 = DType.int64
729
729
  _DTYPES = [float64, float32, int32, int64, DType.object]
730
730
 
731
731
  converter(type, DType, lambda x: convert(np.dtype(x), DType))
732
- converter(type(np.dtype), DType, lambda x: getattr(DType, x.name)) # type: ignore[call-overload]
732
+ converter(type(np.dtype), DType, lambda x: getattr(DType, x.name)) # type:ignore[call-overload]
733
733
 
734
734
 
735
735
  @array_api_ruleset.register
egglog/exp/program_gen.py CHANGED
@@ -79,7 +79,7 @@ class Program(Expr):
79
79
  Triggers compilation of the program.
80
80
  """
81
81
 
82
- @method(merge=lambda old, _new: old) # type: ignore[misc]
82
+ @method(merge=lambda old, _new: old) # type: ignore[prop-decorator]
83
83
  @property
84
84
  def parent(self) -> Program:
85
85
  """
@@ -108,7 +108,7 @@ class EvalProgram(Expr):
108
108
  """
109
109
 
110
110
  # Only allow it to be set once, b/c hash of functions not stable
111
- @method(merge=lambda old, _new: old) # type: ignore[misc]
111
+ @method(merge=lambda old, _new: old) # type: ignore[prop-decorator]
112
112
  @property
113
113
  def as_py_object(self) -> PyObject:
114
114
  """
egglog/pretty.py CHANGED
@@ -98,6 +98,7 @@ def pretty_callable_ref(
98
98
  ref: CallableRef,
99
99
  first_arg: ExprDecl | None = None,
100
100
  bound_tp_params: tuple[JustTypeRef, ...] | None = None,
101
+ include_all_args: bool = False,
101
102
  ) -> str:
102
103
  """
103
104
  Pretty print a callable reference, using a dummy value for
@@ -115,6 +116,13 @@ def pretty_callable_ref(
115
116
  # Either returns a function or a function with args. If args are provided, they would just be called,
116
117
  # on the function, so return them, because they are dummies
117
118
  if isinstance(res, tuple):
119
+ # If we want to include all args as ARG_STR, then we need to figure out how many to use
120
+ # used for set_cost so that `cost(E(...))` will show up as a call
121
+ if include_all_args:
122
+ signature = decls.get_callable_decl(ref).signature
123
+ assert isinstance(signature, FunctionSignature)
124
+ correct_args: list[ExprDecl] = [UnboundVarDecl(ARG_STR)] * len(signature.arg_types)
125
+ return f"{res[0]}({', '.join(context(a, parens=False, unwrap_lit=True) for a in correct_args)})"
118
126
  return res[0]
119
127
  return res
120
128
 
@@ -190,6 +198,9 @@ class TraverseContext:
190
198
  pass
191
199
  case DefaultRewriteDecl():
192
200
  pass
201
+ case SetCostDecl(_, e, c):
202
+ self(e)
203
+ self(c)
193
204
  case _:
194
205
  assert_never(decl)
195
206
 
@@ -285,6 +296,8 @@ class PrettyContext:
285
296
  return f"{change}({self(expr)})", "action"
286
297
  case PanicDecl(s):
287
298
  return f"panic({s!r})", "action"
299
+ case SetCostDecl(_, expr, cost):
300
+ return f"set_cost({self(expr)}, {self(cost, unwrap_lit=True)})", "action"
288
301
  case EqDecl(_, left, right):
289
302
  return f"eq({self(left)}).to({self(right)})", "fact"
290
303
  case RulesetDecl(rules):
egglog/runtime.py CHANGED
@@ -20,6 +20,8 @@ from inspect import Parameter, Signature
20
20
  from itertools import zip_longest
21
21
  from typing import TYPE_CHECKING, Any, TypeVar, Union, cast, get_args, get_origin
22
22
 
23
+ from typing_extensions import assert_never
24
+
23
25
  from .declarations import *
24
26
  from .pretty import *
25
27
  from .thunk import Thunk
@@ -36,6 +38,7 @@ __all__ = [
36
38
  "RuntimeClass",
37
39
  "RuntimeExpr",
38
40
  "RuntimeFunction",
41
+ "create_callable",
39
42
  "define_expr_method",
40
43
  "resolve_callable",
41
44
  "resolve_type_annotation",
@@ -340,7 +343,7 @@ class RuntimeClass(DelayedDeclerations, metaclass=ClassFactory):
340
343
 
341
344
  # Make hashable so can go in Union
342
345
  def __hash__(self) -> int:
343
- return hash((id(self.__egg_decls_thunk__), self.__egg_tp__))
346
+ return hash(self.__egg_tp__)
344
347
 
345
348
  def __eq__(self, other: object) -> bool:
346
349
  """
@@ -478,6 +481,9 @@ class RuntimeFunction(DelayedDeclerations):
478
481
  bound_tp_params = args
479
482
  return pretty_callable_ref(self.__egg_decls__, self.__egg_ref__, first_arg, bound_tp_params)
480
483
 
484
+ def __repr__(self) -> str:
485
+ return str(self)
486
+
481
487
 
482
488
  def to_py_signature(sig: FunctionSignature, decls: Declarations, optional_args: bool) -> Signature:
483
489
  """
@@ -670,11 +676,12 @@ def resolve_callable(callable: object) -> tuple[CallableRef, Declarations]:
670
676
  """
671
677
  Resolves a runtime callable into a ref
672
678
  """
679
+ # TODO: Make runtime class work with __match_args__
680
+ if isinstance(callable, RuntimeClass):
681
+ return InitRef(callable.__egg_tp__.name), callable.__egg_decls__
673
682
  match callable:
674
683
  case RuntimeFunction(decls, ref, _):
675
684
  return ref(), decls()
676
- case RuntimeClass(thunk, tp):
677
- return InitRef(tp.name), thunk()
678
685
  case RuntimeExpr(decl_thunk, expr_thunk):
679
686
  if not isinstance((expr := expr_thunk().expr), CallDecl) or not isinstance(
680
687
  expr.callable, ConstantRef | ClassVariableRef
@@ -683,3 +690,23 @@ def resolve_callable(callable: object) -> tuple[CallableRef, Declarations]:
683
690
  return expr.callable, decl_thunk()
684
691
  case _:
685
692
  raise NotImplementedError(f"Cannot turn {callable} of type {type(callable)} into a callable ref")
693
+
694
+
695
+ def create_callable(decls: Declarations, ref: CallableRef) -> RuntimeClass | RuntimeFunction | RuntimeExpr:
696
+ """
697
+ Creates a callable object from a callable ref. This might not actually be callable, if the ref is a constant
698
+ or classvar then it is a value
699
+ """
700
+ match ref:
701
+ case InitRef(name):
702
+ return RuntimeClass(Thunk.value(decls), TypeRefWithVars(name))
703
+ case FunctionRef() | MethodRef() | ClassMethodRef() | PropertyRef() | UnnamedFunctionRef():
704
+ bound = JustTypeRef(ref.class_name) if isinstance(ref, ClassMethodRef) else None
705
+ return RuntimeFunction(Thunk.value(decls), Thunk.value(ref), bound)
706
+ case ConstantRef(name):
707
+ tp = decls._constants[name].type_ref
708
+ case ClassVariableRef(cls_name, var_name):
709
+ tp = decls._classes[cls_name].class_variables[var_name].type_ref
710
+ case _:
711
+ assert_never(ref)
712
+ return RuntimeExpr.__from_values__(decls, TypedExprDecl(tp, CallDecl(ref)))
egglog/version_compat.py CHANGED
@@ -39,7 +39,7 @@ if BEFORE_3_11:
39
39
  if isinstance(t, typevar_types) and t not in tvars:
40
40
  tvars.append(t)
41
41
  # **MONKEYPATCH CHANGE HERE TO ADD RuntimeClass**
42
- if isinstance(t, (typing._GenericAlias, typing.GenericAlias, types.UnionType, RuntimeClass)): # type: ignore[name-defined]
42
+ if isinstance(t, (typing._GenericAlias, typing.GenericAlias, types.UnionType, RuntimeClass)):
43
43
  tvars.extend([t for t in t.__parameters__ if t not in tvars])
44
44
  return tuple(tvars)
45
45
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: egglog
3
- Version: 11.0.0
3
+ Version: 11.2.0
4
4
  Classifier: Environment :: MacOS X
5
5
  Classifier: Environment :: Win32 (MS Windows)
6
6
  Classifier: Intended Audience :: Developers
@@ -1,16 +1,16 @@
1
- egglog-11.0.0.dist-info/METADATA,sha256=VH4PDa7lqn65KluCyLOf8_o72HX-CBmdxH3Wtl4jWB0,4009
2
- egglog-11.0.0.dist-info/WHEEL,sha256=UDDH43E34LzQ1QIPTshfGkhhSanOxfZ1UINGtXpGIOM,127
3
- egglog-11.0.0.dist-info/licenses/LICENSE,sha256=w7VlVv5O_FPZRo8Z-4Zb_q7D5ac3YDs8JUkMZ4Gq9CE,1070
1
+ egglog-11.2.0.dist-info/METADATA,sha256=10JQyEe0Um6WF78Wz6E6XMAi2zeAF-fT0oAlCVkBh9Q,4009
2
+ egglog-11.2.0.dist-info/WHEEL,sha256=3BYJvT1b9ENqvOQSFc1P7egl6GKTsKbcLNXqZvxSpb8,127
3
+ egglog-11.2.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-313-powerpc64-linux-gnu.so,sha256=tUaZTWpDK9Q5iqXSuuWhSutoCwPqi2KGufBt75Ubi9w,204535048
6
- egglog/bindings.pyi,sha256=QDgs0hKl2xl4Q6f7hXjfDANoMADRrGTYTdGYdri7Vqg,13642
7
- egglog/builtins.py,sha256=PdZFFc1wgDdipQkM4rnwwL7CI595oHtzcvEZYrTBQU4,30110
5
+ egglog/bindings.cpython-313-powerpc64-linux-gnu.so,sha256=dKvPTTBWDx9cDk8Y_o51lYpOZjv8LZbKEgcBw8nX-iE,168081632
6
+ egglog/bindings.pyi,sha256=Y_YpdAKmVHZ0nIHTTPeg0sigBEPiS8z_U-Z161zKSK4,15330
7
+ egglog/builtins.py,sha256=bF3GanSmsrIIutvuMUmr4SnSNF0zAEwjmDYWbPEEayo,30204
8
8
  egglog/config.py,sha256=yM3FIcVCKnhWZmHD0pxkzx7ah7t5PxZx3WUqKtA9tjU,168
9
9
  egglog/conversion.py,sha256=DO76lxRbbTqHs6hRo_Lckvtwu0c6LaKoX7k5_B2AfuY,11238
10
- egglog/declarations.py,sha256=CA8gWolJChVt6-xDL7XvV5ORjNj3O8PREobYCzVFxDI,25784
10
+ egglog/declarations.py,sha256=vBCcK94EqLDfMPasTwCQA_8EU0nVDSLfJoudboi4MgI,25920
11
11
  egglog/deconstruct.py,sha256=CovORrpROMIwOLgERPUw8doqRUDUehj6LJEB5FMbpmI,5635
12
- egglog/egraph.py,sha256=wa_lE-TiJROoeDkR3JlVKZgRQSnp1PO4szr0MgHIzg8,60623
13
- egglog/egraph_state.py,sha256=8-u0BLAHlWgoo_KiyW_aqC6nj_X0XgMFRlXWIyPjF64,28356
12
+ egglog/egraph.py,sha256=HVpHLHzHfvv1ZX7uxmsblUiEF8ZfJKkNjM-h7Cf8Zb0,64227
13
+ egglog/egraph_state.py,sha256=vIa2ACOxXMjrIS4vwA0UkY1I8hDjDUnS9Pq8awFCVfA,30515
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,6 +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
22
  egglog/examples/lambda_.py,sha256=iQvwaXVhp2VNOMS7j1WwceZaiq3dqqilwUkMcW5GFBE,8194
22
23
  egglog/examples/matrix.py,sha256=7_mPcMcgE-t_GJDyf76-nv3xhPIeN2mvFkc_p_Gnr8g,4961
23
24
  egglog/examples/multiset.py,sha256=IBOsB80DkXQ07dYnk1odi27q77LH80Z8zysuLE-Q8F8,1445
@@ -25,21 +26,21 @@ egglog/examples/ndarrays.py,sha256=mfr410eletH8gfdg-P8L90vlF6TUifvYV_-ryOwvZZE,4
25
26
  egglog/examples/resolution.py,sha256=BJd5JClA3DBVGfiVRa-H0gbbFvIqeP3uYbhCXHblSQc,2119
26
27
  egglog/examples/schedule_demo.py,sha256=JbXdPII7_adxtgyKVAiqCyV2sj88VZ-DhomYrdn8vuc,618
27
28
  egglog/exp/__init__.py,sha256=nPtzrH1bz1LVZhZCuS0S9Qild8m5gEikjOVqWAFIa88,49
28
- egglog/exp/array_api.py,sha256=B4tr5DyC8jkKxdax7k98LK-iXOrsBceSaijwYTEnG-Q,65548
29
+ egglog/exp/array_api.py,sha256=dKgEufUIyoT7J_RvnyGtOkg_DK25ZnxIgt7olVygaH8,65547
29
30
  egglog/exp/array_api_jit.py,sha256=Ak4QhmfYLKimjPf8ffUvPv62OhxOneJ9NEWQJuMxKJc,1680
30
31
  egglog/exp/array_api_loopnest.py,sha256=-kbyorlGxvlaNsLx1nmLfEZHQM7VMEBwSKtV0l-bs0g,2444
31
32
  egglog/exp/array_api_numba.py,sha256=X3H1TnCjPL92uVm6OvcWMJ11IeorAE58zWiOX6huPv4,2696
32
33
  egglog/exp/array_api_program_gen.py,sha256=qnve8iqklRQVyGChllG8ZAjAffRpezmdxc3IdaWytoQ,21779
33
- egglog/exp/program_gen.py,sha256=oLhDEFvX9neeSTWiI7pbwEBqRHuj8cXhUCpsyVNZqCw,13013
34
+ egglog/exp/program_gen.py,sha256=CavsD70x0ERS87V4OU9zkgMvLXswGEpb1ZZFK0WyN_g,13033
34
35
  egglog/exp/siu_examples.py,sha256=yZ-sgH2Y12iTdwBUumP7D2OtCGL83M6pPW7PMobVFXc,719
35
36
  egglog/ipython_magic.py,sha256=2hs3g2cSiyDmbCvE2t1OINmu17Bb8MWV--2DpEWwO7I,1189
36
- egglog/pretty.py,sha256=TCkwZIecdFT5eMIy0GGAZuKvPUt0fQeh5K1srgnCJLo,20136
37
+ egglog/pretty.py,sha256=bX1rZnujgo_oUK0QRveS5ES1hECpR665__qksUxeEKQ,20921
37
38
  egglog/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- egglog/runtime.py,sha256=8y1YQ5vFuoHr9B8LGTeQBHZin7S8LYHlsR93LlNl2uo,27979
39
+ egglog/runtime.py,sha256=NJZEE0PJGLfZMeBxhBphKFAuGPq01AaDoHOQxs3k79Y,29160
39
40
  egglog/thunk.py,sha256=MrAlPoGK36VQrUrq8PWSaJFu42sPL0yupwiH18lNips,2271
40
41
  egglog/type_constraint_solver.py,sha256=U2GjLgbebTLv5QY8_TU0As5wMKL5_NxkHLen9rpfMwI,4518
41
- egglog/version_compat.py,sha256=T1lHCmTIgGbuLcv7e6JWPxntVSSDsgxRPIq2NpKZe0I,3542
42
+ egglog/version_compat.py,sha256=EaKRMIOPcatrx9XjCofxZD6Nr5WOooiWNdoapkKleww,3512
42
43
  egglog/visualizer.css,sha256=eL0POoThQRc0P4OYnDT-d808ln9O5Qy6DizH9Z5LgWc,259398
43
44
  egglog/visualizer.js,sha256=2qZZ-9W_INJx4gZMYjnVXl27IjT_JNuQyEeI2dbjWoU,3753315
44
45
  egglog/visualizer_widget.py,sha256=LtVfzOtv2WeKtNuILQQ_9SOHWvRr8YdBYQDKQSgry_s,1319
45
- egglog-11.0.0.dist-info/RECORD,,
46
+ egglog-11.2.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: maturin (1.9.3)
2
+ Generator: maturin (1.9.4)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp313-cp313-manylinux_2_17_ppc64.manylinux2014_ppc64