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