effectful 0.0.1__py3-none-any.whl → 0.1.0__py3-none-any.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.
- effectful/handlers/indexed.py +4 -22
- effectful/handlers/numbers.py +10 -6
- effectful/handlers/pyro.py +2 -2
- effectful/handlers/torch.py +33 -10
- effectful/ops/semantics.py +25 -29
- effectful/ops/syntax.py +633 -86
- effectful/ops/types.py +27 -13
- {effectful-0.0.1.dist-info → effectful-0.1.0.dist-info}/METADATA +17 -12
- effectful-0.1.0.dist-info/RECORD +18 -0
- effectful/internals/base_impl.py +0 -259
- effectful-0.0.1.dist-info/RECORD +0 -19
- {effectful-0.0.1.dist-info → effectful-0.1.0.dist-info}/LICENSE.md +0 -0
- {effectful-0.0.1.dist-info → effectful-0.1.0.dist-info}/WHEEL +0 -0
- {effectful-0.0.1.dist-info → effectful-0.1.0.dist-info}/top_level.txt +0 -0
effectful/ops/types.py
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import abc
|
4
|
+
import collections.abc
|
5
|
+
import inspect
|
4
6
|
import typing
|
5
|
-
from typing import Any, Callable, Generic, Mapping, Sequence,
|
7
|
+
from typing import Any, Callable, Generic, Mapping, Sequence, Type, TypeVar, Union
|
6
8
|
|
7
9
|
from typing_extensions import ParamSpec
|
8
10
|
|
@@ -22,6 +24,9 @@ class Operation(abc.ABC, Generic[Q, V]):
|
|
22
24
|
|
23
25
|
"""
|
24
26
|
|
27
|
+
__signature__: inspect.Signature
|
28
|
+
__name__: str
|
29
|
+
|
25
30
|
@abc.abstractmethod
|
26
31
|
def __eq__(self, other):
|
27
32
|
raise NotImplementedError
|
@@ -38,19 +43,24 @@ class Operation(abc.ABC, Generic[Q, V]):
|
|
38
43
|
"""
|
39
44
|
raise NotImplementedError
|
40
45
|
|
41
|
-
@abc.abstractmethod
|
42
|
-
def __free_rule__(self, *args: Q.args, **kwargs: Q.kwargs) -> "Expr[V]":
|
43
|
-
"""Returns a term for the operation applied to arguments."""
|
44
|
-
raise NotImplementedError
|
45
|
-
|
46
46
|
@abc.abstractmethod
|
47
47
|
def __type_rule__(self, *args: Q.args, **kwargs: Q.kwargs) -> Type[V]:
|
48
48
|
"""Returns the type of the operation applied to arguments."""
|
49
49
|
raise NotImplementedError
|
50
50
|
|
51
51
|
@abc.abstractmethod
|
52
|
-
def __fvs_rule__(self, *args: Q.args, **kwargs: Q.kwargs) ->
|
53
|
-
""
|
52
|
+
def __fvs_rule__(self, *args: Q.args, **kwargs: Q.kwargs) -> tuple[
|
53
|
+
tuple[collections.abc.Set["Operation"], ...],
|
54
|
+
dict[str, collections.abc.Set["Operation"]],
|
55
|
+
]:
|
56
|
+
"""
|
57
|
+
Returns the sets of variables that appear free in each argument and keyword argument
|
58
|
+
but not in the result of the operation, i.e. the variables bound by the operation.
|
59
|
+
|
60
|
+
These are used by :func:`fvsof` to determine the free variables of a term by
|
61
|
+
subtracting the results of this method from the free variables of the subterms,
|
62
|
+
allowing :func:`fvsof` to be implemented in terms of :func:`evaluate` .
|
63
|
+
"""
|
54
64
|
raise NotImplementedError
|
55
65
|
|
56
66
|
@abc.abstractmethod
|
@@ -77,19 +87,19 @@ class Term(abc.ABC, Generic[T]):
|
|
77
87
|
@abc.abstractmethod
|
78
88
|
def op(self) -> Operation[..., T]:
|
79
89
|
"""Abstract property for the operation."""
|
80
|
-
|
90
|
+
raise NotImplementedError
|
81
91
|
|
82
92
|
@property
|
83
93
|
@abc.abstractmethod
|
84
94
|
def args(self) -> Sequence["Expr[Any]"]:
|
85
95
|
"""Abstract property for the arguments."""
|
86
|
-
|
96
|
+
raise NotImplementedError
|
87
97
|
|
88
98
|
@property
|
89
99
|
@abc.abstractmethod
|
90
100
|
def kwargs(self) -> Mapping[str, "Expr[Any]"]:
|
91
101
|
"""Abstract property for the keyword arguments."""
|
92
|
-
|
102
|
+
raise NotImplementedError
|
93
103
|
|
94
104
|
def __repr__(self) -> str:
|
95
105
|
from effectful.internals.runtime import interpreter
|
@@ -106,5 +116,9 @@ Expr = Union[T, Term[T]]
|
|
106
116
|
Interpretation = Mapping[Operation[..., T], Callable[..., V]]
|
107
117
|
|
108
118
|
|
109
|
-
class
|
110
|
-
|
119
|
+
class Annotation(abc.ABC):
|
120
|
+
|
121
|
+
@classmethod
|
122
|
+
@abc.abstractmethod
|
123
|
+
def infer_annotations(cls, sig: inspect.Signature) -> inspect.Signature:
|
124
|
+
raise NotImplementedError
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: effectful
|
3
|
-
Version: 0.0
|
3
|
+
Version: 0.1.0
|
4
4
|
Summary: Metaprogramming infrastructure
|
5
5
|
Home-page: https://www.basis.ai/
|
6
6
|
Author: Basis
|
@@ -28,6 +28,12 @@ Provides-Extra: dev
|
|
28
28
|
Requires-Dist: torch; extra == "dev"
|
29
29
|
Requires-Dist: pyro-ppl; extra == "dev"
|
30
30
|
Requires-Dist: torch; extra == "dev"
|
31
|
+
Requires-Dist: setuptools; extra == "dev"
|
32
|
+
Requires-Dist: sphinx; extra == "dev"
|
33
|
+
Requires-Dist: sphinxcontrib-bibtex; extra == "dev"
|
34
|
+
Requires-Dist: sphinx_rtd_theme; extra == "dev"
|
35
|
+
Requires-Dist: myst-parser; extra == "dev"
|
36
|
+
Requires-Dist: nbsphinx; extra == "dev"
|
31
37
|
Requires-Dist: pytest; extra == "dev"
|
32
38
|
Requires-Dist: pytest-cov; extra == "dev"
|
33
39
|
Requires-Dist: pytest-xdist; extra == "dev"
|
@@ -36,13 +42,15 @@ Requires-Dist: mypy; extra == "dev"
|
|
36
42
|
Requires-Dist: black; extra == "dev"
|
37
43
|
Requires-Dist: flake8; extra == "dev"
|
38
44
|
Requires-Dist: isort; extra == "dev"
|
39
|
-
Requires-Dist: sphinx; extra == "dev"
|
40
|
-
Requires-Dist: sphinxcontrib-bibtex; extra == "dev"
|
41
|
-
Requires-Dist: sphinx_rtd_theme; extra == "dev"
|
42
|
-
Requires-Dist: myst-parser; extra == "dev"
|
43
|
-
Requires-Dist: nbsphinx; extra == "dev"
|
44
45
|
Requires-Dist: nbval; extra == "dev"
|
45
46
|
Requires-Dist: nbqa; extra == "dev"
|
47
|
+
Provides-Extra: docs
|
48
|
+
Requires-Dist: setuptools; extra == "docs"
|
49
|
+
Requires-Dist: sphinx; extra == "docs"
|
50
|
+
Requires-Dist: sphinxcontrib-bibtex; extra == "docs"
|
51
|
+
Requires-Dist: sphinx_rtd_theme; extra == "docs"
|
52
|
+
Requires-Dist: myst-parser; extra == "docs"
|
53
|
+
Requires-Dist: nbsphinx; extra == "docs"
|
46
54
|
Dynamic: author
|
47
55
|
Dynamic: classifier
|
48
56
|
Dynamic: description
|
@@ -55,6 +63,7 @@ Dynamic: requires-dist
|
|
55
63
|
Dynamic: requires-python
|
56
64
|
Dynamic: summary
|
57
65
|
|
66
|
+
|
58
67
|
.. index-inclusion-marker
|
59
68
|
|
60
69
|
Effectful
|
@@ -75,7 +84,7 @@ Install From Source
|
|
75
84
|
git clone git@github.com:BasisResearch/effectful.git
|
76
85
|
cd effectful
|
77
86
|
git checkout master
|
78
|
-
pip install -e .[
|
87
|
+
pip install -e .[pyro]
|
79
88
|
|
80
89
|
Install With Optional PyTorch/Pyro Support
|
81
90
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
@@ -103,16 +112,12 @@ Here's an example demonstrating how ``effectful`` can be used to implement a sim
|
|
103
112
|
|
104
113
|
.. code:: python
|
105
114
|
|
106
|
-
import operator
|
107
115
|
import functools
|
108
116
|
|
109
|
-
from effectful.handlers.operator import OPERATORS
|
110
117
|
from effectful.ops.types import Term
|
111
118
|
from effectful.ops.syntax import defop
|
112
119
|
from effectful.ops.semantics import handler, evaluate, coproduct, fwd
|
113
|
-
|
114
|
-
|
115
|
-
add = OPERATORS[operator.add]
|
120
|
+
from effectful.handlers.numbers import add
|
116
121
|
|
117
122
|
def beta_add(x: int, y: int) -> int:
|
118
123
|
match x, y:
|
@@ -0,0 +1,18 @@
|
|
1
|
+
effectful/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
effectful/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
effectful/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
+
effectful/handlers/indexed.py,sha256=k98C-Gtm8rQPfCYRCUVEPlElwiD3PwWGZ5hwNTTaIt8,12651
|
5
|
+
effectful/handlers/numbers.py,sha256=X-RI9IcOahSrwDNF0xZtQwxBvgKbNQpJRB_m9Vzy-Ew,6656
|
6
|
+
effectful/handlers/pyro.py,sha256=r0Zyv9nNDaAdwujI3J-nlsIrlAHp-AAuLQ5DfG8S2q4,15294
|
7
|
+
effectful/handlers/torch.py,sha256=cQxrIJUiC2Zmiz6e_OS-DgtVsHGr_MCsoTY2kvZ05Y4,18945
|
8
|
+
effectful/internals/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
+
effectful/internals/runtime.py,sha256=E0ce5mfG0-DlTeALYZePWtdxr0AK3y0CPl_LE5pp_0k,1908
|
10
|
+
effectful/ops/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
+
effectful/ops/semantics.py,sha256=w5UWCkUH1UznIB4NKaQE1TCA2cOLlnbRKd0PNma30Rg,10252
|
12
|
+
effectful/ops/syntax.py,sha256=U2URezErfQPySVpLNd7Wzx6ZXZwHDo4LZOvhalaXeBI,38241
|
13
|
+
effectful/ops/types.py,sha256=vTg6eQQN5Xq1KIelUfEUvpofO2iJ3x8YbiyPzNESTjQ,3823
|
14
|
+
effectful-0.1.0.dist-info/LICENSE.md,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
15
|
+
effectful-0.1.0.dist-info/METADATA,sha256=mBVk7m_Lf3GkcR1WVQaKCMJ5f4AeAykMYCocITL7cko,5165
|
16
|
+
effectful-0.1.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
17
|
+
effectful-0.1.0.dist-info/top_level.txt,sha256=gtuJfrE2nXil_lZLCnqWF2KAbOnJs9ILNvK8WnkRzbs,10
|
18
|
+
effectful-0.1.0.dist-info/RECORD,,
|
effectful/internals/base_impl.py
DELETED
@@ -1,259 +0,0 @@
|
|
1
|
-
import collections
|
2
|
-
import functools
|
3
|
-
import inspect
|
4
|
-
import typing
|
5
|
-
from typing import Callable, Generic, Mapping, Sequence, Set, Type, TypeVar
|
6
|
-
|
7
|
-
import tree
|
8
|
-
from typing_extensions import ParamSpec
|
9
|
-
|
10
|
-
from effectful.ops.types import Expr, Operation, Term
|
11
|
-
|
12
|
-
P = ParamSpec("P")
|
13
|
-
Q = ParamSpec("Q")
|
14
|
-
S = TypeVar("S")
|
15
|
-
T = TypeVar("T")
|
16
|
-
V = TypeVar("V")
|
17
|
-
|
18
|
-
|
19
|
-
def rename(
|
20
|
-
subs: Mapping[Operation[..., S], Operation[..., S]],
|
21
|
-
leaf_value: V, # Union[Term[V], Operation[..., V], V],
|
22
|
-
) -> V: # Union[Term[V], Operation[..., V], V]:
|
23
|
-
from effectful.internals.runtime import interpreter
|
24
|
-
from effectful.ops.semantics import apply, evaluate
|
25
|
-
|
26
|
-
if isinstance(leaf_value, Operation):
|
27
|
-
return subs.get(leaf_value, leaf_value) # type: ignore
|
28
|
-
elif isinstance(leaf_value, Term):
|
29
|
-
with interpreter(
|
30
|
-
{apply: lambda _, op, *a, **k: op.__free_rule__(*a, **k), **subs}
|
31
|
-
):
|
32
|
-
return evaluate(leaf_value) # type: ignore
|
33
|
-
else:
|
34
|
-
return leaf_value
|
35
|
-
|
36
|
-
|
37
|
-
class _BaseOperation(Generic[Q, V], Operation[Q, V]):
|
38
|
-
signature: Callable[Q, V]
|
39
|
-
|
40
|
-
def __init__(self, signature: Callable[Q, V]):
|
41
|
-
functools.update_wrapper(self, signature)
|
42
|
-
self.signature = signature
|
43
|
-
|
44
|
-
def __eq__(self, other):
|
45
|
-
if not isinstance(other, Operation):
|
46
|
-
return NotImplemented
|
47
|
-
return self.signature == other.signature
|
48
|
-
|
49
|
-
def __hash__(self):
|
50
|
-
return hash(self.signature)
|
51
|
-
|
52
|
-
def __default_rule__(self, *args: Q.args, **kwargs: Q.kwargs) -> "Expr[V]":
|
53
|
-
from effectful.ops.syntax import NoDefaultRule
|
54
|
-
|
55
|
-
try:
|
56
|
-
return self.signature(*args, **kwargs)
|
57
|
-
except NoDefaultRule:
|
58
|
-
return self.__free_rule__(*args, **kwargs)
|
59
|
-
|
60
|
-
def __free_rule__(self, *args: Q.args, **kwargs: Q.kwargs) -> "Expr[V]":
|
61
|
-
from effectful.ops.syntax import Bound, Scoped, defdata, defop
|
62
|
-
|
63
|
-
sig = inspect.signature(self.signature)
|
64
|
-
bound_sig = sig.bind(*args, **kwargs)
|
65
|
-
bound_sig.apply_defaults()
|
66
|
-
|
67
|
-
bound_vars: dict[int, set[Operation]] = collections.defaultdict(set)
|
68
|
-
scoped_args: dict[int, set[str]] = collections.defaultdict(set)
|
69
|
-
unscoped_args: set[str] = set()
|
70
|
-
for param_name, param in bound_sig.signature.parameters.items():
|
71
|
-
if typing.get_origin(param.annotation) is typing.Annotated:
|
72
|
-
for anno in param.annotation.__metadata__:
|
73
|
-
if isinstance(anno, Bound):
|
74
|
-
scoped_args[anno.scope].add(param_name)
|
75
|
-
if param.kind is inspect.Parameter.VAR_POSITIONAL:
|
76
|
-
assert isinstance(bound_sig.arguments[param_name], tuple)
|
77
|
-
for bound_var in bound_sig.arguments[param_name]:
|
78
|
-
bound_vars[anno.scope].add(bound_var)
|
79
|
-
elif param.kind is inspect.Parameter.VAR_KEYWORD:
|
80
|
-
assert isinstance(bound_sig.arguments[param_name], dict)
|
81
|
-
for bound_var in bound_sig.arguments[param_name].values():
|
82
|
-
bound_vars[anno.scope].add(bound_var)
|
83
|
-
else:
|
84
|
-
bound_vars[anno.scope].add(bound_sig.arguments[param_name])
|
85
|
-
elif isinstance(anno, Scoped):
|
86
|
-
scoped_args[anno.scope].add(param_name)
|
87
|
-
else:
|
88
|
-
unscoped_args.add(param_name)
|
89
|
-
|
90
|
-
# TODO replace this temporary check with more general scope level propagation
|
91
|
-
if bound_vars:
|
92
|
-
min_scope = min(bound_vars.keys(), default=0)
|
93
|
-
scoped_args[min_scope] |= unscoped_args
|
94
|
-
max_scope = max(bound_vars.keys(), default=0)
|
95
|
-
assert all(s in bound_vars or s > max_scope for s in scoped_args.keys())
|
96
|
-
|
97
|
-
# recursively rename bound variables from innermost to outermost scope
|
98
|
-
for scope in sorted(bound_vars.keys()):
|
99
|
-
# create fresh variables for each bound variable in the scope
|
100
|
-
renaming_map = {var: defop(var) for var in bound_vars[scope]}
|
101
|
-
# get just the arguments that are in the scope
|
102
|
-
for name in scoped_args[scope]:
|
103
|
-
bound_sig.arguments[name] = tree.map_structure(
|
104
|
-
lambda a: rename(renaming_map, a),
|
105
|
-
bound_sig.arguments[name],
|
106
|
-
)
|
107
|
-
|
108
|
-
return defdata(_BaseTerm(self, bound_sig.args, bound_sig.kwargs))
|
109
|
-
|
110
|
-
def __type_rule__(self, *args: Q.args, **kwargs: Q.kwargs) -> Type[V]:
|
111
|
-
sig = inspect.signature(self.signature)
|
112
|
-
bound_sig = sig.bind(*args, **kwargs)
|
113
|
-
bound_sig.apply_defaults()
|
114
|
-
|
115
|
-
anno = sig.return_annotation
|
116
|
-
if anno is inspect.Signature.empty:
|
117
|
-
return typing.cast(Type[V], object)
|
118
|
-
elif isinstance(anno, typing.TypeVar):
|
119
|
-
# rudimentary but sound special-case type inference sufficient for syntax ops:
|
120
|
-
# if the return type annotation is a TypeVar,
|
121
|
-
# look for a parameter with the same annotation and return its type,
|
122
|
-
# otherwise give up and return Any/object
|
123
|
-
for name, param in bound_sig.signature.parameters.items():
|
124
|
-
if param.annotation is anno and param.kind not in (
|
125
|
-
inspect.Parameter.VAR_POSITIONAL,
|
126
|
-
inspect.Parameter.VAR_KEYWORD,
|
127
|
-
):
|
128
|
-
arg = bound_sig.arguments[name]
|
129
|
-
tp: Type[V] = type(arg) if not isinstance(arg, type) else arg
|
130
|
-
return tp
|
131
|
-
return typing.cast(Type[V], object)
|
132
|
-
elif typing.get_origin(anno) is typing.Annotated:
|
133
|
-
tp = typing.get_args(anno)[0]
|
134
|
-
if not typing.TYPE_CHECKING:
|
135
|
-
tp = tp if typing.get_origin(tp) is None else typing.get_origin(tp)
|
136
|
-
return tp
|
137
|
-
elif typing.get_origin(anno) is not None:
|
138
|
-
return typing.get_origin(anno)
|
139
|
-
else:
|
140
|
-
return anno
|
141
|
-
|
142
|
-
def __fvs_rule__(self, *args: Q.args, **kwargs: Q.kwargs) -> Set[Operation]:
|
143
|
-
from effectful.ops.syntax import Bound
|
144
|
-
|
145
|
-
sig = inspect.signature(self.signature)
|
146
|
-
bound_sig = sig.bind(*args, **kwargs)
|
147
|
-
bound_sig.apply_defaults()
|
148
|
-
|
149
|
-
bound_vars: Set[Operation] = set()
|
150
|
-
for param_name, param in bound_sig.signature.parameters.items():
|
151
|
-
if typing.get_origin(param.annotation) is typing.Annotated:
|
152
|
-
for anno in param.annotation.__metadata__:
|
153
|
-
if isinstance(anno, Bound):
|
154
|
-
if param.kind is inspect.Parameter.VAR_POSITIONAL:
|
155
|
-
for bound_var in bound_sig.arguments[param_name]:
|
156
|
-
bound_vars.add(bound_var)
|
157
|
-
elif param.kind is inspect.Parameter.VAR_KEYWORD:
|
158
|
-
for bound_var in bound_sig.arguments[param_name].values():
|
159
|
-
bound_vars.add(bound_var)
|
160
|
-
else:
|
161
|
-
bound_var = bound_sig.arguments[param_name]
|
162
|
-
bound_vars.add(bound_var)
|
163
|
-
|
164
|
-
return bound_vars
|
165
|
-
|
166
|
-
def __repr_rule__(self, *args: Q.args, **kwargs: Q.kwargs) -> str:
|
167
|
-
args_str = ", ".join(map(str, args)) if args else ""
|
168
|
-
kwargs_str = (
|
169
|
-
", ".join(f"{k}={str(v)}" for k, v in kwargs.items()) if kwargs else ""
|
170
|
-
)
|
171
|
-
|
172
|
-
ret = f"{self.signature.__name__}({args_str}"
|
173
|
-
if kwargs:
|
174
|
-
ret += f"{', ' if args else ''}"
|
175
|
-
ret += f"{kwargs_str})"
|
176
|
-
return ret
|
177
|
-
|
178
|
-
def __repr__(self):
|
179
|
-
return self.signature.__name__
|
180
|
-
|
181
|
-
|
182
|
-
class _BaseTerm(Generic[T], Term[T]):
|
183
|
-
_op: Operation[..., T]
|
184
|
-
_args: Sequence[Expr]
|
185
|
-
_kwargs: Mapping[str, Expr]
|
186
|
-
|
187
|
-
def __init__(
|
188
|
-
self,
|
189
|
-
op: Operation[..., T],
|
190
|
-
args: Sequence[Expr],
|
191
|
-
kwargs: Mapping[str, Expr],
|
192
|
-
):
|
193
|
-
self._op = op
|
194
|
-
self._args = args
|
195
|
-
self._kwargs = kwargs
|
196
|
-
|
197
|
-
def __eq__(self, other) -> bool:
|
198
|
-
from effectful.ops.syntax import syntactic_eq
|
199
|
-
|
200
|
-
return syntactic_eq(self, other)
|
201
|
-
|
202
|
-
@property
|
203
|
-
def op(self):
|
204
|
-
return self._op
|
205
|
-
|
206
|
-
@property
|
207
|
-
def args(self):
|
208
|
-
return self._args
|
209
|
-
|
210
|
-
@property
|
211
|
-
def kwargs(self):
|
212
|
-
return self._kwargs
|
213
|
-
|
214
|
-
|
215
|
-
class _CallableTerm(Generic[P, T], _BaseTerm[collections.abc.Callable[P, T]]):
|
216
|
-
def __call__(self, *args: Expr, **kwargs: Expr) -> Expr[T]:
|
217
|
-
from effectful.ops.semantics import call
|
218
|
-
|
219
|
-
return call(self, *args, **kwargs) # type: ignore
|
220
|
-
|
221
|
-
|
222
|
-
def _unembed_callable(value: Callable[P, T]) -> Expr[Callable[P, T]]:
|
223
|
-
from effectful.internals.runtime import interpreter
|
224
|
-
from effectful.ops.semantics import apply, call
|
225
|
-
from effectful.ops.syntax import deffn, defop
|
226
|
-
|
227
|
-
assert not isinstance(value, Term)
|
228
|
-
|
229
|
-
try:
|
230
|
-
sig = inspect.signature(value)
|
231
|
-
except ValueError:
|
232
|
-
return value
|
233
|
-
|
234
|
-
for name, param in sig.parameters.items():
|
235
|
-
if param.kind in (
|
236
|
-
inspect.Parameter.VAR_POSITIONAL,
|
237
|
-
inspect.Parameter.VAR_KEYWORD,
|
238
|
-
):
|
239
|
-
raise NotImplementedError(
|
240
|
-
f"cannot unembed {value}: parameter {name} is variadic"
|
241
|
-
)
|
242
|
-
|
243
|
-
bound_sig = sig.bind(
|
244
|
-
**{name: defop(param.annotation) for name, param in sig.parameters.items()}
|
245
|
-
)
|
246
|
-
bound_sig.apply_defaults()
|
247
|
-
|
248
|
-
with interpreter(
|
249
|
-
{
|
250
|
-
apply: lambda _, op, *a, **k: op.__free_rule__(*a, **k),
|
251
|
-
call: call.__default_rule__,
|
252
|
-
}
|
253
|
-
):
|
254
|
-
body = value(
|
255
|
-
*[a() for a in bound_sig.args],
|
256
|
-
**{k: v() for k, v in bound_sig.kwargs.items()},
|
257
|
-
)
|
258
|
-
|
259
|
-
return deffn(body, *bound_sig.args, **bound_sig.kwargs)
|
effectful-0.0.1.dist-info/RECORD
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
effectful/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
effectful/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
-
effectful/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
effectful/handlers/indexed.py,sha256=lNqlHZqD8JBs-KaC3YdCoQDAXHuQ9KhAH0ZhpIqMdFM,13184
|
5
|
-
effectful/handlers/numbers.py,sha256=aKVCJ-l3ISvOGHTfXsQIEp4uEsQsYy7bP-YUCsSO_3o,6557
|
6
|
-
effectful/handlers/pyro.py,sha256=s_CAXe65gqXmKiYLUXJ0_uLQzEEgyQbZv0hQWMMdQJ4,15312
|
7
|
-
effectful/handlers/torch.py,sha256=LJYwud6Dq3xg7A6_6aaDEyP1hT0IB4G_55Gki6izRvo,18401
|
8
|
-
effectful/internals/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
-
effectful/internals/base_impl.py,sha256=6Yxxg5tS_R2RLlHvtOhj_fuA_9hEa_YKf0LhQOX2448,9671
|
10
|
-
effectful/internals/runtime.py,sha256=E0ce5mfG0-DlTeALYZePWtdxr0AK3y0CPl_LE5pp_0k,1908
|
11
|
-
effectful/ops/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
|
-
effectful/ops/semantics.py,sha256=Ihaj2ycildtMg18GSujSJSaAAKsArKoyMmR-gBoWx8E,10208
|
13
|
-
effectful/ops/syntax.py,sha256=nRfguHAol5lDnUv0UMOB0AL6y6By2DCW7hlCYsN3OnM,15331
|
14
|
-
effectful/ops/types.py,sha256=DmVqX8naWNQEW1A6w7ShrXp_LZV6qoK4p_OAM3NitTI,3241
|
15
|
-
effectful-0.0.1.dist-info/LICENSE.md,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
16
|
-
effectful-0.0.1.dist-info/METADATA,sha256=WN7j_mJwZao1T1MTWyAIo_1hP6YUCS4L6rPI9wWCScA,4930
|
17
|
-
effectful-0.0.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
18
|
-
effectful-0.0.1.dist-info/top_level.txt,sha256=gtuJfrE2nXil_lZLCnqWF2KAbOnJs9ILNvK8WnkRzbs,10
|
19
|
-
effectful-0.0.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|