ommx-python-mip-adapter 3.0.0b4__tar.gz → 3.0.0b6__tar.gz

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 (18) hide show
  1. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/PKG-INFO +4 -4
  2. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/README.md +2 -2
  3. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/ommx_python_mip_adapter/adapter.py +26 -21
  4. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/ommx_python_mip_adapter/python_mip_to_ommx.py +14 -6
  5. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/ommx_python_mip_adapter.egg-info/PKG-INFO +4 -4
  6. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/ommx_python_mip_adapter.egg-info/requires.txt +1 -1
  7. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/pyproject.toml +2 -2
  8. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/tests/test_adapter.py +25 -8
  9. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/tests/test_constant_constraint.py +3 -3
  10. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/tests/test_integration.py +9 -9
  11. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/tests/test_model_to_instance.py +13 -13
  12. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/tests/test_tracing.py +3 -3
  13. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/ommx_python_mip_adapter/__init__.py +0 -0
  14. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/ommx_python_mip_adapter/exception.py +0 -0
  15. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/ommx_python_mip_adapter.egg-info/SOURCES.txt +0 -0
  16. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/ommx_python_mip_adapter.egg-info/dependency_links.txt +0 -0
  17. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/ommx_python_mip_adapter.egg-info/top_level.txt +0 -0
  18. {ommx_python_mip_adapter-3.0.0b4 → ommx_python_mip_adapter-3.0.0b6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ommx_python_mip_adapter
3
- Version: 3.0.0b4
3
+ Version: 3.0.0b6
4
4
  Summary: An adapter for the Python-MIP from/to OMMX.
5
5
  Author-email: "Jij Inc." <info@j-ij.com>
6
6
  Project-URL: Repository, https://github.com/Jij-Inc/ommx
@@ -15,7 +15,7 @@ Classifier: License :: OSI Approved :: Apache Software License
15
15
  Classifier: License :: OSI Approved :: MIT License
16
16
  Requires-Python: >=3.10
17
17
  Description-Content-Type: text/markdown
18
- Requires-Dist: ommx<4.0.0,>=3.0.0b4
18
+ Requires-Dist: ommx<4.0.0,>=3.0.0b6
19
19
  Requires-Dist: mip<2.0.0,>=1.17.0
20
20
  Requires-Dist: cffi<2.0.0,>=1.15.0
21
21
 
@@ -67,14 +67,14 @@ Python-MIP can be used through `ommx-python-mip-adapter` by using the following:
67
67
 
68
68
  ```python markdown-code-runner
69
69
  from ommx_python_mip_adapter import OMMXPythonMIPAdapter
70
- from ommx import Instance, DecisionVariable
70
+ from ommx import DecisionVariable, Instance, Sense
71
71
 
72
72
  x1 = DecisionVariable.integer(1, lower=0, upper=5)
73
73
  ommx_instance = Instance.from_components(
74
74
  decision_variables=[x1],
75
75
  objective=x1,
76
76
  constraints={},
77
- sense=Instance.MINIMIZE,
77
+ sense=Sense.Minimize,
78
78
  )
79
79
 
80
80
  # Create `ommx.Solution` from the `mip.Model`
@@ -46,14 +46,14 @@ Python-MIP can be used through `ommx-python-mip-adapter` by using the following:
46
46
 
47
47
  ```python markdown-code-runner
48
48
  from ommx_python_mip_adapter import OMMXPythonMIPAdapter
49
- from ommx import Instance, DecisionVariable
49
+ from ommx import DecisionVariable, Instance, Sense
50
50
 
51
51
  x1 = DecisionVariable.integer(1, lower=0, upper=5)
52
52
  ommx_instance = Instance.from_components(
53
53
  decision_variables=[x1],
54
54
  objective=x1,
55
55
  constraints={},
56
- sense=Instance.MINIMIZE,
56
+ sense=Sense.Minimize,
57
57
  )
58
58
 
59
59
  # Create `ommx.Solution` from the `mip.Model`
@@ -14,15 +14,13 @@ from ommx.adapter import (
14
14
  NoSolutionReturned,
15
15
  )
16
16
  from ommx import (
17
- Constraint,
18
- DecisionVariable,
19
- DegreeBound,
20
17
  Equality,
21
18
  Function,
22
19
  Instance,
23
20
  InstanceClass,
24
21
  InstanceClassClause,
25
22
  Kind,
23
+ PolynomialRequirement,
26
24
  PreparationPolicy,
27
25
  Sense,
28
26
  Solution,
@@ -35,9 +33,9 @@ from .exception import OMMXPythonMIPAdapterError
35
33
 
36
34
  _tracer = trace.get_tracer("ommx.adapter.python_mip")
37
35
 
38
- _LINEAR_CONSTRAINT_DEGREE_BOUNDS = {
39
- Equality.EqualToZero: DegreeBound.at_most(1),
40
- Equality.LessThanOrEqualToZero: DegreeBound.at_most(1),
36
+ _LINEAR_CONSTRAINT_POLYNOMIAL_REQUIREMENTS = {
37
+ Equality.EqualToZero: PolynomialRequirement.at_most(1),
38
+ Equality.LessThanOrEqualToZero: PolynomialRequirement.at_most(1),
41
39
  }
42
40
 
43
41
 
@@ -47,8 +45,10 @@ class OMMXPythonMIPAdapter(SolverAdapter):
47
45
  InstanceClassClause(
48
46
  label="python-mip-linear-mip",
49
47
  allowed_variable_kinds={Kind.Binary, Kind.Integer, Kind.Continuous},
50
- objective_degree_bound=DegreeBound.at_most(1),
51
- regular_constraint_degree_bounds=_LINEAR_CONSTRAINT_DEGREE_BOUNDS,
48
+ objective_polynomial_requirement=PolynomialRequirement.at_most(1),
49
+ regular_constraint_polynomial_requirements=(
50
+ _LINEAR_CONSTRAINT_POLYNOMIAL_REQUIREMENTS
51
+ ),
52
52
  allowed_senses={Sense.Minimize, Sense.Maximize},
53
53
  )
54
54
  ]
@@ -92,9 +92,9 @@ class OMMXPythonMIPAdapter(SolverAdapter):
92
92
  """
93
93
  with _tracer.start_as_current_span("convert"):
94
94
  self.require_applicable(ommx_instance)
95
- if ommx_instance.sense == Instance.MAXIMIZE:
95
+ if ommx_instance.sense == Sense.Maximize:
96
96
  sense = mip.MAXIMIZE
97
- elif ommx_instance.sense == Instance.MINIMIZE:
97
+ elif ommx_instance.sense == Sense.Minimize:
98
98
  sense = mip.MINIMIZE
99
99
  else:
100
100
  raise OMMXPythonMIPAdapterError(
@@ -157,7 +157,7 @@ class OMMXPythonMIPAdapter(SolverAdapter):
157
157
  ... decision_variables=x,
158
158
  ... objective=sum(p[i] * x[i] for i in range(6)),
159
159
  ... constraints={0: sum(w[i] * x[i] for i in range(6)) <= 47},
160
- ... sense=Instance.MAXIMIZE,
160
+ ... sense=Sense.Maximize,
161
161
  ... )
162
162
 
163
163
  Solve it
@@ -192,7 +192,7 @@ class OMMXPythonMIPAdapter(SolverAdapter):
192
192
  ... decision_variables=[x],
193
193
  ... objective=x,
194
194
  ... constraints={0: x >= 4},
195
- ... sense=Instance.MAXIMIZE,
195
+ ... sense=Sense.Maximize,
196
196
  ... )
197
197
 
198
198
  >>> OMMXPythonMIPAdapter.solve(instance)
@@ -212,7 +212,7 @@ class OMMXPythonMIPAdapter(SolverAdapter):
212
212
  ... decision_variables=[x],
213
213
  ... objective=x,
214
214
  ... constraints={},
215
- ... sense=Instance.MAXIMIZE,
215
+ ... sense=Sense.Maximize,
216
216
  ... )
217
217
 
218
218
  >>> OMMXPythonMIPAdapter.solve(instance)
@@ -233,7 +233,7 @@ class OMMXPythonMIPAdapter(SolverAdapter):
233
233
  ... decision_variables=[x, y],
234
234
  ... objective=x + y,
235
235
  ... constraints={0: x + y <= 1},
236
- ... sense=Instance.MAXIMIZE,
236
+ ... sense=Sense.Maximize,
237
237
  ... )
238
238
 
239
239
  >>> solution = OMMXPythonMIPAdapter.solve(instance)
@@ -313,7 +313,7 @@ class OMMXPythonMIPAdapter(SolverAdapter):
313
313
  ... decision_variables=x,
314
314
  ... objective=sum(p[i] * x[i] for i in range(6)),
315
315
  ... constraints={0: sum(w[i] * x[i] for i in range(6)) <= 47},
316
- ... sense=Instance.MAXIMIZE,
316
+ ... sense=Sense.Maximize,
317
317
  ... )
318
318
 
319
319
  >>> adapter = OMMXPythonMIPAdapter(instance)
@@ -371,7 +371,7 @@ class OMMXPythonMIPAdapter(SolverAdapter):
371
371
  ... decision_variables=[x1],
372
372
  ... objective=x1,
373
373
  ... constraints={},
374
- ... sense=Instance.MINIMIZE,
374
+ ... sense=Sense.Minimize,
375
375
  ... )
376
376
  >>> adapter = OMMXPythonMIPAdapter(ommx_instance)
377
377
  >>> model = adapter.solver_input
@@ -414,19 +414,19 @@ class OMMXPythonMIPAdapter(SolverAdapter):
414
414
 
415
415
  def _set_decision_variables(self):
416
416
  for var in self.instance.used_decision_variables:
417
- if var.kind == DecisionVariable.BINARY:
417
+ if var.kind == Kind.Binary:
418
418
  self.model.add_var(
419
419
  name=str(var.id),
420
420
  var_type=mip.BINARY,
421
421
  )
422
- elif var.kind == DecisionVariable.INTEGER:
422
+ elif var.kind == Kind.Integer:
423
423
  self.model.add_var(
424
424
  name=str(var.id),
425
425
  var_type=mip.INTEGER,
426
426
  lb=var.bound.lower, # type: ignore
427
427
  ub=var.bound.upper, # type: ignore
428
428
  )
429
- elif var.kind == DecisionVariable.CONTINUOUS:
429
+ elif var.kind == Kind.Continuous:
430
430
  self.model.add_var(
431
431
  name=str(var.id),
432
432
  var_type=mip.CONTINUOUS,
@@ -447,6 +447,11 @@ class OMMXPythonMIPAdapter(SolverAdapter):
447
447
  Translate ommx.Function to `mip.LinExpr` or `float`.
448
448
  """
449
449
  degree = f.degree()
450
+ if degree is None:
451
+ raise OMMXPythonMIPAdapterError(
452
+ "Non-polynomial functions are not supported. "
453
+ "Only linear (degree 1) and constant (degree 0) functions are supported."
454
+ )
450
455
  constant = f.constant_term
451
456
  if degree > 1:
452
457
  raise OMMXPythonMIPAdapterError(
@@ -470,9 +475,9 @@ class OMMXPythonMIPAdapter(SolverAdapter):
470
475
  def _set_constraints(self):
471
476
  for cid, constraint in self.instance.constraints.items():
472
477
  lin_expr = self._as_lin_expr(constraint.function)
473
- if constraint.equality == Constraint.EQUAL_TO_ZERO:
478
+ if constraint.equality == Equality.EqualToZero:
474
479
  constr_expr = lin_expr == 0
475
- elif constraint.equality == Constraint.LESS_THAN_OR_EQUAL_TO_ZERO:
480
+ elif constraint.equality == Equality.LessThanOrEqualToZero:
476
481
  constr_expr = lin_expr <= 0 # type: ignore
477
482
  else:
478
483
  raise OMMXPythonMIPAdapterError(
@@ -4,7 +4,15 @@ from typing import final
4
4
  import mip
5
5
 
6
6
  from mip.exceptions import ParameterNotAvailable
7
- from ommx import Instance, DecisionVariable, Constraint, Function, Linear
7
+ from ommx import (
8
+ Constraint,
9
+ DecisionVariable,
10
+ Equality,
11
+ Function,
12
+ Instance,
13
+ Linear,
14
+ Sense,
15
+ )
8
16
 
9
17
  from .exception import OMMXPythonMIPAdapterError
10
18
 
@@ -83,13 +91,13 @@ class OMMXInstanceBuilder:
83
91
  if lin_expr.sense == "=":
84
92
  constraint = Constraint(
85
93
  function=self.as_ommx_function(lin_expr),
86
- equality=Constraint.EQUAL_TO_ZERO,
94
+ equality=Equality.EqualToZero,
87
95
  name=name,
88
96
  )
89
97
  elif lin_expr.sense == "<":
90
98
  constraint = Constraint(
91
99
  function=self.as_ommx_function(lin_expr),
92
- equality=Constraint.LESS_THAN_OR_EQUAL_TO_ZERO,
100
+ equality=Equality.LessThanOrEqualToZero,
93
101
  name=name,
94
102
  )
95
103
  elif lin_expr.sense == ">":
@@ -97,7 +105,7 @@ class OMMXInstanceBuilder:
97
105
  # So multiply the linear expression by -1.
98
106
  constraint = Constraint(
99
107
  function=self.as_ommx_function(-lin_expr),
100
- equality=Constraint.LESS_THAN_OR_EQUAL_TO_ZERO,
108
+ equality=Equality.LessThanOrEqualToZero,
101
109
  name=name,
102
110
  )
103
111
  else:
@@ -112,9 +120,9 @@ class OMMXInstanceBuilder:
112
120
 
113
121
  def sense(self):
114
122
  if self.model.sense == mip.MAXIMIZE:
115
- return Instance.MAXIMIZE
123
+ return Sense.Maximize
116
124
  elif self.model.sense == mip.MINIMIZE:
117
- return Instance.MINIMIZE
125
+ return Sense.Minimize
118
126
  raise OMMXPythonMIPAdapterError(f"Not supported sense: {self.model.sense}")
119
127
 
120
128
  @final
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ommx_python_mip_adapter
3
- Version: 3.0.0b4
3
+ Version: 3.0.0b6
4
4
  Summary: An adapter for the Python-MIP from/to OMMX.
5
5
  Author-email: "Jij Inc." <info@j-ij.com>
6
6
  Project-URL: Repository, https://github.com/Jij-Inc/ommx
@@ -15,7 +15,7 @@ Classifier: License :: OSI Approved :: Apache Software License
15
15
  Classifier: License :: OSI Approved :: MIT License
16
16
  Requires-Python: >=3.10
17
17
  Description-Content-Type: text/markdown
18
- Requires-Dist: ommx<4.0.0,>=3.0.0b4
18
+ Requires-Dist: ommx<4.0.0,>=3.0.0b6
19
19
  Requires-Dist: mip<2.0.0,>=1.17.0
20
20
  Requires-Dist: cffi<2.0.0,>=1.15.0
21
21
 
@@ -67,14 +67,14 @@ Python-MIP can be used through `ommx-python-mip-adapter` by using the following:
67
67
 
68
68
  ```python markdown-code-runner
69
69
  from ommx_python_mip_adapter import OMMXPythonMIPAdapter
70
- from ommx import Instance, DecisionVariable
70
+ from ommx import DecisionVariable, Instance, Sense
71
71
 
72
72
  x1 = DecisionVariable.integer(1, lower=0, upper=5)
73
73
  ommx_instance = Instance.from_components(
74
74
  decision_variables=[x1],
75
75
  objective=x1,
76
76
  constraints={},
77
- sense=Instance.MINIMIZE,
77
+ sense=Sense.Minimize,
78
78
  )
79
79
 
80
80
  # Create `ommx.Solution` from the `mip.Model`
@@ -1,3 +1,3 @@
1
- ommx<4.0.0,>=3.0.0b4
1
+ ommx<4.0.0,>=3.0.0b6
2
2
  mip<2.0.0,>=1.17.0
3
3
  cffi<2.0.0,>=1.15.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ommx_python_mip_adapter"
7
- version = "3.0.0b4"
7
+ version = "3.0.0b6"
8
8
 
9
9
  description = "An adapter for the Python-MIP from/to OMMX."
10
10
  authors = [{ name = "Jij Inc.", email = "info@j-ij.com" }]
@@ -23,7 +23,7 @@ classifiers = [
23
23
  ]
24
24
 
25
25
  dependencies = [
26
- "ommx >= 3.0.0b4, < 4.0.0",
26
+ "ommx >= 3.0.0b6, < 4.0.0",
27
27
  "mip >= 1.17.0, < 2.0.0",
28
28
  "cffi >= 1.15.0, < 2.0.0",
29
29
  ]
@@ -2,13 +2,14 @@ import pytest
2
2
 
3
3
  from ommx import (
4
4
  DecisionVariable,
5
- DegreeBound,
6
5
  Equality,
6
+ Function,
7
7
  IndicatorConstraint,
8
8
  Instance,
9
9
  InstanceClassMismatch,
10
10
  Kind,
11
11
  OneHotConstraint,
12
+ PolynomialRequirement,
12
13
  Sense,
13
14
  Sos1Constraint,
14
15
  )
@@ -26,12 +27,12 @@ def test_declares_linear_mip_input_class() -> None:
26
27
  Kind.Integer,
27
28
  Kind.Continuous,
28
29
  }
29
- assert clause.objective_degree_bound == DegreeBound.at_most(1)
30
- assert clause.regular_constraint_degree_bounds == {
31
- Equality.EqualToZero: DegreeBound.at_most(1),
32
- Equality.LessThanOrEqualToZero: DegreeBound.at_most(1),
30
+ assert clause.objective_polynomial_requirement == PolynomialRequirement.at_most(1)
31
+ assert clause.regular_constraint_polynomial_requirements == {
32
+ Equality.EqualToZero: PolynomialRequirement.at_most(1),
33
+ Equality.LessThanOrEqualToZero: PolynomialRequirement.at_most(1),
33
34
  }
34
- assert clause.indicator_constraint_degree_bounds == {}
35
+ assert clause.indicator_body_polynomial_requirements == {}
35
36
  assert not clause.allows_one_hot
36
37
  assert not clause.allows_sos1
37
38
  assert clause.allowed_senses == {Sense.Minimize, Sense.Maximize}
@@ -62,7 +63,7 @@ def test_error_nonlinear_objective():
62
63
  decision_variables=[x],
63
64
  objective=2.3 * x * x,
64
65
  constraints={},
65
- sense=Instance.MINIMIZE,
66
+ sense=Sense.Minimize,
66
67
  )
67
68
 
68
69
  with pytest.raises(AdapterNotApplicableError) as e:
@@ -73,6 +74,22 @@ def test_error_nonlinear_objective():
73
74
  )
74
75
 
75
76
 
77
+ def test_error_non_polynomial_objective() -> None:
78
+ x = DecisionVariable.continuous(0)
79
+ instance = Instance.from_components(
80
+ decision_variables=[x],
81
+ objective=abs(Function(x)),
82
+ constraints={},
83
+ sense=Sense.Minimize,
84
+ )
85
+
86
+ with pytest.raises(AdapterNotApplicableError) as error:
87
+ OMMXPythonMIPAdapter(instance)
88
+
89
+ [mismatch] = error.value.report.clause_reports[0].mismatches
90
+ assert isinstance(mismatch, InstanceClassMismatch.ObjectiveFunctionNotPolynomial)
91
+
92
+
76
93
  def test_error_nonlinear_constraint():
77
94
  # Objective function: 0
78
95
  # Constraint: 2.3 * x * x = 0
@@ -81,7 +98,7 @@ def test_error_nonlinear_constraint():
81
98
  decision_variables=[x],
82
99
  objective=0.0,
83
100
  constraints={0: 2.3 * x * x == 0},
84
- sense=Instance.MINIMIZE,
101
+ sense=Sense.Minimize,
85
102
  )
86
103
 
87
104
  with pytest.raises(AdapterNotApplicableError) as e:
@@ -1,5 +1,5 @@
1
1
  from ommx_python_mip_adapter import OMMXPythonMIPAdapter
2
- from ommx import Instance, DecisionVariable, Linear
2
+ from ommx import DecisionVariable, Instance, Linear, Sense
3
3
  from ommx.adapter import InfeasibleDetected
4
4
  import pytest
5
5
 
@@ -17,7 +17,7 @@ def test_constant_constraint_feasible():
17
17
  Linear(terms={}, constant=1) >= 0,
18
18
  1: x <= 1,
19
19
  },
20
- sense=Instance.MAXIMIZE,
20
+ sense=Sense.Maximize,
21
21
  )
22
22
  solution = OMMXPythonMIPAdapter.solve(instance)
23
23
 
@@ -40,7 +40,7 @@ def test_constant_constraint_infeasible():
40
40
  Linear(terms={}, constant=-1) >= 0,
41
41
  1: x <= 1,
42
42
  },
43
- sense=Instance.MAXIMIZE,
43
+ sense=Sense.Maximize,
44
44
  )
45
45
  with pytest.raises(InfeasibleDetected):
46
46
  OMMXPythonMIPAdapter.solve(instance)
@@ -49,7 +49,7 @@ def test_integration_milp():
49
49
  decision_variables=[x1, x2],
50
50
  objective=-x1 - x2,
51
51
  constraints={0: 3 * x1 - x2 <= 6, 1: -x1 + 3 * x2 <= 6},
52
- sense=Instance.MINIMIZE,
52
+ sense=Sense.Minimize,
53
53
  )
54
54
 
55
55
  adapter = OMMXPythonMIPAdapter(ommx_instance)
@@ -68,7 +68,7 @@ def test_solution_optimality():
68
68
  decision_variables=[x, y],
69
69
  objective=x + y,
70
70
  constraints={},
71
- sense=Instance.MAXIMIZE,
71
+ sense=Sense.Maximize,
72
72
  )
73
73
 
74
74
  solution = OMMXPythonMIPAdapter.solve(ommx_instance)
@@ -81,7 +81,7 @@ def test_solution_optimality_is_not_transported_through_fixed_penalty():
81
81
  decision_variables=[x],
82
82
  objective=x,
83
83
  constraints={7: x == 1},
84
- sense=Instance.MINIMIZE,
84
+ sense=Sense.Minimize,
85
85
  )
86
86
  instance.to_qubo(uniform_penalty_weight=0.0)
87
87
 
@@ -115,7 +115,7 @@ def test_partial_evaluate():
115
115
  decision_variables=x,
116
116
  objective=x[0] + x[1] + x[2],
117
117
  constraints={0: x[0] + x[1] + x[2] <= 1}, # one-hot constraint
118
- sense=Instance.MINIMIZE,
118
+ sense=Sense.Minimize,
119
119
  )
120
120
  assert instance.used_decision_variables == x
121
121
  partial = instance.partial_evaluate({0: 1})
@@ -141,7 +141,7 @@ def test_relax_constraint():
141
141
  decision_variables=x,
142
142
  objective=x[0] + x[1],
143
143
  constraints={0: x[0] + 2 * x[1] <= 1, 1: x[1] + x[2] <= 1},
144
- sense=Instance.MINIMIZE,
144
+ sense=Sense.Minimize,
145
145
  )
146
146
 
147
147
  assert instance.used_decision_variables == x
@@ -182,7 +182,7 @@ def test_integration_timelimit():
182
182
  decision_variables=x,
183
183
  objective=sum(v[i] * x[i] for i in range(n)),
184
184
  constraints={0: constraint},
185
- sense=Instance.MAXIMIZE,
185
+ sense=Sense.Maximize,
186
186
  )
187
187
  adapter = OMMXPythonMIPAdapter(instance)
188
188
  model = adapter.solver_input
@@ -204,7 +204,7 @@ def test_infeasible_problem():
204
204
  decision_variables=[x],
205
205
  objective=x,
206
206
  constraints={0: x >= 4},
207
- sense=Instance.MAXIMIZE,
207
+ sense=Sense.Maximize,
208
208
  )
209
209
  adapter = OMMXPythonMIPAdapter(instance)
210
210
  model = adapter.solver_input
@@ -221,7 +221,7 @@ def test_unbounded_problem():
221
221
  decision_variables=[x],
222
222
  objective=x,
223
223
  constraints={},
224
- sense=Instance.MAXIMIZE,
224
+ sense=Sense.Maximize,
225
225
  )
226
226
  adapter = OMMXPythonMIPAdapter(instance)
227
227
  model = adapter.solver_input
@@ -237,7 +237,7 @@ def test_decode_before_optimize():
237
237
  decision_variables=[x],
238
238
  objective=x,
239
239
  constraints={},
240
- sense=Instance.MINIMIZE,
240
+ sense=Sense.Minimize,
241
241
  )
242
242
  adapter = OMMXPythonMIPAdapter(instance)
243
243
  model = adapter.solver_input
@@ -1,6 +1,6 @@
1
1
  import mip
2
2
 
3
- from ommx import DecisionVariable, Instance, Constraint
3
+ from ommx import Equality, Kind, Sense
4
4
 
5
5
  from ommx_python_mip_adapter import model_to_instance
6
6
 
@@ -45,25 +45,25 @@ def test_milp():
45
45
 
46
46
  ommx_instance = model_to_instance(model)
47
47
 
48
- assert ommx_instance.sense == Instance.MINIMIZE
48
+ assert ommx_instance.sense == Sense.Minimize
49
49
 
50
50
  # Check the decision variables
51
51
  assert len(ommx_instance.decision_variables) == 3
52
52
  decision_variables_x1 = ommx_instance.get_decision_variable_by_id(0)
53
53
  assert decision_variables_x1.id == 0
54
- assert decision_variables_x1.kind == DecisionVariable.CONTINUOUS
54
+ assert decision_variables_x1.kind == Kind.Continuous
55
55
  assert decision_variables_x1.bound.lower == CONTINUOUS_LOWER_BOUND
56
56
  assert decision_variables_x1.bound.upper == CONTINUOUS_UPPER_BOUND
57
57
  assert decision_variables_x1.name == "1"
58
58
  decision_variables_x2 = ommx_instance.get_decision_variable_by_id(1)
59
59
  assert decision_variables_x2.id == 1
60
- assert decision_variables_x2.kind == DecisionVariable.INTEGER
60
+ assert decision_variables_x2.kind == Kind.Integer
61
61
  assert decision_variables_x2.bound.lower == INTEGER_LOWER_BOUND
62
62
  assert decision_variables_x2.bound.upper == INTEGER_UPPER_BOUND
63
63
  assert decision_variables_x2.name == "2"
64
64
  decision_variables_x3 = ommx_instance.get_decision_variable_by_id(2)
65
65
  assert decision_variables_x3.id == 2
66
- assert decision_variables_x3.kind == DecisionVariable.BINARY
66
+ assert decision_variables_x3.kind == Kind.Binary
67
67
  assert decision_variables_x3.bound.lower == 0
68
68
  assert decision_variables_x3.bound.upper == 1
69
69
  assert decision_variables_x3.name == "3"
@@ -81,7 +81,7 @@ def test_milp():
81
81
  assert len(ommx_instance.constraints) == 3
82
82
 
83
83
  constraint1 = ommx_instance.get_constraint_by_id(0)
84
- assert constraint1.equality == Constraint.EQUAL_TO_ZERO
84
+ assert constraint1.equality == Equality.EqualToZero
85
85
  assert constraint1.function.degree() == 1
86
86
  assert constraint1.function.constant_term == 6
87
87
  constraint1_terms = constraint1.function.linear_terms
@@ -90,7 +90,7 @@ def test_milp():
90
90
  assert constraint1_terms[1] == -5
91
91
 
92
92
  constraint2 = ommx_instance.get_constraint_by_id(1)
93
- assert constraint2.equality == Constraint.LESS_THAN_OR_EQUAL_TO_ZERO
93
+ assert constraint2.equality == Equality.LessThanOrEqualToZero
94
94
  assert constraint2.function.degree() == 1
95
95
  assert constraint2.function.constant_term == -9
96
96
  constraint2_terms = constraint2.function.linear_terms
@@ -99,7 +99,7 @@ def test_milp():
99
99
  assert constraint2_terms[2] == 8
100
100
 
101
101
  constraint3 = ommx_instance.get_constraint_by_id(2)
102
- assert constraint3.equality == Constraint.LESS_THAN_OR_EQUAL_TO_ZERO
102
+ assert constraint3.equality == Equality.LessThanOrEqualToZero
103
103
  assert constraint3.function.degree() == 1
104
104
  assert constraint3.function.constant_term == -12
105
105
  constraint3_terms = constraint3.function.linear_terms
@@ -138,19 +138,19 @@ def test_no_objective_model():
138
138
 
139
139
  ommx_instance = model_to_instance(model)
140
140
 
141
- assert ommx_instance.sense == Instance.MAXIMIZE
141
+ assert ommx_instance.sense == Sense.Maximize
142
142
 
143
143
  # Check the decision variables
144
144
  assert len(ommx_instance.decision_variables) == 2
145
145
  decision_variables_x1 = ommx_instance.get_decision_variable_by_id(0)
146
146
  assert decision_variables_x1.id == 0
147
- assert decision_variables_x1.kind == DecisionVariable.CONTINUOUS
147
+ assert decision_variables_x1.kind == Kind.Continuous
148
148
  assert decision_variables_x1.bound.lower == LOWER_BOUND
149
149
  assert decision_variables_x1.bound.upper == UPPER_BOUND
150
150
  assert decision_variables_x1.name == "1"
151
151
  decision_variables_x2 = ommx_instance.get_decision_variable_by_id(1)
152
152
  assert decision_variables_x2.id == 1
153
- assert decision_variables_x2.kind == DecisionVariable.CONTINUOUS
153
+ assert decision_variables_x2.kind == Kind.Continuous
154
154
  assert decision_variables_x2.bound.lower == LOWER_BOUND
155
155
  assert decision_variables_x2.bound.upper == UPPER_BOUND
156
156
  assert decision_variables_x2.name == "2"
@@ -163,7 +163,7 @@ def test_no_objective_model():
163
163
  assert len(ommx_instance.constraints) == 2
164
164
 
165
165
  constraint1 = ommx_instance.get_constraint_by_id(0)
166
- assert constraint1.equality == Constraint.EQUAL_TO_ZERO
166
+ assert constraint1.equality == Equality.EqualToZero
167
167
  assert constraint1.function.degree() == 1
168
168
  assert constraint1.function.constant_term == -5
169
169
  constraint1_terms = constraint1.function.linear_terms
@@ -172,7 +172,7 @@ def test_no_objective_model():
172
172
  assert constraint1_terms[1] == 2
173
173
 
174
174
  constraint2 = ommx_instance.get_constraint_by_id(1)
175
- assert constraint2.equality == Constraint.EQUAL_TO_ZERO
175
+ assert constraint2.equality == Equality.EqualToZero
176
176
  assert constraint2.function.degree() == 1
177
177
  assert constraint2.function.constant_term == -10
178
178
  constraint2_terms = constraint2.function.linear_terms
@@ -1,5 +1,5 @@
1
1
  from ommx.tracing import capture_trace
2
- from ommx import DecisionVariable, Instance
2
+ from ommx import DecisionVariable, Instance, Sense
3
3
 
4
4
  from ommx_python_mip_adapter import OMMXPythonMIPAdapter
5
5
 
@@ -10,7 +10,7 @@ def test_solve_emits_convert_solve_decode_spans():
10
10
  decision_variables=x,
11
11
  objective=x[0] + x[1] + x[2],
12
12
  constraints={0: x[0] + x[1] + x[2] <= 2},
13
- sense=Instance.MINIMIZE,
13
+ sense=Sense.Minimize,
14
14
  )
15
15
 
16
16
  with capture_trace() as result:
@@ -29,7 +29,7 @@ def test_manual_flow_emits_convert_and_decode_spans():
29
29
  decision_variables=x,
30
30
  objective=x[0] + x[1] + x[2],
31
31
  constraints={0: x[0] + x[1] + x[2] <= 2},
32
- sense=Instance.MINIMIZE,
32
+ sense=Sense.Minimize,
33
33
  )
34
34
 
35
35
  with capture_trace() as result: