Standard Nodes and Effects
Generic Utilities
spawn_node
spawn_node(node_type: type[N], **args: Any) -> NodeBuilder[Any, Any]
A convenience helper to write effect triggering functions.
Attributes:
Name | Type | Description |
---|---|---|
node_type |
The type of the node to spawn (e.g., |
|
args |
Arguments to populate the node fields, passed to
|
Source code in src/delphyne/stdlib/nodes.py
19 20 21 22 23 24 25 26 27 28 29 30 |
|
FromPolicy
FromPolicy: Callable[[Any], T]
Type for an inner-policy-dependent data field.
We use Any
instead of introducing an inner policy type parameter P
,
since Node
is not parametric either. Thus, this alias is mostly meant
for readability and expressing intent.
NodeMeta
Abstract base class for node metadata.
Nodes can feature fields with arbitrary metadata accessible to
policies (e.g., meta
field of Branch
). Typing those fields with
NodeMeta
instead of object
or Any
allows for better type
safety. In particular, it prevents errors that arise from
accidentally passing uninstantiated parametric inner policy fields.
Source code in src/delphyne/stdlib/nodes.py
43 44 45 46 47 48 49 50 51 52 53 54 |
|
Branch
Branch
dataclass
Bases: Node
The standard Branch
effect.
Can be triggered using the branch
function, which allows branching
over elements of an opaque space.
Source code in src/delphyne/stdlib/nodes.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
|
branch
branch(
cands: Opaque[P, T],
meta: Callable[[P], NodeMeta] | None = None,
inner_policy_type: type[P] | None = None,
) -> Strategy[Branch, P, T]
Branch over the elements of an opaque space.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
cands
|
Opaque[P, T]
|
An opaque space, which can be defined from either a query
or a strategy via the |
required |
meta
|
Callable[[P], NodeMeta] | None
|
An optional mapping from the ambient inner policy to arbitrary metadata accessible to search policies. |
None
|
inner_policy_type
|
type[P] | None
|
Ambient inner policy type. This information is not used at runtime but it can be provided to help type inference when necessary. |
None
|
Source code in src/delphyne/stdlib/nodes.py
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
|
Fail
Fail
dataclass
Bases: Node
The standard Fail
effect.
Can be triggered using the fail
and ensure
functions.
Source code in src/delphyne/stdlib/nodes.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
|
fail
fail(
label: str | None = None, *, message: str | None = None, error: Error | None = None
) -> Strategy[Fail, object, NoReturn]
Fail immediately with an error.
The error can be specified using the error
keyword argument. As a
shortcut, the label
and message
arguments can also be used to
directly specify the corresponding fields of the Error
type. Those
arguments can only be used if error
is not provided.
Warning
Like all effect triggering functions, this function must be invoked as:
yield from fail(...)
Forgetting yield from
may not result in a type error but will
result in a no-op at runtime.
Source code in src/delphyne/stdlib/nodes.py
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
|
ensure
ensure(
prop: bool,
label: str | None = None,
*,
message: str | None = None,
error: Error | None = None,
) -> Strategy[Fail, object, None]
Ensure that a property holds, otherwise fail with an error.
See fail
regarding the label
, message
and error
arguments.
Warning
Like all effect triggering functions, this function must be invoked as:
yield from ensure(...)
Forgetting yield from
may not result in a type error but will
result in a no-op at runtime.
Source code in src/delphyne/stdlib/nodes.py
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
|
Message
Message
dataclass
Bases: Node
The standard Message
effect.
Message nodes are tree nodes carrying a message. They have a unique
child. They can be eliminated using the elim_messages
tree
transformer, which automatically logs their content.
This effect is useful for debugging strategies. Using print
statements in strategies is discouraged since strategy computations
are replayed every time a child of the associated tree is computed,
causing the same message to be repeatedly printed.
Source code in src/delphyne/stdlib/nodes.py
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
|
message
Log a debugging message.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
msg
|
str
|
The message to log. |
required |
data
|
object | None
|
Optional data to attach to the message. |
None
|
Warning
Like all effect triggering functions, this function must be invoked as:
yield from message(...)
Forgetting yield from
may not result in a type error but will
result in a no-op at runtime.
Source code in src/delphyne/stdlib/nodes.py
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
|
elim_messages
elim_messages(
env: PolicyEnv, policy: Any, show_in_log: bool = True
) -> PureTreeTransformerFn[Message, Never]
Eliminate the Message
effect.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
show_in_log
|
bool
|
Whether to log the associated content whenever a message node is encountered. |
True
|
Source code in src/delphyne/stdlib/nodes.py
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
|
Factor and Value
Factor
dataclass
Bases: Node
The standard Factor
effect.
A Factor
node allows computing a confidence score in the [0, 1]
interval. This confidence can be computed by a query or a dedicated
strategy but only one element will be generated from the resulting
space. Instead of having an oracle compute a numerical value
directly, it computes an evaluation object that is then transformed
into a number using a policy-provided function. This allows greater
flexibility on the policy side. If no such function is given, the
whole node is ignored.
Source code in src/delphyne/stdlib/nodes.py
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
|
factor
factor(
eval: Opaque[P, E],
factor: Callable[[P], Callable[[E], float] | None],
inner_policy_type: type[P] | None = None,
) -> Strategy[Factor, P, None]
Apply a multiplicative penalty to the current search branch.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
eval
|
Opaque[P, E]
|
An opaque space, typically induced by a strategy or a
query whose purpose is to evaluate the current search state,
returning an evaluation object of type |
required |
factor
|
Callable[[P], Callable[[E], float] | None]
|
An inner-policy-dependent function that maps an
evaluation object of type |
required |
Warning
Like all effect triggering functions, this function must be invoked as:
yield from factor(...)
Forgetting yield from
may not result in a type error but will
result in a no-op at runtime.
Source code in src/delphyne/stdlib/nodes.py
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 |
|
Value
dataclass
Bases: Node
The standard Value
effect.
Similar to Factor
, except that the resulting number is used to set
the whole value of the branch instead of just multiplying it.
Source code in src/delphyne/stdlib/nodes.py
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
|
value
value(
eval: Opaque[P, E],
value: Callable[[P], Callable[[E], float] | None],
inner_policy_type: type[P] | None = None,
) -> Strategy[Value, P, None]
Set the value of the current search branch.
See the similar factor
function for more details.
Warning
Like all effect triggering functions, this function must be invoked as:
yield from message(...)
Forgetting yield from
may not result in a type error but will
result in a no-op at runtime.
Source code in src/delphyne/stdlib/nodes.py
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
|
Join
Join
dataclass
Bases: Node
The standard Join
effect.
This effect can be triggered using the join
function. A Join
node features a sequence of embedded trees.
Source code in src/delphyne/stdlib/nodes.py
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
|
join
join(
subs: Sequence[StrategyComp[N, P, T]],
meta: Callable[[P], NodeMeta] | None = None,
) -> Strategy[N, P, Sequence[T]]
Evaluate a sequence of independent strategy computations, possibly in parallel.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
subs
|
Sequence[StrategyComp[N, P, T]]
|
A sequence of strategy computations to evaluate. |
required |
meta
|
Callable[[P], NodeMeta] | None
|
An optional mapping from the ambient inner policy to arbitrary metadata accessible to search policies. |
None
|
Returns:
Type | Description |
---|---|
Strategy[N, P, Sequence[T]]
|
A sequence featuring all computation results. |
Source code in src/delphyne/stdlib/nodes.py
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
|
Compute
Compute
dataclass
Bases: ComputationNode
The standard Compute
effect.
For efficiency and replicability reasons, strategies must not directly perform expensive and possibly non-replicable computations. For example, a strategy should not directly call an SMT solver since:
- The call may be expensive, and stratgy computations are replayed from
scratch every time a child is computed in the corresponding tree (see
documentation for
reify
). - SMT solvers using wall-time timeouts may return different results when called repeatedly on the same input.
The Compute
effect allows performing an expensive and possibly
non-deterministic computation by issuing a special __Computation__
query that specifies the computation to be performed. Such a query is
not answered by an LLM, but by actually performing the described
computation. Special support is available in the demonstration
interpreter in the form of implicit answers, allowing
__Computation__
queries to be automatically answered when running
tests. Generated answers can be hardcoded in demonstrations after
the fact via proper editor support.
Source code in src/delphyne/stdlib/computations.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
|
compute
Triggering function for the Compute
effect.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
f
|
Callable[P, T]
|
Function performing an expensive computation. It must feature type annotations and its arguments must be JSON-serializable. It does not need to be deterministic. |
required |
*args
|
P.args
|
Positional arguments to pass to |
()
|
**kwargs
|
P.kwargs
|
Keyword arguments to pass to |
{}
|
Source code in src/delphyne/stdlib/computations.py
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
|
elim_compute
elim_compute(
env: PolicyEnv, policy: Any, force_bypass_cache: bool = False
) -> PureTreeTransformerFn[Compute, Never]
Eliminate the Compute
effect by performing the computation when
computing tree children (making the child
function possibly
nondeterministic).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
force_bypass_cache
|
bool
|
if set to |
False
|
Source code in src/delphyne/stdlib/computations.py
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
|
__Computation__
dataclass
Bases: AbstractQuery[object]
A special query that represents a computation.
Returns a parsed JSON result.
Attributes:
Name | Type | Description |
---|---|---|
fun |
str
|
Name of the function to call. |
args |
dict[str, Any]
|
Arguments to pass to the function, as a dictionary. |
Source code in src/delphyne/stdlib/computations.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
|
Flag
Flag
dataclass
Bases: Node
The standard Flag
effect.
Flags allow providing several implementations for a strategy component, and have policies select which variant to use (or perform search at runtime for selecting variants).
For each flag, a subclass of FlagQuery
must be defined, which
admits a finite set of answers (one per allowed flag value), along
with a default answer. Type parameter F
denotes the type of the
flag query that can be issued. To express a signature wih several
flag queries, use Flag[A] | Flag[B]
instead of Flag[A | B]
, so
that both kinds of flags can be eliminated separately.
Behavior in demonstrations
Because flag queries override AbstractQuery.default_answer
,
default flag values are automatically selected by the
demonstration interpreter. This behaviour can be overriden by
adding answers for flag queries in the queries
section, or by
using value-based hints (i.e., #flag_value
, which is possible
since flag queries implement AbstractQuery.finite_answer_set
).
Source code in src/delphyne/stdlib/flags.py
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
|
get_flag
Triggering function for the Flag
effect.
Takes a flag query type as an argument and return a flag value.
Info
A more precise type cannot be given for this function since Python does not support higher-kinded types.
Source code in src/delphyne/stdlib/flags.py
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
|
elim_flag
elim_flag(
env: PolicyEnv, policy: Any, flag: type[F], val: str
) -> PureTreeTransformerFn[Flag[F], Never]
Source code in src/delphyne/stdlib/flags.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
|
FlagQuery
Bases: Query[T]
Base class for flag queries.
Type parameter T
must be of the form Literal[s1, ..., sn]
where
si
are string literals. The first value is considered the default.
Source code in src/delphyne/stdlib/flags.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
|