zuspec-solver 0.1.1__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.
@@ -0,0 +1,6 @@
1
+ """zuspec.solver -- Zuspec IR solve problems, translated for a solver.
2
+
3
+ The translation lives in :mod:`zuspec.solver.translate`.
4
+ """
5
+
6
+ from .__version__ import version as __version__
@@ -0,0 +1,20 @@
1
+
2
+ #****************************************************************************
3
+ # Copyright 2019-2025 Matthew Ballance and contributors
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #****************************************************************************
17
+ BASE="0.1.1"
18
+ SUFFIX=""
19
+ VERSION="%s%s" % (BASE, SUFFIX)
20
+ version=VERSION
@@ -0,0 +1,31 @@
1
+ """
2
+ zuspec.solver.translate -- Zuspec IR solve problems, translated for a solver.
3
+
4
+ ir-core collects a solve problem (``xf.pss_lower.constraints`` ->
5
+ ``ScSolveProblem``); this package translates it, once, for whichever backend
6
+ solves it. :func:`build_solve_blob` is the dv-solve form every in-process
7
+ solver runs (be-bc's interpreter, its native engine, pssc's presolve).
8
+ """
9
+ from __future__ import annotations
10
+
11
+ from typing import Dict, Tuple
12
+
13
+ from .errors import TranslateError
14
+ from .sink import Sink, builder_sink
15
+ from .walk import ProblemTranslator, slot_of, translate, writeback_slots
16
+
17
+ __all__ = [
18
+ "TranslateError", "Sink", "builder_sink", "ProblemTranslator",
19
+ "slot_of", "translate", "writeback_slots", "build_solve_blob",
20
+ ]
21
+
22
+
23
+ def build_solve_blob(problem) -> Tuple[bytes, Dict[int, int]]:
24
+ """*problem* as a relocatable dv-solve ``SolveProblem`` blob, with its
25
+ write-back map (object field slot -> solver var_id)."""
26
+ sp = builder_sink()
27
+ try:
28
+ wb = translate(problem, sp)
29
+ return sp.finalize_bytes(), wb
30
+ finally:
31
+ sp.destroy()
@@ -0,0 +1,14 @@
1
+ """Translation error type."""
2
+
3
+
4
+ class TranslateError(Exception):
5
+ """A constraint the solver cannot take.
6
+
7
+ Carries an optional ``loc`` (source location). A backend re-raises it as
8
+ its own error type: be-bc as a ``LoweringError``, so a refusal reads the
9
+ same whichever package found it.
10
+ """
11
+
12
+ def __init__(self, message, loc=None):
13
+ super().__init__(message)
14
+ self.loc = loc
@@ -0,0 +1,56 @@
1
+ """
2
+ sink.py -- what the constraint walk writes into.
3
+
4
+ A sink is the subset of dv-solve's growable builder
5
+ (``dv_solve.builder.SolveProblemBuilder``) that :mod:`.walk` calls. Each
6
+ ``expr_*`` returns a handle that a later call passes back; what a handle is is
7
+ the sink's business (the builder's are node offsets in its blob, a C-source
8
+ sink's would be the names of the C variables holding ``dvs_builder_*``
9
+ results). So the builder is a sink as it stands, and a new output is a new
10
+ class with these methods, not a second walk.
11
+ """
12
+ from __future__ import annotations
13
+
14
+ from typing import Dict, Iterable, List, Protocol, Sequence, Tuple
15
+
16
+
17
+ class Sink(Protocol):
18
+ def add_var(self, var_id: int, width: int, is_signed: bool,
19
+ lo: int, hi: int) -> None: ...
20
+
21
+ def expr_const(self, value: int, is_signed: bool = ..., width: int = ...): ...
22
+
23
+ def expr_var(self, var_id: int): ...
24
+
25
+ def expr_binary(self, op: int, lhs, rhs): ...
26
+
27
+ def expr_unary(self, op: int, operand): ...
28
+
29
+ def expr_ite(self, cond, then, els): ...
30
+
31
+ def expr_cast(self, operand, width: int, is_signed: bool): ...
32
+
33
+ def expr_in_range(self, value, lo, hi): ...
34
+
35
+ def expr_in_ranges(self, value, pairs: Sequence[Tuple[object, object]]): ...
36
+
37
+ def add_constraint(self, expr) -> None: ...
38
+
39
+ def add_soft_constraint(self, expr, priority: int) -> None: ...
40
+
41
+ def add_dist(self, var_id: int, entries: List[Dict]) -> None: ...
42
+
43
+ def add_all_different(self, var_ids: Iterable[int]) -> None: ...
44
+
45
+
46
+ def builder_sink():
47
+ """A fresh dv-solve growable builder. The caller ``finalize_bytes()``s it
48
+ and then ``destroy()``s it."""
49
+ try:
50
+ from dv_solve.builder import SolveProblemBuilder
51
+ except Exception as exc: # pragma: no cover - environment-dependent
52
+ from .errors import TranslateError
53
+ raise TranslateError(
54
+ "dv-solve is required to build a solve blob "
55
+ "(cannot import dv_solve.builder): %s" % exc)
56
+ return SolveProblemBuilder()