egglog 7.0.0__cp312-none-win_amd64.whl → 7.2.0__cp312-none-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/bindings.cp312-win_amd64.pyd +0 -0
- egglog/bindings.pyi +7 -0
- egglog/builtins.py +41 -1
- egglog/conversion.py +22 -17
- egglog/declarations.py +122 -37
- egglog/egraph.py +219 -78
- egglog/egraph_state.py +124 -54
- egglog/examples/higher_order_functions.py +50 -0
- egglog/exp/array_api.py +12 -9
- egglog/pretty.py +71 -15
- egglog/runtime.py +118 -33
- egglog/thunk.py +17 -6
- egglog/type_constraint_solver.py +5 -4
- {egglog-7.0.0.dist-info → egglog-7.2.0.dist-info}/METADATA +10 -10
- {egglog-7.0.0.dist-info → egglog-7.2.0.dist-info}/RECORD +17 -16
- {egglog-7.0.0.dist-info → egglog-7.2.0.dist-info}/WHEEL +0 -0
- {egglog-7.0.0.dist-info → egglog-7.2.0.dist-info}/license_files/LICENSE +0 -0
egglog/runtime.py
CHANGED
|
@@ -11,7 +11,8 @@ so they are not mangled by Python and can be accessed by the user.
|
|
|
11
11
|
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
|
-
from
|
|
14
|
+
from collections.abc import Callable
|
|
15
|
+
from dataclasses import dataclass, replace
|
|
15
16
|
from inspect import Parameter, Signature
|
|
16
17
|
from itertools import zip_longest
|
|
17
18
|
from typing import TYPE_CHECKING, NoReturn, TypeVar, Union, cast, get_args, get_origin
|
|
@@ -22,7 +23,7 @@ from .thunk import Thunk
|
|
|
22
23
|
from .type_constraint_solver import *
|
|
23
24
|
|
|
24
25
|
if TYPE_CHECKING:
|
|
25
|
-
from collections.abc import
|
|
26
|
+
from collections.abc import Iterable
|
|
26
27
|
|
|
27
28
|
from .egraph import Expr
|
|
28
29
|
|
|
@@ -60,6 +61,8 @@ REFLECTED_BINARY_METHODS = {
|
|
|
60
61
|
# Set this globally so we can get access to PyObject when we have a type annotation of just object.
|
|
61
62
|
# This is the only time a type annotation doesn't need to include the egglog type b/c object is top so that would be redundant statically.
|
|
62
63
|
_PY_OBJECT_CLASS: RuntimeClass | None = None
|
|
64
|
+
# Same for functions
|
|
65
|
+
_UNSTABLE_FN_CLASS: RuntimeClass | None = None
|
|
63
66
|
|
|
64
67
|
T = TypeVar("T")
|
|
65
68
|
|
|
@@ -67,6 +70,8 @@ T = TypeVar("T")
|
|
|
67
70
|
def resolve_type_annotation(decls: Declarations, tp: object) -> TypeOrVarRef:
|
|
68
71
|
"""
|
|
69
72
|
Resolves a type object into a type reference.
|
|
73
|
+
|
|
74
|
+
Any runtime type object decls will be add to those passed in.
|
|
70
75
|
"""
|
|
71
76
|
if isinstance(tp, TypeVar):
|
|
72
77
|
return ClassTypeVarRef(tp.__name__)
|
|
@@ -79,6 +84,11 @@ def resolve_type_annotation(decls: Declarations, tp: object) -> TypeOrVarRef:
|
|
|
79
84
|
if tp == object:
|
|
80
85
|
assert _PY_OBJECT_CLASS
|
|
81
86
|
return resolve_type_annotation(decls, _PY_OBJECT_CLASS)
|
|
87
|
+
# If the type is a `Callable` then convert it into a UnstableFn
|
|
88
|
+
if get_origin(tp) == Callable:
|
|
89
|
+
assert _UNSTABLE_FN_CLASS
|
|
90
|
+
args, ret = get_args(tp)
|
|
91
|
+
return resolve_type_annotation(decls, _UNSTABLE_FN_CLASS[(ret, *args)])
|
|
82
92
|
if isinstance(tp, RuntimeClass):
|
|
83
93
|
decls |= tp
|
|
84
94
|
return tp.__egg_tp__
|
|
@@ -95,9 +105,11 @@ class RuntimeClass(DelayedDeclerations):
|
|
|
95
105
|
__egg_tp__: TypeRefWithVars
|
|
96
106
|
|
|
97
107
|
def __post_init__(self) -> None:
|
|
98
|
-
global _PY_OBJECT_CLASS
|
|
99
|
-
if self.__egg_tp__.name == "PyObject":
|
|
108
|
+
global _PY_OBJECT_CLASS, _UNSTABLE_FN_CLASS
|
|
109
|
+
if (name := self.__egg_tp__.name) == "PyObject":
|
|
100
110
|
_PY_OBJECT_CLASS = self
|
|
111
|
+
elif name == "UnstableFn" and not self.__egg_tp__.args:
|
|
112
|
+
_UNSTABLE_FN_CLASS = self
|
|
101
113
|
|
|
102
114
|
def verify(self) -> None:
|
|
103
115
|
if not self.__egg_tp__.args:
|
|
@@ -113,26 +125,46 @@ class RuntimeClass(DelayedDeclerations):
|
|
|
113
125
|
Create an instance of this kind by calling the __init__ classmethod
|
|
114
126
|
"""
|
|
115
127
|
# If this is a literal type, initializing it with a literal should return a literal
|
|
116
|
-
if self.__egg_tp__.name == "PyObject":
|
|
128
|
+
if (name := self.__egg_tp__.name) == "PyObject":
|
|
117
129
|
assert len(args) == 1
|
|
118
130
|
return RuntimeExpr.__from_value__(
|
|
119
131
|
self.__egg_decls__, TypedExprDecl(self.__egg_tp__.to_just(), PyObjectDecl(args[0]))
|
|
120
132
|
)
|
|
121
|
-
if
|
|
133
|
+
if name == "UnstableFn":
|
|
134
|
+
assert not kwargs
|
|
135
|
+
fn_arg, *partial_args = args
|
|
136
|
+
del args
|
|
137
|
+
# Assumes we don't have types set for UnstableFn w/ generics, that they have to be inferred
|
|
138
|
+
|
|
139
|
+
# 1. Create a runtime function for the first arg
|
|
140
|
+
assert isinstance(fn_arg, RuntimeFunction)
|
|
141
|
+
# 2. Call it with the partial args, and use untyped vars for the rest of the args
|
|
142
|
+
res = fn_arg(*partial_args, _egg_partial_function=True)
|
|
143
|
+
assert res is not None, "Mutable partial functions not supported"
|
|
144
|
+
# 3. Use the inferred return type and inferred rest arg types as the types of the function, and
|
|
145
|
+
# the partially applied args as the args.
|
|
146
|
+
call = (res_typed_expr := res.__egg_typed_expr__).expr
|
|
147
|
+
return_tp = res_typed_expr.tp
|
|
148
|
+
assert isinstance(call, CallDecl), "partial function must be a call"
|
|
149
|
+
n_args = len(partial_args)
|
|
150
|
+
value = PartialCallDecl(replace(call, args=call.args[:n_args]))
|
|
151
|
+
remaining_arg_types = [a.tp for a in call.args[n_args:]]
|
|
152
|
+
type_ref = JustTypeRef("UnstableFn", (return_tp, *remaining_arg_types))
|
|
153
|
+
return RuntimeExpr.__from_value__(Declarations.create(self, res), TypedExprDecl(type_ref, value))
|
|
154
|
+
|
|
155
|
+
if name in UNARY_LIT_CLASS_NAMES:
|
|
122
156
|
assert len(args) == 1
|
|
123
157
|
assert isinstance(args[0], int | float | str | bool)
|
|
124
158
|
return RuntimeExpr.__from_value__(
|
|
125
159
|
self.__egg_decls__, TypedExprDecl(self.__egg_tp__.to_just(), LitDecl(args[0]))
|
|
126
160
|
)
|
|
127
|
-
if
|
|
161
|
+
if name == UNIT_CLASS_NAME:
|
|
128
162
|
assert len(args) == 0
|
|
129
163
|
return RuntimeExpr.__from_value__(
|
|
130
164
|
self.__egg_decls__, TypedExprDecl(self.__egg_tp__.to_just(), LitDecl(None))
|
|
131
165
|
)
|
|
132
|
-
|
|
133
|
-
return
|
|
134
|
-
Thunk.value(self.__egg_decls__), ClassMethodRef(self.__egg_tp__.name, "__init__"), self.__egg_tp__.to_just()
|
|
135
|
-
)(*args, **kwargs)
|
|
166
|
+
fn = RuntimeFunction(Thunk.value(self.__egg_decls__), InitRef(name), self.__egg_tp__.to_just())
|
|
167
|
+
return fn(*args, **kwargs) # type: ignore[arg-type]
|
|
136
168
|
|
|
137
169
|
def __dir__(self) -> list[str]:
|
|
138
170
|
cls_decl = self.__egg_decls__.get_class_decl(self.__egg_tp__.name)
|
|
@@ -184,6 +216,12 @@ class RuntimeClass(DelayedDeclerations):
|
|
|
184
216
|
return RuntimeFunction(
|
|
185
217
|
Thunk.value(self.__egg_decls__), ClassMethodRef(self.__egg_tp__.name, name), self.__egg_tp__.to_just()
|
|
186
218
|
)
|
|
219
|
+
# allow referencing properties and methods as class variables as well
|
|
220
|
+
if name in cls_decl.properties:
|
|
221
|
+
return RuntimeFunction(Thunk.value(self.__egg_decls__), PropertyRef(self.__egg_tp__.name, name))
|
|
222
|
+
if name in cls_decl.methods:
|
|
223
|
+
return RuntimeFunction(Thunk.value(self.__egg_decls__), MethodRef(self.__egg_tp__.name, name))
|
|
224
|
+
|
|
187
225
|
msg = f"Class {self.__egg_tp__.name} has no method {name}"
|
|
188
226
|
if name == "__ne__":
|
|
189
227
|
msg += ". Did you mean to use the ne(...).to(...)?"
|
|
@@ -207,24 +245,50 @@ class RuntimeFunction(DelayedDeclerations):
|
|
|
207
245
|
# bound methods need to store RuntimeExpr not just TypedExprDecl, so they can mutate the expr if required on self
|
|
208
246
|
__egg_bound__: JustTypeRef | RuntimeExpr | None = None
|
|
209
247
|
|
|
210
|
-
def __call__(self, *args: object, **kwargs: object) -> RuntimeExpr | None:
|
|
248
|
+
def __call__(self, *args: object, _egg_partial_function: bool = False, **kwargs: object) -> RuntimeExpr | None:
|
|
211
249
|
from .conversion import resolve_literal
|
|
212
250
|
|
|
213
251
|
if isinstance(self.__egg_bound__, RuntimeExpr):
|
|
214
252
|
args = (self.__egg_bound__, *args)
|
|
215
|
-
|
|
253
|
+
signature = self.__egg_decls__.get_callable_decl(self.__egg_ref__).to_function_decl().signature
|
|
254
|
+
decls = self.__egg_decls__.copy()
|
|
255
|
+
# Special case function application bc we dont support variadic generics yet generally
|
|
256
|
+
if signature == "fn-app":
|
|
257
|
+
fn, *rest_args = args
|
|
258
|
+
args = tuple(rest_args)
|
|
259
|
+
assert not kwargs
|
|
260
|
+
assert isinstance(fn, RuntimeExpr)
|
|
261
|
+
decls.update(fn)
|
|
262
|
+
function_value = fn.__egg_typed_expr__
|
|
263
|
+
fn_tp = function_value.tp
|
|
264
|
+
assert fn_tp.name == "UnstableFn"
|
|
265
|
+
fn_return_tp, *fn_arg_tps = fn_tp.args
|
|
266
|
+
signature = FunctionSignature(
|
|
267
|
+
tuple(tp.to_var() for tp in fn_arg_tps),
|
|
268
|
+
tuple(f"_{i}" for i in range(len(fn_arg_tps))),
|
|
269
|
+
(None,) * len(fn_arg_tps),
|
|
270
|
+
fn_return_tp.to_var(),
|
|
271
|
+
)
|
|
272
|
+
else:
|
|
273
|
+
function_value = None
|
|
274
|
+
assert isinstance(signature, FunctionSignature)
|
|
275
|
+
|
|
216
276
|
# Turn all keyword args into positional args
|
|
217
|
-
|
|
277
|
+
py_signature = to_py_signature(signature, self.__egg_decls__, _egg_partial_function)
|
|
278
|
+
try:
|
|
279
|
+
bound = py_signature.bind(*args, **kwargs)
|
|
280
|
+
except TypeError as err:
|
|
281
|
+
raise TypeError(f"Failed to call {self} with args {args} and kwargs {kwargs}") from err
|
|
282
|
+
del kwargs
|
|
218
283
|
bound.apply_defaults()
|
|
219
284
|
assert not bound.kwargs
|
|
220
|
-
|
|
285
|
+
args = bound.args
|
|
221
286
|
|
|
222
287
|
upcasted_args = [
|
|
223
288
|
resolve_literal(cast(TypeOrVarRef, tp), arg)
|
|
224
|
-
for arg, tp in zip_longest(
|
|
289
|
+
for arg, tp in zip_longest(args, signature.arg_types, fillvalue=signature.var_arg_type)
|
|
225
290
|
]
|
|
226
|
-
|
|
227
|
-
decls = Declarations.create(self, *upcasted_args)
|
|
291
|
+
decls.update(*upcasted_args)
|
|
228
292
|
|
|
229
293
|
tcs = TypeConstraintSolver(decls)
|
|
230
294
|
bound_tp = (
|
|
@@ -234,19 +298,29 @@ class RuntimeFunction(DelayedDeclerations):
|
|
|
234
298
|
if isinstance(self.__egg_bound__, RuntimeExpr)
|
|
235
299
|
else self.__egg_bound__
|
|
236
300
|
)
|
|
237
|
-
if
|
|
301
|
+
if (
|
|
302
|
+
bound_tp
|
|
303
|
+
and bound_tp.args
|
|
304
|
+
# Don't bind class if we have a first class function arg, b/c we don't support that yet
|
|
305
|
+
and not function_value
|
|
306
|
+
):
|
|
238
307
|
tcs.bind_class(bound_tp)
|
|
239
308
|
arg_exprs = tuple(arg.__egg_typed_expr__ for arg in upcasted_args)
|
|
240
309
|
arg_types = [expr.tp for expr in arg_exprs]
|
|
241
310
|
cls_name = bound_tp.name if bound_tp else None
|
|
242
311
|
return_tp = tcs.infer_return_type(
|
|
243
|
-
|
|
312
|
+
signature.arg_types, signature.semantic_return_type, signature.var_arg_type, arg_types, cls_name
|
|
244
313
|
)
|
|
245
|
-
bound_params =
|
|
314
|
+
bound_params = (
|
|
315
|
+
cast(JustTypeRef, bound_tp).args if isinstance(self.__egg_ref__, ClassMethodRef | InitRef) else None
|
|
316
|
+
)
|
|
317
|
+
# If we were using unstable-app to call a funciton, add that function back as the first arg.
|
|
318
|
+
if function_value:
|
|
319
|
+
arg_exprs = (function_value, *arg_exprs)
|
|
246
320
|
expr_decl = CallDecl(self.__egg_ref__, arg_exprs, bound_params)
|
|
247
321
|
typed_expr_decl = TypedExprDecl(return_tp, expr_decl)
|
|
248
322
|
# If there is not return type, we are mutating the first arg
|
|
249
|
-
if not
|
|
323
|
+
if not signature.return_type:
|
|
250
324
|
first_arg = upcasted_args[0]
|
|
251
325
|
first_arg.__egg_thunk__ = Thunk.value((decls, typed_expr_decl))
|
|
252
326
|
return None
|
|
@@ -262,19 +336,26 @@ class RuntimeFunction(DelayedDeclerations):
|
|
|
262
336
|
return pretty_callable_ref(self.__egg_decls__, self.__egg_ref__, first_arg, bound_tp_params)
|
|
263
337
|
|
|
264
338
|
|
|
265
|
-
def
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
339
|
+
def to_py_signature(sig: FunctionSignature, decls: Declarations, optional_args: bool) -> Signature:
|
|
340
|
+
"""
|
|
341
|
+
Convert to a Python signature.
|
|
342
|
+
|
|
343
|
+
If optional_args is true, then all args will be treated as optional, as if a default was provided that makes them
|
|
344
|
+
a var with that arg name as the value.
|
|
345
|
+
|
|
346
|
+
Used for partial application to try binding a function with only some of its args.
|
|
347
|
+
"""
|
|
269
348
|
parameters = [
|
|
270
349
|
Parameter(
|
|
271
350
|
n,
|
|
272
351
|
Parameter.POSITIONAL_OR_KEYWORD,
|
|
273
|
-
default=RuntimeExpr.__from_value__(decls, TypedExprDecl(t.to_just(), d
|
|
352
|
+
default=RuntimeExpr.__from_value__(decls, TypedExprDecl(t.to_just(), d if d is not None else VarDecl(n)))
|
|
353
|
+
if d is not None or optional_args
|
|
354
|
+
else Parameter.empty,
|
|
274
355
|
)
|
|
275
|
-
for n, d, t in zip(
|
|
356
|
+
for n, d, t in zip(sig.arg_names, sig.arg_defaults, sig.arg_types, strict=True)
|
|
276
357
|
]
|
|
277
|
-
if isinstance(
|
|
358
|
+
if isinstance(sig, FunctionSignature) and sig.var_arg_type is not None:
|
|
278
359
|
parameters.append(Parameter("__rest", Parameter.VAR_POSITIONAL))
|
|
279
360
|
return Signature(parameters)
|
|
280
361
|
|
|
@@ -412,10 +493,14 @@ for name in list(BINARY_METHODS) + list(UNARY_METHODS) + ["__getitem__", "__call
|
|
|
412
493
|
try:
|
|
413
494
|
return call_method_min_conversion(self, args[0], __name)
|
|
414
495
|
except ConvertError:
|
|
415
|
-
|
|
496
|
+
# Defer raising not imeplemented in case the dunder method is not symmetrical, then
|
|
497
|
+
# we use the standard process
|
|
498
|
+
pass
|
|
416
499
|
if __name in class_decl.methods:
|
|
417
500
|
fn = RuntimeFunction(Thunk.value(self.__egg_decls__), MethodRef(class_name, __name), self)
|
|
418
|
-
return fn(*args, **kwargs)
|
|
501
|
+
return fn(*args, **kwargs) # type: ignore[arg-type]
|
|
502
|
+
if __name in PARTIAL_METHODS:
|
|
503
|
+
return NotImplemented
|
|
419
504
|
raise TypeError(f"{class_name!r} object does not support {__name}")
|
|
420
505
|
|
|
421
506
|
setattr(RuntimeExpr, name, _special_method)
|
|
@@ -436,8 +521,8 @@ def call_method_min_conversion(slf: object, other: object, name: str) -> Runtime
|
|
|
436
521
|
# find a minimum type that both can be converted to
|
|
437
522
|
# This is so so that calls like `-0.1 * Int("x")` work by upcasting both to floats.
|
|
438
523
|
min_tp = min_convertable_tp(slf, other, name)
|
|
439
|
-
slf = resolve_literal(min_tp
|
|
440
|
-
other = resolve_literal(min_tp
|
|
524
|
+
slf = resolve_literal(TypeRefWithVars(min_tp), slf)
|
|
525
|
+
other = resolve_literal(TypeRefWithVars(min_tp), other)
|
|
441
526
|
method = RuntimeFunction(Thunk.value(slf.__egg_decls__), MethodRef(slf.__egg_class_name__, name), slf)
|
|
442
527
|
return method(other)
|
|
443
528
|
|
egglog/thunk.py
CHANGED
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from typing import TYPE_CHECKING, Generic, TypeVar
|
|
5
5
|
|
|
6
|
-
from typing_extensions import
|
|
6
|
+
from typing_extensions import TypeVarTuple, Unpack
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
9
|
from collections.abc import Callable
|
|
@@ -12,7 +12,6 @@ if TYPE_CHECKING:
|
|
|
12
12
|
__all__ = ["Thunk"]
|
|
13
13
|
|
|
14
14
|
T = TypeVar("T")
|
|
15
|
-
P = ParamSpec("P")
|
|
16
15
|
TS = TypeVarTuple("TS")
|
|
17
16
|
|
|
18
17
|
|
|
@@ -22,7 +21,7 @@ class Thunk(Generic[T, Unpack[TS]]):
|
|
|
22
21
|
Cached delayed function call.
|
|
23
22
|
"""
|
|
24
23
|
|
|
25
|
-
state: Resolved[T] | Unresolved[T, Unpack[TS]] | Resolving[T]
|
|
24
|
+
state: Resolved[T] | Unresolved[T, Unpack[TS]] | Resolving[T] | Error
|
|
26
25
|
|
|
27
26
|
@classmethod
|
|
28
27
|
def fn(
|
|
@@ -45,14 +44,21 @@ class Thunk(Generic[T, Unpack[TS]]):
|
|
|
45
44
|
return value
|
|
46
45
|
case Unresolved(fn, args, fallback):
|
|
47
46
|
self.state = Resolving(fallback)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
try:
|
|
48
|
+
res = fn(*args)
|
|
49
|
+
except Exception as e:
|
|
50
|
+
self.state = Error(e)
|
|
51
|
+
raise
|
|
52
|
+
else:
|
|
53
|
+
self.state = Resolved(res)
|
|
54
|
+
return res
|
|
51
55
|
case Resolving(fallback):
|
|
52
56
|
if fallback is None:
|
|
53
57
|
msg = "Recursively resolving thunk without fallback"
|
|
54
58
|
raise ValueError(msg)
|
|
55
59
|
return fallback()
|
|
60
|
+
case Error(e):
|
|
61
|
+
raise e
|
|
56
62
|
|
|
57
63
|
|
|
58
64
|
@dataclass
|
|
@@ -70,3 +76,8 @@ class Unresolved(Generic[T, Unpack[TS]]):
|
|
|
70
76
|
@dataclass
|
|
71
77
|
class Resolving(Generic[T]):
|
|
72
78
|
fallback: Callable[[], T] | None
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass
|
|
82
|
+
class Error:
|
|
83
|
+
e: Exception
|
egglog/type_constraint_solver.py
CHANGED
|
@@ -79,9 +79,10 @@ class TypeConstraintSolver:
|
|
|
79
79
|
Also returns the bound type params if the class name is passed in.
|
|
80
80
|
"""
|
|
81
81
|
self._infer_typevars(fn_return, return_, cls_name)
|
|
82
|
-
arg_types = (
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
arg_types: Iterable[JustTypeRef] = [self._subtitute_typevars(a, cls_name) for a in fn_args]
|
|
83
|
+
if fn_var_args:
|
|
84
|
+
# Need to be generator so it can be infinite for variable args
|
|
85
|
+
arg_types = chain(arg_types, repeat(self._subtitute_typevars(fn_var_args, cls_name)))
|
|
85
86
|
bound_typevars = (
|
|
86
87
|
tuple(
|
|
87
88
|
v
|
|
@@ -132,8 +133,8 @@ class TypeConstraintSolver:
|
|
|
132
133
|
def _subtitute_typevars(self, tp: TypeOrVarRef, cls_name: str | None) -> JustTypeRef:
|
|
133
134
|
match tp:
|
|
134
135
|
case ClassTypeVarRef(name):
|
|
136
|
+
assert cls_name is not None
|
|
135
137
|
try:
|
|
136
|
-
assert cls_name is not None
|
|
137
138
|
return self._cls_typevar_index_to_type[cls_name][name]
|
|
138
139
|
except KeyError as e:
|
|
139
140
|
raise TypeConstraintError(f"Not enough bound typevars for {tp}") from e
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: egglog
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.2.0
|
|
4
4
|
Classifier: Environment :: MacOS X
|
|
5
5
|
Classifier: Environment :: Win32 (MS Windows)
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -31,11 +31,6 @@ Requires-Dist: egglog[array]; extra == 'docs'
|
|
|
31
31
|
Requires-Dist: line-profiler; extra == 'docs'
|
|
32
32
|
Requires-Dist: sphinxcontrib-mermaid; extra == 'docs'
|
|
33
33
|
Requires-Dist: ablog; extra == 'docs'
|
|
34
|
-
Requires-Dist: pre-commit; extra == 'dev'
|
|
35
|
-
Requires-Dist: ruff; extra == 'dev'
|
|
36
|
-
Requires-Dist: mypy; extra == 'dev'
|
|
37
|
-
Requires-Dist: anywidget[dev]; extra == 'dev'
|
|
38
|
-
Requires-Dist: egglog[docs,test]; extra == 'dev'
|
|
39
34
|
Requires-Dist: pytest; extra == 'test'
|
|
40
35
|
Requires-Dist: mypy; extra == 'test'
|
|
41
36
|
Requires-Dist: syrupy; extra == 'test'
|
|
@@ -45,12 +40,17 @@ Requires-Dist: pytest-benchmark; extra == 'test'
|
|
|
45
40
|
Requires-Dist: pytest-xdist; extra == 'test'
|
|
46
41
|
Requires-Dist: scikit-learn; extra == 'array'
|
|
47
42
|
Requires-Dist: array_api_compat; extra == 'array'
|
|
48
|
-
Requires-Dist: numba==0.59.
|
|
49
|
-
Requires-Dist: llvmlite==0.42.
|
|
43
|
+
Requires-Dist: numba==0.59.1; extra == 'array'
|
|
44
|
+
Requires-Dist: llvmlite==0.42.0; extra == 'array'
|
|
45
|
+
Requires-Dist: pre-commit; extra == 'dev'
|
|
46
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
47
|
+
Requires-Dist: mypy; extra == 'dev'
|
|
48
|
+
Requires-Dist: anywidget[dev]; extra == 'dev'
|
|
49
|
+
Requires-Dist: egglog[docs,test]; extra == 'dev'
|
|
50
50
|
Provides-Extra: docs
|
|
51
|
-
Provides-Extra: dev
|
|
52
51
|
Provides-Extra: test
|
|
53
52
|
Provides-Extra: array
|
|
53
|
+
Provides-Extra: dev
|
|
54
54
|
License-File: LICENSE
|
|
55
55
|
Summary: e-graphs in Python built around the the egglog rust library
|
|
56
56
|
License: MIT
|
|
@@ -59,7 +59,7 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
|
59
59
|
|
|
60
60
|
# `egglog` Python wrapper
|
|
61
61
|
|
|
62
|
-
[](https://egglog-python.readthedocs.io/
|
|
62
|
+
[](https://egglog-python.readthedocs.io/latest/?badge=latest) [](https://github.com/egraphs-good/egglog-python/actions/workflows/CI.yml) [](https://pypi.org/project/egglog/) [](https://pypi.org/project/egglog/) [](https://pypi.org/project/egglog/) [](https://github.com/pre-commit/pre-commit) [](https://codspeed.io/egraphs-good/egglog-python)
|
|
63
63
|
|
|
64
64
|
`egglog` is a Python package that provides bindings to the Rust library [`egglog`](https://github.com/egraphs-good/egglog/),
|
|
65
65
|
allowing you to use e-graphs in Python for optimization, symbolic computation, and analysis.
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
egglog-7.
|
|
2
|
-
egglog-7.
|
|
3
|
-
egglog-7.
|
|
4
|
-
egglog/bindings.pyi,sha256=
|
|
5
|
-
egglog/builtins.py,sha256=
|
|
1
|
+
egglog-7.2.0.dist-info/METADATA,sha256=O3Uq5oIIHWZ-bG2XVILykl-0dYyuNuoR9Dxj38v6bXs,3829
|
|
2
|
+
egglog-7.2.0.dist-info/WHEEL,sha256=5VSD4WjrAS64a1-QM6eGcLa48TnO082fkviTtVvn8m4,96
|
|
3
|
+
egglog-7.2.0.dist-info/license_files/LICENSE,sha256=TfaboMVZ81Q6OUaKjU7z6uVjSlcGKclLYcOpgDbm9_s,1091
|
|
4
|
+
egglog/bindings.pyi,sha256=iFdtYHqPjuVt46qh1IE81cOI-lbGgPISKQB-3ERNzhI,11770
|
|
5
|
+
egglog/builtins.py,sha256=p5oZLDleCgQC8G2Zp2EvmqsfVnpgmARqUHqosKSSKnQ,13120
|
|
6
6
|
egglog/config.py,sha256=mALVaxh7zmGrbuyzaVKVmYKcu1lF703QsKJw8AF7gSM,176
|
|
7
|
-
egglog/conversion.py,sha256=
|
|
8
|
-
egglog/declarations.py,sha256=
|
|
9
|
-
egglog/egraph.py,sha256=
|
|
10
|
-
egglog/egraph_state.py,sha256=
|
|
7
|
+
egglog/conversion.py,sha256=4JhocGd1_nwmFMVNCzDDwj6aWfhBFTX2hm_7Xc_DiUM,6328
|
|
8
|
+
egglog/declarations.py,sha256=WpZ1yyw4vlWm3Xi_otPP2IU51IqNcDmJA5y20RcBFBQ,18583
|
|
9
|
+
egglog/egraph.py,sha256=Q3ZJhtzzWcsukuarT0vT48-DkfHe17adLLUHn-pILPE,68657
|
|
10
|
+
egglog/egraph_state.py,sha256=kXCNt4zenG1meRv5T6B8xI5oH_NreA06JMhmqv_F-og,21802
|
|
11
11
|
egglog/examples/bool.py,sha256=pWZTjfXR1cFy3KcihLBU5AF5rn83ImORlhUUJ1YiAXc,733
|
|
12
12
|
egglog/examples/eqsat_basic.py,sha256=ORXFYYEDsEZK2IPhHtoFsd-LdjMiQi1nn7kix4Nam0s,1011
|
|
13
13
|
egglog/examples/fib.py,sha256=wAn-PjazxgHDkXAU4o2xTk_GtM_iGL0biV66vWM1st4,520
|
|
14
|
+
egglog/examples/higher_order_functions.py,sha256=CBZqnqVdYGgztHw5QWtcnUhzs1nnBcw4O-gjSzAxjRc,1203
|
|
14
15
|
egglog/examples/lambda_.py,sha256=hQBOaSw_yorNcbkQVu2EhgSc0IZNWIny7asaOlcUk9s,8496
|
|
15
16
|
egglog/examples/matrix.py,sha256=_zmjgfFr2O_LjTcsTD-45_38Y_M1sP3AV39K6oFxAdw,5136
|
|
16
17
|
egglog/examples/ndarrays.py,sha256=T-wwef-n-3LDSjaO35zA8AZH5DXFFqq0XBSCQKEXV6E,4186
|
|
@@ -18,7 +19,7 @@ egglog/examples/README.rst,sha256=QrbfmivODBvUvmY3-dHarcbC6bEvwoqAfTDhiI-aJxU,23
|
|
|
18
19
|
egglog/examples/resolution.py,sha256=sKkbRI_v9XkQM0DriacKLINqKKDqYGFhvMCAS9tZbTA,2203
|
|
19
20
|
egglog/examples/schedule_demo.py,sha256=iJtIbcLaZ7zK8UalY0z7KAKMqYjQx0MKTsNF24lKtik,652
|
|
20
21
|
egglog/examples/__init__.py,sha256=KuhaJFOyz_rpUvEqZubsgLnv6rhQNE_AVFXA6bUnpdY,34
|
|
21
|
-
egglog/exp/array_api.py,sha256=
|
|
22
|
+
egglog/exp/array_api.py,sha256=b7MoUuH2sIW3KnUX7fGPaflwlCCskgrt1GsidVT-KG4,41474
|
|
22
23
|
egglog/exp/array_api_jit.py,sha256=HIZzd0G17u-u_F4vfRdhoYvRo-ETx5HFO3RBcOfLcco,1287
|
|
23
24
|
egglog/exp/array_api_numba.py,sha256=OjONBLdFRukx4vKiNK_rBxjMzsxbWpMEdD7JcGHJjmY,2924
|
|
24
25
|
egglog/exp/array_api_program_gen.py,sha256=crgUYXXNhQdfTq31FSIpWLIfzNsgQD8ngg3OosCtIgg,19680
|
|
@@ -27,13 +28,13 @@ egglog/exp/siu_examples.py,sha256=KZmpkSCgbL4uqHhx2Jh9Adz1_cDbkIlyXPa1Kh_0O_8,78
|
|
|
27
28
|
egglog/exp/__init__.py,sha256=G9zeKUcPBgIhgUg1meC86OfZVFETYIugyHWseTcCe_0,52
|
|
28
29
|
egglog/graphviz_widget.py,sha256=YtI7LCFWHihDQ1qLvdj2SVYEcuZLSooFUYheunOTxdc,1339
|
|
29
30
|
egglog/ipython_magic.py,sha256=VA19xAb6Sz7-IxlJBbnZW_gVFDqaYNnvdMB9QitndjE,1254
|
|
30
|
-
egglog/pretty.py,sha256=
|
|
31
|
+
egglog/pretty.py,sha256=s5XBIB7kMrxV25aO-F4NW5Jli2DOoc72wwswFYxJPjM,19561
|
|
31
32
|
egglog/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
-
egglog/runtime.py,sha256=
|
|
33
|
-
egglog/thunk.py,sha256=
|
|
34
|
-
egglog/type_constraint_solver.py,sha256=
|
|
33
|
+
egglog/runtime.py,sha256=s32xdoD_mIdDRi_PJQ5E_kSNyhUkT310osH38kZfCSk,23174
|
|
34
|
+
egglog/thunk.py,sha256=bm1zZUzwey0DijtMZkSulyfiWjCAg_1UmXaSG8qvvjs,2170
|
|
35
|
+
egglog/type_constraint_solver.py,sha256=MW22gwryNOqsYaB__dCCjVvdnB1Km5fovoW2IgUXaVo,5836
|
|
35
36
|
egglog/widget.css,sha256=WJS2M1wQdujhSTCakMa_ZXuoTPre1Uy1lPcvBE1LZQU,102
|
|
36
37
|
egglog/widget.js,sha256=UNOER3sYZ-bS7Qhw9S6qtpR81FuHa5DzXQaWWtQq334,2021
|
|
37
38
|
egglog/__init__.py,sha256=iUrVe5fb0XFyMCS3CwTjwhKEtU8KpIkdTpJpnUhm8o0,247
|
|
38
|
-
egglog/bindings.cp312-win_amd64.pyd,sha256=
|
|
39
|
-
egglog-7.
|
|
39
|
+
egglog/bindings.cp312-win_amd64.pyd,sha256=fYGMMgJx6iehBvLFrjqCRropokuwQPKBMcs5E4dSxG4,4620288
|
|
40
|
+
egglog-7.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|