egglog 12.0.0__cp313-cp313t-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.
Files changed (48) hide show
  1. egglog/__init__.py +13 -0
  2. egglog/bindings.cpython-313t-powerpc64-linux-gnu.so +0 -0
  3. egglog/bindings.pyi +887 -0
  4. egglog/builtins.py +1144 -0
  5. egglog/config.py +8 -0
  6. egglog/conversion.py +290 -0
  7. egglog/declarations.py +964 -0
  8. egglog/deconstruct.py +176 -0
  9. egglog/egraph.py +2247 -0
  10. egglog/egraph_state.py +978 -0
  11. egglog/examples/README.rst +5 -0
  12. egglog/examples/__init__.py +3 -0
  13. egglog/examples/bignum.py +32 -0
  14. egglog/examples/bool.py +38 -0
  15. egglog/examples/eqsat_basic.py +44 -0
  16. egglog/examples/fib.py +28 -0
  17. egglog/examples/higher_order_functions.py +42 -0
  18. egglog/examples/jointree.py +64 -0
  19. egglog/examples/lambda_.py +287 -0
  20. egglog/examples/matrix.py +175 -0
  21. egglog/examples/multiset.py +60 -0
  22. egglog/examples/ndarrays.py +144 -0
  23. egglog/examples/resolution.py +84 -0
  24. egglog/examples/schedule_demo.py +34 -0
  25. egglog/exp/MoA.ipynb +617 -0
  26. egglog/exp/__init__.py +3 -0
  27. egglog/exp/any_expr.py +947 -0
  28. egglog/exp/any_expr_example.ipynb +408 -0
  29. egglog/exp/array_api.py +2019 -0
  30. egglog/exp/array_api_jit.py +51 -0
  31. egglog/exp/array_api_loopnest.py +74 -0
  32. egglog/exp/array_api_numba.py +69 -0
  33. egglog/exp/array_api_program_gen.py +510 -0
  34. egglog/exp/program_gen.py +427 -0
  35. egglog/exp/siu_examples.py +32 -0
  36. egglog/ipython_magic.py +41 -0
  37. egglog/pretty.py +566 -0
  38. egglog/py.typed +0 -0
  39. egglog/runtime.py +888 -0
  40. egglog/thunk.py +97 -0
  41. egglog/type_constraint_solver.py +111 -0
  42. egglog/visualizer.css +1 -0
  43. egglog/visualizer.js +35798 -0
  44. egglog/visualizer_widget.py +39 -0
  45. egglog-12.0.0.dist-info/METADATA +93 -0
  46. egglog-12.0.0.dist-info/RECORD +48 -0
  47. egglog-12.0.0.dist-info/WHEEL +5 -0
  48. egglog-12.0.0.dist-info/licenses/LICENSE +21 -0
egglog/builtins.py ADDED
@@ -0,0 +1,1144 @@
1
+ # mypy: disable-error-code="empty-body"
2
+ """
3
+ Builtin sorts and function to egg.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from collections.abc import Callable
9
+ from dataclasses import dataclass
10
+ from fractions import Fraction
11
+ from functools import partial, reduce
12
+ from inspect import signature
13
+ from types import FunctionType, MethodType
14
+ from typing import TYPE_CHECKING, Generic, Protocol, TypeAlias, TypeVar, cast, overload
15
+
16
+ import cloudpickle
17
+ from typing_extensions import TypeVarTuple, Unpack, deprecated
18
+
19
+ from .conversion import convert, converter, get_type_args, resolve_literal
20
+ from .declarations import *
21
+ from .deconstruct import get_callable_args, get_literal_value
22
+ from .egraph import BaseExpr, BuiltinExpr, _add_default_rewrite_inner, expr_fact, function, get_current_ruleset, method
23
+ from .runtime import RuntimeExpr, RuntimeFunction, resolve_type_annotation_mutate
24
+ from .thunk import Thunk
25
+
26
+ if TYPE_CHECKING:
27
+ from collections.abc import Iterator
28
+
29
+
30
+ __all__ = [
31
+ "BigInt",
32
+ "BigIntLike",
33
+ "BigRat",
34
+ "BigRatLike",
35
+ "Bool",
36
+ "BoolLike",
37
+ "Container",
38
+ "ExprValueError",
39
+ "Map",
40
+ "MapLike",
41
+ "MultiSet",
42
+ "Primitive",
43
+ "PyObject",
44
+ "Rational",
45
+ "Set",
46
+ "SetLike",
47
+ "String",
48
+ "StringLike",
49
+ "Unit",
50
+ "UnstableFn",
51
+ "Vec",
52
+ "VecLike",
53
+ "f64",
54
+ "f64Like",
55
+ "i64",
56
+ "i64Like",
57
+ "join",
58
+ "py_eval",
59
+ "py_eval_fn",
60
+ "py_exec",
61
+ ]
62
+
63
+
64
+ @dataclass
65
+ class ExprValueError(AttributeError):
66
+ """
67
+ Raised when an expression cannot be converted to a Python value because the value is not a constructor.
68
+ """
69
+
70
+ expr: BaseExpr
71
+ allowed: str
72
+
73
+ def __str__(self) -> str:
74
+ return f"Cannot get Python value of {self.expr}, must be of form {self.allowed}. Try calling `extract` on it to get the underlying value."
75
+
76
+
77
+ class Unit(BuiltinExpr, egg_sort="Unit"):
78
+ """
79
+ The unit type. This is used to reprsent if a value exists in the e-graph or not.
80
+ """
81
+
82
+ def __init__(self) -> None: ...
83
+
84
+ @method(preserve=True)
85
+ def __bool__(self) -> bool:
86
+ return bool(expr_fact(self))
87
+
88
+
89
+ class String(BuiltinExpr, egg_sort="String"):
90
+ def __init__(self, value: str) -> None: ...
91
+
92
+ @method(preserve=True)
93
+ @deprecated("use .value")
94
+ def eval(self) -> str:
95
+ return self.value
96
+
97
+ @method(preserve=True) # type: ignore[prop-decorator]
98
+ @property
99
+ def value(self) -> str:
100
+ if (value := get_literal_value(self)) is not None:
101
+ return value
102
+ raise ExprValueError(self, "String")
103
+
104
+ __match_args__ = ("value",)
105
+
106
+ @method(egg_fn="replace")
107
+ def replace(self, old: StringLike, new: StringLike) -> String: ...
108
+
109
+ @method(preserve=True)
110
+ def __add__(self, other: StringLike) -> String:
111
+ return join(self, other)
112
+
113
+
114
+ StringLike: TypeAlias = String | str
115
+
116
+
117
+ @function(egg_fn="+", builtin=True)
118
+ def join(*strings: StringLike) -> String: ...
119
+
120
+
121
+ converter(str, String, String)
122
+
123
+
124
+ class Bool(BuiltinExpr, egg_sort="bool"):
125
+ def __init__(self, value: bool) -> None: ...
126
+
127
+ @method(preserve=True)
128
+ @deprecated("use .value")
129
+ def eval(self) -> bool:
130
+ return self.value
131
+
132
+ @method(preserve=True) # type: ignore[prop-decorator]
133
+ @property
134
+ def value(self) -> bool:
135
+ if (value := get_literal_value(self)) is not None:
136
+ return value
137
+ raise ExprValueError(self, "Bool")
138
+
139
+ __match_args__ = ("value",)
140
+
141
+ @method(preserve=True)
142
+ def __bool__(self) -> bool:
143
+ return self.value
144
+
145
+ @method(egg_fn="not")
146
+ def __invert__(self) -> Bool: ...
147
+
148
+ @method(egg_fn="and")
149
+ def __and__(self, other: BoolLike) -> Bool: ...
150
+
151
+ @method(egg_fn="or")
152
+ def __or__(self, other: BoolLike) -> Bool: ...
153
+
154
+ @method(egg_fn="xor")
155
+ def __xor__(self, other: BoolLike) -> Bool: ...
156
+
157
+ @method(egg_fn="=>")
158
+ def implies(self, other: BoolLike) -> Bool: ...
159
+
160
+
161
+ BoolLike: TypeAlias = Bool | bool
162
+
163
+
164
+ converter(bool, Bool, Bool)
165
+
166
+
167
+ class i64(BuiltinExpr, egg_sort="i64"): # noqa: N801
168
+ def __init__(self, value: int) -> None: ...
169
+
170
+ @method(preserve=True)
171
+ @deprecated("use .value")
172
+ def eval(self) -> int:
173
+ return self.value
174
+
175
+ @method(preserve=True) # type: ignore[prop-decorator]
176
+ @property
177
+ def value(self) -> int:
178
+ if (value := get_literal_value(self)) is not None:
179
+ return value
180
+ raise ExprValueError(self, "i64")
181
+
182
+ __match_args__ = ("value",)
183
+
184
+ @method(preserve=True)
185
+ def __index__(self) -> int:
186
+ return self.value
187
+
188
+ @method(preserve=True)
189
+ def __int__(self) -> int:
190
+ return self.value
191
+
192
+ @method(egg_fn="+")
193
+ def __add__(self, other: i64Like) -> i64: ...
194
+
195
+ @method(egg_fn="-")
196
+ def __sub__(self, other: i64Like) -> i64: ...
197
+
198
+ @method(egg_fn="*")
199
+ def __mul__(self, other: i64Like) -> i64: ...
200
+
201
+ @method(egg_fn="/")
202
+ def __truediv__(self, other: i64Like) -> i64: ...
203
+
204
+ @method(egg_fn="%")
205
+ def __mod__(self, other: i64Like) -> i64: ...
206
+
207
+ @method(egg_fn="&")
208
+ def __and__(self, other: i64Like) -> i64: ...
209
+
210
+ @method(egg_fn="|")
211
+ def __or__(self, other: i64Like) -> i64: ...
212
+
213
+ @method(egg_fn="^")
214
+ def __xor__(self, other: i64Like) -> i64: ...
215
+
216
+ @method(egg_fn="<<")
217
+ def __lshift__(self, other: i64Like) -> i64: ...
218
+
219
+ @method(egg_fn=">>")
220
+ def __rshift__(self, other: i64Like) -> i64: ...
221
+
222
+ def __radd__(self, other: i64Like) -> i64: ...
223
+
224
+ def __rsub__(self, other: i64Like) -> i64: ...
225
+
226
+ def __rmul__(self, other: i64Like) -> i64: ...
227
+
228
+ def __rtruediv__(self, other: i64Like) -> i64: ...
229
+
230
+ def __rmod__(self, other: i64Like) -> i64: ...
231
+
232
+ def __rand__(self, other: i64Like) -> i64: ...
233
+
234
+ def __ror__(self, other: i64Like) -> i64: ...
235
+
236
+ def __rxor__(self, other: i64Like) -> i64: ...
237
+
238
+ def __rlshift__(self, other: i64Like) -> i64: ...
239
+
240
+ def __rrshift__(self, other: i64Like) -> i64: ...
241
+
242
+ @method(egg_fn="log2")
243
+ def log2(self) -> i64: ...
244
+
245
+ @method(egg_fn="not-i64")
246
+ def __invert__(self) -> i64: ...
247
+
248
+ @method(egg_fn="<")
249
+ def __lt__(self, other: i64Like) -> Unit: # type: ignore[has-type]
250
+ ...
251
+
252
+ @method(egg_fn=">")
253
+ def __gt__(self, other: i64Like) -> Unit: ...
254
+
255
+ @method(egg_fn="<=")
256
+ def __le__(self, other: i64Like) -> Unit: # type: ignore[has-type]
257
+ ...
258
+
259
+ @method(egg_fn=">=")
260
+ def __ge__(self, other: i64Like) -> Unit: ...
261
+
262
+ @method(egg_fn="min")
263
+ def min(self, other: i64Like) -> i64: ...
264
+
265
+ @method(egg_fn="max")
266
+ def max(self, other: i64Like) -> i64: ...
267
+
268
+ @method(egg_fn="to-string")
269
+ def to_string(self) -> String: ...
270
+
271
+ @method(egg_fn="bool-<")
272
+ def bool_lt(self, other: i64Like) -> Bool: ...
273
+
274
+ @method(egg_fn="bool->")
275
+ def bool_gt(self, other: i64Like) -> Bool: ...
276
+
277
+ @method(egg_fn="bool-<=")
278
+ def bool_le(self, other: i64Like) -> Bool: ...
279
+
280
+ @method(egg_fn="bool->=")
281
+ def bool_ge(self, other: i64Like) -> Bool: ...
282
+
283
+
284
+ # The types which can be convertered into an i64
285
+ i64Like: TypeAlias = i64 | int # noqa: N816, PYI042
286
+
287
+ converter(int, i64, i64)
288
+
289
+
290
+ @function(builtin=True, egg_fn="count-matches")
291
+ def count_matches(s: StringLike, pattern: StringLike) -> i64: ...
292
+
293
+
294
+ class f64(BuiltinExpr, egg_sort="f64"): # noqa: N801
295
+ def __init__(self, value: float) -> None: ...
296
+
297
+ @method(preserve=True)
298
+ @deprecated("use .value")
299
+ def eval(self) -> float:
300
+ return self.value
301
+
302
+ @method(preserve=True) # type: ignore[prop-decorator]
303
+ @property
304
+ def value(self) -> float:
305
+ if (value := get_literal_value(self)) is not None:
306
+ return value
307
+ raise ExprValueError(self, "f64")
308
+
309
+ __match_args__ = ("value",)
310
+
311
+ @method(preserve=True)
312
+ def __float__(self) -> float:
313
+ return self.value
314
+
315
+ @method(preserve=True)
316
+ def __int__(self) -> int:
317
+ return int(self.value)
318
+
319
+ @method(egg_fn="neg")
320
+ def __neg__(self) -> f64: ...
321
+
322
+ @method(egg_fn="+")
323
+ def __add__(self, other: f64Like) -> f64: ...
324
+
325
+ @method(egg_fn="-")
326
+ def __sub__(self, other: f64Like) -> f64: ...
327
+
328
+ @method(egg_fn="*")
329
+ def __mul__(self, other: f64Like) -> f64: ...
330
+
331
+ @method(egg_fn="/")
332
+ def __truediv__(self, other: f64Like) -> f64: ...
333
+
334
+ @method(egg_fn="%")
335
+ def __mod__(self, other: f64Like) -> f64: ...
336
+
337
+ @method(egg_fn="^")
338
+ def __pow__(self, other: f64Like) -> f64: ...
339
+
340
+ def __radd__(self, other: f64Like) -> f64: ...
341
+
342
+ def __rsub__(self, other: f64Like) -> f64: ...
343
+
344
+ def __rmul__(self, other: f64Like) -> f64: ...
345
+
346
+ def __rtruediv__(self, other: f64Like) -> f64: ...
347
+
348
+ def __rmod__(self, other: f64Like) -> f64: ...
349
+
350
+ @method(egg_fn="<")
351
+ def __lt__(self, other: f64Like) -> Unit: # type: ignore[has-type]
352
+ ...
353
+
354
+ @method(egg_fn=">")
355
+ def __gt__(self, other: f64Like) -> Unit: ...
356
+
357
+ @method(egg_fn="<=")
358
+ def __le__(self, other: f64Like) -> Unit: # type: ignore[has-type]
359
+ ...
360
+
361
+ @method(egg_fn=">=")
362
+ def __ge__(self, other: f64Like) -> Unit: ...
363
+
364
+ @method(egg_fn="min")
365
+ def min(self, other: f64Like) -> f64: ...
366
+
367
+ @method(egg_fn="max")
368
+ def max(self, other: f64Like) -> f64: ...
369
+
370
+ @method(egg_fn="to-i64")
371
+ def to_i64(self) -> i64: ...
372
+
373
+ @method(egg_fn="to-f64")
374
+ @classmethod
375
+ def from_i64(cls, i: i64) -> f64: ...
376
+
377
+ @method(egg_fn="to-string")
378
+ def to_string(self) -> String: ...
379
+
380
+
381
+ f64Like: TypeAlias = f64 | float # noqa: N816, PYI042
382
+
383
+
384
+ converter(float, f64, f64)
385
+
386
+
387
+ T = TypeVar("T", bound=BaseExpr)
388
+ V = TypeVar("V", bound=BaseExpr)
389
+
390
+
391
+ class Map(BuiltinExpr, Generic[T, V], egg_sort="Map"):
392
+ @method(preserve=True)
393
+ @deprecated("use .value")
394
+ def eval(self) -> dict[T, V]:
395
+ return self.value
396
+
397
+ @method(preserve=True) # type: ignore[prop-decorator]
398
+ @property
399
+ def value(self) -> dict[T, V]:
400
+ d = {}
401
+ while args := get_callable_args(self, Map[T, V].insert):
402
+ self, k, v = args # noqa: PLW0642
403
+ d[k] = v
404
+ if get_callable_args(self, Map.empty) is None:
405
+ raise ExprValueError(self, "Map.empty or Map.insert")
406
+ return d
407
+
408
+ __match_args__ = ("value",)
409
+
410
+ @method(preserve=True)
411
+ def __iter__(self) -> Iterator[T]:
412
+ return iter(self.value)
413
+
414
+ @method(preserve=True)
415
+ def __len__(self) -> int:
416
+ return len(self.value)
417
+
418
+ @method(preserve=True)
419
+ def __contains__(self, key: T) -> bool:
420
+ return key in self.value
421
+
422
+ @method(egg_fn="map-empty")
423
+ @classmethod
424
+ def empty(cls) -> Map[T, V]: ...
425
+
426
+ @method(egg_fn="map-insert")
427
+ def insert(self, key: T, value: V) -> Map[T, V]: ...
428
+
429
+ @method(egg_fn="map-get")
430
+ def __getitem__(self, key: T) -> V: ...
431
+
432
+ @method(egg_fn="map-not-contains")
433
+ def not_contains(self, key: T) -> Unit: ...
434
+
435
+ @method(egg_fn="map-contains")
436
+ def contains(self, key: T) -> Unit: ...
437
+
438
+ @method(egg_fn="map-remove")
439
+ def remove(self, key: T) -> Map[T, V]: ...
440
+
441
+ @method(egg_fn="rebuild")
442
+ def rebuild(self) -> Map[T, V]: ...
443
+
444
+
445
+ TO = TypeVar("TO")
446
+ VO = TypeVar("VO")
447
+
448
+ converter(
449
+ dict,
450
+ Map,
451
+ lambda t: reduce(
452
+ (lambda acc, kv: acc.insert(convert(kv[0], get_type_args()[0]), convert(kv[1], get_type_args()[1]))),
453
+ t.items(),
454
+ Map[get_type_args()].empty(), # type: ignore[misc]
455
+ ),
456
+ )
457
+
458
+ MapLike: TypeAlias = Map[T, V] | dict[TO, VO]
459
+
460
+
461
+ class Set(BuiltinExpr, Generic[T], egg_sort="Set"):
462
+ @method(preserve=True)
463
+ @deprecated("use .value")
464
+ def eval(self) -> set[T]:
465
+ return self.value
466
+
467
+ @method(preserve=True) # type: ignore[prop-decorator]
468
+ @property
469
+ def value(self) -> set[T]:
470
+ if (args := get_callable_args(self, Set[T])) is not None:
471
+ return set(args)
472
+ raise ExprValueError(self, "Set(*xs)")
473
+
474
+ __match_args__ = ("value",)
475
+
476
+ @method(preserve=True)
477
+ def __iter__(self) -> Iterator[T]:
478
+ return iter(self.value)
479
+
480
+ @method(preserve=True)
481
+ def __len__(self) -> int:
482
+ return len(self.value)
483
+
484
+ @method(preserve=True)
485
+ def __contains__(self, key: T) -> bool:
486
+ return key in self.value
487
+
488
+ @method(egg_fn="set-of")
489
+ def __init__(self, *args: T) -> None: ...
490
+
491
+ @method(egg_fn="set-empty")
492
+ @classmethod
493
+ def empty(cls) -> Set[T]: ...
494
+
495
+ @method(egg_fn="set-insert")
496
+ def insert(self, value: T) -> Set[T]: ...
497
+
498
+ @method(egg_fn="set-not-contains")
499
+ def not_contains(self, value: T) -> Unit: ...
500
+
501
+ @method(egg_fn="set-contains")
502
+ def contains(self, value: T) -> Unit: ...
503
+
504
+ @method(egg_fn="set-remove")
505
+ def remove(self, value: T) -> Set[T]: ...
506
+
507
+ @method(egg_fn="set-union")
508
+ def __or__(self, other: Set[T]) -> Set[T]: ...
509
+
510
+ @method(egg_fn="set-diff")
511
+ def __sub__(self, other: Set[T]) -> Set[T]: ...
512
+
513
+ @method(egg_fn="set-intersect")
514
+ def __and__(self, other: Set[T]) -> Set[T]: ...
515
+
516
+ @method(egg_fn="rebuild")
517
+ def rebuild(self) -> Set[T]: ...
518
+
519
+
520
+ converter(
521
+ set,
522
+ Set,
523
+ lambda t: Set[get_type_args()[0]]( # type: ignore[misc,operator]
524
+ *(convert(x, get_type_args()[0]) for x in t)
525
+ ),
526
+ )
527
+
528
+ SetLike: TypeAlias = Set[T] | set[TO]
529
+
530
+
531
+ class MultiSet(BuiltinExpr, Generic[T], egg_sort="MultiSet"):
532
+ @method(preserve=True)
533
+ @deprecated("use .value")
534
+ def eval(self) -> list[T]:
535
+ return self.value
536
+
537
+ @method(preserve=True) # type: ignore[prop-decorator]
538
+ @property
539
+ def value(self) -> list[T]:
540
+ if (args := get_callable_args(self, MultiSet[T])) is not None:
541
+ return list(args)
542
+ raise ExprValueError(self, "MultiSet")
543
+
544
+ __match_args__ = ("value",)
545
+
546
+ @method(preserve=True)
547
+ def __iter__(self) -> Iterator[T]:
548
+ return iter(self.value)
549
+
550
+ @method(preserve=True)
551
+ def __len__(self) -> int:
552
+ return len(self.value)
553
+
554
+ @method(preserve=True)
555
+ def __contains__(self, key: T) -> bool:
556
+ return key in self.value
557
+
558
+ @method(egg_fn="multiset-of")
559
+ def __init__(self, *args: T) -> None: ...
560
+
561
+ @method(egg_fn="multiset-insert")
562
+ def insert(self, value: T) -> MultiSet[T]: ...
563
+
564
+ @method(egg_fn="multiset-not-contains")
565
+ def not_contains(self, value: T) -> Unit: ...
566
+
567
+ @method(egg_fn="multiset-contains")
568
+ def contains(self, value: T) -> Unit: ...
569
+
570
+ @method(egg_fn="multiset-remove")
571
+ def remove(self, value: T) -> MultiSet[T]: ...
572
+
573
+ @method(egg_fn="multiset-length")
574
+ def length(self) -> i64: ...
575
+
576
+ @method(egg_fn="multiset-pick")
577
+ def pick(self) -> T: ...
578
+
579
+ @method(egg_fn="multiset-sum")
580
+ def __add__(self, other: MultiSet[T]) -> MultiSet[T]: ...
581
+
582
+ @method(egg_fn="unstable-multiset-map", reverse_args=True)
583
+ def map(self, f: Callable[[T], T]) -> MultiSet[T]: ...
584
+
585
+
586
+ class Rational(BuiltinExpr, egg_sort="Rational"):
587
+ @method(preserve=True)
588
+ @deprecated("use .value")
589
+ def eval(self) -> Fraction:
590
+ return self.value
591
+
592
+ @method(preserve=True) # type: ignore[prop-decorator]
593
+ @property
594
+ def value(self) -> Fraction:
595
+ match get_callable_args(self, Rational):
596
+ case (i64(num), i64(den)):
597
+ return Fraction(num, den)
598
+ raise ExprValueError(self, "Rational(i64(num), i64(den))")
599
+
600
+ __match_args__ = ("value",)
601
+
602
+ @method(preserve=True)
603
+ def __float__(self) -> float:
604
+ return float(self.value)
605
+
606
+ @method(preserve=True)
607
+ def __int__(self) -> int:
608
+ return int(self.value)
609
+
610
+ @method(egg_fn="rational")
611
+ def __init__(self, num: i64Like, den: i64Like) -> None: ...
612
+
613
+ @method(egg_fn="to-f64")
614
+ def to_f64(self) -> f64: ...
615
+
616
+ @method(egg_fn="+")
617
+ def __add__(self, other: Rational) -> Rational: ...
618
+
619
+ @method(egg_fn="-")
620
+ def __sub__(self, other: Rational) -> Rational: ...
621
+
622
+ @method(egg_fn="*")
623
+ def __mul__(self, other: Rational) -> Rational: ...
624
+
625
+ @method(egg_fn="/")
626
+ def __truediv__(self, other: Rational) -> Rational: ...
627
+
628
+ @method(egg_fn="min")
629
+ def min(self, other: Rational) -> Rational: ...
630
+
631
+ @method(egg_fn="max")
632
+ def max(self, other: Rational) -> Rational: ...
633
+
634
+ @method(egg_fn="neg")
635
+ def __neg__(self) -> Rational: ...
636
+
637
+ @method(egg_fn="abs")
638
+ def __abs__(self) -> Rational: ...
639
+
640
+ @method(egg_fn="floor")
641
+ def floor(self) -> Rational: ...
642
+
643
+ @method(egg_fn="ceil")
644
+ def ceil(self) -> Rational: ...
645
+
646
+ @method(egg_fn="round")
647
+ def round(self) -> Rational: ...
648
+
649
+ @method(egg_fn="pow")
650
+ def __pow__(self, other: Rational) -> Rational: ...
651
+
652
+ @method(egg_fn="log")
653
+ def log(self) -> Rational: ...
654
+
655
+ @method(egg_fn="sqrt")
656
+ def sqrt(self) -> Rational: ...
657
+
658
+ @method(egg_fn="cbrt")
659
+ def cbrt(self) -> Rational: ...
660
+
661
+ @method(egg_fn="numer") # type: ignore[prop-decorator]
662
+ @property
663
+ def numer(self) -> i64: ...
664
+
665
+ @method(egg_fn="denom") # type: ignore[prop-decorator]
666
+ @property
667
+ def denom(self) -> i64: ...
668
+
669
+
670
+ class BigInt(BuiltinExpr, egg_sort="BigInt"):
671
+ @method(preserve=True)
672
+ @deprecated("use .value")
673
+ def eval(self) -> int:
674
+ return self.value
675
+
676
+ @method(preserve=True) # type: ignore[prop-decorator]
677
+ @property
678
+ def value(self) -> int:
679
+ match get_callable_args(self, BigInt.from_string):
680
+ case (String(s),):
681
+ return int(s)
682
+ raise ExprValueError(self, "BigInt.from_string(String(s))")
683
+
684
+ __match_args__ = ("value",)
685
+
686
+ @method(preserve=True)
687
+ def __index__(self) -> int:
688
+ return self.value
689
+
690
+ @method(preserve=True)
691
+ def __int__(self) -> int:
692
+ return self.value
693
+
694
+ @method(egg_fn="from-string")
695
+ @classmethod
696
+ def from_string(cls, s: StringLike) -> BigInt: ...
697
+
698
+ @method(egg_fn="bigint")
699
+ def __init__(self, value: i64Like) -> None: ...
700
+
701
+ @method(egg_fn="+")
702
+ def __add__(self, other: BigIntLike) -> BigInt: ...
703
+
704
+ @method(egg_fn="-")
705
+ def __sub__(self, other: BigIntLike) -> BigInt: ...
706
+
707
+ @method(egg_fn="*")
708
+ def __mul__(self, other: BigIntLike) -> BigInt: ...
709
+
710
+ @method(egg_fn="/")
711
+ def __truediv__(self, other: BigIntLike) -> BigInt: ...
712
+
713
+ @method(egg_fn="%")
714
+ def __mod__(self, other: BigIntLike) -> BigInt: ...
715
+
716
+ @method(egg_fn="&")
717
+ def __and__(self, other: BigIntLike) -> BigInt: ...
718
+
719
+ @method(egg_fn="|")
720
+ def __or__(self, other: BigIntLike) -> BigInt: ...
721
+
722
+ @method(egg_fn="^")
723
+ def __xor__(self, other: BigIntLike) -> BigInt: ...
724
+
725
+ @method(egg_fn="<<")
726
+ def __lshift__(self, other: i64Like) -> BigInt: ...
727
+
728
+ @method(egg_fn=">>")
729
+ def __rshift__(self, other: i64Like) -> BigInt: ...
730
+
731
+ def __radd__(self, other: BigIntLike) -> BigInt: ...
732
+
733
+ def __rsub__(self, other: BigIntLike) -> BigInt: ...
734
+
735
+ def __rmul__(self, other: BigIntLike) -> BigInt: ...
736
+
737
+ def __rtruediv__(self, other: BigIntLike) -> BigInt: ...
738
+
739
+ def __rmod__(self, other: BigIntLike) -> BigInt: ...
740
+
741
+ def __rand__(self, other: BigIntLike) -> BigInt: ...
742
+
743
+ def __ror__(self, other: BigIntLike) -> BigInt: ...
744
+
745
+ def __rxor__(self, other: BigIntLike) -> BigInt: ...
746
+
747
+ @method(egg_fn="not-Z")
748
+ def __invert__(self) -> BigInt: ...
749
+
750
+ @method(egg_fn="bits")
751
+ def bits(self) -> BigInt: ...
752
+
753
+ @method(egg_fn="<")
754
+ def __lt__(self, other: BigIntLike) -> Unit: # type: ignore[has-type]
755
+ ...
756
+
757
+ @method(egg_fn=">")
758
+ def __gt__(self, other: BigIntLike) -> Unit: ...
759
+
760
+ @method(egg_fn="<=")
761
+ def __le__(self, other: BigIntLike) -> Unit: # type: ignore[has-type]
762
+ ...
763
+
764
+ @method(egg_fn=">=")
765
+ def __ge__(self, other: BigIntLike) -> Unit: ...
766
+
767
+ @method(egg_fn="min")
768
+ def min(self, other: BigIntLike) -> BigInt: ...
769
+
770
+ @method(egg_fn="max")
771
+ def max(self, other: BigIntLike) -> BigInt: ...
772
+
773
+ @method(egg_fn="to-string")
774
+ def to_string(self) -> String: ...
775
+
776
+ @method(egg_fn="bool-=")
777
+ def bool_eq(self, other: BigIntLike) -> Bool: ...
778
+
779
+ @method(egg_fn="bool-<")
780
+ def bool_lt(self, other: BigIntLike) -> Bool: ...
781
+
782
+ @method(egg_fn="bool->")
783
+ def bool_gt(self, other: BigIntLike) -> Bool: ...
784
+
785
+ @method(egg_fn="bool-<=")
786
+ def bool_le(self, other: BigIntLike) -> Bool: ...
787
+
788
+ @method(egg_fn="bool->=")
789
+ def bool_ge(self, other: BigIntLike) -> Bool: ...
790
+
791
+
792
+ converter(i64, BigInt, lambda i: BigInt(i))
793
+
794
+ BigIntLike: TypeAlias = BigInt | i64Like
795
+
796
+
797
+ class BigRat(BuiltinExpr, egg_sort="BigRat"):
798
+ @method(preserve=True)
799
+ @deprecated("use .value")
800
+ def eval(self) -> Fraction:
801
+ return self.value
802
+
803
+ @method(preserve=True) # type: ignore[prop-decorator]
804
+ @property
805
+ def value(self) -> Fraction:
806
+ match get_callable_args(self, BigRat):
807
+ case (BigInt(num), BigInt(den)):
808
+ return Fraction(num, den)
809
+ raise ExprValueError(self, "BigRat(BigInt(num), BigInt(den))")
810
+
811
+ __match_args__ = ("value",)
812
+
813
+ @method(preserve=True)
814
+ def __float__(self) -> float:
815
+ return float(self.value)
816
+
817
+ @method(preserve=True)
818
+ def __int__(self) -> int:
819
+ return int(self.value)
820
+
821
+ @method(egg_fn="bigrat")
822
+ def __init__(self, num: BigIntLike, den: BigIntLike) -> None: ...
823
+
824
+ @method(egg_fn="to-f64")
825
+ def to_f64(self) -> f64: ...
826
+
827
+ @method(egg_fn="+")
828
+ def __add__(self, other: BigRatLike) -> BigRat: ...
829
+
830
+ @method(egg_fn="-")
831
+ def __sub__(self, other: BigRatLike) -> BigRat: ...
832
+
833
+ @method(egg_fn="*")
834
+ def __mul__(self, other: BigRatLike) -> BigRat: ...
835
+
836
+ @method(egg_fn="/")
837
+ def __truediv__(self, other: BigRatLike) -> BigRat: ...
838
+
839
+ @method(egg_fn="min")
840
+ def min(self, other: BigRatLike) -> BigRat: ...
841
+
842
+ @method(egg_fn="max")
843
+ def max(self, other: BigRatLike) -> BigRat: ...
844
+
845
+ @method(egg_fn="neg")
846
+ def __neg__(self) -> BigRat: ...
847
+
848
+ @method(egg_fn="abs")
849
+ def __abs__(self) -> BigRat: ...
850
+
851
+ @method(egg_fn="floor")
852
+ def floor(self) -> BigRat: ...
853
+
854
+ @method(egg_fn="ceil")
855
+ def ceil(self) -> BigRat: ...
856
+
857
+ @method(egg_fn="round")
858
+ def round(self) -> BigRat: ...
859
+
860
+ @method(egg_fn="pow")
861
+ def __pow__(self, other: BigRatLike) -> BigRat: ...
862
+
863
+ @method(egg_fn="log")
864
+ def log(self) -> BigRat: ...
865
+
866
+ @method(egg_fn="sqrt")
867
+ def sqrt(self) -> BigRat: ...
868
+
869
+ @method(egg_fn="cbrt")
870
+ def cbrt(self) -> BigRat: ...
871
+
872
+ @method(egg_fn="numer") # type: ignore[prop-decorator]
873
+ @property
874
+ def numer(self) -> BigInt: ...
875
+
876
+ @method(egg_fn="denom") # type: ignore[prop-decorator]
877
+ @property
878
+ def denom(self) -> BigInt: ...
879
+
880
+ @method(egg_fn="<")
881
+ def __lt__(self, other: BigRatLike) -> Unit: ... # type: ignore[has-type]
882
+
883
+ @method(egg_fn=">")
884
+ def __gt__(self, other: BigRatLike) -> Unit: ...
885
+
886
+ @method(egg_fn=">=")
887
+ def __ge__(self, other: BigRatLike) -> Unit: ... # type: ignore[has-type]
888
+
889
+ @method(egg_fn="<=")
890
+ def __le__(self, other: BigRatLike) -> Unit: ...
891
+
892
+
893
+ converter(Fraction, BigRat, lambda f: BigRat(f.numerator, f.denominator))
894
+ BigRatLike: TypeAlias = BigRat | Fraction
895
+
896
+
897
+ class Vec(BuiltinExpr, Generic[T], egg_sort="Vec"):
898
+ @method(preserve=True)
899
+ @deprecated("use .value")
900
+ def eval(self) -> tuple[T, ...]:
901
+ return self.value
902
+
903
+ @method(preserve=True) # type: ignore[prop-decorator]
904
+ @property
905
+ def value(self) -> tuple[T, ...]:
906
+ if get_callable_args(self, Vec.empty) is not None:
907
+ return ()
908
+ if (args := get_callable_args(self, Vec[T])) is not None:
909
+ return args
910
+ raise ExprValueError(self, "Vec(*xs) or Vec.empty()")
911
+
912
+ __match_args__ = ("value",)
913
+
914
+ @method(preserve=True)
915
+ def __iter__(self) -> Iterator[T]:
916
+ return iter(self.value)
917
+
918
+ @method(preserve=True)
919
+ def __len__(self) -> int:
920
+ return len(self.value)
921
+
922
+ @method(preserve=True)
923
+ def __contains__(self, key: T) -> bool:
924
+ return key in self.value
925
+
926
+ @method(egg_fn="vec-of")
927
+ def __init__(self, *args: T) -> None: ...
928
+
929
+ @method(egg_fn="vec-empty")
930
+ @classmethod
931
+ def empty(cls) -> Vec[T]: ...
932
+
933
+ @method(egg_fn="vec-append")
934
+ def append(self, *others: Vec[T]) -> Vec[T]: ...
935
+
936
+ @method(egg_fn="vec-push")
937
+ def push(self, value: T) -> Vec[T]: ...
938
+
939
+ @method(egg_fn="vec-pop")
940
+ def pop(self) -> Vec[T]: ...
941
+
942
+ @method(egg_fn="vec-not-contains")
943
+ def not_contains(self, value: T) -> Unit: ...
944
+
945
+ @method(egg_fn="vec-contains")
946
+ def contains(self, value: T) -> Unit: ...
947
+
948
+ @method(egg_fn="vec-length")
949
+ def length(self) -> i64: ...
950
+
951
+ @method(egg_fn="vec-get")
952
+ def __getitem__(self, index: i64Like) -> T: ...
953
+
954
+ @method(egg_fn="rebuild")
955
+ def rebuild(self) -> Vec[T]: ...
956
+
957
+ @method(egg_fn="vec-remove")
958
+ def remove(self, index: i64Like) -> Vec[T]: ...
959
+
960
+ @method(egg_fn="vec-set")
961
+ def set(self, index: i64Like, value: T) -> Vec[T]: ...
962
+
963
+
964
+ for sequence_type in (list, tuple):
965
+ converter(
966
+ sequence_type,
967
+ Vec,
968
+ lambda t: Vec[get_type_args()[0]]( # type: ignore[misc,operator]
969
+ *(convert(x, get_type_args()[0]) for x in t)
970
+ ),
971
+ )
972
+
973
+ VecLike: TypeAlias = Vec[T] | tuple[TO, ...] | list[TO]
974
+
975
+
976
+ class PyObject(BuiltinExpr, egg_sort="PyObject"):
977
+ @method(preserve=True)
978
+ @deprecated("use .value")
979
+ def eval(self) -> object:
980
+ return self.value
981
+
982
+ @method(preserve=True) # type: ignore[prop-decorator]
983
+ @property
984
+ def value(self) -> object:
985
+ expr = cast("RuntimeExpr", self).__egg_typed_expr__.expr
986
+ if not isinstance(expr, PyObjectDecl):
987
+ raise ExprValueError(self, "PyObject(x)")
988
+ return cloudpickle.loads(expr.pickled)
989
+
990
+ __match_args__ = ("value",)
991
+
992
+ def __init__(self, value: object) -> None: ...
993
+
994
+ @method(egg_fn="py-call")
995
+ def __call__(self, *args: object) -> PyObject: ...
996
+
997
+ @method(egg_fn="py-call-extended")
998
+ def call_extended(self, args: PyObject, kwargs: PyObject) -> PyObject:
999
+ """
1000
+ Call the PyObject with the given args and kwargs PyObjects.
1001
+ """
1002
+
1003
+ @method(egg_fn="py-from-string")
1004
+ @classmethod
1005
+ def from_string(cls, s: StringLike) -> PyObject: ...
1006
+
1007
+ @method(egg_fn="py-to-string")
1008
+ def to_string(self) -> String: ...
1009
+
1010
+ @method(egg_fn="py-to-bool")
1011
+ def to_bool(self) -> Bool: ...
1012
+
1013
+ @method(egg_fn="py-dict-update")
1014
+ def dict_update(self, *keys_and_values: object) -> PyObject: ...
1015
+
1016
+ @method(egg_fn="py-from-int")
1017
+ @classmethod
1018
+ def from_int(cls, i: i64Like) -> PyObject: ...
1019
+
1020
+ @method(egg_fn="py-dict")
1021
+ @classmethod
1022
+ def dict(cls, *keys_and_values: object) -> PyObject: ...
1023
+
1024
+
1025
+ converter(object, PyObject, PyObject)
1026
+
1027
+
1028
+ @function(builtin=True, egg_fn="py-eval")
1029
+ def py_eval(code: StringLike, globals: object = PyObject.dict(), locals: object = PyObject.dict()) -> PyObject: ...
1030
+
1031
+
1032
+ class PyObjectFunction(Protocol):
1033
+ def __call__(self, *__args: PyObject) -> PyObject: ...
1034
+
1035
+
1036
+ @deprecated("use PyObject(fn) directly")
1037
+ def py_eval_fn(fn: Callable) -> PyObjectFunction:
1038
+ """
1039
+ Takes a python callable and maps it to a callable which takes and returns PyObjects.
1040
+
1041
+ It translates it to a call which uses `py_eval` to call the function, passing in the
1042
+ args as locals, and using the globals from function.
1043
+ """
1044
+ return PyObject(fn)
1045
+
1046
+
1047
+ @function(builtin=True, egg_fn="py-exec")
1048
+ def py_exec(code: StringLike, globals: object = PyObject.dict(), locals: object = PyObject.dict()) -> PyObject:
1049
+ """
1050
+ Copies the locals, execs the Python code, and returns the locals with any updates.
1051
+ """
1052
+
1053
+
1054
+ TS = TypeVarTuple("TS")
1055
+
1056
+ T1 = TypeVar("T1")
1057
+ T2 = TypeVar("T2")
1058
+ T3 = TypeVar("T3")
1059
+
1060
+
1061
+ class UnstableFn(BuiltinExpr, Generic[T, *TS], egg_sort="UnstableFn"):
1062
+ @overload
1063
+ def __init__(self, f: Callable[[Unpack[TS]], T]) -> None: ...
1064
+
1065
+ @overload
1066
+ def __init__(self, f: Callable[[T1, Unpack[TS]], T], _a: T1, /) -> None: ...
1067
+
1068
+ @overload
1069
+ def __init__(self, f: Callable[[T1, T2, Unpack[TS]], T], _a: T1, _b: T2, /) -> None: ...
1070
+
1071
+ # Removing due to bug in MyPy
1072
+ # https://github.com/python/mypy/issues/17212
1073
+ # @overload
1074
+ # def __init__(self, f: Callable[[T1, T2, T3, Unpack[TS]], T], _a: T1, _b: T2, _c: T3, /) -> None: ...
1075
+
1076
+ # etc, for partial application
1077
+
1078
+ @method(egg_fn="unstable-fn")
1079
+ def __init__(self, f, *partial) -> None: ...
1080
+
1081
+ @method(preserve=True)
1082
+ @deprecated("use .value")
1083
+ def eval(self) -> Callable[[Unpack[TS]], T]:
1084
+ return self.value
1085
+
1086
+ @method(preserve=True) # type: ignore[prop-decorator]
1087
+ @property
1088
+ def value(self) -> Callable[[Unpack[TS]], T]:
1089
+ """
1090
+ If this is a constructor, returns either the callable directly or a `functools.partial` function if args are provided.
1091
+ """
1092
+ if (fn := get_literal_value(self)) is not None:
1093
+ return fn
1094
+ raise ExprValueError(self, "UnstableFn(f, *args)")
1095
+
1096
+ __match_args__ = ("value",)
1097
+
1098
+ @method(egg_fn="unstable-app")
1099
+ def __call__(self, *args: *TS) -> T: ...
1100
+
1101
+
1102
+ # Method Type is for builtins like __getitem__
1103
+ converter(MethodType, UnstableFn, lambda m: UnstableFn(m.__func__, m.__self__))
1104
+ converter(RuntimeFunction, UnstableFn, UnstableFn)
1105
+ converter(partial, UnstableFn, lambda p: UnstableFn(p.func, *p.args))
1106
+
1107
+
1108
+ def _convert_function(fn: FunctionType) -> UnstableFn:
1109
+ """
1110
+ Converts a function type to an unstable function. This function will be an anon function in egglog.
1111
+
1112
+ Would just be UnstableFn(function(a)) but we have to account for unbound vars within the body.
1113
+
1114
+ This means that we have to turn all of those unbound vars into args to the function, and then
1115
+ partially apply them, alongside creating a default rewrite for the function.
1116
+ """
1117
+ decls = Declarations()
1118
+ return_type, *arg_types = [resolve_type_annotation_mutate(decls, tp) for tp in get_type_args()]
1119
+ arg_names = [p.name for p in signature(fn).parameters.values()]
1120
+ arg_decls = [
1121
+ TypedExprDecl(tp.to_just(), UnboundVarDecl(name)) for name, tp in zip(arg_names, arg_types, strict=True)
1122
+ ]
1123
+ res = resolve_literal(
1124
+ return_type, fn(*(RuntimeExpr.__from_values__(decls, a) for a in arg_decls)), Thunk.value(decls)
1125
+ )
1126
+ res_expr = res.__egg_typed_expr__
1127
+ decls |= res
1128
+ # these are all the args that appear in the body that are not bound by the args of the function
1129
+ unbound_vars = list(collect_unbound_vars(res_expr) - set(arg_decls))
1130
+ # prefix the args with them
1131
+ fn_ref = UnnamedFunctionRef(tuple(unbound_vars + arg_decls), res_expr)
1132
+ rewrite_decl = DefaultRewriteDecl(fn_ref, res_expr.expr, subsume=True)
1133
+ ruleset_decls = _add_default_rewrite_inner(decls, rewrite_decl, get_current_ruleset())
1134
+ ruleset_decls |= res
1135
+
1136
+ fn = RuntimeFunction(Thunk.value(decls), Thunk.value(fn_ref))
1137
+ return UnstableFn(fn, *(RuntimeExpr.__from_values__(decls, v) for v in unbound_vars))
1138
+
1139
+
1140
+ converter(FunctionType, UnstableFn, _convert_function)
1141
+
1142
+
1143
+ Container: TypeAlias = Map | Set | MultiSet | Vec | UnstableFn
1144
+ Primitive: TypeAlias = String | Bool | i64 | f64 | Rational | BigInt | BigRat | PyObject | Unit