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.
- zuspec/solver/__init__.py +6 -0
- zuspec/solver/__version__.py +20 -0
- zuspec/solver/translate/__init__.py +31 -0
- zuspec/solver/translate/errors.py +14 -0
- zuspec/solver/translate/sink.py +56 -0
- zuspec/solver/translate/walk.py +1030 -0
- zuspec_solver-0.1.1.dist-info/METADATA +43 -0
- zuspec_solver-0.1.1.dist-info/RECORD +11 -0
- zuspec_solver-0.1.1.dist-info/WHEEL +5 -0
- zuspec_solver-0.1.1.dist-info/licenses/LICENSE +201 -0
- zuspec_solver-0.1.1.dist-info/top_level.txt +1 -0
|
@@ -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()
|