From db4062419b56d810f30c05a96f72cca5eefdfd1a Mon Sep 17 00:00:00 2001 From: Bernard Knueven Date: Thu, 7 Mar 2024 11:07:40 -0700 Subject: [PATCH 1/2] add failing test --- .../solvers/tests/test_persistent_solvers.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pyomo/contrib/appsi/solvers/tests/test_persistent_solvers.py b/pyomo/contrib/appsi/solvers/tests/test_persistent_solvers.py index af615d1ed8b..ae189aca701 100644 --- a/pyomo/contrib/appsi/solvers/tests/test_persistent_solvers.py +++ b/pyomo/contrib/appsi/solvers/tests/test_persistent_solvers.py @@ -918,6 +918,27 @@ def test_bounds_with_params( res = opt.solve(m) self.assertAlmostEqual(m.y.value, 3) + @parameterized.expand(input=_load_tests(all_solvers, only_child_vars_options)) + def test_bounds_with_immutable_params( + self, name: str, opt_class: Type[PersistentSolver], only_child_vars + ): + # this test is for issue #2574 + opt: PersistentSolver = opt_class(only_child_vars=only_child_vars) + if not opt.available(): + raise unittest.SkipTest + m = pe.ConcreteModel() + m.p = pe.Param(mutable=False, initialize=1) + m.q = pe.Param([1, 2], mutable=False, initialize=10) + m.y = pe.Var() + m.y.setlb(m.p) + m.y.setub(m.q[1]) + m.obj = pe.Objective(expr=m.y) + res = opt.solve(m) + self.assertAlmostEqual(m.y.value, 1) + m.y.setlb(m.q[2]) + res = opt.solve(m) + self.assertAlmostEqual(m.y.value, 10) + @parameterized.expand(input=_load_tests(all_solvers, only_child_vars_options)) def test_solution_loader( self, name: str, opt_class: Type[PersistentSolver], only_child_vars From b09b3077c10be1431452c877e86593476f267a1b Mon Sep 17 00:00:00 2001 From: Bernard Knueven Date: Thu, 7 Mar 2024 11:10:05 -0700 Subject: [PATCH 2/2] apply patch --- pyomo/contrib/appsi/cmodel/src/expression.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyomo/contrib/appsi/cmodel/src/expression.cpp b/pyomo/contrib/appsi/cmodel/src/expression.cpp index 234ef47e86f..8079de42b21 100644 --- a/pyomo/contrib/appsi/cmodel/src/expression.cpp +++ b/pyomo/contrib/appsi/cmodel/src/expression.cpp @@ -1548,7 +1548,10 @@ appsi_operator_from_pyomo_expr(py::handle expr, py::handle var_map, break; } case param: { - res = param_map[expr_types.id(expr)].cast>(); + if (expr.attr("parent_component")().attr("mutable").cast()) + res = param_map[expr_types.id(expr)].cast>(); + else + res = std::make_shared(expr.attr("value").cast()); break; } case product: {