solverpilot 0.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.
Files changed (201) hide show
  1. solverpilot/__init__.py +250 -0
  2. solverpilot/_immutability.py +27 -0
  3. solverpilot/_version.py +3 -0
  4. solverpilot/applications/__init__.py +3 -0
  5. solverpilot/applications/routing/__init__.py +19 -0
  6. solverpilot/applications/routing/compile_milp.py +321 -0
  7. solverpilot/applications/routing/diagnostics.py +78 -0
  8. solverpilot/applications/routing/errors.py +14 -0
  9. solverpilot/applications/routing/heuristics.py +167 -0
  10. solverpilot/applications/routing/model.py +259 -0
  11. solverpilot/applications/routing/reference.py +81 -0
  12. solverpilot/applications/routing/solution.py +89 -0
  13. solverpilot/applications/routing/timeline.py +79 -0
  14. solverpilot/applications/routing/validation.py +169 -0
  15. solverpilot/applications/tsp/__init__.py +41 -0
  16. solverpilot/applications/tsp/compile_cp.py +121 -0
  17. solverpilot/applications/tsp/compile_milp.py +139 -0
  18. solverpilot/applications/tsp/distance.py +60 -0
  19. solverpilot/applications/tsp/errors.py +17 -0
  20. solverpilot/applications/tsp/heuristics.py +112 -0
  21. solverpilot/applications/tsp/model.py +175 -0
  22. solverpilot/applications/tsp/reference.py +121 -0
  23. solverpilot/applications/tsp/solution.py +65 -0
  24. solverpilot/applications/tsp/validation.py +92 -0
  25. solverpilot/backends/__init__.py +51 -0
  26. solverpilot/backends/_casadi_highs_worker.py +92 -0
  27. solverpilot/backends/base.py +28 -0
  28. solverpilot/backends/bundled_capi.py +910 -0
  29. solverpilot/backends/casadi_conic.py +303 -0
  30. solverpilot/backends/health.py +240 -0
  31. solverpilot/backends/highspy_native.py +217 -0
  32. solverpilot/backends/nlopt_native.py +237 -0
  33. solverpilot/backends/osqp_native.py +297 -0
  34. solverpilot/backends/protocol_v2.py +119 -0
  35. solverpilot/backends/pyscipopt_native.py +200 -0
  36. solverpilot/backends/registry.py +38 -0
  37. solverpilot/backends/scipy_highs.py +138 -0
  38. solverpilot/backends/scipy_highs_lp.py +195 -0
  39. solverpilot/backends/scipy_slsqp_qp.py +133 -0
  40. solverpilot/backends/scipy_vendored_highs_dev.py +363 -0
  41. solverpilot/benchmark/__init__.py +23 -0
  42. solverpilot/benchmark/acquire.py +199 -0
  43. solverpilot/benchmark/baselines.py +70 -0
  44. solverpilot/benchmark/bundle.py +37 -0
  45. solverpilot/benchmark/campaign.py +150 -0
  46. solverpilot/benchmark/environment.py +115 -0
  47. solverpilot/benchmark/integrity.py +46 -0
  48. solverpilot/benchmark/model.py +146 -0
  49. solverpilot/benchmark/policy.py +182 -0
  50. solverpilot/benchmark/registry.py +38 -0
  51. solverpilot/benchmark/report.py +44 -0
  52. solverpilot/benchmark/runner.py +516 -0
  53. solverpilot/benchmark/slurm.py +55 -0
  54. solverpilot/benchmark/specs.py +75 -0
  55. solverpilot/benchmark/splits.py +181 -0
  56. solverpilot/benchmark/summary.py +384 -0
  57. solverpilot/benchmark/verify.py +142 -0
  58. solverpilot/benchmark/worker.py +71 -0
  59. solverpilot/bridges/__init__.py +19 -0
  60. solverpilot/bridges/engine.py +44 -0
  61. solverpilot/bridges/indicator.py +232 -0
  62. solverpilot/bridges/registry.py +78 -0
  63. solverpilot/bridges/transformation-tape.schema.json +53 -0
  64. solverpilot/bridges/types.py +149 -0
  65. solverpilot/bridges/validation.py +110 -0
  66. solverpilot/capabilities/__init__.py +32 -0
  67. solverpilot/capabilities/backend-capability-v2.schema.json +21 -0
  68. solverpilot/capabilities/conformance.py +151 -0
  69. solverpilot/capabilities/enums.py +27 -0
  70. solverpilot/capabilities/manifest.py +19 -0
  71. solverpilot/capabilities/ontology.py +73 -0
  72. solverpilot/capabilities/requirements.py +37 -0
  73. solverpilot/capabilities/resolve.py +30 -0
  74. solverpilot/capabilities/v2.py +711 -0
  75. solverpilot/cli/__init__.py +1 -0
  76. solverpilot/cli/backend_health.py +77 -0
  77. solverpilot/cli/benchmark.py +331 -0
  78. solverpilot/cli/benchmark_worker.py +33 -0
  79. solverpilot/cli/capabilities.py +65 -0
  80. solverpilot/conic/__init__.py +11 -0
  81. solverpilot/conic/backend.py +263 -0
  82. solverpilot/conic/compiler.py +310 -0
  83. solverpilot/conic/conformance.py +60 -0
  84. solverpilot/conic/conic-ir-v1.schema.json +24 -0
  85. solverpilot/conic/ir.py +299 -0
  86. solverpilot/conic/validation.py +149 -0
  87. solverpilot/cp/__init__.py +7 -0
  88. solverpilot/cp/conformance.py +32 -0
  89. solverpilot/cp/cp-ir-v1.schema.json +13 -0
  90. solverpilot/cp/ir.py +170 -0
  91. solverpilot/cp/model.py +143 -0
  92. solverpilot/cp/ortools_backend.py +423 -0
  93. solverpilot/cp/ortools_worker.py +75 -0
  94. solverpilot/cp/reference.py +51 -0
  95. solverpilot/cp/serialization.py +117 -0
  96. solverpilot/cp/validate.py +83 -0
  97. solverpilot/diagnose/__init__.py +33 -0
  98. solverpilot/diagnose/infeasibility.py +463 -0
  99. solverpilot/diagnose/model.py +87 -0
  100. solverpilot/evaluation/__init__.py +53 -0
  101. solverpilot/evaluation/metrics.py +150 -0
  102. solverpilot/evaluation/oracle.py +288 -0
  103. solverpilot/evaluation/proof.py +53 -0
  104. solverpilot/evaluation/references.py +73 -0
  105. solverpilot/evaluation/regret.py +281 -0
  106. solverpilot/exceptions.py +34 -0
  107. solverpilot/experimental/__init__.py +32 -0
  108. solverpilot/extensions/__init__.py +56 -0
  109. solverpilot/extensions/entrypoints.py +34 -0
  110. solverpilot/extensions/errors.py +35 -0
  111. solverpilot/extensions/manager.py +651 -0
  112. solverpilot/extensions/manifest.py +232 -0
  113. solverpilot/extensions/model.py +101 -0
  114. solverpilot/extensions/versioning.py +136 -0
  115. solverpilot/history/__init__.py +22 -0
  116. solverpilot/history/errors.py +15 -0
  117. solverpilot/history/model.py +129 -0
  118. solverpilot/history/sqlite.py +651 -0
  119. solverpilot/inspect/__init__.py +3 -0
  120. solverpilot/inspect/fingerprint.py +199 -0
  121. solverpilot/intelligence/__init__.py +36 -0
  122. solverpilot/intelligence/errors.py +16 -0
  123. solverpilot/intelligence/fingerprint.py +108 -0
  124. solverpilot/intelligence/leakage.py +69 -0
  125. solverpilot/intelligence/schema.py +314 -0
  126. solverpilot/intelligence/shift.py +208 -0
  127. solverpilot/io/__init__.py +41 -0
  128. solverpilot/io/binary64.py +49 -0
  129. solverpilot/io/csv.py +230 -0
  130. solverpilot/io/errors.py +25 -0
  131. solverpilot/io/hashing.py +111 -0
  132. solverpilot/io/json.py +90 -0
  133. solverpilot/io/mapping.py +195 -0
  134. solverpilot/io/model.py +407 -0
  135. solverpilot/io/numeric.py +108 -0
  136. solverpilot/io/provenance.py +114 -0
  137. solverpilot/io/result.py +45 -0
  138. solverpilot/io/source.py +104 -0
  139. solverpilot/io/strict_json.py +133 -0
  140. solverpilot/minlp/__init__.py +6 -0
  141. solverpilot/minlp/compiler.py +66 -0
  142. solverpilot/minlp/conformance.py +34 -0
  143. solverpilot/minlp/convexity.py +85 -0
  144. solverpilot/minlp/ir.py +35 -0
  145. solverpilot/minlp/minlp-ir-v1.schema.json +1 -0
  146. solverpilot/minlp/orchestrator.py +220 -0
  147. solverpilot/minlp/validation.py +28 -0
  148. solverpilot/model/__init__.py +27 -0
  149. solverpilot/model/compiler.py +1263 -0
  150. solverpilot/model/errors.py +22 -0
  151. solverpilot/model/expression.py +373 -0
  152. solverpilot/model/model.py +716 -0
  153. solverpilot/model/sets.py +60 -0
  154. solverpilot/model/types.py +36 -0
  155. solverpilot/nlp/__init__.py +7 -0
  156. solverpilot/nlp/ad.py +166 -0
  157. solverpilot/nlp/backend.py +113 -0
  158. solverpilot/nlp/compiler.py +116 -0
  159. solverpilot/nlp/conformance.py +58 -0
  160. solverpilot/nlp/ir.py +70 -0
  161. solverpilot/nlp/nlp-ir-v1.schema.json +1 -0
  162. solverpilot/nlp/validation.py +60 -0
  163. solverpilot/plan/__init__.py +33 -0
  164. solverpilot/plan/model.py +79 -0
  165. solverpilot/plan/planner.py +201 -0
  166. solverpilot/plan/production.py +627 -0
  167. solverpilot/plan/selective_lp.py +65 -0
  168. solverpilot/problem/__init__.py +16 -0
  169. solverpilot/problem/enums.py +20 -0
  170. solverpilot/problem/hashing.py +88 -0
  171. solverpilot/problem/linear.py +196 -0
  172. solverpilot/problem/mps.py +447 -0
  173. solverpilot/problem/quadratic.py +192 -0
  174. solverpilot/reporting/__init__.py +27 -0
  175. solverpilot/reporting/explain.py +327 -0
  176. solverpilot/reporting/model.py +264 -0
  177. solverpilot/reporting/render.py +55 -0
  178. solverpilot/runtime/__init__.py +19 -0
  179. solverpilot/runtime/auto.py +193 -0
  180. solverpilot/runtime/budgeting.py +43 -0
  181. solverpilot/runtime/executor.py +126 -0
  182. solverpilot/runtime/portfolio.py +197 -0
  183. solverpilot/runtime/result.py +72 -0
  184. solverpilot/session/__init__.py +29 -0
  185. solverpilot/session/conformance_v2.py +239 -0
  186. solverpilot/session/mutations.py +115 -0
  187. solverpilot/session/persistent-session-trace.schema.json +45 -0
  188. solverpilot/session/persistent.py +491 -0
  189. solverpilot/session/reuse.py +81 -0
  190. solverpilot/session/session.py +236 -0
  191. solverpilot/trace/__init__.py +3 -0
  192. solverpilot/trace/schema.py +47 -0
  193. solverpilot/validate/__init__.py +10 -0
  194. solverpilot/validate/core.py +179 -0
  195. solverpilot/validate/result.py +55 -0
  196. solverpilot-0.1.dist-info/METADATA +554 -0
  197. solverpilot-0.1.dist-info/RECORD +201 -0
  198. solverpilot-0.1.dist-info/WHEEL +5 -0
  199. solverpilot-0.1.dist-info/entry_points.txt +4 -0
  200. solverpilot-0.1.dist-info/licenses/LICENSE +202 -0
  201. solverpilot-0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,51 @@
1
+ from __future__ import annotations
2
+ from collections.abc import Mapping
3
+ from dataclasses import dataclass
4
+ from typing import Any
5
+ import itertools, math
6
+ from solverpilot._immutability import deep_freeze
7
+ from .ir import *
8
+ from .validate import validate_cp_solution, complete_assignment
9
+
10
+ @dataclass(frozen=True, slots=True)
11
+ class CPSolveResult:
12
+ status:str
13
+ assignment:Mapping[int,int]|None
14
+ objective:int|None
15
+ validation:object
16
+ optimality_proven:bool
17
+ backend:str
18
+ raw_statistics:Mapping[str,Any]
19
+
20
+ def __post_init__(self):
21
+ if self.assignment is not None:
22
+ object.__setattr__(self, 'assignment', deep_freeze(dict(self.assignment)))
23
+ object.__setattr__(self, 'raw_statistics', deep_freeze(dict(self.raw_statistics)))
24
+
25
+ class ReferenceCPBackend:
26
+ name='reference-cp-enumeration'
27
+ verification_only=True
28
+ def __init__(self,max_states=1_000_000): self.max_states=int(max_states)
29
+ def is_available(self): return True
30
+ def solve(self,problem:CPProblem,*,max_states=None):
31
+ limit=self.max_states if max_states is None else int(max_states)
32
+ base=problem.base_variables
33
+ states=math.prod(len(v.domain) for v in base)
34
+ if states>limit:
35
+ return CPSolveResult('unknown_state_limit',None,None,validate_cp_solution(problem,{}),False,self.name,{'states_total':states,'states_examined':0,'limit':limit})
36
+ best=None; best_obj=None; examined=0; feasible=0
37
+ for values in itertools.product(*(v.domain for v in base)):
38
+ examined+=1; a={v.var_id:int(x) for v,x in zip(base,values)}; a=complete_assignment(problem,a)
39
+ rep=validate_cp_solution(problem,a)
40
+ if not rep.valid: continue
41
+ feasible+=1; obj=rep.objective_recomputed
42
+ if problem.objective is None:
43
+ best=a; best_obj=None; break
44
+ if best is None or (problem.objective_sense is CPObjectiveSense.MINIMIZE and obj<best_obj) or (problem.objective_sense is CPObjectiveSense.MAXIMIZE and obj>best_obj):
45
+ best=a.copy(); best_obj=obj
46
+ if best is None:
47
+ # If objective-free search stops at first feasible only when found; no feasible means full enumeration.
48
+ return CPSolveResult('infeasible',None,None,validate_cp_solution(problem,{}),True,self.name,{'states_total':states,'states_examined':examined,'feasible_seen':feasible})
49
+ rep=validate_cp_solution(problem,best,best_obj)
50
+ proof = problem.objective is None or examined==states
51
+ return CPSolveResult('optimal' if problem.objective is not None and proof else 'feasible',best,best_obj,rep,proof,self.name,{'states_total':states,'states_examined':examined,'feasible_seen':feasible})
@@ -0,0 +1,117 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Mapping
4
+
5
+ from .ir import (
6
+ CPAllDifferentIR,
7
+ CPCircuitIR,
8
+ CPCumulativeIR,
9
+ CPElementIR,
10
+ CPExactlyOneIR,
11
+ CPIntVarIR,
12
+ CPIntervalIR,
13
+ CPLinearConstraintIR,
14
+ CPLinearExprIR,
15
+ CPNoOverlapIR,
16
+ CPObjectiveSense,
17
+ CPProblem,
18
+ CPTableIR,
19
+ )
20
+
21
+
22
+ def _expr_from_dict(payload: Mapping[str, Any]) -> CPLinearExprIR:
23
+ return CPLinearExprIR(
24
+ terms=tuple((int(v), int(c)) for v, c in payload.get("terms", ())),
25
+ constant=int(payload.get("constant", 0)),
26
+ )
27
+
28
+
29
+ def problem_from_canonical_dict(payload: Mapping[str, Any]) -> CPProblem:
30
+ """Reconstruct canonical CP IR from :meth:`CPProblem.canonical_dict` output.
31
+
32
+ This deliberately accepts only the closed P9 schema families. It is used by
33
+ the isolated CP-SAT worker so no pickle/arbitrary-code serialization crosses
34
+ the process boundary.
35
+ """
36
+ variables = tuple(
37
+ CPIntVarIR(
38
+ var_id=int(v["id"]),
39
+ name=str(v["name"]),
40
+ domain=tuple(int(x) for x in v["domain"]),
41
+ kind=str(v.get("kind", "int")),
42
+ derived_from=None
43
+ if v.get("derived_from") is None
44
+ else (int(v["derived_from"][0]), int(v["derived_from"][1])),
45
+ )
46
+ for v in payload.get("variables", ())
47
+ )
48
+ intervals = tuple(
49
+ CPIntervalIR(
50
+ interval_id=int(i["id"]),
51
+ name=str(i["name"]),
52
+ start_var=int(i["start_var"]),
53
+ size=int(i["size"]),
54
+ end_var=int(i["end_var"]),
55
+ )
56
+ for i in payload.get("intervals", ())
57
+ )
58
+
59
+ constraints = []
60
+ for c in payload.get("constraints", ()):
61
+ kind = c["kind"]
62
+ if kind == "linear":
63
+ constraints.append(
64
+ CPLinearConstraintIR(
65
+ _expr_from_dict(c["expr"]),
66
+ None if c.get("lower") is None else int(c["lower"]),
67
+ None if c.get("upper") is None else int(c["upper"]),
68
+ )
69
+ )
70
+ elif kind == "all_different":
71
+ constraints.append(CPAllDifferentIR(tuple(int(x) for x in c["var_ids"])))
72
+ elif kind == "exactly_one":
73
+ constraints.append(CPExactlyOneIR(tuple(int(x) for x in c["literal_ids"])))
74
+ elif kind == "table":
75
+ constraints.append(
76
+ CPTableIR(
77
+ tuple(int(x) for x in c["var_ids"]),
78
+ tuple(tuple(int(x) for x in row) for row in c["allowed_tuples"]),
79
+ )
80
+ )
81
+ elif kind == "element":
82
+ constraints.append(
83
+ CPElementIR(
84
+ int(c["index_var"]),
85
+ tuple(int(x) for x in c["values"]),
86
+ int(c["target_var"]),
87
+ )
88
+ )
89
+ elif kind == "circuit":
90
+ constraints.append(
91
+ CPCircuitIR(tuple(tuple(int(x) for x in arc) for arc in c["arcs"]))
92
+ )
93
+ elif kind == "no_overlap":
94
+ constraints.append(CPNoOverlapIR(tuple(int(x) for x in c["interval_ids"])))
95
+ elif kind == "cumulative":
96
+ constraints.append(
97
+ CPCumulativeIR(
98
+ tuple(int(x) for x in c["interval_ids"]),
99
+ tuple(int(x) for x in c["demands"]),
100
+ int(c["capacity"]),
101
+ )
102
+ )
103
+ else:
104
+ raise ValueError(f"unsupported CP constraint kind in isolated payload: {kind!r}")
105
+
106
+ objective_payload = payload.get("objective")
107
+ objective = None if objective_payload is None else _expr_from_dict(objective_payload)
108
+ return CPProblem(
109
+ variables=variables,
110
+ intervals=intervals,
111
+ constraints=tuple(constraints),
112
+ objective=objective,
113
+ objective_sense=CPObjectiveSense(payload.get("objective_sense", "minimize")),
114
+ name=payload.get("name"),
115
+ metadata=dict(payload.get("metadata", {})),
116
+ schema_version=str(payload.get("schema_version", "solverpilot.cp-ir.v1")),
117
+ )
@@ -0,0 +1,83 @@
1
+ from __future__ import annotations
2
+ from dataclasses import dataclass
3
+ from typing import Mapping
4
+ import math
5
+ from .ir import *
6
+
7
+ @dataclass(frozen=True, slots=True)
8
+ class CPValidationReport:
9
+ valid:bool
10
+ domain_violations:tuple[int,...]
11
+ constraint_violations:tuple[int,...]
12
+ derived_violations:tuple[int,...]
13
+ objective_recomputed:int|None
14
+ objective_reported:int|None
15
+ objective_consistent:bool|None
16
+
17
+ def _expr(e, a): return e.constant + sum(c*a[v] for v,c in e.terms)
18
+
19
+ def complete_assignment(problem,assignment):
20
+ a={int(k):int(v) for k,v in dict(assignment).items()}
21
+ pending=True
22
+ while pending:
23
+ pending=False
24
+ for v in problem.variables:
25
+ if v.var_id in a: continue
26
+ if v.derived_from is not None:
27
+ s,size=v.derived_from
28
+ if s in a: a[v.var_id]=a[s]+size; pending=True
29
+ return a
30
+
31
+ def _circuit_ok(c,a):
32
+ nodes=set(); selected=[]
33
+ for t,h,l in c.arcs:
34
+ nodes.add(t); nodes.add(h)
35
+ if a[l]==1: selected.append((t,h))
36
+ # CP-SAT semantics: incident nodes exactly one selected incoming/outgoing.
37
+ for n in nodes:
38
+ if sum(1 for t,h in selected if t==n)!=1: return False
39
+ if sum(1 for t,h in selected if h==n)!=1: return False
40
+ nonself=[e for e in selected if e[0]!=e[1]]
41
+ if not nonself: return True
42
+ active=set(x for e in nonself for x in e)
43
+ start=next(iter(active)); seen={start}; cur=start
44
+ for _ in range(len(active)):
45
+ nxts=[h for t,h in nonself if t==cur]
46
+ if len(nxts)!=1: return False
47
+ cur=nxts[0]
48
+ if cur==start: break
49
+ if cur in seen: return False
50
+ seen.add(cur)
51
+ return cur==start and seen==active
52
+
53
+ def validate_cp_solution(problem:CPProblem,assignment:Mapping[int,int],objective_reported=None):
54
+ a=complete_assignment(problem,assignment); dviol=[]; derived=[]; cviol=[]
55
+ for v in problem.variables:
56
+ if v.var_id not in a or a[v.var_id] not in v.domain: dviol.append(v.var_id)
57
+ if v.derived_from is not None and v.var_id in a:
58
+ s,size=v.derived_from
59
+ if s not in a or a[v.var_id] != a[s]+size: derived.append(v.var_id)
60
+ imap=problem.interval_map
61
+ for idx,c in enumerate(problem.constraints):
62
+ ok=True
63
+ try:
64
+ if isinstance(c,CPLinearConstraintIR):
65
+ val=_expr(c.expr,a); ok=(c.lower is None or val>=c.lower) and (c.upper is None or val<=c.upper)
66
+ elif isinstance(c,CPAllDifferentIR): ok=len({a[v] for v in c.var_ids})==len(c.var_ids)
67
+ elif isinstance(c,CPExactlyOneIR): ok=sum(a[v] for v in c.literal_ids)==1
68
+ elif isinstance(c,CPTableIR): ok=tuple(a[v] for v in c.var_ids) in set(c.allowed_tuples)
69
+ elif isinstance(c,CPElementIR):
70
+ ix=a[c.index_var]; ok=0<=ix<len(c.values) and a[c.target_var]==c.values[ix]
71
+ elif isinstance(c,CPCircuitIR): ok=_circuit_ok(c,a)
72
+ elif isinstance(c,CPNoOverlapIR):
73
+ spans=[(a[imap[i].start_var],a[imap[i].end_var]) for i in c.interval_ids]
74
+ ok=all(e1<=s2 or e2<=s1 for j,(s1,e1) in enumerate(spans) for s2,e2 in spans[j+1:])
75
+ elif isinstance(c,CPCumulativeIR):
76
+ items=[(a[imap[i].start_var],a[imap[i].end_var],d) for i,d in zip(c.interval_ids,c.demands)]
77
+ points=sorted({s for s,e,d in items if s<e})
78
+ ok=c.capacity>=0 and all(sum(d for s,e,d in items if s<=t<e)<=c.capacity for t in points)
79
+ except KeyError: ok=False
80
+ if not ok: cviol.append(idx)
81
+ obj=None if problem.objective is None or any(v not in a for v,c in problem.objective.terms) else _expr(problem.objective,a)
82
+ consistent=None if objective_reported is None or obj is None else int(objective_reported)==int(obj)
83
+ return CPValidationReport(not dviol and not derived and not cviol and consistent is not False,tuple(dviol),tuple(cviol),tuple(derived),obj,None if objective_reported is None else int(objective_reported),consistent)
@@ -0,0 +1,33 @@
1
+ from .infeasibility import (
2
+ deletion_filter_conflict,
3
+ diagnose_infeasibility,
4
+ elastic_relaxation,
5
+ find_static_infeasibility,
6
+ )
7
+ from .model import (
8
+ ConflictAtom,
9
+ ConflictSetResult,
10
+ DiagnosticIssue,
11
+ ElasticRelaxationResult,
12
+ EvidenceKind,
13
+ InfeasibilityReport,
14
+ NormalizedIISEvidence,
15
+ RelaxationViolation,
16
+ ViolationKind,
17
+ )
18
+
19
+ __all__ = [
20
+ "ConflictAtom",
21
+ "ConflictSetResult",
22
+ "DiagnosticIssue",
23
+ "ElasticRelaxationResult",
24
+ "EvidenceKind",
25
+ "InfeasibilityReport",
26
+ "NormalizedIISEvidence",
27
+ "RelaxationViolation",
28
+ "ViolationKind",
29
+ "deletion_filter_conflict",
30
+ "diagnose_infeasibility",
31
+ "elastic_relaxation",
32
+ "find_static_infeasibility",
33
+ ]