diff --git a/pyomo/common/tests/test_timing.py b/pyomo/common/tests/test_timing.py index 48288746882..90f4cdcd034 100644 --- a/pyomo/common/tests/test_timing.py +++ b/pyomo/common/tests/test_timing.py @@ -35,7 +35,7 @@ Any, TransformationFactory, ) -from pyomo.core.base.var import _VarData +from pyomo.core.base.var import VarData class _pseudo_component(Var): @@ -62,7 +62,7 @@ def test_raw_construction_timer(self): ) v = Var() v.construct() - a = ConstructionTimer(_VarData(v)) + a = ConstructionTimer(VarData(v)) self.assertRegex( str(a), r"ConstructionTimer object for Var ScalarVar\[NOTSET\]; " diff --git a/pyomo/contrib/appsi/base.py b/pyomo/contrib/appsi/base.py index 201e5975ac9..6655ec26524 100644 --- a/pyomo/contrib/appsi/base.py +++ b/pyomo/contrib/appsi/base.py @@ -21,12 +21,12 @@ Tuple, MutableMapping, ) -from pyomo.core.base.constraint import _GeneralConstraintData, Constraint -from pyomo.core.base.sos import _SOSConstraintData, SOSConstraint -from pyomo.core.base.var import _GeneralVarData, Var -from pyomo.core.base.param import _ParamData, Param -from pyomo.core.base.block import _BlockData, Block -from pyomo.core.base.objective import _GeneralObjectiveData +from pyomo.core.base.constraint import ConstraintData, Constraint +from pyomo.core.base.sos import SOSConstraintData, SOSConstraint +from pyomo.core.base.var import VarData, Var +from pyomo.core.base.param import ParamData, Param +from pyomo.core.base.block import BlockData, Block +from pyomo.core.base.objective import ObjectiveData from pyomo.common.collections import ComponentMap from .utils.get_objective import get_objective from .utils.collect_vars_and_named_exprs import collect_vars_and_named_exprs @@ -179,9 +179,7 @@ def __init__( class SolutionLoaderBase(abc.ABC): - def load_vars( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> NoReturn: + def load_vars(self, vars_to_load: Optional[Sequence[VarData]] = None) -> NoReturn: """ Load the solution of the primal variables into the value attribute of the variables. @@ -197,8 +195,8 @@ def load_vars( @abc.abstractmethod def get_primals( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: """ Returns a ComponentMap mapping variable to var value. @@ -216,8 +214,8 @@ def get_primals( pass def get_duals( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: """ Returns a dictionary mapping constraint to dual value. @@ -235,8 +233,8 @@ def get_duals( raise NotImplementedError(f'{type(self)} does not support the get_duals method') def get_slacks( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: """ Returns a dictionary mapping constraint to slack. @@ -256,8 +254,8 @@ def get_slacks( ) def get_reduced_costs( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: """ Returns a ComponentMap mapping variable to reduced cost. @@ -303,8 +301,8 @@ def __init__( self._reduced_costs = reduced_costs def get_primals( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: if self._primals is None: raise RuntimeError( 'Solution loader does not currently have a valid solution. Please ' @@ -319,8 +317,8 @@ def get_primals( return primals def get_duals( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: if self._duals is None: raise RuntimeError( 'Solution loader does not currently have valid duals. Please ' @@ -336,8 +334,8 @@ def get_duals( return duals def get_slacks( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: if self._slacks is None: raise RuntimeError( 'Solution loader does not currently have valid slacks. Please ' @@ -353,8 +351,8 @@ def get_slacks( return slacks def get_reduced_costs( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: if self._reduced_costs is None: raise RuntimeError( 'Solution loader does not currently have valid reduced costs. Please ' @@ -621,13 +619,13 @@ def __str__(self): return self.name @abc.abstractmethod - def solve(self, model: _BlockData, timer: HierarchicalTimer = None) -> Results: + def solve(self, model: BlockData, timer: HierarchicalTimer = None) -> Results: """ Solve a Pyomo model. Parameters ---------- - model: _BlockData + model: BlockData The Pyomo model to be solved timer: HierarchicalTimer An option timer for reporting timing @@ -708,9 +706,7 @@ class PersistentSolver(Solver): def is_persistent(self): return True - def load_vars( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> NoReturn: + def load_vars(self, vars_to_load: Optional[Sequence[VarData]] = None) -> NoReturn: """ Load the solution of the primal variables into the value attribute of the variables. @@ -726,13 +722,13 @@ def load_vars( @abc.abstractmethod def get_primals( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: pass def get_duals( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: """ Declare sign convention in docstring here. @@ -752,8 +748,8 @@ def get_duals( ) def get_slacks( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: """ Parameters ---------- @@ -771,8 +767,8 @@ def get_slacks( ) def get_reduced_costs( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: """ Parameters ---------- @@ -799,43 +795,43 @@ def set_instance(self, model): pass @abc.abstractmethod - def add_variables(self, variables: List[_GeneralVarData]): + def add_variables(self, variables: List[VarData]): pass @abc.abstractmethod - def add_params(self, params: List[_ParamData]): + def add_params(self, params: List[ParamData]): pass @abc.abstractmethod - def add_constraints(self, cons: List[_GeneralConstraintData]): + def add_constraints(self, cons: List[ConstraintData]): pass @abc.abstractmethod - def add_block(self, block: _BlockData): + def add_block(self, block: BlockData): pass @abc.abstractmethod - def remove_variables(self, variables: List[_GeneralVarData]): + def remove_variables(self, variables: List[VarData]): pass @abc.abstractmethod - def remove_params(self, params: List[_ParamData]): + def remove_params(self, params: List[ParamData]): pass @abc.abstractmethod - def remove_constraints(self, cons: List[_GeneralConstraintData]): + def remove_constraints(self, cons: List[ConstraintData]): pass @abc.abstractmethod - def remove_block(self, block: _BlockData): + def remove_block(self, block: BlockData): pass @abc.abstractmethod - def set_objective(self, obj: _GeneralObjectiveData): + def set_objective(self, obj: ObjectiveData): pass @abc.abstractmethod - def update_variables(self, variables: List[_GeneralVarData]): + def update_variables(self, variables: List[VarData]): pass @abc.abstractmethod @@ -857,20 +853,20 @@ def get_primals(self, vars_to_load=None): return self._solver.get_primals(vars_to_load=vars_to_load) def get_duals( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: self._assert_solution_still_valid() return self._solver.get_duals(cons_to_load=cons_to_load) def get_slacks( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: self._assert_solution_still_valid() return self._solver.get_slacks(cons_to_load=cons_to_load) def get_reduced_costs( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: self._assert_solution_still_valid() return self._solver.get_reduced_costs(vars_to_load=vars_to_load) @@ -954,10 +950,10 @@ def set_instance(self, model): self.set_objective(None) @abc.abstractmethod - def _add_variables(self, variables: List[_GeneralVarData]): + def _add_variables(self, variables: List[VarData]): pass - def add_variables(self, variables: List[_GeneralVarData]): + def add_variables(self, variables: List[VarData]): for v in variables: if id(v) in self._referenced_variables: raise ValueError( @@ -975,19 +971,19 @@ def add_variables(self, variables: List[_GeneralVarData]): self._add_variables(variables) @abc.abstractmethod - def _add_params(self, params: List[_ParamData]): + def _add_params(self, params: List[ParamData]): pass - def add_params(self, params: List[_ParamData]): + def add_params(self, params: List[ParamData]): for p in params: self._params[id(p)] = p self._add_params(params) @abc.abstractmethod - def _add_constraints(self, cons: List[_GeneralConstraintData]): + def _add_constraints(self, cons: List[ConstraintData]): pass - def _check_for_new_vars(self, variables: List[_GeneralVarData]): + def _check_for_new_vars(self, variables: List[VarData]): new_vars = dict() for v in variables: v_id = id(v) @@ -995,7 +991,7 @@ def _check_for_new_vars(self, variables: List[_GeneralVarData]): new_vars[v_id] = v self.add_variables(list(new_vars.values())) - def _check_to_remove_vars(self, variables: List[_GeneralVarData]): + def _check_to_remove_vars(self, variables: List[VarData]): vars_to_remove = dict() for v in variables: v_id = id(v) @@ -1004,7 +1000,7 @@ def _check_to_remove_vars(self, variables: List[_GeneralVarData]): vars_to_remove[v_id] = v self.remove_variables(list(vars_to_remove.values())) - def add_constraints(self, cons: List[_GeneralConstraintData]): + def add_constraints(self, cons: List[ConstraintData]): all_fixed_vars = dict() for con in cons: if con in self._named_expressions: @@ -1034,10 +1030,10 @@ def add_constraints(self, cons: List[_GeneralConstraintData]): v.fix() @abc.abstractmethod - def _add_sos_constraints(self, cons: List[_SOSConstraintData]): + def _add_sos_constraints(self, cons: List[SOSConstraintData]): pass - def add_sos_constraints(self, cons: List[_SOSConstraintData]): + def add_sos_constraints(self, cons: List[SOSConstraintData]): for con in cons: if con in self._vars_referenced_by_con: raise ValueError( @@ -1054,10 +1050,10 @@ def add_sos_constraints(self, cons: List[_SOSConstraintData]): self._add_sos_constraints(cons) @abc.abstractmethod - def _set_objective(self, obj: _GeneralObjectiveData): + def _set_objective(self, obj: ObjectiveData): pass - def set_objective(self, obj: _GeneralObjectiveData): + def set_objective(self, obj: ObjectiveData): if self._objective is not None: for v in self._vars_referenced_by_obj: self._referenced_variables[id(v)][2] = None @@ -1132,10 +1128,10 @@ def add_block(self, block): self.set_objective(obj) @abc.abstractmethod - def _remove_constraints(self, cons: List[_GeneralConstraintData]): + def _remove_constraints(self, cons: List[ConstraintData]): pass - def remove_constraints(self, cons: List[_GeneralConstraintData]): + def remove_constraints(self, cons: List[ConstraintData]): self._remove_constraints(cons) for con in cons: if con not in self._named_expressions: @@ -1154,10 +1150,10 @@ def remove_constraints(self, cons: List[_GeneralConstraintData]): del self._vars_referenced_by_con[con] @abc.abstractmethod - def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): + def _remove_sos_constraints(self, cons: List[SOSConstraintData]): pass - def remove_sos_constraints(self, cons: List[_SOSConstraintData]): + def remove_sos_constraints(self, cons: List[SOSConstraintData]): self._remove_sos_constraints(cons) for con in cons: if con not in self._vars_referenced_by_con: @@ -1174,10 +1170,10 @@ def remove_sos_constraints(self, cons: List[_SOSConstraintData]): del self._vars_referenced_by_con[con] @abc.abstractmethod - def _remove_variables(self, variables: List[_GeneralVarData]): + def _remove_variables(self, variables: List[VarData]): pass - def remove_variables(self, variables: List[_GeneralVarData]): + def remove_variables(self, variables: List[VarData]): self._remove_variables(variables) for v in variables: v_id = id(v) @@ -1198,10 +1194,10 @@ def remove_variables(self, variables: List[_GeneralVarData]): del self._vars[v_id] @abc.abstractmethod - def _remove_params(self, params: List[_ParamData]): + def _remove_params(self, params: List[ParamData]): pass - def remove_params(self, params: List[_ParamData]): + def remove_params(self, params: List[ParamData]): self._remove_params(params) for p in params: del self._params[id(p)] @@ -1246,10 +1242,10 @@ def remove_block(self, block): ) @abc.abstractmethod - def _update_variables(self, variables: List[_GeneralVarData]): + def _update_variables(self, variables: List[VarData]): pass - def update_variables(self, variables: List[_GeneralVarData]): + def update_variables(self, variables: List[VarData]): for v in variables: self._vars[id(v)] = ( v, @@ -1334,12 +1330,12 @@ def update(self, timer: HierarchicalTimer = None): for c in self._vars_referenced_by_con.keys(): if c not in current_cons_dict and c not in current_sos_dict: if (c.ctype is Constraint) or ( - c.ctype is None and isinstance(c, _GeneralConstraintData) + c.ctype is None and isinstance(c, ConstraintData) ): old_cons.append(c) else: assert (c.ctype is SOSConstraint) or ( - c.ctype is None and isinstance(c, _SOSConstraintData) + c.ctype is None and isinstance(c, SOSConstraintData) ) old_sos.append(c) self.remove_constraints(old_cons) @@ -1529,7 +1525,7 @@ def update(self, timer: HierarchicalTimer = None): class LegacySolverInterface(object): def solve( self, - model: _BlockData, + model: BlockData, tee: bool = False, load_solutions: bool = True, logfile: Optional[str] = None, diff --git a/pyomo/contrib/appsi/cmodel/src/expression.hpp b/pyomo/contrib/appsi/cmodel/src/expression.hpp index 0c0777ef468..e91ca0af3b3 100644 --- a/pyomo/contrib/appsi/cmodel/src/expression.hpp +++ b/pyomo/contrib/appsi/cmodel/src/expression.hpp @@ -680,10 +680,10 @@ class PyomoExprTypes { expr_type_map[np_float32] = py_float; expr_type_map[np_float64] = py_float; expr_type_map[ScalarVar] = var; - expr_type_map[_GeneralVarData] = var; + expr_type_map[VarData] = var; expr_type_map[AutoLinkedBinaryVar] = var; expr_type_map[ScalarParam] = param; - expr_type_map[_ParamData] = param; + expr_type_map[ParamData] = param; expr_type_map[MonomialTermExpression] = product; expr_type_map[ProductExpression] = product; expr_type_map[NPV_ProductExpression] = product; @@ -700,7 +700,7 @@ class PyomoExprTypes { expr_type_map[UnaryFunctionExpression] = unary_func; expr_type_map[NPV_UnaryFunctionExpression] = unary_func; expr_type_map[LinearExpression] = linear; - expr_type_map[_GeneralExpressionData] = named_expr; + expr_type_map[ExpressionData] = named_expr; expr_type_map[ScalarExpression] = named_expr; expr_type_map[Integral] = named_expr; expr_type_map[ScalarIntegral] = named_expr; @@ -728,12 +728,12 @@ class PyomoExprTypes { py::type np_float64 = np.attr("float64"); py::object ScalarParam = py::module_::import("pyomo.core.base.param").attr("ScalarParam"); - py::object _ParamData = - py::module_::import("pyomo.core.base.param").attr("_ParamData"); + py::object ParamData = + py::module_::import("pyomo.core.base.param").attr("ParamData"); py::object ScalarVar = py::module_::import("pyomo.core.base.var").attr("ScalarVar"); - py::object _GeneralVarData = - py::module_::import("pyomo.core.base.var").attr("_GeneralVarData"); + py::object VarData = + py::module_::import("pyomo.core.base.var").attr("VarData"); py::object AutoLinkedBinaryVar = py::module_::import("pyomo.gdp.disjunct").attr("AutoLinkedBinaryVar"); py::object numeric_expr = py::module_::import("pyomo.core.expr.numeric_expr"); @@ -765,8 +765,8 @@ class PyomoExprTypes { py::object NumericConstant = py::module_::import("pyomo.core.expr.numvalue").attr("NumericConstant"); py::object expr_module = py::module_::import("pyomo.core.base.expression"); - py::object _GeneralExpressionData = - expr_module.attr("_GeneralExpressionData"); + py::object ExpressionData = + expr_module.attr("ExpressionData"); py::object ScalarExpression = expr_module.attr("ScalarExpression"); py::object ScalarIntegral = py::module_::import("pyomo.dae.integral").attr("ScalarIntegral"); diff --git a/pyomo/contrib/appsi/fbbt.py b/pyomo/contrib/appsi/fbbt.py index 8b6cc52d2aa..8e0c74b00e9 100644 --- a/pyomo/contrib/appsi/fbbt.py +++ b/pyomo/contrib/appsi/fbbt.py @@ -18,12 +18,12 @@ ) from .cmodel import cmodel, cmodel_available from typing import List, Optional -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.param import _ParamData -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.sos import _SOSConstraintData -from pyomo.core.base.objective import _GeneralObjectiveData, minimize, maximize -from pyomo.core.base.block import _BlockData +from pyomo.core.base.var import VarData +from pyomo.core.base.param import ParamData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.sos import SOSConstraintData +from pyomo.core.base.objective import ObjectiveData, minimize, maximize +from pyomo.core.base.block import BlockData from pyomo.core.base import SymbolMap, TextLabeler from pyomo.common.errors import InfeasibleConstraintException @@ -121,7 +121,7 @@ def set_instance(self, model, symbolic_solver_labels: Optional[bool] = None): if self._objective is None: self.set_objective(None) - def _add_variables(self, variables: List[_GeneralVarData]): + def _add_variables(self, variables: List[VarData]): if self._symbolic_solver_labels: set_name = True symbol_map = self._symbol_map @@ -143,7 +143,7 @@ def _add_variables(self, variables: List[_GeneralVarData]): False, ) - def _add_params(self, params: List[_ParamData]): + def _add_params(self, params: List[ParamData]): cparams = cmodel.create_params(len(params)) for ndx, p in enumerate(params): cp = cparams[ndx] @@ -154,7 +154,7 @@ def _add_params(self, params: List[_ParamData]): cp = cparams[ndx] cp.name = self._symbol_map.getSymbol(p, self._param_labeler) - def _add_constraints(self, cons: List[_GeneralConstraintData]): + def _add_constraints(self, cons: List[ConstraintData]): cmodel.process_fbbt_constraints( self._cmodel, self._pyomo_expr_types, @@ -169,13 +169,13 @@ def _add_constraints(self, cons: List[_GeneralConstraintData]): for c, cc in self._con_map.items(): cc.name = self._symbol_map.getSymbol(c, self._con_labeler) - def _add_sos_constraints(self, cons: List[_SOSConstraintData]): + def _add_sos_constraints(self, cons: List[SOSConstraintData]): if len(cons) != 0: raise NotImplementedError( 'IntervalTightener does not support SOS constraints' ) - def _remove_constraints(self, cons: List[_GeneralConstraintData]): + def _remove_constraints(self, cons: List[ConstraintData]): if self._symbolic_solver_labels: for c in cons: self._symbol_map.removeSymbol(c) @@ -184,13 +184,13 @@ def _remove_constraints(self, cons: List[_GeneralConstraintData]): self._cmodel.remove_constraint(cc) del self._rcon_map[cc] - def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): + def _remove_sos_constraints(self, cons: List[SOSConstraintData]): if len(cons) != 0: raise NotImplementedError( 'IntervalTightener does not support SOS constraints' ) - def _remove_variables(self, variables: List[_GeneralVarData]): + def _remove_variables(self, variables: List[VarData]): if self._symbolic_solver_labels: for v in variables: self._symbol_map.removeSymbol(v) @@ -198,14 +198,14 @@ def _remove_variables(self, variables: List[_GeneralVarData]): cvar = self._var_map.pop(id(v)) del self._rvar_map[cvar] - def _remove_params(self, params: List[_ParamData]): + def _remove_params(self, params: List[ParamData]): if self._symbolic_solver_labels: for p in params: self._symbol_map.removeSymbol(p) for p in params: del self._param_map[id(p)] - def _update_variables(self, variables: List[_GeneralVarData]): + def _update_variables(self, variables: List[VarData]): cmodel.process_pyomo_vars( self._pyomo_expr_types, variables, @@ -224,13 +224,13 @@ def update_params(self): cp = self._param_map[p_id] cp.value = p.value - def set_objective(self, obj: _GeneralObjectiveData): + def set_objective(self, obj: ObjectiveData): if self._symbolic_solver_labels: if self._objective is not None: self._symbol_map.removeSymbol(self._objective) super().set_objective(obj) - def _set_objective(self, obj: _GeneralObjectiveData): + def _set_objective(self, obj: ObjectiveData): if obj is None: ce = cmodel.Constant(0) sense = 0 @@ -275,7 +275,7 @@ def _deactivate_satisfied_cons(self): c.deactivate() def perform_fbbt( - self, model: _BlockData, symbolic_solver_labels: Optional[bool] = None + self, model: BlockData, symbolic_solver_labels: Optional[bool] = None ): if model is not self._model: self.set_instance(model, symbolic_solver_labels=symbolic_solver_labels) @@ -304,7 +304,7 @@ def perform_fbbt( self._deactivate_satisfied_cons() return n_iter - def perform_fbbt_with_seed(self, model: _BlockData, seed_var: _GeneralVarData): + def perform_fbbt_with_seed(self, model: BlockData, seed_var: VarData): if model is not self._model: self.set_instance(model) else: diff --git a/pyomo/contrib/appsi/solvers/cbc.py b/pyomo/contrib/appsi/solvers/cbc.py index 7f04ffbfce7..08833e747e2 100644 --- a/pyomo/contrib/appsi/solvers/cbc.py +++ b/pyomo/contrib/appsi/solvers/cbc.py @@ -26,11 +26,11 @@ import math from pyomo.common.collections import ComponentMap from typing import Optional, Sequence, NoReturn, List, Mapping -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.block import _BlockData -from pyomo.core.base.param import _ParamData -from pyomo.core.base.objective import _GeneralObjectiveData +from pyomo.core.base.var import VarData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.block import BlockData +from pyomo.core.base.param import ParamData +from pyomo.core.base.objective import ObjectiveData from pyomo.common.timing import HierarchicalTimer from pyomo.common.tee import TeeStream import sys @@ -164,34 +164,34 @@ def symbol_map(self): def set_instance(self, model): self._writer.set_instance(model) - def add_variables(self, variables: List[_GeneralVarData]): + def add_variables(self, variables: List[VarData]): self._writer.add_variables(variables) - def add_params(self, params: List[_ParamData]): + def add_params(self, params: List[ParamData]): self._writer.add_params(params) - def add_constraints(self, cons: List[_GeneralConstraintData]): + def add_constraints(self, cons: List[ConstraintData]): self._writer.add_constraints(cons) - def add_block(self, block: _BlockData): + def add_block(self, block: BlockData): self._writer.add_block(block) - def remove_variables(self, variables: List[_GeneralVarData]): + def remove_variables(self, variables: List[VarData]): self._writer.remove_variables(variables) - def remove_params(self, params: List[_ParamData]): + def remove_params(self, params: List[ParamData]): self._writer.remove_params(params) - def remove_constraints(self, cons: List[_GeneralConstraintData]): + def remove_constraints(self, cons: List[ConstraintData]): self._writer.remove_constraints(cons) - def remove_block(self, block: _BlockData): + def remove_block(self, block: BlockData): self._writer.remove_block(block) - def set_objective(self, obj: _GeneralObjectiveData): + def set_objective(self, obj: ObjectiveData): self._writer.set_objective(obj) - def update_variables(self, variables: List[_GeneralVarData]): + def update_variables(self, variables: List[VarData]): self._writer.update_variables(variables) def update_params(self): @@ -440,8 +440,8 @@ def _check_and_escape_options(): return results def get_primals( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: if ( self._last_results_object is None or self._last_results_object.best_feasible_objective is None @@ -477,8 +477,8 @@ def get_duals(self, cons_to_load=None): return {c: self._dual_sol[c] for c in cons_to_load} def get_reduced_costs( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: if ( self._last_results_object is None or self._last_results_object.termination_condition diff --git a/pyomo/contrib/appsi/solvers/cplex.py b/pyomo/contrib/appsi/solvers/cplex.py index 1b7ab5000d2..10de981ce7d 100644 --- a/pyomo/contrib/appsi/solvers/cplex.py +++ b/pyomo/contrib/appsi/solvers/cplex.py @@ -22,11 +22,11 @@ import math from pyomo.common.collections import ComponentMap from typing import Optional, Sequence, NoReturn, List, Mapping, Dict -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.block import _BlockData -from pyomo.core.base.param import _ParamData -from pyomo.core.base.objective import _GeneralObjectiveData +from pyomo.core.base.var import VarData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.block import BlockData +from pyomo.core.base.param import ParamData +from pyomo.core.base.objective import ObjectiveData from pyomo.common.timing import HierarchicalTimer import sys import time @@ -179,34 +179,34 @@ def update_config(self): def set_instance(self, model): self._writer.set_instance(model) - def add_variables(self, variables: List[_GeneralVarData]): + def add_variables(self, variables: List[VarData]): self._writer.add_variables(variables) - def add_params(self, params: List[_ParamData]): + def add_params(self, params: List[ParamData]): self._writer.add_params(params) - def add_constraints(self, cons: List[_GeneralConstraintData]): + def add_constraints(self, cons: List[ConstraintData]): self._writer.add_constraints(cons) - def add_block(self, block: _BlockData): + def add_block(self, block: BlockData): self._writer.add_block(block) - def remove_variables(self, variables: List[_GeneralVarData]): + def remove_variables(self, variables: List[VarData]): self._writer.remove_variables(variables) - def remove_params(self, params: List[_ParamData]): + def remove_params(self, params: List[ParamData]): self._writer.remove_params(params) - def remove_constraints(self, cons: List[_GeneralConstraintData]): + def remove_constraints(self, cons: List[ConstraintData]): self._writer.remove_constraints(cons) - def remove_block(self, block: _BlockData): + def remove_block(self, block: BlockData): self._writer.remove_block(block) - def set_objective(self, obj: _GeneralObjectiveData): + def set_objective(self, obj: ObjectiveData): self._writer.set_objective(obj) - def update_variables(self, variables: List[_GeneralVarData]): + def update_variables(self, variables: List[VarData]): self._writer.update_variables(variables) def update_params(self): @@ -362,8 +362,8 @@ def _postsolve(self, timer: HierarchicalTimer, solve_time): return results def get_primals( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: if ( self._cplex_model.solution.get_solution_type() == self._cplex_model.solution.type.none @@ -389,8 +389,8 @@ def get_primals( return res def get_duals( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: if ( self._cplex_model.solution.get_solution_type() == self._cplex_model.solution.type.none @@ -440,8 +440,8 @@ def get_duals( return res def get_reduced_costs( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: if ( self._cplex_model.solution.get_solution_type() == self._cplex_model.solution.type.none diff --git a/pyomo/contrib/appsi/solvers/gurobi.py b/pyomo/contrib/appsi/solvers/gurobi.py index 1e18862e3bd..2719ecc2a00 100644 --- a/pyomo/contrib/appsi/solvers/gurobi.py +++ b/pyomo/contrib/appsi/solvers/gurobi.py @@ -23,10 +23,10 @@ from pyomo.common.config import ConfigValue, NonNegativeInt from pyomo.core.kernel.objective import minimize, maximize from pyomo.core.base import SymbolMap, NumericLabeler, TextLabeler -from pyomo.core.base.var import Var, _GeneralVarData -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.sos import _SOSConstraintData -from pyomo.core.base.param import _ParamData +from pyomo.core.base.var import Var, VarData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.sos import SOSConstraintData +from pyomo.core.base.param import ParamData from pyomo.core.expr.numvalue import value, is_constant, is_fixed, native_numeric_types from pyomo.repn import generate_standard_repn from pyomo.core.expr.numeric_expr import NPV_MaxExpression, NPV_MinExpression @@ -458,7 +458,7 @@ def _process_domain_and_bounds( return lb, ub, vtype - def _add_variables(self, variables: List[_GeneralVarData]): + def _add_variables(self, variables: List[VarData]): var_names = list() vtypes = list() lbs = list() @@ -489,7 +489,7 @@ def _add_variables(self, variables: List[_GeneralVarData]): self._vars_added_since_update.update(variables) self._needs_updated = True - def _add_params(self, params: List[_ParamData]): + def _add_params(self, params: List[ParamData]): pass def _reinit(self): @@ -579,7 +579,7 @@ def _get_expr_from_pyomo_expr(self, expr): mutable_quadratic_coefficients, ) - def _add_constraints(self, cons: List[_GeneralConstraintData]): + def _add_constraints(self, cons: List[ConstraintData]): for con in cons: conname = self._symbol_map.getSymbol(con, self._labeler) ( @@ -709,7 +709,7 @@ def _add_constraints(self, cons: List[_GeneralConstraintData]): self._constraints_added_since_update.update(cons) self._needs_updated = True - def _add_sos_constraints(self, cons: List[_SOSConstraintData]): + def _add_sos_constraints(self, cons: List[SOSConstraintData]): for con in cons: conname = self._symbol_map.getSymbol(con, self._labeler) level = con.level @@ -735,7 +735,7 @@ def _add_sos_constraints(self, cons: List[_SOSConstraintData]): self._constraints_added_since_update.update(cons) self._needs_updated = True - def _remove_constraints(self, cons: List[_GeneralConstraintData]): + def _remove_constraints(self, cons: List[ConstraintData]): for con in cons: if con in self._constraints_added_since_update: self._update_gurobi_model() @@ -749,7 +749,7 @@ def _remove_constraints(self, cons: List[_GeneralConstraintData]): self._mutable_quadratic_helpers.pop(con, None) self._needs_updated = True - def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): + def _remove_sos_constraints(self, cons: List[SOSConstraintData]): for con in cons: if con in self._constraints_added_since_update: self._update_gurobi_model() @@ -759,7 +759,7 @@ def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): del self._pyomo_sos_to_solver_sos_map[con] self._needs_updated = True - def _remove_variables(self, variables: List[_GeneralVarData]): + def _remove_variables(self, variables: List[VarData]): for var in variables: v_id = id(var) if var in self._vars_added_since_update: @@ -771,10 +771,10 @@ def _remove_variables(self, variables: List[_GeneralVarData]): self._mutable_bounds.pop(v_id, None) self._needs_updated = True - def _remove_params(self, params: List[_ParamData]): + def _remove_params(self, params: List[ParamData]): pass - def _update_variables(self, variables: List[_GeneralVarData]): + def _update_variables(self, variables: List[VarData]): for var in variables: var_id = id(var) if var_id not in self._pyomo_var_to_solver_var_map: @@ -1195,7 +1195,7 @@ def set_linear_constraint_attr(self, con, attr, val): Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The pyomo constraint for which the corresponding gurobi constraint attribute should be modified. attr: str @@ -1221,7 +1221,7 @@ def set_var_attr(self, var, attr, val): Parameters ---------- - var: pyomo.core.base.var._GeneralVarData + var: pyomo.core.base.var.VarData The pyomo var for which the corresponding gurobi var attribute should be modified. attr: str @@ -1256,7 +1256,7 @@ def get_var_attr(self, var, attr): Parameters ---------- - var: pyomo.core.base.var._GeneralVarData + var: pyomo.core.base.var.VarData The pyomo var for which the corresponding gurobi var attribute should be retrieved. attr: str @@ -1272,7 +1272,7 @@ def get_linear_constraint_attr(self, con, attr): Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The pyomo constraint for which the corresponding gurobi constraint attribute should be retrieved. attr: str @@ -1288,7 +1288,7 @@ def get_sos_attr(self, con, attr): Parameters ---------- - con: pyomo.core.base.sos._SOSConstraintData + con: pyomo.core.base.sos.SOSConstraintData The pyomo SOS constraint for which the corresponding gurobi SOS constraint attribute should be retrieved. attr: str @@ -1304,7 +1304,7 @@ def get_quadratic_constraint_attr(self, con, attr): Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The pyomo constraint for which the corresponding gurobi constraint attribute should be retrieved. attr: str @@ -1425,7 +1425,7 @@ def cbCut(self, con): Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The cut to add """ if not con.active: @@ -1510,7 +1510,7 @@ def cbLazy(self, con): """ Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The lazy constraint to add """ if not con.active: diff --git a/pyomo/contrib/appsi/solvers/highs.py b/pyomo/contrib/appsi/solvers/highs.py index 3612b9d5014..6410700c569 100644 --- a/pyomo/contrib/appsi/solvers/highs.py +++ b/pyomo/contrib/appsi/solvers/highs.py @@ -20,10 +20,10 @@ from pyomo.common.log import LogStream from pyomo.core.kernel.objective import minimize, maximize from pyomo.core.base import SymbolMap -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.sos import _SOSConstraintData -from pyomo.core.base.param import _ParamData +from pyomo.core.base.var import VarData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.sos import SOSConstraintData +from pyomo.core.base.param import ParamData from pyomo.core.expr.numvalue import value, is_constant from pyomo.repn import generate_standard_repn from pyomo.core.expr.numeric_expr import NPV_MaxExpression, NPV_MinExpression @@ -308,7 +308,7 @@ def _process_domain_and_bounds(self, var_id): return lb, ub, vtype - def _add_variables(self, variables: List[_GeneralVarData]): + def _add_variables(self, variables: List[VarData]): self._sol = None if self._last_results_object is not None: self._last_results_object.solution_loader.invalidate() @@ -335,7 +335,7 @@ def _add_variables(self, variables: List[_GeneralVarData]): len(vtypes), np.array(indices), np.array(vtypes) ) - def _add_params(self, params: List[_ParamData]): + def _add_params(self, params: List[ParamData]): pass def _reinit(self): @@ -376,7 +376,7 @@ def set_instance(self, model): if self._objective is None: self.set_objective(None) - def _add_constraints(self, cons: List[_GeneralConstraintData]): + def _add_constraints(self, cons: List[ConstraintData]): self._sol = None if self._last_results_object is not None: self._last_results_object.solution_loader.invalidate() @@ -456,13 +456,13 @@ def _add_constraints(self, cons: List[_GeneralConstraintData]): np.array(coef_values, dtype=np.double), ) - def _add_sos_constraints(self, cons: List[_SOSConstraintData]): + def _add_sos_constraints(self, cons: List[SOSConstraintData]): if cons: raise NotImplementedError( 'Highs interface does not support SOS constraints' ) - def _remove_constraints(self, cons: List[_GeneralConstraintData]): + def _remove_constraints(self, cons: List[ConstraintData]): self._sol = None if self._last_results_object is not None: self._last_results_object.solution_loader.invalidate() @@ -487,13 +487,13 @@ def _remove_constraints(self, cons: List[_GeneralConstraintData]): {v: k for k, v in self._pyomo_con_to_solver_con_map.items()} ) - def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): + def _remove_sos_constraints(self, cons: List[SOSConstraintData]): if cons: raise NotImplementedError( 'Highs interface does not support SOS constraints' ) - def _remove_variables(self, variables: List[_GeneralVarData]): + def _remove_variables(self, variables: List[VarData]): self._sol = None if self._last_results_object is not None: self._last_results_object.solution_loader.invalidate() @@ -515,10 +515,10 @@ def _remove_variables(self, variables: List[_GeneralVarData]): self._pyomo_var_to_solver_var_map.clear() self._pyomo_var_to_solver_var_map.update(new_var_map) - def _remove_params(self, params: List[_ParamData]): + def _remove_params(self, params: List[ParamData]): pass - def _update_variables(self, variables: List[_GeneralVarData]): + def _update_variables(self, variables: List[VarData]): self._sol = None if self._last_results_object is not None: self._last_results_object.solution_loader.invalidate() diff --git a/pyomo/contrib/appsi/solvers/ipopt.py b/pyomo/contrib/appsi/solvers/ipopt.py index 54e21d333e5..76cd204e36d 100644 --- a/pyomo/contrib/appsi/solvers/ipopt.py +++ b/pyomo/contrib/appsi/solvers/ipopt.py @@ -28,11 +28,11 @@ from pyomo.core.expr.numvalue import value from pyomo.core.expr.visitor import replace_expressions from typing import Optional, Sequence, NoReturn, List, Mapping -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.block import _BlockData -from pyomo.core.base.param import _ParamData -from pyomo.core.base.objective import _GeneralObjectiveData +from pyomo.core.base.var import VarData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.block import BlockData +from pyomo.core.base.param import ParamData +from pyomo.core.base.objective import ObjectiveData from pyomo.common.timing import HierarchicalTimer from pyomo.common.tee import TeeStream import sys @@ -228,34 +228,34 @@ def set_instance(self, model): self._writer.config.symbolic_solver_labels = self.config.symbolic_solver_labels self._writer.set_instance(model) - def add_variables(self, variables: List[_GeneralVarData]): + def add_variables(self, variables: List[VarData]): self._writer.add_variables(variables) - def add_params(self, params: List[_ParamData]): + def add_params(self, params: List[ParamData]): self._writer.add_params(params) - def add_constraints(self, cons: List[_GeneralConstraintData]): + def add_constraints(self, cons: List[ConstraintData]): self._writer.add_constraints(cons) - def add_block(self, block: _BlockData): + def add_block(self, block: BlockData): self._writer.add_block(block) - def remove_variables(self, variables: List[_GeneralVarData]): + def remove_variables(self, variables: List[VarData]): self._writer.remove_variables(variables) - def remove_params(self, params: List[_ParamData]): + def remove_params(self, params: List[ParamData]): self._writer.remove_params(params) - def remove_constraints(self, cons: List[_GeneralConstraintData]): + def remove_constraints(self, cons: List[ConstraintData]): self._writer.remove_constraints(cons) - def remove_block(self, block: _BlockData): + def remove_block(self, block: BlockData): self._writer.remove_block(block) - def set_objective(self, obj: _GeneralObjectiveData): + def set_objective(self, obj: ObjectiveData): self._writer.set_objective(obj) - def update_variables(self, variables: List[_GeneralVarData]): + def update_variables(self, variables: List[VarData]): self._writer.update_variables(variables) def update_params(self): @@ -514,8 +514,8 @@ def _apply_solver(self, timer: HierarchicalTimer): return results def get_primals( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: if ( self._last_results_object is None or self._last_results_object.best_feasible_objective is None @@ -534,9 +534,7 @@ def get_primals( res[v] = self._primal_sol[v] return res - def get_duals( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ): + def get_duals(self, cons_to_load: Optional[Sequence[ConstraintData]] = None): if ( self._last_results_object is None or self._last_results_object.termination_condition @@ -553,8 +551,8 @@ def get_duals( return {c: self._dual_sol[c] for c in cons_to_load} def get_reduced_costs( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: if ( self._last_results_object is None or self._last_results_object.termination_condition diff --git a/pyomo/contrib/appsi/solvers/wntr.py b/pyomo/contrib/appsi/solvers/wntr.py index 00c0598c687..0a66cc640e5 100644 --- a/pyomo/contrib/appsi/solvers/wntr.py +++ b/pyomo/contrib/appsi/solvers/wntr.py @@ -39,10 +39,10 @@ from pyomo.common.collections import ComponentMap from pyomo.core.expr.numvalue import native_numeric_types from typing import Dict, Optional, List -from pyomo.core.base.block import _BlockData -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.param import _ParamData -from pyomo.core.base.constraint import _GeneralConstraintData +from pyomo.core.base.block import BlockData +from pyomo.core.base.var import VarData +from pyomo.core.base.param import ParamData +from pyomo.core.base.constraint import ConstraintData from pyomo.common.timing import HierarchicalTimer from pyomo.core.base import SymbolMap, NumericLabeler, TextLabeler from pyomo.common.dependencies import attempt_import @@ -178,7 +178,7 @@ def _solve(self, timer: HierarchicalTimer): ) return results - def solve(self, model: _BlockData, timer: HierarchicalTimer = None) -> Results: + def solve(self, model: BlockData, timer: HierarchicalTimer = None) -> Results: StaleFlagManager.mark_all_as_stale() if self._last_results_object is not None: self._last_results_object.solution_loader.invalidate() @@ -239,7 +239,7 @@ def set_instance(self, model): self.add_block(model) - def _add_variables(self, variables: List[_GeneralVarData]): + def _add_variables(self, variables: List[VarData]): aml = wntr.sim.aml.aml for var in variables: varname = self._symbol_map.getSymbol(var, self._labeler) @@ -270,7 +270,7 @@ def _add_variables(self, variables: List[_GeneralVarData]): ) self._needs_updated = True - def _add_params(self, params: List[_ParamData]): + def _add_params(self, params: List[ParamData]): aml = wntr.sim.aml.aml for p in params: pname = self._symbol_map.getSymbol(p, self._labeler) @@ -278,7 +278,7 @@ def _add_params(self, params: List[_ParamData]): setattr(self._solver_model, pname, wntr_p) self._pyomo_param_to_solver_param_map[id(p)] = wntr_p - def _add_constraints(self, cons: List[_GeneralConstraintData]): + def _add_constraints(self, cons: List[ConstraintData]): aml = wntr.sim.aml.aml for con in cons: if not con.equality: @@ -294,7 +294,7 @@ def _add_constraints(self, cons: List[_GeneralConstraintData]): self._pyomo_con_to_solver_con_map[con] = wntr_con self._needs_updated = True - def _remove_constraints(self, cons: List[_GeneralConstraintData]): + def _remove_constraints(self, cons: List[ConstraintData]): for con in cons: solver_con = self._pyomo_con_to_solver_con_map[con] delattr(self._solver_model, solver_con.name) @@ -302,7 +302,7 @@ def _remove_constraints(self, cons: List[_GeneralConstraintData]): del self._pyomo_con_to_solver_con_map[con] self._needs_updated = True - def _remove_variables(self, variables: List[_GeneralVarData]): + def _remove_variables(self, variables: List[VarData]): for var in variables: v_id = id(var) solver_var = self._pyomo_var_to_solver_var_map[v_id] @@ -314,7 +314,7 @@ def _remove_variables(self, variables: List[_GeneralVarData]): del self._solver_model._wntr_fixed_var_cons[v_id] self._needs_updated = True - def _remove_params(self, params: List[_ParamData]): + def _remove_params(self, params: List[ParamData]): for p in params: p_id = id(p) solver_param = self._pyomo_param_to_solver_param_map[p_id] @@ -322,7 +322,7 @@ def _remove_params(self, params: List[_ParamData]): self._symbol_map.removeSymbol(p) del self._pyomo_param_to_solver_param_map[p_id] - def _update_variables(self, variables: List[_GeneralVarData]): + def _update_variables(self, variables: List[VarData]): aml = wntr.sim.aml.aml for var in variables: v_id = id(var) diff --git a/pyomo/contrib/appsi/writers/lp_writer.py b/pyomo/contrib/appsi/writers/lp_writer.py index 9984cb7465d..788dfde7892 100644 --- a/pyomo/contrib/appsi/writers/lp_writer.py +++ b/pyomo/contrib/appsi/writers/lp_writer.py @@ -10,12 +10,12 @@ # ___________________________________________________________________________ from typing import List -from pyomo.core.base.param import _ParamData -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.objective import _GeneralObjectiveData -from pyomo.core.base.sos import _SOSConstraintData -from pyomo.core.base.block import _BlockData +from pyomo.core.base.param import ParamData +from pyomo.core.base.var import VarData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.objective import ObjectiveData +from pyomo.core.base.sos import SOSConstraintData +from pyomo.core.base.block import BlockData from pyomo.repn.standard_repn import generate_standard_repn from pyomo.core.expr.numvalue import value from pyomo.contrib.appsi.base import PersistentBase @@ -77,7 +77,7 @@ def set_instance(self, model): if self._objective is None: self.set_objective(None) - def _add_variables(self, variables: List[_GeneralVarData]): + def _add_variables(self, variables: List[VarData]): cmodel.process_pyomo_vars( self._expr_types, variables, @@ -91,7 +91,7 @@ def _add_variables(self, variables: List[_GeneralVarData]): False, ) - def _add_params(self, params: List[_ParamData]): + def _add_params(self, params: List[ParamData]): cparams = cmodel.create_params(len(params)) for ndx, p in enumerate(params): cp = cparams[ndx] @@ -99,36 +99,36 @@ def _add_params(self, params: List[_ParamData]): cp.value = p.value self._pyomo_param_to_solver_param_map[id(p)] = cp - def _add_constraints(self, cons: List[_GeneralConstraintData]): + def _add_constraints(self, cons: List[ConstraintData]): cmodel.process_lp_constraints(cons, self) - def _add_sos_constraints(self, cons: List[_SOSConstraintData]): + def _add_sos_constraints(self, cons: List[SOSConstraintData]): if len(cons) != 0: raise NotImplementedError('LP writer does not yet support SOS constraints') - def _remove_constraints(self, cons: List[_GeneralConstraintData]): + def _remove_constraints(self, cons: List[ConstraintData]): for c in cons: cc = self._pyomo_con_to_solver_con_map.pop(c) self._writer.remove_constraint(cc) self._symbol_map.removeSymbol(c) del self._solver_con_to_pyomo_con_map[cc] - def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): + def _remove_sos_constraints(self, cons: List[SOSConstraintData]): if len(cons) != 0: raise NotImplementedError('LP writer does not yet support SOS constraints') - def _remove_variables(self, variables: List[_GeneralVarData]): + def _remove_variables(self, variables: List[VarData]): for v in variables: cvar = self._pyomo_var_to_solver_var_map.pop(id(v)) del self._solver_var_to_pyomo_var_map[cvar] self._symbol_map.removeSymbol(v) - def _remove_params(self, params: List[_ParamData]): + def _remove_params(self, params: List[ParamData]): for p in params: del self._pyomo_param_to_solver_param_map[id(p)] self._symbol_map.removeSymbol(p) - def _update_variables(self, variables: List[_GeneralVarData]): + def _update_variables(self, variables: List[VarData]): cmodel.process_pyomo_vars( self._expr_types, variables, @@ -147,7 +147,7 @@ def update_params(self): cp = self._pyomo_param_to_solver_param_map[p_id] cp.value = p.value - def _set_objective(self, obj: _GeneralObjectiveData): + def _set_objective(self, obj: ObjectiveData): cobj = cmodel.process_lp_objective( self._expr_types, obj, @@ -167,7 +167,7 @@ def _set_objective(self, obj: _GeneralObjectiveData): cobj.name = cname self._writer.objective = cobj - def write(self, model: _BlockData, filename: str, timer: HierarchicalTimer = None): + def write(self, model: BlockData, filename: str, timer: HierarchicalTimer = None): if timer is None: timer = HierarchicalTimer() if model is not self._model: diff --git a/pyomo/contrib/appsi/writers/nl_writer.py b/pyomo/contrib/appsi/writers/nl_writer.py index bd24a86216a..27cdca004cb 100644 --- a/pyomo/contrib/appsi/writers/nl_writer.py +++ b/pyomo/contrib/appsi/writers/nl_writer.py @@ -10,12 +10,12 @@ # ___________________________________________________________________________ from typing import List -from pyomo.core.base.param import _ParamData -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.objective import _GeneralObjectiveData -from pyomo.core.base.sos import _SOSConstraintData -from pyomo.core.base.block import _BlockData +from pyomo.core.base.param import ParamData +from pyomo.core.base.var import VarData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.objective import ObjectiveData +from pyomo.core.base.sos import SOSConstraintData +from pyomo.core.base.block import BlockData from pyomo.repn.standard_repn import generate_standard_repn from pyomo.core.expr.numvalue import value from pyomo.contrib.appsi.base import PersistentBase @@ -78,7 +78,7 @@ def set_instance(self, model): self.set_objective(None) self._set_pyomo_amplfunc_env() - def _add_variables(self, variables: List[_GeneralVarData]): + def _add_variables(self, variables: List[VarData]): if self.config.symbolic_solver_labels: set_name = True symbol_map = self._symbol_map @@ -100,7 +100,7 @@ def _add_variables(self, variables: List[_GeneralVarData]): False, ) - def _add_params(self, params: List[_ParamData]): + def _add_params(self, params: List[ParamData]): cparams = cmodel.create_params(len(params)) for ndx, p in enumerate(params): cp = cparams[ndx] @@ -111,7 +111,7 @@ def _add_params(self, params: List[_ParamData]): cp = cparams[ndx] cp.name = self._symbol_map.getSymbol(p, self._param_labeler) - def _add_constraints(self, cons: List[_GeneralConstraintData]): + def _add_constraints(self, cons: List[ConstraintData]): cmodel.process_nl_constraints( self._writer, self._expr_types, @@ -126,11 +126,11 @@ def _add_constraints(self, cons: List[_GeneralConstraintData]): for c, cc in self._pyomo_con_to_solver_con_map.items(): cc.name = self._symbol_map.getSymbol(c, self._con_labeler) - def _add_sos_constraints(self, cons: List[_SOSConstraintData]): + def _add_sos_constraints(self, cons: List[SOSConstraintData]): if len(cons) != 0: raise NotImplementedError('NL writer does not support SOS constraints') - def _remove_constraints(self, cons: List[_GeneralConstraintData]): + def _remove_constraints(self, cons: List[ConstraintData]): if self.config.symbolic_solver_labels: for c in cons: self._symbol_map.removeSymbol(c) @@ -140,11 +140,11 @@ def _remove_constraints(self, cons: List[_GeneralConstraintData]): self._writer.remove_constraint(cc) del self._solver_con_to_pyomo_con_map[cc] - def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): + def _remove_sos_constraints(self, cons: List[SOSConstraintData]): if len(cons) != 0: raise NotImplementedError('NL writer does not support SOS constraints') - def _remove_variables(self, variables: List[_GeneralVarData]): + def _remove_variables(self, variables: List[VarData]): if self.config.symbolic_solver_labels: for v in variables: self._symbol_map.removeSymbol(v) @@ -153,7 +153,7 @@ def _remove_variables(self, variables: List[_GeneralVarData]): cvar = self._pyomo_var_to_solver_var_map.pop(id(v)) del self._solver_var_to_pyomo_var_map[cvar] - def _remove_params(self, params: List[_ParamData]): + def _remove_params(self, params: List[ParamData]): if self.config.symbolic_solver_labels: for p in params: self._symbol_map.removeSymbol(p) @@ -161,7 +161,7 @@ def _remove_params(self, params: List[_ParamData]): for p in params: del self._pyomo_param_to_solver_param_map[id(p)] - def _update_variables(self, variables: List[_GeneralVarData]): + def _update_variables(self, variables: List[VarData]): cmodel.process_pyomo_vars( self._expr_types, variables, @@ -180,7 +180,7 @@ def update_params(self): cp = self._pyomo_param_to_solver_param_map[p_id] cp.value = p.value - def _set_objective(self, obj: _GeneralObjectiveData): + def _set_objective(self, obj: ObjectiveData): if obj is None: const = cmodel.Constant(0) lin_vars = list() @@ -232,7 +232,7 @@ def _set_objective(self, obj: _GeneralObjectiveData): cobj.sense = sense self._writer.objective = cobj - def write(self, model: _BlockData, filename: str, timer: HierarchicalTimer = None): + def write(self, model: BlockData, filename: str, timer: HierarchicalTimer = None): if timer is None: timer = HierarchicalTimer() if model is not self._model: diff --git a/pyomo/contrib/benders/benders_cuts.py b/pyomo/contrib/benders/benders_cuts.py index cf96ba26164..0653be55986 100644 --- a/pyomo/contrib/benders/benders_cuts.py +++ b/pyomo/contrib/benders/benders_cuts.py @@ -9,7 +9,7 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ -from pyomo.core.base.block import _BlockData, declare_custom_block +from pyomo.core.base.block import BlockData, declare_custom_block import pyomo.environ as pyo from pyomo.solvers.plugins.solvers.persistent_solver import PersistentSolver from pyomo.core.expr.visitor import identify_variables @@ -166,13 +166,13 @@ def _setup_subproblem(b, root_vars, relax_subproblem_cons): @declare_custom_block(name='BendersCutGenerator') -class BendersCutGeneratorData(_BlockData): +class BendersCutGeneratorData(BlockData): def __init__(self, component): if not mpi4py_available: raise ImportError('BendersCutGenerator requires mpi4py.') if not numpy_available: raise ImportError('BendersCutGenerator requires numpy.') - _BlockData.__init__(self, component) + BlockData.__init__(self, component) self.num_subproblems_by_rank = 0 # np.zeros(self.comm.Get_size()) self.subproblems = list() diff --git a/pyomo/contrib/community_detection/detection.py b/pyomo/contrib/community_detection/detection.py index 5bf8187a243..0e2c3912e06 100644 --- a/pyomo/contrib/community_detection/detection.py +++ b/pyomo/contrib/community_detection/detection.py @@ -31,7 +31,7 @@ Objective, ConstraintList, ) -from pyomo.core.base.objective import _GeneralObjectiveData +from pyomo.core.base.objective import ObjectiveData from pyomo.core.expr.visitor import replace_expressions, identify_variables from pyomo.contrib.community_detection.community_graph import generate_model_graph from pyomo.common.dependencies import networkx as nx @@ -750,7 +750,7 @@ def generate_structured_model(self): # Check to see whether 'stored_constraint' is actually an objective (since constraints and objectives # grouped together) if self.with_objective and isinstance( - stored_constraint, (_GeneralObjectiveData, Objective) + stored_constraint, (ObjectiveData, Objective) ): # If the constraint is actually an objective, we add it to the block as an objective new_objective = Objective( diff --git a/pyomo/contrib/cp/interval_var.py b/pyomo/contrib/cp/interval_var.py index 953b859ea20..ff11d6e3a9f 100644 --- a/pyomo/contrib/cp/interval_var.py +++ b/pyomo/contrib/cp/interval_var.py @@ -18,7 +18,7 @@ from pyomo.core import Integers, value from pyomo.core.base import Any, ScalarVar, ScalarBooleanVar -from pyomo.core.base.block import _BlockData, Block +from pyomo.core.base.block import BlockData, Block from pyomo.core.base.component import ModelComponentFactory from pyomo.core.base.global_set import UnindexedComponent_index from pyomo.core.base.indexed_component import IndexedComponent, UnindexedComponent_set @@ -87,14 +87,14 @@ def get_associated_interval_var(self): return self.parent_block() -class IntervalVarData(_BlockData): +class IntervalVarData(BlockData): """This class defines the abstract interface for a single interval variable.""" # We will put our four variables on this, and everything else is off limits. _Block_reserved_words = Any def __init__(self, component=None): - _BlockData.__init__(self, component) + BlockData.__init__(self, component) with self._declare_reserved_components(): self.is_present = IntervalVarPresence() diff --git a/pyomo/contrib/cp/repn/docplex_writer.py b/pyomo/contrib/cp/repn/docplex_writer.py index 8356a1e752f..37429d420d2 100644 --- a/pyomo/contrib/cp/repn/docplex_writer.py +++ b/pyomo/contrib/cp/repn/docplex_writer.py @@ -60,12 +60,12 @@ ) from pyomo.core.base.boolean_var import ( ScalarBooleanVar, - _GeneralBooleanVarData, + BooleanVarData, IndexedBooleanVar, ) -from pyomo.core.base.expression import ScalarExpression, _GeneralExpressionData -from pyomo.core.base.param import IndexedParam, ScalarParam, _ParamData -from pyomo.core.base.var import ScalarVar, _GeneralVarData, IndexedVar +from pyomo.core.base.expression import ScalarExpression, ExpressionData +from pyomo.core.base.param import IndexedParam, ScalarParam, ParamData +from pyomo.core.base.var import ScalarVar, VarData, IndexedVar import pyomo.core.expr as EXPR from pyomo.core.expr.visitor import StreamBasedExpressionVisitor, identify_variables from pyomo.core.base import Set, RangeSet @@ -949,7 +949,7 @@ class LogicalToDoCplex(StreamBasedExpressionVisitor): BeforeExpression: _handle_before_expression_node, AtExpression: _handle_at_expression_node, AlwaysIn: _handle_always_in_node, - _GeneralExpressionData: _handle_named_expression_node, + ExpressionData: _handle_named_expression_node, ScalarExpression: _handle_named_expression_node, } _var_handles = { @@ -961,16 +961,16 @@ class LogicalToDoCplex(StreamBasedExpressionVisitor): IntervalVarData: _before_interval_var, IndexedIntervalVar: _before_indexed_interval_var, ScalarVar: _before_var, - _GeneralVarData: _before_var, + VarData: _before_var, IndexedVar: _before_indexed_var, ScalarBooleanVar: _before_boolean_var, - _GeneralBooleanVarData: _before_boolean_var, + BooleanVarData: _before_boolean_var, IndexedBooleanVar: _before_indexed_boolean_var, - _GeneralExpressionData: _before_named_expression, + ExpressionData: _before_named_expression, ScalarExpression: _before_named_expression, IndexedParam: _before_indexed_param, # Because of indirection ScalarParam: _before_param, - _ParamData: _before_param, + ParamData: _before_param, } def __init__(self, cpx_model, symbolic_solver_labels=False): diff --git a/pyomo/contrib/cp/transform/logical_to_disjunctive_program.py b/pyomo/contrib/cp/transform/logical_to_disjunctive_program.py index e318e621e88..c29bf3f2675 100644 --- a/pyomo/contrib/cp/transform/logical_to_disjunctive_program.py +++ b/pyomo/contrib/cp/transform/logical_to_disjunctive_program.py @@ -26,7 +26,7 @@ Transformation, NonNegativeIntegers, ) -from pyomo.core.base.block import _BlockData +from pyomo.core.base.block import BlockData from pyomo.core.base import SortComponents from pyomo.core.util import target_list from pyomo.gdp import Disjunct, Disjunction @@ -73,7 +73,7 @@ def _apply_to(self, model, **kwds): transBlocks = {} visitor = LogicalToDisjunctiveVisitor() for t in targets: - if t.ctype is Block or isinstance(t, _BlockData): + if t.ctype is Block or isinstance(t, BlockData): self._transform_block(t, model, visitor, transBlocks) elif t.ctype is LogicalConstraint: if t.is_indexed(): diff --git a/pyomo/contrib/cp/transform/logical_to_disjunctive_walker.py b/pyomo/contrib/cp/transform/logical_to_disjunctive_walker.py index d5f13e91535..fdcfd5a8308 100644 --- a/pyomo/contrib/cp/transform/logical_to_disjunctive_walker.py +++ b/pyomo/contrib/cp/transform/logical_to_disjunctive_walker.py @@ -27,9 +27,9 @@ value, ) import pyomo.core.base.boolean_var as BV -from pyomo.core.base.expression import ScalarExpression, _GeneralExpressionData -from pyomo.core.base.param import ScalarParam, _ParamData -from pyomo.core.base.var import ScalarVar, _GeneralVarData +from pyomo.core.base.expression import ScalarExpression, ExpressionData +from pyomo.core.base.param import ScalarParam, ParamData +from pyomo.core.base.var import ScalarVar, VarData from pyomo.gdp.disjunct import AutoLinkedBooleanVar, Disjunct, Disjunction @@ -209,15 +209,15 @@ def _dispatch_atmost(visitor, node, *args): _before_child_dispatcher = {} _before_child_dispatcher[BV.ScalarBooleanVar] = _dispatch_boolean_var -_before_child_dispatcher[BV._GeneralBooleanVarData] = _dispatch_boolean_var +_before_child_dispatcher[BV.BooleanVarData] = _dispatch_boolean_var _before_child_dispatcher[AutoLinkedBooleanVar] = _dispatch_boolean_var -_before_child_dispatcher[_ParamData] = _dispatch_param +_before_child_dispatcher[ParamData] = _dispatch_param _before_child_dispatcher[ScalarParam] = _dispatch_param # for the moment, these are all just so we can get good error messages when we # don't handle them: _before_child_dispatcher[ScalarVar] = _dispatch_var -_before_child_dispatcher[_GeneralVarData] = _dispatch_var -_before_child_dispatcher[_GeneralExpressionData] = _dispatch_expression +_before_child_dispatcher[VarData] = _dispatch_var +_before_child_dispatcher[ExpressionData] = _dispatch_expression _before_child_dispatcher[ScalarExpression] = _dispatch_expression diff --git a/pyomo/contrib/fbbt/fbbt.py b/pyomo/contrib/fbbt/fbbt.py index bde33b3caa0..1507c4a3cc5 100644 --- a/pyomo/contrib/fbbt/fbbt.py +++ b/pyomo/contrib/fbbt/fbbt.py @@ -24,9 +24,10 @@ import math from pyomo.core.base.block import Block from pyomo.core.base.constraint import Constraint +from pyomo.core.base.expression import ExpressionData, ScalarExpression +from pyomo.core.base.objective import ObjectiveData, ScalarObjective from pyomo.core.base.var import Var from pyomo.gdp import Disjunct -from pyomo.core.base.expression import _GeneralExpressionData, ScalarExpression import logging from pyomo.common.errors import InfeasibleConstraintException, PyomoException from pyomo.common.config import ( @@ -333,15 +334,15 @@ def _prop_bnds_leaf_to_root_UnaryFunctionExpression(visitor, node, arg): _unary_leaf_to_root_map[node.getname()](visitor, node, arg) -def _prop_bnds_leaf_to_root_GeneralExpression(visitor, node, expr): +def _prop_bnds_leaf_to_root_NamedExpression(visitor, node, expr): """ Propagate bounds from children to parent Parameters ---------- visitor: _FBBTVisitorLeafToRoot - node: pyomo.core.base.expression._GeneralExpressionData - expr: GeneralExpression arg + node: pyomo.core.base.expression.NamedExpressionData + expr: NamedExpressionData arg """ bnds_dict = visitor.bnds_dict if node in bnds_dict: @@ -366,8 +367,10 @@ def _prop_bnds_leaf_to_root_GeneralExpression(visitor, node, expr): numeric_expr.UnaryFunctionExpression: _prop_bnds_leaf_to_root_UnaryFunctionExpression, numeric_expr.LinearExpression: _prop_bnds_leaf_to_root_SumExpression, numeric_expr.AbsExpression: _prop_bnds_leaf_to_root_abs, - _GeneralExpressionData: _prop_bnds_leaf_to_root_GeneralExpression, - ScalarExpression: _prop_bnds_leaf_to_root_GeneralExpression, + ExpressionData: _prop_bnds_leaf_to_root_NamedExpression, + ScalarExpression: _prop_bnds_leaf_to_root_NamedExpression, + ObjectiveData: _prop_bnds_leaf_to_root_NamedExpression, + ScalarObjective: _prop_bnds_leaf_to_root_NamedExpression, }, ) @@ -898,13 +901,13 @@ def _prop_bnds_root_to_leaf_UnaryFunctionExpression(node, bnds_dict, feasibility ) -def _prop_bnds_root_to_leaf_GeneralExpression(node, bnds_dict, feasibility_tol): +def _prop_bnds_root_to_leaf_NamedExpression(node, bnds_dict, feasibility_tol): """ Propagate bounds from parent to children. Parameters ---------- - node: pyomo.core.base.expression._GeneralExpressionData + node: pyomo.core.base.expression.NamedExpressionData bnds_dict: ComponentMap feasibility_tol: float If the bounds computed on the body of a constraint violate the bounds of the constraint by more than @@ -945,12 +948,10 @@ def _prop_bnds_root_to_leaf_GeneralExpression(node, bnds_dict, feasibility_tol): ) _prop_bnds_root_to_leaf_map[numeric_expr.AbsExpression] = _prop_bnds_root_to_leaf_abs -_prop_bnds_root_to_leaf_map[_GeneralExpressionData] = ( - _prop_bnds_root_to_leaf_GeneralExpression -) -_prop_bnds_root_to_leaf_map[ScalarExpression] = ( - _prop_bnds_root_to_leaf_GeneralExpression -) +_prop_bnds_root_to_leaf_map[ExpressionData] = _prop_bnds_root_to_leaf_NamedExpression +_prop_bnds_root_to_leaf_map[ScalarExpression] = _prop_bnds_root_to_leaf_NamedExpression +_prop_bnds_root_to_leaf_map[ObjectiveData] = _prop_bnds_root_to_leaf_NamedExpression +_prop_bnds_root_to_leaf_map[ScalarObjective] = _prop_bnds_root_to_leaf_NamedExpression def _check_and_reset_bounds(var, lb, ub): diff --git a/pyomo/contrib/fme/fourier_motzkin_elimination.py b/pyomo/contrib/fme/fourier_motzkin_elimination.py index a1b5d744cf4..4636450c58e 100644 --- a/pyomo/contrib/fme/fourier_motzkin_elimination.py +++ b/pyomo/contrib/fme/fourier_motzkin_elimination.py @@ -23,7 +23,7 @@ value, ConstraintList, ) -from pyomo.core.base import TransformationFactory, _VarData +from pyomo.core.base import TransformationFactory, VarData from pyomo.core.plugins.transform.hierarchy import Transformation from pyomo.common.config import ConfigBlock, ConfigValue, NonNegativeFloat from pyomo.common.modeling import unique_component_name @@ -58,7 +58,7 @@ def _check_var_bounds_filter(constraint): def vars_to_eliminate_list(x): - if isinstance(x, (Var, _VarData)): + if isinstance(x, (Var, VarData)): if not x.is_indexed(): return ComponentSet([x]) ans = ComponentSet() diff --git a/pyomo/contrib/gdp_bounds/info.py b/pyomo/contrib/gdp_bounds/info.py index 6f39af5908d..e65df2bfab0 100644 --- a/pyomo/contrib/gdp_bounds/info.py +++ b/pyomo/contrib/gdp_bounds/info.py @@ -35,10 +35,10 @@ def disjunctive_bound(var, scope): """Compute the disjunctive bounds for a variable in a given scope. Args: - var (_VarData): Variable for which to compute bound + var (VarData): Variable for which to compute bound scope (Component): The scope in which to compute the bound. If not a - _DisjunctData, it will walk up the tree and use the scope of the - most immediate enclosing _DisjunctData. + DisjunctData, it will walk up the tree and use the scope of the + most immediate enclosing DisjunctData. Returns: numeric: the tighter of either the disjunctive lower bound, the diff --git a/pyomo/contrib/incidence_analysis/interface.py b/pyomo/contrib/incidence_analysis/interface.py index 0f47e03d0a2..b73ec17f36c 100644 --- a/pyomo/contrib/incidence_analysis/interface.py +++ b/pyomo/contrib/incidence_analysis/interface.py @@ -15,7 +15,7 @@ import enum import textwrap -from pyomo.core.base.block import _BlockData +from pyomo.core.base.block import BlockData from pyomo.core.base.var import Var from pyomo.core.base.constraint import Constraint from pyomo.core.base.objective import Objective @@ -279,7 +279,7 @@ def __init__(self, model=None, active=True, include_inequality=True, **kwds): self._incidence_graph = None self._variables = None self._constraints = None - elif isinstance(model, _BlockData): + elif isinstance(model, BlockData): self._constraints = [ con for con in model.component_data_objects(Constraint, active=active) @@ -348,7 +348,7 @@ def __init__(self, model=None, active=True, include_inequality=True, **kwds): else: raise TypeError( "Unsupported type for incidence graph. Expected PyomoNLP" - " or _BlockData but got %s." % type(model) + " or BlockData but got %s." % type(model) ) @property diff --git a/pyomo/contrib/incidence_analysis/scc_solver.py b/pyomo/contrib/incidence_analysis/scc_solver.py index 0c59fe8703e..378647c190c 100644 --- a/pyomo/contrib/incidence_analysis/scc_solver.py +++ b/pyomo/contrib/incidence_analysis/scc_solver.py @@ -27,7 +27,7 @@ def generate_strongly_connected_components( constraints, variables=None, include_fixed=False, igraph=None ): - """Yield in order ``_BlockData`` that each contain the variables and + """Yield in order ``BlockData`` that each contain the variables and constraints of a single diagonal block in a block lower triangularization of the incidence matrix of constraints and variables @@ -51,7 +51,7 @@ def generate_strongly_connected_components( Yields ------ - Tuple of ``_BlockData``, list-of-variables + Tuple of ``BlockData``, list-of-variables Blocks containing the variables and constraints of every strongly connected component, in a topological order. The variables are the "input variables" for that block. diff --git a/pyomo/contrib/incidence_analysis/tests/test_interface.py b/pyomo/contrib/incidence_analysis/tests/test_interface.py index b0a9661aa54..9957e78168b 100644 --- a/pyomo/contrib/incidence_analysis/tests/test_interface.py +++ b/pyomo/contrib/incidence_analysis/tests/test_interface.py @@ -1920,7 +1920,7 @@ def test_block_data_obj(self): self.assertEqual(len(var_dmp.unmatched), 1) self.assertEqual(len(con_dmp.unmatched), 1) - msg = "Unsupported type.*_BlockData" + msg = "Unsupported type.*BlockData" with self.assertRaisesRegex(TypeError, msg): igraph = IncidenceGraphInterface(m.block) diff --git a/pyomo/contrib/latex_printer/latex_printer.py b/pyomo/contrib/latex_printer/latex_printer.py index 0a595dd8e1b..cf286472a66 100644 --- a/pyomo/contrib/latex_printer/latex_printer.py +++ b/pyomo/contrib/latex_printer/latex_printer.py @@ -34,8 +34,8 @@ from pyomo.core.expr.visitor import identify_components from pyomo.core.expr.base import ExpressionBase -from pyomo.core.base.expression import ScalarExpression, _GeneralExpressionData -from pyomo.core.base.objective import ScalarObjective, _GeneralObjectiveData +from pyomo.core.base.expression import ScalarExpression, ExpressionData +from pyomo.core.base.objective import ScalarObjective, ObjectiveData import pyomo.core.kernel as kernel from pyomo.core.expr.template_expr import ( GetItemExpression, @@ -47,9 +47,9 @@ resolve_template, templatize_rule, ) -from pyomo.core.base.var import ScalarVar, _GeneralVarData, IndexedVar -from pyomo.core.base.param import _ParamData, ScalarParam, IndexedParam -from pyomo.core.base.set import _SetData, SetOperator +from pyomo.core.base.var import ScalarVar, VarData, IndexedVar +from pyomo.core.base.param import ParamData, ScalarParam, IndexedParam +from pyomo.core.base.set import SetData, SetOperator from pyomo.core.base.constraint import ScalarConstraint, IndexedConstraint from pyomo.common.collections.component_map import ComponentMap from pyomo.common.collections.component_set import ComponentSet @@ -64,7 +64,7 @@ from pyomo.core.base.external import _PythonCallbackFunctionID from pyomo.core.base.enums import SortComponents -from pyomo.core.base.block import _BlockData +from pyomo.core.base.block import BlockData from pyomo.repn.util import ExprType @@ -399,12 +399,12 @@ def __init__(self): EqualityExpression: handle_equality_node, InequalityExpression: handle_inequality_node, RangedExpression: handle_ranged_inequality_node, - _GeneralExpressionData: handle_named_expression_node, + ExpressionData: handle_named_expression_node, ScalarExpression: handle_named_expression_node, kernel.expression.expression: handle_named_expression_node, kernel.expression.noclone: handle_named_expression_node, - _GeneralObjectiveData: handle_named_expression_node, - _GeneralVarData: handle_var_node, + ObjectiveData: handle_named_expression_node, + VarData: handle_var_node, ScalarObjective: handle_named_expression_node, kernel.objective.objective: handle_named_expression_node, ExternalFunctionExpression: handle_external_function_node, @@ -417,7 +417,7 @@ def __init__(self): Numeric_GetItemExpression: handle_numericGetItemExpression_node, TemplateSumExpression: handle_templateSumExpression_node, ScalarParam: handle_param_node, - _ParamData: handle_param_node, + ParamData: handle_param_node, IndexedParam: handle_param_node, NPV_Numeric_GetItemExpression: handle_numericGetItemExpression_node, IndexedBlock: handle_indexedBlock_node, @@ -587,7 +587,7 @@ def latex_printer( Parameters ---------- - pyomo_component: _BlockData or Model or Objective or Constraint or Expression + pyomo_component: BlockData or Model or Objective or Constraint or Expression The Pyomo component to be printed latex_component_map: pyomo.common.collections.component_map.ComponentMap @@ -674,7 +674,7 @@ def latex_printer( use_equation_environment = True isSingle = True - elif isinstance(pyomo_component, _BlockData): + elif isinstance(pyomo_component, BlockData): objectives = [ obj for obj in pyomo_component.component_data_objects( @@ -705,10 +705,8 @@ def latex_printer( if isSingle: temp_comp, temp_indexes = templatize_fcn(pyomo_component) variableList = [] - for v in identify_components( - temp_comp, [ScalarVar, _GeneralVarData, IndexedVar] - ): - if isinstance(v, _GeneralVarData): + for v in identify_components(temp_comp, [ScalarVar, VarData, IndexedVar]): + if isinstance(v, VarData): v_write = v.parent_component() if v_write not in ComponentSet(variableList): variableList.append(v_write) @@ -717,10 +715,8 @@ def latex_printer( variableList.append(v) parameterList = [] - for p in identify_components( - temp_comp, [ScalarParam, _ParamData, IndexedParam] - ): - if isinstance(p, _ParamData): + for p in identify_components(temp_comp, [ScalarParam, ParamData, IndexedParam]): + if isinstance(p, ParamData): p_write = p.parent_component() if p_write not in ComponentSet(parameterList): parameterList.append(p_write) @@ -1275,17 +1271,17 @@ def get_index_names(st, lcm): rep_dict = {} for ky in reversed(list(latex_component_map)): - if isinstance(ky, (pyo.Var, _GeneralVarData)): + if isinstance(ky, (pyo.Var, VarData)): overwrite_value = latex_component_map[ky] if ky not in existing_components: overwrite_value = overwrite_value.replace('_', '\\_') rep_dict[variableMap[ky]] = overwrite_value - elif isinstance(ky, (pyo.Param, _ParamData)): + elif isinstance(ky, (pyo.Param, ParamData)): overwrite_value = latex_component_map[ky] if ky not in existing_components: overwrite_value = overwrite_value.replace('_', '\\_') rep_dict[parameterMap[ky]] = overwrite_value - elif isinstance(ky, _SetData): + elif isinstance(ky, SetData): # already handled pass elif isinstance(ky, (float, int)): diff --git a/pyomo/contrib/mcpp/pyomo_mcpp.py b/pyomo/contrib/mcpp/pyomo_mcpp.py index 35e883f98da..0ef0237681b 100644 --- a/pyomo/contrib/mcpp/pyomo_mcpp.py +++ b/pyomo/contrib/mcpp/pyomo_mcpp.py @@ -20,7 +20,7 @@ from pyomo.common.fileutils import Library from pyomo.core import value, Expression from pyomo.core.base.block import SubclassOf -from pyomo.core.base.expression import _ExpressionData +from pyomo.core.base.expression import NamedExpressionData from pyomo.core.expr.numvalue import nonpyomo_leaf_types from pyomo.core.expr.numeric_expr import ( AbsExpression, @@ -307,7 +307,9 @@ def exitNode(self, node, data): ans = self.mcpp.newConstant(node) elif not node.is_expression_type(): ans = self.register_num(node) - elif type(node) in SubclassOf(Expression) or isinstance(node, _ExpressionData): + elif type(node) in SubclassOf(Expression) or isinstance( + node, NamedExpressionData + ): ans = data[0] else: raise RuntimeError("Unhandled expression type: %s" % (type(node))) diff --git a/pyomo/contrib/parmest/utils/scenario_tree.py b/pyomo/contrib/parmest/utils/scenario_tree.py index e71f51877b5..f245e053cad 100644 --- a/pyomo/contrib/parmest/utils/scenario_tree.py +++ b/pyomo/contrib/parmest/utils/scenario_tree.py @@ -25,7 +25,7 @@ def build_vardatalist(self, model, varlist=None): """ - Convert a list of pyomo variables to a list of ScalarVar and _GeneralVarData. If varlist is none, builds a + Convert a list of pyomo variables to a list of ScalarVar and VarData. If varlist is none, builds a list of all variables in the model. The new list is stored in the vars_to_tighten attribute. By CD Laird Parameters diff --git a/pyomo/contrib/piecewise/piecewise_linear_function.py b/pyomo/contrib/piecewise/piecewise_linear_function.py index 66ca02ad125..e92edacc756 100644 --- a/pyomo/contrib/piecewise/piecewise_linear_function.py +++ b/pyomo/contrib/piecewise/piecewise_linear_function.py @@ -20,7 +20,7 @@ PiecewiseLinearExpression, ) from pyomo.core import Any, NonNegativeIntegers, value, Var -from pyomo.core.base.block import _BlockData, Block +from pyomo.core.base.block import BlockData, Block from pyomo.core.base.component import ModelComponentFactory from pyomo.core.base.expression import Expression from pyomo.core.base.global_set import UnindexedComponent_index @@ -36,11 +36,11 @@ logger = logging.getLogger(__name__) -class PiecewiseLinearFunctionData(_BlockData): +class PiecewiseLinearFunctionData(BlockData): _Block_reserved_words = Any def __init__(self, component=None): - _BlockData.__init__(self, component) + BlockData.__init__(self, component) with self._declare_reserved_components(): self._expressions = Expression(NonNegativeIntegers) diff --git a/pyomo/contrib/piecewise/transform/piecewise_to_gdp_transformation.py b/pyomo/contrib/piecewise/transform/piecewise_to_gdp_transformation.py index 2e056c47a15..5417cbc17f4 100644 --- a/pyomo/contrib/piecewise/transform/piecewise_to_gdp_transformation.py +++ b/pyomo/contrib/piecewise/transform/piecewise_to_gdp_transformation.py @@ -33,7 +33,7 @@ Any, ) from pyomo.core.base import Transformation -from pyomo.core.base.block import _BlockData, Block +from pyomo.core.base.block import Block from pyomo.core.util import target_list from pyomo.gdp import Disjunct, Disjunction from pyomo.gdp.util import is_child_of @@ -147,7 +147,7 @@ def _apply_to_impl(self, instance, **kwds): self._transform_piecewise_linear_function( t, config.descend_into_expressions ) - elif t.ctype is Block or isinstance(t, _BlockData): + elif issubclass(t.ctype, Block): self._transform_block(t, config.descend_into_expressions) elif t.ctype is Constraint: if not config.descend_into_expressions: diff --git a/pyomo/contrib/pynumero/algorithms/solvers/pyomo_ext_cyipopt.py b/pyomo/contrib/pynumero/algorithms/solvers/pyomo_ext_cyipopt.py index 16c5a19a5c6..7f43f6ac7c0 100644 --- a/pyomo/contrib/pynumero/algorithms/solvers/pyomo_ext_cyipopt.py +++ b/pyomo/contrib/pynumero/algorithms/solvers/pyomo_ext_cyipopt.py @@ -16,7 +16,7 @@ from pyomo.contrib.pynumero.interfaces.pyomo_nlp import PyomoNLP from pyomo.contrib.pynumero.sparse.block_vector import BlockVector from pyomo.environ import Var, Constraint, value -from pyomo.core.base.var import _VarData +from pyomo.core.base.var import VarData from pyomo.common.modeling import unique_component_name """ @@ -109,12 +109,12 @@ def __init__( An instance of a derived class (from ExternalInputOutputModel) that provides the methods to compute the outputs and the derivatives. - inputs : list of Pyomo variables (_VarData) + inputs : list of Pyomo variables (VarData) The Pyomo model needs to have variables to represent the inputs to the external model. This is the list of those input variables in the order that corresponds to the input_values vector provided in the set_inputs call. - outputs : list of Pyomo variables (_VarData) + outputs : list of Pyomo variables (VarData) The Pyomo model needs to have variables to represent the outputs from the external model. This is the list of those output variables in the order that corresponds to the numpy array returned from the evaluate_outputs call. @@ -130,7 +130,7 @@ def __init__( # verify that the inputs and outputs were passed correctly self._inputs = [v for v in inputs] for v in self._inputs: - if not isinstance(v, _VarData): + if not isinstance(v, VarData): raise RuntimeError( 'Argument inputs passed to PyomoExternalCyIpoptProblem must be' ' a list of VarData objects. Note: if you have an indexed variable, pass' @@ -139,7 +139,7 @@ def __init__( self._outputs = [v for v in outputs] for v in self._outputs: - if not isinstance(v, _VarData): + if not isinstance(v, VarData): raise RuntimeError( 'Argument outputs passed to PyomoExternalCyIpoptProblem must be' ' a list of VarData objects. Note: if you have an indexed variable, pass' diff --git a/pyomo/contrib/pynumero/interfaces/external_grey_box.py b/pyomo/contrib/pynumero/interfaces/external_grey_box.py index 7e42f161bee..68e652575cc 100644 --- a/pyomo/contrib/pynumero/interfaces/external_grey_box.py +++ b/pyomo/contrib/pynumero/interfaces/external_grey_box.py @@ -18,7 +18,7 @@ from pyomo.common.log import is_debug_set from pyomo.common.timing import ConstructionTimer from pyomo.core.base import Var, Set, Constraint, value -from pyomo.core.base.block import _BlockData, Block, declare_custom_block +from pyomo.core.base.block import BlockData, Block, declare_custom_block from pyomo.core.base.global_set import UnindexedComponent_index from pyomo.core.base.initializer import Initializer from pyomo.core.base.set import UnindexedComponent_set @@ -316,7 +316,7 @@ def evaluate_jacobian_outputs(self): # -class ExternalGreyBoxBlockData(_BlockData): +class ExternalGreyBoxBlockData(BlockData): def set_external_model(self, external_grey_box_model, inputs=None, outputs=None): """ Parameters @@ -424,7 +424,7 @@ class ScalarExternalGreyBoxBlock(ExternalGreyBoxBlockData, ExternalGreyBoxBlock) def __init__(self, *args, **kwds): ExternalGreyBoxBlockData.__init__(self, component=self) ExternalGreyBoxBlock.__init__(self, *args, **kwds) - # The above inherit from Block and _BlockData, so it's not until here + # The above inherit from Block and BlockData, so it's not until here # that we know it's scalar. So we set the index accordingly. self._index = UnindexedComponent_index diff --git a/pyomo/contrib/pyros/config.py b/pyomo/contrib/pyros/config.py index 8ab24939349..c02dcd7ed0f 100644 --- a/pyomo/contrib/pyros/config.py +++ b/pyomo/contrib/pyros/config.py @@ -16,8 +16,8 @@ Path, ) from pyomo.common.errors import ApplicationError, PyomoException -from pyomo.core.base import Var, _VarData -from pyomo.core.base.param import Param, _ParamData +from pyomo.core.base import Var, VarData +from pyomo.core.base.param import Param, ParamData from pyomo.opt import SolverFactory from pyomo.contrib.pyros.util import ObjectiveType, setup_pyros_logger from pyomo.contrib.pyros.uncertainty_sets import UncertaintySet @@ -62,7 +62,7 @@ def mutable_param_validator(param_obj): Parameters ---------- - param_obj : Param or _ParamData + param_obj : Param or ParamData Param-like object of interest. Raises @@ -98,7 +98,7 @@ class InputDataStandardizer(object): Pyomo component type, such as Component, Var or Param. cdatatype : type Corresponding Pyomo component data type, such as - _ComponentData, _VarData, or _ParamData. + ComponentData, VarData, or ParamData. ctype_validator : callable, optional Validator function for objects of type `ctype`. cdatatype_validator : callable, optional @@ -526,7 +526,7 @@ def pyros_config(): "first_stage_variables", ConfigValue( default=[], - domain=InputDataStandardizer(Var, _VarData, allow_repeats=False), + domain=InputDataStandardizer(Var, VarData, allow_repeats=False), description="First-stage (or design) variables.", visibility=1, ), @@ -535,7 +535,7 @@ def pyros_config(): "second_stage_variables", ConfigValue( default=[], - domain=InputDataStandardizer(Var, _VarData, allow_repeats=False), + domain=InputDataStandardizer(Var, VarData, allow_repeats=False), description="Second-stage (or control) variables.", visibility=1, ), @@ -546,7 +546,7 @@ def pyros_config(): default=[], domain=InputDataStandardizer( ctype=Param, - cdatatype=_ParamData, + cdatatype=ParamData, ctype_validator=mutable_param_validator, allow_repeats=False, ), diff --git a/pyomo/contrib/pyros/pyros_algorithm_methods.py b/pyomo/contrib/pyros/pyros_algorithm_methods.py index 5987db074e6..cfb57b08c7f 100644 --- a/pyomo/contrib/pyros/pyros_algorithm_methods.py +++ b/pyomo/contrib/pyros/pyros_algorithm_methods.py @@ -28,7 +28,7 @@ from pyomo.core.base import value from pyomo.core.expr import MonomialTermExpression from pyomo.common.collections import ComponentSet, ComponentMap -from pyomo.core.base.var import _VarData as VarData +from pyomo.core.base.var import VarData as VarData from itertools import chain from pyomo.common.dependencies import numpy as np diff --git a/pyomo/contrib/pyros/tests/test_config.py b/pyomo/contrib/pyros/tests/test_config.py index 0f52d04135d..166fbada4ff 100644 --- a/pyomo/contrib/pyros/tests/test_config.py +++ b/pyomo/contrib/pyros/tests/test_config.py @@ -5,10 +5,10 @@ import logging import unittest -from pyomo.core.base import ConcreteModel, Var, _VarData +from pyomo.core.base import ConcreteModel, Var, VarData from pyomo.common.log import LoggingIntercept from pyomo.common.errors import ApplicationError -from pyomo.core.base.param import Param, _ParamData +from pyomo.core.base.param import Param, ParamData from pyomo.contrib.pyros.config import ( InputDataStandardizer, mutable_param_validator, @@ -38,7 +38,7 @@ def test_single_component_data(self): mdl = ConcreteModel() mdl.v = Var([0, 1]) - standardizer_func = InputDataStandardizer(Var, _VarData) + standardizer_func = InputDataStandardizer(Var, VarData) standardizer_input = mdl.v[0] standardizer_output = standardizer_func(standardizer_input) @@ -74,7 +74,7 @@ def test_standardizer_indexed_component(self): mdl = ConcreteModel() mdl.v = Var([0, 1]) - standardizer_func = InputDataStandardizer(Var, _VarData) + standardizer_func = InputDataStandardizer(Var, VarData) standardizer_input = mdl.v standardizer_output = standardizer_func(standardizer_input) @@ -113,7 +113,7 @@ def test_standardizer_multiple_components(self): mdl.v = Var([0, 1]) mdl.x = Var(["a", "b"]) - standardizer_func = InputDataStandardizer(Var, _VarData) + standardizer_func = InputDataStandardizer(Var, VarData) standardizer_input = [mdl.v[0], mdl.x] standardizer_output = standardizer_func(standardizer_input) @@ -154,7 +154,7 @@ def test_standardizer_invalid_duplicates(self): mdl.v = Var([0, 1]) mdl.x = Var(["a", "b"]) - standardizer_func = InputDataStandardizer(Var, _VarData, allow_repeats=False) + standardizer_func = InputDataStandardizer(Var, VarData, allow_repeats=False) exc_str = r"Standardized.*list.*contains duplicate entries\." with self.assertRaisesRegex(ValueError, exc_str): @@ -165,7 +165,7 @@ def test_standardizer_invalid_type(self): Test standardizer raises exception as expected when input is of invalid type. """ - standardizer_func = InputDataStandardizer(Var, _VarData) + standardizer_func = InputDataStandardizer(Var, VarData) exc_str = r"Input object .*is not of valid component type.*" with self.assertRaisesRegex(TypeError, exc_str): @@ -178,7 +178,7 @@ def test_standardizer_iterable_with_invalid_type(self): """ mdl = ConcreteModel() mdl.v = Var([0, 1]) - standardizer_func = InputDataStandardizer(Var, _VarData) + standardizer_func = InputDataStandardizer(Var, VarData) exc_str = r"Input object .*entry of iterable.*is not of valid component type.*" with self.assertRaisesRegex(TypeError, exc_str): @@ -189,7 +189,7 @@ def test_standardizer_invalid_str_passed(self): Test standardizer raises exception as expected when input is of invalid type str. """ - standardizer_func = InputDataStandardizer(Var, _VarData) + standardizer_func = InputDataStandardizer(Var, VarData) exc_str = r"Input object .*is not of valid component type.*" with self.assertRaisesRegex(TypeError, exc_str): @@ -201,7 +201,7 @@ def test_standardizer_invalid_uninitialized_params(self): uninitialized entries passed. """ standardizer_func = InputDataStandardizer( - ctype=Param, cdatatype=_ParamData, ctype_validator=mutable_param_validator + ctype=Param, cdatatype=ParamData, ctype_validator=mutable_param_validator ) mdl = ConcreteModel() @@ -217,7 +217,7 @@ def test_standardizer_invalid_immutable_params(self): Param object(s) passed. """ standardizer_func = InputDataStandardizer( - ctype=Param, cdatatype=_ParamData, ctype_validator=mutable_param_validator + ctype=Param, cdatatype=ParamData, ctype_validator=mutable_param_validator ) mdl = ConcreteModel() @@ -237,7 +237,7 @@ def test_standardizer_valid_mutable_params(self): mdl.p2 = Param(["a", "b"], initialize=1, mutable=True) standardizer_func = InputDataStandardizer( - ctype=Param, cdatatype=_ParamData, ctype_validator=mutable_param_validator + ctype=Param, cdatatype=ParamData, ctype_validator=mutable_param_validator ) standardizer_input = [mdl.p1[0], mdl.p2] diff --git a/pyomo/contrib/pyros/tests/test_grcs.py b/pyomo/contrib/pyros/tests/test_grcs.py index d49ed6b1002..f7efec4d6e7 100644 --- a/pyomo/contrib/pyros/tests/test_grcs.py +++ b/pyomo/contrib/pyros/tests/test_grcs.py @@ -19,7 +19,7 @@ from pyomo.common.collections import ComponentSet, ComponentMap from pyomo.common.config import ConfigBlock, ConfigValue from pyomo.core.base.set_types import NonNegativeIntegers -from pyomo.core.base.var import _VarData +from pyomo.core.base.var import VarData from pyomo.core.expr import ( identify_variables, identify_mutable_parameters, @@ -592,7 +592,7 @@ def test_dr_eqns_form_correct(self): param_product_multiplicand = term.args[0] dr_var_multiplicand = term.args[1] else: - self.assertIsInstance(term, _VarData) + self.assertIsInstance(term, VarData) param_product_multiplicand = 1 dr_var_multiplicand = term diff --git a/pyomo/contrib/pyros/util.py b/pyomo/contrib/pyros/util.py index 23cde45d0cf..3b0187af7dd 100644 --- a/pyomo/contrib/pyros/util.py +++ b/pyomo/contrib/pyros/util.py @@ -862,7 +862,7 @@ def get_state_vars(blk, first_stage_variables, second_stage_variables): Get state variables of a modeling block. The state variables with respect to `blk` are the unfixed - `_VarData` objects participating in the active objective + `VarData` objects participating in the active objective or constraints descended from `blk` which are not first-stage variables or second-stage variables. @@ -877,7 +877,7 @@ def get_state_vars(blk, first_stage_variables, second_stage_variables): Yields ------ - _VarData + VarData State variable. """ dof_var_set = ComponentSet(first_stage_variables) | ComponentSet( @@ -984,7 +984,7 @@ def validate_variable_partitioning(model, config): Returns ------- - list of _VarData + list of VarData State variables of the model. Raises diff --git a/pyomo/contrib/solver/base.py b/pyomo/contrib/solver/base.py index 736bf8b5a7c..98bf3836004 100644 --- a/pyomo/contrib/solver/base.py +++ b/pyomo/contrib/solver/base.py @@ -14,11 +14,11 @@ from typing import Sequence, Dict, Optional, Mapping, NoReturn, List, Tuple import os -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.param import _ParamData -from pyomo.core.base.block import _BlockData -from pyomo.core.base.objective import Objective, _GeneralObjectiveData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.var import VarData +from pyomo.core.base.param import ParamData +from pyomo.core.base.block import BlockData +from pyomo.core.base.objective import Objective, ObjectiveData from pyomo.common.config import document_kwargs_from_configdict, ConfigValue from pyomo.common.errors import ApplicationError from pyomo.common.deprecation import deprecation_warning @@ -110,13 +110,13 @@ def __str__(self): @document_kwargs_from_configdict(CONFIG) @abc.abstractmethod - def solve(self, model: _BlockData, **kwargs) -> Results: + def solve(self, model: BlockData, **kwargs) -> Results: """ Solve a Pyomo model. Parameters ---------- - model: _BlockData + model: BlockData The Pyomo model to be solved **kwargs Additional keyword arguments (including solver_options - passthrough @@ -184,7 +184,7 @@ class PersistentSolverBase(SolverBase): @document_kwargs_from_configdict(PersistentSolverConfig()) @abc.abstractmethod - def solve(self, model: _BlockData, **kwargs) -> Results: + def solve(self, model: BlockData, **kwargs) -> Results: super().solve(model, kwargs) def is_persistent(self): @@ -196,9 +196,7 @@ def is_persistent(self): """ return True - def _load_vars( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> NoReturn: + def _load_vars(self, vars_to_load: Optional[Sequence[VarData]] = None) -> NoReturn: """ Load the solution of the primal variables into the value attribute of the variables. @@ -214,19 +212,19 @@ def _load_vars( @abc.abstractmethod def _get_primals( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: """ Get mapping of variables to primals. Parameters ---------- - vars_to_load : Optional[Sequence[_GeneralVarData]], optional + vars_to_load : Optional[Sequence[VarData]], optional Which vars to be populated into the map. The default is None. Returns ------- - Mapping[_GeneralVarData, float] + Mapping[VarData, float] A map of variables to primals. """ raise NotImplementedError( @@ -234,8 +232,8 @@ def _get_primals( ) def _get_duals( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: """ Declare sign convention in docstring here. @@ -253,8 +251,8 @@ def _get_duals( raise NotImplementedError(f'{type(self)} does not support the get_duals method') def _get_reduced_costs( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: """ Parameters ---------- @@ -278,61 +276,61 @@ def set_instance(self, model): """ @abc.abstractmethod - def set_objective(self, obj: _GeneralObjectiveData): + def set_objective(self, obj: ObjectiveData): """ Set current objective for the model """ @abc.abstractmethod - def add_variables(self, variables: List[_GeneralVarData]): + def add_variables(self, variables: List[VarData]): """ Add variables to the model """ @abc.abstractmethod - def add_parameters(self, params: List[_ParamData]): + def add_parameters(self, params: List[ParamData]): """ Add parameters to the model """ @abc.abstractmethod - def add_constraints(self, cons: List[_GeneralConstraintData]): + def add_constraints(self, cons: List[ConstraintData]): """ Add constraints to the model """ @abc.abstractmethod - def add_block(self, block: _BlockData): + def add_block(self, block: BlockData): """ Add a block to the model """ @abc.abstractmethod - def remove_variables(self, variables: List[_GeneralVarData]): + def remove_variables(self, variables: List[VarData]): """ Remove variables from the model """ @abc.abstractmethod - def remove_parameters(self, params: List[_ParamData]): + def remove_parameters(self, params: List[ParamData]): """ Remove parameters from the model """ @abc.abstractmethod - def remove_constraints(self, cons: List[_GeneralConstraintData]): + def remove_constraints(self, cons: List[ConstraintData]): """ Remove constraints from the model """ @abc.abstractmethod - def remove_block(self, block: _BlockData): + def remove_block(self, block: BlockData): """ Remove a block from the model """ @abc.abstractmethod - def update_variables(self, variables: List[_GeneralVarData]): + def update_variables(self, variables: List[VarData]): """ Update variables on the model """ @@ -539,7 +537,7 @@ def _solution_handler( def solve( self, - model: _BlockData, + model: BlockData, tee: bool = False, load_solutions: bool = True, logfile: Optional[str] = None, diff --git a/pyomo/contrib/solver/gurobi.py b/pyomo/contrib/solver/gurobi.py index d0ac0d80f45..10d8120c8b3 100644 --- a/pyomo/contrib/solver/gurobi.py +++ b/pyomo/contrib/solver/gurobi.py @@ -22,10 +22,10 @@ from pyomo.common.config import ConfigValue from pyomo.core.kernel.objective import minimize, maximize from pyomo.core.base import SymbolMap, NumericLabeler, TextLabeler -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.sos import _SOSConstraintData -from pyomo.core.base.param import _ParamData +from pyomo.core.base.var import VarData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.sos import SOSConstraintData +from pyomo.core.base.param import ParamData from pyomo.core.expr.numvalue import value, is_constant, is_fixed, native_numeric_types from pyomo.repn import generate_standard_repn from pyomo.core.expr.numeric_expr import NPV_MaxExpression, NPV_MinExpression @@ -438,7 +438,7 @@ def _process_domain_and_bounds( return lb, ub, vtype - def _add_variables(self, variables: List[_GeneralVarData]): + def _add_variables(self, variables: List[VarData]): var_names = list() vtypes = list() lbs = list() @@ -469,7 +469,7 @@ def _add_variables(self, variables: List[_GeneralVarData]): self._vars_added_since_update.update(variables) self._needs_updated = True - def _add_parameters(self, params: List[_ParamData]): + def _add_parameters(self, params: List[ParamData]): pass def _reinit(self): @@ -555,7 +555,7 @@ def _get_expr_from_pyomo_expr(self, expr): mutable_quadratic_coefficients, ) - def _add_constraints(self, cons: List[_GeneralConstraintData]): + def _add_constraints(self, cons: List[ConstraintData]): for con in cons: conname = self._symbol_map.getSymbol(con, self._labeler) ( @@ -685,7 +685,7 @@ def _add_constraints(self, cons: List[_GeneralConstraintData]): self._constraints_added_since_update.update(cons) self._needs_updated = True - def _add_sos_constraints(self, cons: List[_SOSConstraintData]): + def _add_sos_constraints(self, cons: List[SOSConstraintData]): for con in cons: conname = self._symbol_map.getSymbol(con, self._labeler) level = con.level @@ -711,7 +711,7 @@ def _add_sos_constraints(self, cons: List[_SOSConstraintData]): self._constraints_added_since_update.update(cons) self._needs_updated = True - def _remove_constraints(self, cons: List[_GeneralConstraintData]): + def _remove_constraints(self, cons: List[ConstraintData]): for con in cons: if con in self._constraints_added_since_update: self._update_gurobi_model() @@ -725,7 +725,7 @@ def _remove_constraints(self, cons: List[_GeneralConstraintData]): self._mutable_quadratic_helpers.pop(con, None) self._needs_updated = True - def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): + def _remove_sos_constraints(self, cons: List[SOSConstraintData]): for con in cons: if con in self._constraints_added_since_update: self._update_gurobi_model() @@ -735,7 +735,7 @@ def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): del self._pyomo_sos_to_solver_sos_map[con] self._needs_updated = True - def _remove_variables(self, variables: List[_GeneralVarData]): + def _remove_variables(self, variables: List[VarData]): for var in variables: v_id = id(var) if var in self._vars_added_since_update: @@ -747,10 +747,10 @@ def _remove_variables(self, variables: List[_GeneralVarData]): self._mutable_bounds.pop(v_id, None) self._needs_updated = True - def _remove_parameters(self, params: List[_ParamData]): + def _remove_parameters(self, params: List[ParamData]): pass - def _update_variables(self, variables: List[_GeneralVarData]): + def _update_variables(self, variables: List[VarData]): for var in variables: var_id = id(var) if var_id not in self._pyomo_var_to_solver_var_map: @@ -1125,7 +1125,7 @@ def set_linear_constraint_attr(self, con, attr, val): Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The pyomo constraint for which the corresponding gurobi constraint attribute should be modified. attr: str @@ -1151,7 +1151,7 @@ def set_var_attr(self, var, attr, val): Parameters ---------- - var: pyomo.core.base.var._GeneralVarData + var: pyomo.core.base.var.VarData The pyomo var for which the corresponding gurobi var attribute should be modified. attr: str @@ -1186,7 +1186,7 @@ def get_var_attr(self, var, attr): Parameters ---------- - var: pyomo.core.base.var._GeneralVarData + var: pyomo.core.base.var.VarData The pyomo var for which the corresponding gurobi var attribute should be retrieved. attr: str @@ -1202,7 +1202,7 @@ def get_linear_constraint_attr(self, con, attr): Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The pyomo constraint for which the corresponding gurobi constraint attribute should be retrieved. attr: str @@ -1218,7 +1218,7 @@ def get_sos_attr(self, con, attr): Parameters ---------- - con: pyomo.core.base.sos._SOSConstraintData + con: pyomo.core.base.sos.SOSConstraintData The pyomo SOS constraint for which the corresponding gurobi SOS constraint attribute should be retrieved. attr: str @@ -1234,7 +1234,7 @@ def get_quadratic_constraint_attr(self, con, attr): Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The pyomo constraint for which the corresponding gurobi constraint attribute should be retrieved. attr: str @@ -1355,7 +1355,7 @@ def cbCut(self, con): Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The cut to add """ if not con.active: @@ -1440,7 +1440,7 @@ def cbLazy(self, con): """ Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The lazy constraint to add """ if not con.active: diff --git a/pyomo/contrib/solver/ipopt.py b/pyomo/contrib/solver/ipopt.py index 588e06ad74c..c88696f531b 100644 --- a/pyomo/contrib/solver/ipopt.py +++ b/pyomo/contrib/solver/ipopt.py @@ -25,7 +25,7 @@ ) from pyomo.common.tempfiles import TempfileManager from pyomo.common.timing import HierarchicalTimer -from pyomo.core.base.var import _GeneralVarData +from pyomo.core.base.var import VarData from pyomo.core.staleflag import StaleFlagManager from pyomo.repn.plugins.nl_writer import NLWriter, NLWriterInfo from pyomo.contrib.solver.base import SolverBase @@ -80,8 +80,8 @@ def __init__( class IpoptSolutionLoader(SolSolutionLoader): def get_reduced_costs( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: if self._nl_info is None: raise RuntimeError( 'Solution loader does not currently have a valid solution. Please ' diff --git a/pyomo/contrib/solver/persistent.py b/pyomo/contrib/solver/persistent.py index 4b1a7c58dcd..71322b7043e 100644 --- a/pyomo/contrib/solver/persistent.py +++ b/pyomo/contrib/solver/persistent.py @@ -12,11 +12,11 @@ import abc from typing import List -from pyomo.core.base.constraint import _GeneralConstraintData, Constraint -from pyomo.core.base.sos import _SOSConstraintData, SOSConstraint -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.param import _ParamData, Param -from pyomo.core.base.objective import _GeneralObjectiveData +from pyomo.core.base.constraint import ConstraintData, Constraint +from pyomo.core.base.sos import SOSConstraintData, SOSConstraint +from pyomo.core.base.var import VarData +from pyomo.core.base.param import ParamData, Param +from pyomo.core.base.objective import ObjectiveData from pyomo.common.collections import ComponentMap from pyomo.common.timing import HierarchicalTimer from pyomo.core.expr.numvalue import NumericConstant @@ -54,10 +54,10 @@ def set_instance(self, model): self.set_objective(None) @abc.abstractmethod - def _add_variables(self, variables: List[_GeneralVarData]): + def _add_variables(self, variables: List[VarData]): pass - def add_variables(self, variables: List[_GeneralVarData]): + def add_variables(self, variables: List[VarData]): for v in variables: if id(v) in self._referenced_variables: raise ValueError( @@ -75,19 +75,19 @@ def add_variables(self, variables: List[_GeneralVarData]): self._add_variables(variables) @abc.abstractmethod - def _add_parameters(self, params: List[_ParamData]): + def _add_parameters(self, params: List[ParamData]): pass - def add_parameters(self, params: List[_ParamData]): + def add_parameters(self, params: List[ParamData]): for p in params: self._params[id(p)] = p self._add_parameters(params) @abc.abstractmethod - def _add_constraints(self, cons: List[_GeneralConstraintData]): + def _add_constraints(self, cons: List[ConstraintData]): pass - def _check_for_new_vars(self, variables: List[_GeneralVarData]): + def _check_for_new_vars(self, variables: List[VarData]): new_vars = {} for v in variables: v_id = id(v) @@ -95,7 +95,7 @@ def _check_for_new_vars(self, variables: List[_GeneralVarData]): new_vars[v_id] = v self.add_variables(list(new_vars.values())) - def _check_to_remove_vars(self, variables: List[_GeneralVarData]): + def _check_to_remove_vars(self, variables: List[VarData]): vars_to_remove = {} for v in variables: v_id = id(v) @@ -104,7 +104,7 @@ def _check_to_remove_vars(self, variables: List[_GeneralVarData]): vars_to_remove[v_id] = v self.remove_variables(list(vars_to_remove.values())) - def add_constraints(self, cons: List[_GeneralConstraintData]): + def add_constraints(self, cons: List[ConstraintData]): all_fixed_vars = {} for con in cons: if con in self._named_expressions: @@ -130,10 +130,10 @@ def add_constraints(self, cons: List[_GeneralConstraintData]): v.fix() @abc.abstractmethod - def _add_sos_constraints(self, cons: List[_SOSConstraintData]): + def _add_sos_constraints(self, cons: List[SOSConstraintData]): pass - def add_sos_constraints(self, cons: List[_SOSConstraintData]): + def add_sos_constraints(self, cons: List[SOSConstraintData]): for con in cons: if con in self._vars_referenced_by_con: raise ValueError( @@ -149,10 +149,10 @@ def add_sos_constraints(self, cons: List[_SOSConstraintData]): self._add_sos_constraints(cons) @abc.abstractmethod - def _set_objective(self, obj: _GeneralObjectiveData): + def _set_objective(self, obj: ObjectiveData): pass - def set_objective(self, obj: _GeneralObjectiveData): + def set_objective(self, obj: ObjectiveData): if self._objective is not None: for v in self._vars_referenced_by_obj: self._referenced_variables[id(v)][2] = None @@ -209,10 +209,10 @@ def add_block(self, block): self.set_objective(obj) @abc.abstractmethod - def _remove_constraints(self, cons: List[_GeneralConstraintData]): + def _remove_constraints(self, cons: List[ConstraintData]): pass - def remove_constraints(self, cons: List[_GeneralConstraintData]): + def remove_constraints(self, cons: List[ConstraintData]): self._remove_constraints(cons) for con in cons: if con not in self._named_expressions: @@ -230,10 +230,10 @@ def remove_constraints(self, cons: List[_GeneralConstraintData]): del self._vars_referenced_by_con[con] @abc.abstractmethod - def _remove_sos_constraints(self, cons: List[_SOSConstraintData]): + def _remove_sos_constraints(self, cons: List[SOSConstraintData]): pass - def remove_sos_constraints(self, cons: List[_SOSConstraintData]): + def remove_sos_constraints(self, cons: List[SOSConstraintData]): self._remove_sos_constraints(cons) for con in cons: if con not in self._vars_referenced_by_con: @@ -250,10 +250,10 @@ def remove_sos_constraints(self, cons: List[_SOSConstraintData]): del self._vars_referenced_by_con[con] @abc.abstractmethod - def _remove_variables(self, variables: List[_GeneralVarData]): + def _remove_variables(self, variables: List[VarData]): pass - def remove_variables(self, variables: List[_GeneralVarData]): + def remove_variables(self, variables: List[VarData]): self._remove_variables(variables) for v in variables: v_id = id(v) @@ -274,10 +274,10 @@ def remove_variables(self, variables: List[_GeneralVarData]): del self._vars[v_id] @abc.abstractmethod - def _remove_parameters(self, params: List[_ParamData]): + def _remove_parameters(self, params: List[ParamData]): pass - def remove_parameters(self, params: List[_ParamData]): + def remove_parameters(self, params: List[ParamData]): self._remove_parameters(params) for p in params: del self._params[id(p)] @@ -309,10 +309,10 @@ def remove_block(self, block): ) @abc.abstractmethod - def _update_variables(self, variables: List[_GeneralVarData]): + def _update_variables(self, variables: List[VarData]): pass - def update_variables(self, variables: List[_GeneralVarData]): + def update_variables(self, variables: List[VarData]): for v in variables: self._vars[id(v)] = ( v, @@ -384,12 +384,12 @@ def update(self, timer: HierarchicalTimer = None): for c in self._vars_referenced_by_con.keys(): if c not in current_cons_dict and c not in current_sos_dict: if (c.ctype is Constraint) or ( - c.ctype is None and isinstance(c, _GeneralConstraintData) + c.ctype is None and isinstance(c, ConstraintData) ): old_cons.append(c) else: assert (c.ctype is SOSConstraint) or ( - c.ctype is None and isinstance(c, _SOSConstraintData) + c.ctype is None and isinstance(c, SOSConstraintData) ) old_sos.append(c) self.remove_constraints(old_cons) diff --git a/pyomo/contrib/solver/solution.py b/pyomo/contrib/solver/solution.py index 32e84d2abca..a3e66475982 100644 --- a/pyomo/contrib/solver/solution.py +++ b/pyomo/contrib/solver/solution.py @@ -12,8 +12,8 @@ import abc from typing import Sequence, Dict, Optional, Mapping, NoReturn -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.var import _GeneralVarData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.var import VarData from pyomo.core.expr import value from pyomo.common.collections import ComponentMap from pyomo.common.errors import DeveloperError @@ -30,9 +30,7 @@ class SolutionLoaderBase(abc.ABC): Intent of this class and its children is to load the solution back into the model. """ - def load_vars( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> NoReturn: + def load_vars(self, vars_to_load: Optional[Sequence[VarData]] = None) -> NoReturn: """ Load the solution of the primal variables into the value attribute of the variables. @@ -49,8 +47,8 @@ def load_vars( @abc.abstractmethod def get_primals( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: """ Returns a ComponentMap mapping variable to var value. @@ -67,8 +65,8 @@ def get_primals( """ def get_duals( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: """ Returns a dictionary mapping constraint to dual value. @@ -86,8 +84,8 @@ def get_duals( raise NotImplementedError(f'{type(self)} does not support the get_duals method') def get_reduced_costs( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: """ Returns a ComponentMap mapping variable to reduced cost. @@ -121,14 +119,14 @@ def get_primals(self, vars_to_load=None): return self._solver._get_primals(vars_to_load=vars_to_load) def get_duals( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: self._assert_solution_still_valid() return self._solver._get_duals(cons_to_load=cons_to_load) def get_reduced_costs( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: self._assert_solution_still_valid() return self._solver._get_reduced_costs(vars_to_load=vars_to_load) @@ -141,9 +139,7 @@ def __init__(self, sol_data: SolFileData, nl_info: NLWriterInfo) -> None: self._sol_data = sol_data self._nl_info = nl_info - def load_vars( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> NoReturn: + def load_vars(self, vars_to_load: Optional[Sequence[VarData]] = None) -> NoReturn: if self._nl_info is None: raise RuntimeError( 'Solution loader does not currently have a valid solution. Please ' @@ -169,8 +165,8 @@ def load_vars( StaleFlagManager.mark_all_as_stale(delayed=True) def get_primals( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: if self._nl_info is None: raise RuntimeError( 'Solution loader does not currently have a valid solution. Please ' @@ -205,8 +201,8 @@ def get_primals( return res def get_duals( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: if self._nl_info is None: raise RuntimeError( 'Solution loader does not currently have a valid solution. Please ' diff --git a/pyomo/contrib/solver/tests/unit/test_results.py b/pyomo/contrib/solver/tests/unit/test_results.py index 74404aaba4c..a15c9b87253 100644 --- a/pyomo/contrib/solver/tests/unit/test_results.py +++ b/pyomo/contrib/solver/tests/unit/test_results.py @@ -15,8 +15,8 @@ from pyomo.common import unittest from pyomo.common.config import ConfigDict -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.var import _GeneralVarData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.var import VarData from pyomo.common.collections import ComponentMap from pyomo.contrib.solver import results from pyomo.contrib.solver import solution @@ -51,8 +51,8 @@ def __init__( self._reduced_costs = reduced_costs def get_primals( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: if self._primals is None: raise RuntimeError( 'Solution loader does not currently have a valid solution. Please ' @@ -67,8 +67,8 @@ def get_primals( return primals def get_duals( - self, cons_to_load: Optional[Sequence[_GeneralConstraintData]] = None - ) -> Dict[_GeneralConstraintData, float]: + self, cons_to_load: Optional[Sequence[ConstraintData]] = None + ) -> Dict[ConstraintData, float]: if self._duals is None: raise RuntimeError( 'Solution loader does not currently have valid duals. Please ' @@ -84,8 +84,8 @@ def get_duals( return duals def get_reduced_costs( - self, vars_to_load: Optional[Sequence[_GeneralVarData]] = None - ) -> Mapping[_GeneralVarData, float]: + self, vars_to_load: Optional[Sequence[VarData]] = None + ) -> Mapping[VarData, float]: if self._reduced_costs is None: raise RuntimeError( 'Solution loader does not currently have valid reduced costs. Please ' diff --git a/pyomo/contrib/trustregion/tests/test_interface.py b/pyomo/contrib/trustregion/tests/test_interface.py index 148caceddd1..0922ccf950b 100644 --- a/pyomo/contrib/trustregion/tests/test_interface.py +++ b/pyomo/contrib/trustregion/tests/test_interface.py @@ -33,7 +33,7 @@ cos, SolverFactory, ) -from pyomo.core.base.var import _GeneralVarData +from pyomo.core.base.var import VarData from pyomo.core.expr.numeric_expr import ExternalFunctionExpression from pyomo.core.expr.visitor import identify_variables from pyomo.contrib.trustregion.interface import TRFInterface @@ -158,7 +158,7 @@ def test_replaceExternalFunctionsWithVariables(self): self.assertIsInstance(k, ExternalFunctionExpression) self.assertIn(str(self.interface.model.x[0]), str(k)) self.assertIn(str(self.interface.model.x[1]), str(k)) - self.assertIsInstance(i, _GeneralVarData) + self.assertIsInstance(i, VarData) self.assertEqual(i, self.interface.data.ef_outputs[1]) for i, k in self.interface.data.basis_expressions.items(): self.assertEqual(k, 0) diff --git a/pyomo/contrib/viewer/model_browser.py b/pyomo/contrib/viewer/model_browser.py index 5887a577ba0..91dc946c55d 100644 --- a/pyomo/contrib/viewer/model_browser.py +++ b/pyomo/contrib/viewer/model_browser.py @@ -33,7 +33,7 @@ import pyomo.contrib.viewer.qt as myqt from pyomo.contrib.viewer.report import value_no_exception, get_residual -from pyomo.core.base.param import _ParamData +from pyomo.core.base.param import ParamData from pyomo.environ import ( Block, BooleanVar, @@ -243,7 +243,7 @@ def _get_expr_callback(self): return None def _get_value_callback(self): - if isinstance(self.data, _ParamData): + if isinstance(self.data, ParamData): v = value_no_exception(self.data, div0="divide_by_0") # Check the param value for numpy float and int, sometimes numpy # values can sneak in especially if you set parameters from data @@ -295,7 +295,7 @@ def _get_residual_callback(self): def _get_units_callback(self): if isinstance(self.data, (Var, Var._ComponentDataClass)): return str(units.get_units(self.data)) - if isinstance(self.data, (Param, _ParamData)): + if isinstance(self.data, (Param, ParamData)): return str(units.get_units(self.data)) return self._cache_units @@ -320,7 +320,7 @@ def _set_value_callback(self, val): o.value = val except: return - elif isinstance(self.data, _ParamData): + elif isinstance(self.data, ParamData): if not self.data.parent_component().mutable: return try: diff --git a/pyomo/contrib/viewer/report.py b/pyomo/contrib/viewer/report.py index f83a53c608d..a28e0082212 100644 --- a/pyomo/contrib/viewer/report.py +++ b/pyomo/contrib/viewer/report.py @@ -50,7 +50,7 @@ def get_residual(ui_data, c): values of the constraint body. This function uses the cached values and will not trigger recalculation. If variable values have changed, this may not yield accurate results. - c(_ConstraintData): a constraint or constraint data + c(ConstraintData): a constraint or constraint data Returns: (float) residual """ @@ -149,7 +149,7 @@ def degrees_of_freedom(blk): Return the degrees of freedom. Args: - blk (Block or _BlockData): Block to count degrees of freedom in + blk (Block or BlockData): Block to count degrees of freedom in Returns: (int): Number of degrees of freedom """ diff --git a/pyomo/core/base/__init__.py b/pyomo/core/base/__init__.py index df5ce743888..2b21725d82f 100644 --- a/pyomo/core/base/__init__.py +++ b/pyomo/core/base/__init__.py @@ -34,9 +34,11 @@ BooleanValue, native_logical_values, ) -from pyomo.core.base.config import PyomoOptions -from pyomo.core.base.expression import Expression, _ExpressionData +from pyomo.core.base.component import name, Component, ModelComponentFactory +from pyomo.core.base.componentuid import ComponentUID +from pyomo.core.base.config import PyomoOptions +from pyomo.core.base.enums import SortComponents, TraversalStrategy from pyomo.core.base.label import ( CuidLabeler, CounterLabeler, @@ -47,56 +49,73 @@ NameLabeler, ShortNameLabeler, ) +from pyomo.core.base.misc import display +from pyomo.core.base.reference import Reference +from pyomo.core.base.symbol_map import symbol_map_from_instance +from pyomo.core.base.transformation import ( + Transformation, + TransformationFactory, + ReverseTransformationToken, +) + +from pyomo.core.base.PyomoModel import ( + global_option, + ModelSolution, + ModelSolutions, + Model, + ConcreteModel, + AbstractModel, +) # # Components # -from pyomo.core.base.component import name, Component, ModelComponentFactory -from pyomo.core.base.componentuid import ComponentUID from pyomo.core.base.action import BuildAction -from pyomo.core.base.check import BuildCheck -from pyomo.core.base.set import Set, SetOf, simple_set_rule, RangeSet -from pyomo.core.base.param import Param -from pyomo.core.base.var import Var, _VarData, _GeneralVarData, ScalarVar, VarList +from pyomo.core.base.block import ( + Block, + BlockData, + ScalarBlock, + active_components, + components, + active_components_data, + components_data, +) from pyomo.core.base.boolean_var import ( BooleanVar, - _BooleanVarData, - _GeneralBooleanVarData, + BooleanVarData, BooleanVarList, ScalarBooleanVar, ) +from pyomo.core.base.check import BuildCheck +from pyomo.core.base.connector import Connector, ConnectorData from pyomo.core.base.constraint import ( simple_constraint_rule, simple_constraintlist_rule, ConstraintList, Constraint, - _ConstraintData, + ConstraintData, ) +from pyomo.core.base.expression import Expression, NamedExpressionData, ExpressionData +from pyomo.core.base.external import ExternalFunction from pyomo.core.base.logical_constraint import ( LogicalConstraint, LogicalConstraintList, - _LogicalConstraintData, + LogicalConstraintData, ) from pyomo.core.base.objective import ( simple_objective_rule, simple_objectivelist_rule, Objective, ObjectiveList, - _ObjectiveData, -) -from pyomo.core.base.connector import Connector -from pyomo.core.base.sos import SOSConstraint -from pyomo.core.base.piecewise import Piecewise -from pyomo.core.base.suffix import ( - active_export_suffix_generator, - active_import_suffix_generator, - Suffix, + ObjectiveData, ) -from pyomo.core.base.external import ExternalFunction -from pyomo.core.base.symbol_map import symbol_map_from_instance -from pyomo.core.base.reference import Reference - +from pyomo.core.base.param import Param, ParamData +from pyomo.core.base.piecewise import Piecewise, PiecewiseData from pyomo.core.base.set import ( + Set, + SetData, + SetOf, + RangeSet, Reals, PositiveReals, NonPositiveReals, @@ -116,34 +135,21 @@ PercentFraction, RealInterval, IntegerInterval, + simple_set_rule, ) -from pyomo.core.base.misc import display -from pyomo.core.base.block import ( - Block, - ScalarBlock, - active_components, - components, - active_components_data, - components_data, -) -from pyomo.core.base.enums import SortComponents, TraversalStrategy -from pyomo.core.base.PyomoModel import ( - global_option, - ModelSolution, - ModelSolutions, - Model, - ConcreteModel, - AbstractModel, -) -from pyomo.core.base.transformation import ( - Transformation, - TransformationFactory, - ReverseTransformationToken, +from pyomo.core.base.sos import SOSConstraint, SOSConstraintData +from pyomo.core.base.suffix import ( + active_export_suffix_generator, + active_import_suffix_generator, + Suffix, ) +from pyomo.core.base.var import Var, VarData, ScalarVar, VarList from pyomo.core.base.instance2dat import instance2dat +# # These APIs are deprecated and should be removed in the near future +# from pyomo.core.base.set import set_options, RealSet, IntegerSet, BooleanSet from pyomo.common.deprecation import relocated_module_attribute @@ -155,4 +161,25 @@ relocated_module_attribute( 'SimpleBooleanVar', 'pyomo.core.base.boolean_var.SimpleBooleanVar', version='6.0' ) +# Historically, only a subset of "private" component data classes were imported here +relocated_module_attribute( + f'_GeneralVarData', f'pyomo.core.base.VarData', version='6.7.2.dev0' +) +relocated_module_attribute( + f'_GeneralBooleanVarData', f'pyomo.core.base.BooleanVarData', version='6.7.2.dev0' +) +relocated_module_attribute( + f'_ExpressionData', f'pyomo.core.base.NamedExpressionData', version='6.7.2.dev0' +) +for _cdata in ( + 'ConstraintData', + 'LogicalConstraintData', + 'VarData', + 'BooleanVarData', + 'ObjectiveData', +): + relocated_module_attribute( + f'_{_cdata}', f'pyomo.core.base.{_cdata}', version='6.7.2.dev0' + ) +del _cdata del relocated_module_attribute diff --git a/pyomo/core/base/block.py b/pyomo/core/base/block.py index 2918ef78b00..3eb18dde7a9 100644 --- a/pyomo/core/base/block.py +++ b/pyomo/core/base/block.py @@ -160,13 +160,13 @@ def __init__(self): self.seen_data = set() def unique(self, comp, items, are_values): - """Returns generator that filters duplicate _ComponentData objects from items + """Returns generator that filters duplicate ComponentData objects from items Parameters ---------- comp: ComponentBase The Component (indexed or scalar) that contains all - _ComponentData returned by the `items` generator. `comp` may + ComponentData returned by the `items` generator. `comp` may be an IndexedComponent generated by :py:func:`Reference` (and hence may not own the component datas in `items`) @@ -175,8 +175,8 @@ def unique(self, comp, items, are_values): `comp` Component. are_values: bool - If `True`, `items` yields _ComponentData objects, otherwise, - `items` yields `(index, _ComponentData)` tuples. + If `True`, `items` yields ComponentData objects, otherwise, + `items` yields `(index, ComponentData)` tuples. """ if comp.is_reference(): @@ -254,7 +254,7 @@ class _BlockConstruction(object): class PseudoMap(AutoSlots.Mixin): """ This class presents a "mock" dict interface to the internal - _BlockData data structures. We return this object to the + BlockData data structures. We return this object to the user to preserve the historical "{ctype : {name : obj}}" interface without actually regenerating that dict-of-dicts data structure. @@ -487,7 +487,7 @@ def iteritems(self): return self.items() -class _BlockData(ActiveComponentData): +class BlockData(ActiveComponentData): """ This class holds the fundamental block data. """ @@ -537,9 +537,9 @@ def __init__(self, component): # _ctypes: { ctype -> [1st idx, last idx, count] } # _decl: { name -> idx } # _decl_order: list( tuples( obj, next_type_idx ) ) - super(_BlockData, self).__setattr__('_ctypes', {}) - super(_BlockData, self).__setattr__('_decl', {}) - super(_BlockData, self).__setattr__('_decl_order', []) + super(BlockData, self).__setattr__('_ctypes', {}) + super(BlockData, self).__setattr__('_decl', {}) + super(BlockData, self).__setattr__('_decl_order', []) self._private_data = None def __getattr__(self, val) -> Union[Component, IndexedComponent, Any]: @@ -574,7 +574,7 @@ def __setattr__(self, name: str, val: Union[Component, IndexedComponent, Any]): # Other Python objects are added with the standard __setattr__ # method. # - super(_BlockData, self).__setattr__(name, val) + super(BlockData, self).__setattr__(name, val) # # Case 2. The attribute exists and it is a component in the # list of declarations in this block. We will use the @@ -628,11 +628,11 @@ def __setattr__(self, name: str, val: Union[Component, IndexedComponent, Any]): # else: # - # NB: This is important: the _BlockData is either a scalar + # NB: This is important: the BlockData is either a scalar # Block (where _parent and _component are defined) or a # single block within an Indexed Block (where only # _component is defined). Regardless, the - # _BlockData.__init__() method declares these methods and + # BlockData.__init__() method declares these methods and # sets them either to None or a weakref. Thus, we will # never have a problem converting these objects from # weakrefs into Blocks and back (when pickling); the @@ -647,23 +647,23 @@ def __setattr__(self, name: str, val: Union[Component, IndexedComponent, Any]): # return True, this shouldn't be too inefficient. # if name == '_parent': - if val is not None and not isinstance(val(), _BlockData): + if val is not None and not isinstance(val(), BlockData): raise ValueError( "Cannot set the '_parent' attribute of Block '%s' " "to a non-Block object (with type=%s); Did you " "try to create a model component named '_parent'?" % (self.name, type(val)) ) - super(_BlockData, self).__setattr__(name, val) + super(BlockData, self).__setattr__(name, val) elif name == '_component': - if val is not None and not isinstance(val(), _BlockData): + if val is not None and not isinstance(val(), BlockData): raise ValueError( "Cannot set the '_component' attribute of Block '%s' " "to a non-Block object (with type=%s); Did you " "try to create a model component named '_component'?" % (self.name, type(val)) ) - super(_BlockData, self).__setattr__(name, val) + super(BlockData, self).__setattr__(name, val) # # At this point, we should only be seeing non-component data # the user is hanging on the blocks (uncommon) or the @@ -680,7 +680,7 @@ def __setattr__(self, name: str, val: Union[Component, IndexedComponent, Any]): delattr(self, name) self.add_component(name, val) else: - super(_BlockData, self).__setattr__(name, val) + super(BlockData, self).__setattr__(name, val) def __delattr__(self, name): """ @@ -703,7 +703,7 @@ def __delattr__(self, name): # Other Python objects are removed with the standard __detattr__ # method. # - super(_BlockData, self).__delattr__(name) + super(BlockData, self).__delattr__(name) def _compact_decl_storage(self): idxMap = {} @@ -775,11 +775,11 @@ def transfer_attributes_from(self, src): Parameters ---------- - src: _BlockData or dict + src: BlockData or dict The Block or mapping that contains the new attributes to assign to this block. """ - if isinstance(src, _BlockData): + if isinstance(src, BlockData): # There is a special case where assigning a parent block to # this block creates a circular hierarchy if src is self: @@ -788,7 +788,7 @@ def transfer_attributes_from(self, src): while p_block is not None: if p_block is src: raise ValueError( - "_BlockData.transfer_attributes_from(): Cannot set a " + "BlockData.transfer_attributes_from(): Cannot set a " "sub-block (%s) to a parent block (%s): creates a " "circular hierarchy" % (self, src) ) @@ -804,7 +804,7 @@ def transfer_attributes_from(self, src): del_src_comp = lambda x: None else: raise ValueError( - "_BlockData.transfer_attributes_from(): expected a " + "BlockData.transfer_attributes_from(): expected a " "Block or dict; received %s" % (type(src).__name__,) ) @@ -878,7 +878,7 @@ def collect_ctypes(self, active=None, descend_into=True): def model(self): # - # Special case: the "Model" is always the top-level _BlockData, + # Special case: the "Model" is always the top-level BlockData, # so if this is the top-level block, it must be the model # # Also note the interesting and intentional characteristic for @@ -1035,7 +1035,7 @@ def add_component(self, name, val): # is inappropriate here. The correct way to add the attribute # is to delegate the work to the next class up the MRO. # - super(_BlockData, self).__setattr__(name, val) + super(BlockData, self).__setattr__(name, val) # # Update the ctype linked lists # @@ -1106,7 +1106,7 @@ def add_component(self, name, val): # This is tricky: If we are in the middle of # constructing an indexed block, the block component # already has _constructed=True. Now, if the - # _BlockData.__init__() defines any local variables + # BlockData.__init__() defines any local variables # (like pyomo.gdp.Disjunct's indicator_var), name(True) # will fail: this block data exists and has a parent(), # but it has not yet been added to the parent's _data @@ -1194,7 +1194,7 @@ def del_component(self, name_or_object): # Note: 'del self.__dict__[name]' is inappropriate here. The # correct way to add the attribute is to delegate the work to # the next class up the MRO. - super(_BlockData, self).__delattr__(name) + super(BlockData, self).__delattr__(name) def reclassify_component_type( self, name_or_object, new_ctype, preserve_declaration_order=True @@ -1399,7 +1399,7 @@ def _component_data_iteritems(self, ctype, active, sort, dedup): Generator that returns a nested 2-tuple of - ((component name, index value), _ComponentData) + ((component name, index value), ComponentData) for every component data in the block matching the specified ctype(s). @@ -1416,7 +1416,7 @@ def _component_data_iteritems(self, ctype, active, sort, dedup): Iterate over the components in a specified sorted order dedup: _DeduplicateInfo - Deduplicator to prevent returning the same _ComponentData twice + Deduplicator to prevent returning the same ComponentData twice """ for name, comp in PseudoMap(self, ctype, active, sort).items(): # NOTE: Suffix has a dict interface (something other derived @@ -1452,7 +1452,7 @@ def _component_data_iteritems(self, ctype, active, sort, dedup): yield from dedup.unique(comp, _items, False) def _component_data_itervalues(self, ctype, active, sort, dedup): - """Generator that returns the _ComponentData for every component data + """Generator that returns the ComponentData for every component data in the block. Parameters @@ -1467,7 +1467,7 @@ def _component_data_itervalues(self, ctype, active, sort, dedup): Iterate over the components in a specified sorted order dedup: _DeduplicateInfo - Deduplicator to prevent returning the same _ComponentData twice + Deduplicator to prevent returning the same ComponentData twice """ for comp in PseudoMap(self, ctype, active, sort).values(): # NOTE: Suffix has a dict interface (something other derived @@ -1573,7 +1573,7 @@ def component_data_iterindex( generator recursively descends into sub-blocks. The tuple is - ((component name, index value), _ComponentData) + ((component name, index value), ComponentData) """ dedup = _DeduplicateInfo() @@ -1994,6 +1994,11 @@ def private_data(self, scope=None): return self._private_data[scope] +class _BlockData(metaclass=RenamedClass): + __renamed__new_class__ = BlockData + __renamed__version__ = '6.7.2.dev0' + + @ModelComponentFactory.register( "A component that contains one or more model components." ) @@ -2007,7 +2012,7 @@ class Block(ActiveIndexedComponent): is deferred. """ - _ComponentDataClass = _BlockData + _ComponentDataClass = BlockData _private_data_initializers = defaultdict(lambda: dict) @overload @@ -2100,7 +2105,7 @@ def _getitem_when_not_present(self, idx): # components declared by the rule have the opportunity # to be initialized with data from # _BlockConstruction.data as they are transferred over. - if obj is not _block and isinstance(obj, _BlockData): + if obj is not _block and isinstance(obj, BlockData): _block.transfer_attributes_from(obj) finally: if data is not None and _block is not self: @@ -2221,7 +2226,7 @@ def display(self, filename=None, ostream=None, prefix=""): ostream = sys.stdout for key in sorted(self): - _BlockData.display(self[key], filename, ostream, prefix) + BlockData.display(self[key], filename, ostream, prefix) @staticmethod def register_private_data_initializer(initializer, scope=None): @@ -2241,9 +2246,9 @@ def register_private_data_initializer(initializer, scope=None): Block._private_data_initializers[scope] = initializer -class ScalarBlock(_BlockData, Block): +class ScalarBlock(BlockData, Block): def __init__(self, *args, **kwds): - _BlockData.__init__(self, component=self) + BlockData.__init__(self, component=self) Block.__init__(self, *args, **kwds) # Initialize the data dict so that (abstract) attribute # assignment will work. Note that we do not trigger @@ -2266,7 +2271,7 @@ def __init__(self, *args, **kwds): Block.__init__(self, *args, **kwds) @overload - def __getitem__(self, index) -> _BlockData: ... + def __getitem__(self, index) -> BlockData: ... __getitem__ = IndexedComponent.__getitem__ # type: ignore @@ -2325,7 +2330,7 @@ def components_data(block, ctype, sort=None, sort_by_keys=False, sort_by_names=F # Create a Block and record all the default attributes, methods, etc. # These will be assumed to be the set of illegal component names. # -_BlockData._Block_reserved_words = set(dir(Block())) +BlockData._Block_reserved_words = set(dir(Block())) class _IndexedCustomBlockMeta(type): @@ -2376,7 +2381,7 @@ def declare_custom_block(name, new_ctype=None): """Decorator to declare components for a custom block data class >>> @declare_custom_block(name=FooBlock) - ... class FooBlockData(_BlockData): + ... class FooBlockData(BlockData): ... # custom block data class ... pass """ diff --git a/pyomo/core/base/boolean_var.py b/pyomo/core/base/boolean_var.py index 246dcea6214..67c06bdacce 100644 --- a/pyomo/core/base/boolean_var.py +++ b/pyomo/core/base/boolean_var.py @@ -68,27 +68,65 @@ def __setstate__(self, state): self._boolvar = weakref_ref(state) -class _BooleanVarData(ComponentData, BooleanValue): - """ - This class defines the data for a single variable. - - Constructor Arguments: - component The BooleanVar object that owns this data. - Public Class Attributes: - fixed If True, then this variable is treated as a - fixed constant in the model. - stale A Boolean indicating whether the value of this variable is - legitimate. This value is true if the value should - be considered legitimate for purposes of reporting or - other interrogation. - value The numeric value of this variable. +def _associated_binary_mapper(encode, val): + if val is None: + return None + if encode: + if val.__class__ is not _DeprecatedImplicitAssociatedBinaryVariable: + return val() + else: + if val.__class__ is not _DeprecatedImplicitAssociatedBinaryVariable: + return weakref_ref(val) + return val + + +class BooleanVarData(ComponentData, BooleanValue): + """This class defines the data for a single Boolean variable. + + Parameters + ---------- + component: Component + The BooleanVar object that owns this data. + + Attributes + ---------- + domain: SetData + The domain of this variable. + + fixed: bool + If True, then this variable is treated as a fixed constant in + the model. + + stale: bool + A Boolean indicating whether the value of this variable is + Consistent with the most recent solve. `True` indicates that + this variable's value was set prior to the most recent solve and + was not updated by the results returned by the solve. + + value: bool + The value of this variable. """ - __slots__ = () + __slots__ = ('_value', 'fixed', '_stale', '_associated_binary') + __autoslot_mappers__ = { + '_associated_binary': _associated_binary_mapper, + '_stale': StaleFlagManager.stale_mapper, + } def __init__(self, component=None): + # + # These lines represent in-lining of the + # following constructors: + # - BooleanVarData + # - ComponentData + # - BooleanValue self._component = weakref_ref(component) if (component is not None) else None self._index = NOTSET + self._value = None + self.fixed = False + self._stale = 0 # True + + self._associated_binary = None def is_fixed(self): """Returns True if this variable is fixed, otherwise returns False.""" @@ -132,113 +170,6 @@ def __call__(self, exception=True): """Compute the value of this variable.""" return self.value - @property - def value(self): - """Return the value for this variable.""" - raise NotImplementedError - - @property - def domain(self): - """Return the domain for this variable.""" - raise NotImplementedError - - @property - def fixed(self): - """Return the fixed indicator for this variable.""" - raise NotImplementedError - - @property - def stale(self): - """Return the stale indicator for this variable.""" - raise NotImplementedError - - def fix(self, value=NOTSET, skip_validation=False): - """Fix the value of this variable (treat as nonvariable) - - This sets the `fixed` indicator to True. If ``value`` is - provided, the value (and the ``skip_validation`` flag) are first - passed to :py:meth:`set_value()`. - - """ - self.fixed = True - if value is not NOTSET: - self.set_value(value, skip_validation) - - def unfix(self): - """Unfix this variable (treat as variable) - - This sets the `fixed` indicator to False. - - """ - self.fixed = False - - def free(self): - """Alias for :py:meth:`unfix`""" - return self.unfix() - - -def _associated_binary_mapper(encode, val): - if val is None: - return None - if encode: - if val.__class__ is not _DeprecatedImplicitAssociatedBinaryVariable: - return val() - else: - if val.__class__ is not _DeprecatedImplicitAssociatedBinaryVariable: - return weakref_ref(val) - return val - - -class _GeneralBooleanVarData(_BooleanVarData): - """ - This class defines the data for a single Boolean variable. - - Constructor Arguments: - component The BooleanVar object that owns this data. - - Public Class Attributes: - domain The domain of this variable. - fixed If True, then this variable is treated as a - fixed constant in the model. - stale A Boolean indicating whether the value of this variable is - legitimiate. This value is true if the value should - be considered legitimate for purposes of reporting or - other interrogation. - value The numeric value of this variable. - - The domain attribute is a property because it is - too widely accessed directly to enforce explicit getter/setter - methods and we need to deter directly modifying or accessing - these attributes in certain cases. - """ - - __slots__ = ('_value', 'fixed', '_stale', '_associated_binary') - __autoslot_mappers__ = { - '_associated_binary': _associated_binary_mapper, - '_stale': StaleFlagManager.stale_mapper, - } - - def __init__(self, component=None): - # - # These lines represent in-lining of the - # following constructors: - # - _BooleanVarData - # - ComponentData - # - BooleanValue - self._component = weakref_ref(component) if (component is not None) else None - self._index = NOTSET - self._value = None - self.fixed = False - self._stale = 0 # True - - self._associated_binary = None - - # - # Abstract Interface - # - - # value is an attribute - @property def value(self): """Return (or set) the value for this variable.""" @@ -265,14 +196,14 @@ def stale(self, val): self._stale = StaleFlagManager.get_flag(0) def get_associated_binary(self): - """Get the binary _VarData associated with this - _GeneralBooleanVarData""" + """Get the binary VarData associated with this + BooleanVarData""" return ( self._associated_binary() if self._associated_binary is not None else None ) def associate_binary_var(self, binary_var): - """Associate a binary _VarData to this _GeneralBooleanVarData""" + """Associate a binary VarData to this BooleanVarData""" if ( self._associated_binary is not None and type(self._associated_binary) @@ -294,6 +225,40 @@ def associate_binary_var(self, binary_var): if binary_var is not None: self._associated_binary = weakref_ref(binary_var) + def fix(self, value=NOTSET, skip_validation=False): + """Fix the value of this variable (treat as nonvariable) + + This sets the `fixed` indicator to True. If ``value`` is + provided, the value (and the ``skip_validation`` flag) are first + passed to :py:meth:`set_value()`. + + """ + self.fixed = True + if value is not NOTSET: + self.set_value(value, skip_validation) + + def unfix(self): + """Unfix this variable (treat as variable) + + This sets the `fixed` indicator to False. + + """ + self.fixed = False + + def free(self): + """Alias for :py:meth:`unfix`""" + return self.unfix() + + +class _BooleanVarData(metaclass=RenamedClass): + __renamed__new_class__ = BooleanVarData + __renamed__version__ = '6.7.2.dev0' + + +class _GeneralBooleanVarData(metaclass=RenamedClass): + __renamed__new_class__ = BooleanVarData + __renamed__version__ = '6.7.2.dev0' + @ModelComponentFactory.register("Logical decision variables.") class BooleanVar(IndexedComponent): @@ -309,7 +274,7 @@ class BooleanVar(IndexedComponent): to True. """ - _ComponentDataClass = _GeneralBooleanVarData + _ComponentDataClass = BooleanVarData def __new__(cls, *args, **kwds): if cls != BooleanVar: @@ -390,7 +355,7 @@ def construct(self, data=None): _set.construct() # - # Construct _BooleanVarData objects for all index values + # Construct BooleanVarData objects for all index values # if not self.is_indexed(): self._data[None] = self @@ -501,11 +466,11 @@ def _pprint(self): ) -class ScalarBooleanVar(_GeneralBooleanVarData, BooleanVar): +class ScalarBooleanVar(BooleanVarData, BooleanVar): """A single variable.""" def __init__(self, *args, **kwd): - _GeneralBooleanVarData.__init__(self, component=self) + BooleanVarData.__init__(self, component=self) BooleanVar.__init__(self, *args, **kwd) self._index = UnindexedComponent_index @@ -521,7 +486,7 @@ def __init__(self, *args, **kwd): def value(self): """Return the value for this variable.""" if self._constructed: - return _GeneralBooleanVarData.value.fget(self) + return BooleanVarData.value.fget(self) raise ValueError( "Accessing the value of variable '%s' " "before the Var has been constructed (there " @@ -532,7 +497,7 @@ def value(self): def value(self, val): """Set the value for this variable.""" if self._constructed: - return _GeneralBooleanVarData.value.fset(self, val) + return BooleanVarData.value.fset(self, val) raise ValueError( "Setting the value of variable '%s' " "before the Var has been constructed (there " @@ -541,7 +506,7 @@ def value(self, val): @property def domain(self): - return _GeneralBooleanVarData.domain.fget(self) + return BooleanVarData.domain.fget(self) def fix(self, value=NOTSET, skip_validation=False): """ @@ -549,7 +514,7 @@ def fix(self, value=NOTSET, skip_validation=False): indicating the variable should be fixed at its current value. """ if self._constructed: - return _GeneralBooleanVarData.fix(self, value, skip_validation) + return BooleanVarData.fix(self, value, skip_validation) raise ValueError( "Fixing variable '%s' " "before the Var has been constructed (there " @@ -559,7 +524,7 @@ def fix(self, value=NOTSET, skip_validation=False): def unfix(self): """Sets the fixed indicator to False.""" if self._constructed: - return _GeneralBooleanVarData.unfix(self) + return BooleanVarData.unfix(self) raise ValueError( "Freeing variable '%s' " "before the Var has been constructed (there " diff --git a/pyomo/core/base/component.py b/pyomo/core/base/component.py index 9b1929daa06..d06b85dcdd4 100644 --- a/pyomo/core/base/component.py +++ b/pyomo/core/base/component.py @@ -20,6 +20,7 @@ from pyomo.common.autoslots import AutoSlots, fast_deepcopy from pyomo.common.collections import OrderedDict from pyomo.common.deprecation import ( + RenamedClass, deprecated, deprecation_warning, relocated_module_attribute, @@ -79,7 +80,7 @@ class CloneError(pyomo.common.errors.PyomoException): pass -class _ComponentBase(PyomoObject): +class ComponentBase(PyomoObject): """A base class for Component and ComponentData This class defines some fundamental methods and properties that are @@ -474,7 +475,12 @@ def _pprint_base_impl( ostream.write(_data) -class Component(_ComponentBase): +class _ComponentBase(metaclass=RenamedClass): + __renamed__new_class__ = ComponentBase + __renamed__version__ = '6.7.2.dev0' + + +class Component(ComponentBase): """ This is the base class for all Pyomo modeling components. @@ -779,7 +785,7 @@ def deactivate(self): self._active = False -class ComponentData(_ComponentBase): +class ComponentData(ComponentBase): """ This is the base class for the component data used in Pyomo modeling components. Subclasses of ComponentData are @@ -802,11 +808,11 @@ class ComponentData(_ComponentBase): __autoslot_mappers__ = {'_component': AutoSlots.weakref_mapper} # NOTE: This constructor is in-lined in the constructors for the following - # classes: _BooleanVarData, _ConnectorData, _ConstraintData, - # _GeneralExpressionData, _LogicalConstraintData, - # _GeneralLogicalConstraintData, _GeneralObjectiveData, - # _ParamData,_GeneralVarData, _GeneralBooleanVarData, _DisjunctionData, - # _ArcData, _PortData, _LinearConstraintData, and + # classes: BooleanVarData, ConnectorData, ConstraintData, + # ExpressionData, LogicalConstraintData, + # LogicalConstraintData, ObjectiveData, + # ParamData,VarData, BooleanVarData, DisjunctionData, + # ArcData, PortData, _LinearConstraintData, and # _LinearMatrixConstraintData. Changes made here need to be made in those # constructors as well! def __init__(self, component): diff --git a/pyomo/core/base/connector.py b/pyomo/core/base/connector.py index 435a2c2fccb..e383b52fc11 100644 --- a/pyomo/core/base/connector.py +++ b/pyomo/core/base/connector.py @@ -28,7 +28,7 @@ logger = logging.getLogger('pyomo.core') -class _ConnectorData(ComponentData, NumericValue): +class ConnectorData(ComponentData, NumericValue): """Holds the actual connector information""" __slots__ = ('vars', 'aggregators') @@ -105,6 +105,11 @@ def _iter_vars(self): yield v +class _ConnectorData(metaclass=RenamedClass): + __renamed__new_class__ = ConnectorData + __renamed__version__ = '6.7.2.dev0' + + @ModelComponentFactory.register( "A bundle of variables that can be manipulated together." ) @@ -157,7 +162,7 @@ def __init__(self, *args, **kwd): # IndexedComponent # def _getitem_when_not_present(self, idx): - _conval = self._data[idx] = _ConnectorData(component=self) + _conval = self._data[idx] = ConnectorData(component=self) return _conval def construct(self, data=None): @@ -170,7 +175,7 @@ def construct(self, data=None): timer = ConstructionTimer(self) self._constructed = True # - # Construct _ConnectorData objects for all index values + # Construct ConnectorData objects for all index values # if self.is_indexed(): self._initialize_members(self._index_set) @@ -258,9 +263,9 @@ def _line_generator(k, v): ) -class ScalarConnector(Connector, _ConnectorData): +class ScalarConnector(Connector, ConnectorData): def __init__(self, *args, **kwd): - _ConnectorData.__init__(self, component=self) + ConnectorData.__init__(self, component=self) Connector.__init__(self, *args, **kwd) self._index = UnindexedComponent_index diff --git a/pyomo/core/base/constraint.py b/pyomo/core/base/constraint.py index fde1160e563..eb4af76fdc1 100644 --- a/pyomo/core/base/constraint.py +++ b/pyomo/core/base/constraint.py @@ -125,17 +125,13 @@ def C_rule(model, i, j): return rule_wrapper(rule, result_map, map_types=map_types) -# -# This class is a pure interface -# - - -class _ConstraintData(ActiveComponentData): +class ConstraintData(ActiveComponentData): """ - This class defines the data for a single constraint. + This class defines the data for a single algebraic constraint. Constructor arguments: component The Constraint object that owns this data. + expr The Pyomo expression stored in this constraint. Public class attributes: active A boolean that is true if this constraint is @@ -155,164 +151,17 @@ class _ConstraintData(ActiveComponentData): _active A boolean that indicates whether this data is active """ - __slots__ = () + __slots__ = ('_body', '_lower', '_upper', '_expr') # Set to true when a constraint class stores its expression # in linear canonical form _linear_canonical_form = False - def __init__(self, component=None): - # - # These lines represent in-lining of the - # following constructors: - # - _ConstraintData, - # - ActiveComponentData - # - ComponentData - self._component = weakref_ref(component) if (component is not None) else None - self._index = NOTSET - self._active = True - - # - # Interface - # - - def __call__(self, exception=True): - """Compute the value of the body of this constraint.""" - return value(self.body, exception=exception) - - def has_lb(self): - """Returns :const:`False` when the lower bound is - :const:`None` or negative infinity""" - return self.lb is not None - - def has_ub(self): - """Returns :const:`False` when the upper bound is - :const:`None` or positive infinity""" - return self.ub is not None - - def lslack(self): - """ - Returns the value of f(x)-L for constraints of the form: - L <= f(x) (<= U) - (U >=) f(x) >= L - """ - lb = self.lb - if lb is None: - return _inf - else: - return value(self.body) - lb - - def uslack(self): - """ - Returns the value of U-f(x) for constraints of the form: - (L <=) f(x) <= U - U >= f(x) (>= L) - """ - ub = self.ub - if ub is None: - return _inf - else: - return ub - value(self.body) - - def slack(self): - """ - Returns the smaller of lslack and uslack values - """ - lb = self.lb - ub = self.ub - body = value(self.body) - if lb is None: - return ub - body - elif ub is None: - return body - lb - return min(ub - body, body - lb) - - # - # Abstract Interface - # - - @property - def body(self): - """Access the body of a constraint expression.""" - raise NotImplementedError - - @property - def lower(self): - """Access the lower bound of a constraint expression.""" - raise NotImplementedError - - @property - def upper(self): - """Access the upper bound of a constraint expression.""" - raise NotImplementedError - - @property - def lb(self): - """Access the value of the lower bound of a constraint expression.""" - raise NotImplementedError - - @property - def ub(self): - """Access the value of the upper bound of a constraint expression.""" - raise NotImplementedError - - @property - def equality(self): - """A boolean indicating whether this is an equality constraint.""" - raise NotImplementedError - - @property - def strict_lower(self): - """True if this constraint has a strict lower bound.""" - raise NotImplementedError - - @property - def strict_upper(self): - """True if this constraint has a strict upper bound.""" - raise NotImplementedError - - def set_value(self, expr): - """Set the expression on this constraint.""" - raise NotImplementedError - - def get_value(self): - """Get the expression on this constraint.""" - raise NotImplementedError - - -class _GeneralConstraintData(_ConstraintData): - """ - This class defines the data for a single general constraint. - - Constructor arguments: - component The Constraint object that owns this data. - expr The Pyomo expression stored in this constraint. - - Public class attributes: - active A boolean that is true if this constraint is - active in the model. - body The Pyomo expression for this constraint - lower The Pyomo expression for the lower bound - upper The Pyomo expression for the upper bound - equality A boolean that indicates whether this is an - equality constraint - strict_lower A boolean that indicates whether this - constraint uses a strict lower bound - strict_upper A boolean that indicates whether this - constraint uses a strict upper bound - - Private class attributes: - _component The objective component. - _active A boolean that indicates whether this data is active - """ - - __slots__ = ('_body', '_lower', '_upper', '_expr') - def __init__(self, expr=None, component=None): # # These lines represent in-lining of the # following constructors: - # - _ConstraintData, + # - ConstraintData, # - ActiveComponentData # - ComponentData self._component = weakref_ref(component) if (component is not None) else None @@ -325,9 +174,9 @@ def __init__(self, expr=None, component=None): if expr is not None: self.set_value(expr) - # - # Abstract Interface - # + def __call__(self, exception=True): + """Compute the value of the body of this constraint.""" + return value(self.body, exception=exception) @property def body(self): @@ -451,6 +300,16 @@ def strict_upper(self): """True if this constraint has a strict upper bound.""" return False + def has_lb(self): + """Returns :const:`False` when the lower bound is + :const:`None` or negative infinity""" + return self.lb is not None + + def has_ub(self): + """Returns :const:`False` when the upper bound is + :const:`None` or positive infinity""" + return self.ub is not None + @property def expr(self): """Return the expression associated with this constraint.""" @@ -678,6 +537,53 @@ def set_value(self, expr): "upper bound (%s)." % (self.name, self._upper) ) + def lslack(self): + """ + Returns the value of f(x)-L for constraints of the form: + L <= f(x) (<= U) + (U >=) f(x) >= L + """ + lb = self.lb + if lb is None: + return _inf + else: + return value(self.body) - lb + + def uslack(self): + """ + Returns the value of U-f(x) for constraints of the form: + (L <=) f(x) <= U + U >= f(x) (>= L) + """ + ub = self.ub + if ub is None: + return _inf + else: + return ub - value(self.body) + + def slack(self): + """ + Returns the smaller of lslack and uslack values + """ + lb = self.lb + ub = self.ub + body = value(self.body) + if lb is None: + return ub - body + elif ub is None: + return body - lb + return min(ub - body, body - lb) + + +class _ConstraintData(metaclass=RenamedClass): + __renamed__new_class__ = ConstraintData + __renamed__version__ = '6.7.2.dev0' + + +class _GeneralConstraintData(metaclass=RenamedClass): + __renamed__new_class__ = ConstraintData + __renamed__version__ = '6.7.2.dev0' + @ModelComponentFactory.register("General constraint expressions.") class Constraint(ActiveIndexedComponent): @@ -721,7 +627,7 @@ class Constraint(ActiveIndexedComponent): The class type for the derived subclass """ - _ComponentDataClass = _GeneralConstraintData + _ComponentDataClass = ConstraintData class Infeasible(object): pass @@ -879,14 +785,14 @@ def display(self, prefix="", ostream=None): ) -class ScalarConstraint(_GeneralConstraintData, Constraint): +class ScalarConstraint(ConstraintData, Constraint): """ ScalarConstraint is the implementation representing a single, non-indexed constraint. """ def __init__(self, *args, **kwds): - _GeneralConstraintData.__init__(self, component=self, expr=None) + ConstraintData.__init__(self, component=self, expr=None) Constraint.__init__(self, *args, **kwds) self._index = UnindexedComponent_index @@ -897,7 +803,7 @@ def __init__(self, *args, **kwds): # currently in place). So during initialization only, we will # treat them as "indexed" objects where things like # Constraint.Skip are managed. But after that they will behave - # like _ConstraintData objects where set_value does not handle + # like ConstraintData objects where set_value does not handle # Constraint.Skip but expects a valid expression or None. # @property @@ -910,7 +816,7 @@ def body(self): "an expression. There is currently " "nothing to access." % (self.name) ) - return _GeneralConstraintData.body.fget(self) + return ConstraintData.body.fget(self) @property def lower(self): @@ -922,7 +828,7 @@ def lower(self): "an expression. There is currently " "nothing to access." % (self.name) ) - return _GeneralConstraintData.lower.fget(self) + return ConstraintData.lower.fget(self) @property def upper(self): @@ -934,7 +840,7 @@ def upper(self): "an expression. There is currently " "nothing to access." % (self.name) ) - return _GeneralConstraintData.upper.fget(self) + return ConstraintData.upper.fget(self) @property def equality(self): @@ -946,7 +852,7 @@ def equality(self): "an expression. There is currently " "nothing to access." % (self.name) ) - return _GeneralConstraintData.equality.fget(self) + return ConstraintData.equality.fget(self) @property def strict_lower(self): @@ -958,7 +864,7 @@ def strict_lower(self): "an expression. There is currently " "nothing to access." % (self.name) ) - return _GeneralConstraintData.strict_lower.fget(self) + return ConstraintData.strict_lower.fget(self) @property def strict_upper(self): @@ -970,7 +876,7 @@ def strict_upper(self): "an expression. There is currently " "nothing to access." % (self.name) ) - return _GeneralConstraintData.strict_upper.fget(self) + return ConstraintData.strict_upper.fget(self) def clear(self): self._data = {} @@ -1035,7 +941,7 @@ def add(self, index, expr): return self.__setitem__(index, expr) @overload - def __getitem__(self, index) -> _GeneralConstraintData: ... + def __getitem__(self, index) -> ConstraintData: ... __getitem__ = IndexedComponent.__getitem__ # type: ignore diff --git a/pyomo/core/base/expression.py b/pyomo/core/base/expression.py index 3ce998b62a4..013c388e6e5 100644 --- a/pyomo/core/base/expression.py +++ b/pyomo/core/base/expression.py @@ -36,24 +36,24 @@ logger = logging.getLogger('pyomo.core') -class _ExpressionData(numeric_expr.NumericValue): - """ - An object that defines a named expression. +class NamedExpressionData(numeric_expr.NumericValue): + """An object that defines a generic "named expression". + + This is the base class for both :py:class:`ExpressionData` and + :py:class:`ObjectiveData`. Public Class Attributes expr The expression owned by this data. + """ + # Note: derived classes are expected to declare the _args_ slot __slots__ = () EXPRESSION_SYSTEM = EXPR.ExpressionType.NUMERIC PRECEDENCE = 0 ASSOCIATIVITY = EXPR.OperatorAssociativity.NON_ASSOCIATIVE - # - # Interface - # - def __call__(self, exception=True): """Compute the value of this expression.""" (arg,) = self._args_ @@ -62,6 +62,18 @@ def __call__(self, exception=True): return arg return arg(exception=exception) + def create_node_with_local_data(self, values): + """ + Construct a simple expression after constructing the + contained expression. + + This class provides a consistent interface for constructing a + node, which is used in tree visitor scripts. + """ + obj = self.__class__() + obj._args_ = values + return obj + def is_named_expression_type(self): """A boolean indicating whether this in a named expression.""" return True @@ -110,9 +122,10 @@ def _compute_polynomial_degree(self, result): def _is_fixed(self, values): return values[0] - # - # Abstract Interface - # + # NamedExpressionData should never return False because + # they can store subexpressions that contain variables + def is_potentially_variable(self): + return True @property def expr(self): @@ -125,58 +138,6 @@ def expr(self): def expr(self, value): self.set_value(value) - def set_value(self, expr): - """Set the expression on this expression.""" - raise NotImplementedError - - def is_constant(self): - """A boolean indicating whether this expression is constant.""" - raise NotImplementedError - - def is_fixed(self): - """A boolean indicating whether this expression is fixed.""" - raise NotImplementedError - - # _ExpressionData should never return False because - # they can store subexpressions that contain variables - def is_potentially_variable(self): - return True - - -class _GeneralExpressionDataImpl(_ExpressionData): - """ - An object that defines an expression that is never cloned - - Constructor Arguments - expr The Pyomo expression stored in this expression. - component The Expression object that owns this data. - - Public Class Attributes - expr The expression owned by this data. - """ - - __slots__ = () - - def __init__(self, expr=None): - self._args_ = (expr,) - - def create_node_with_local_data(self, values): - """ - Construct a simple expression after constructing the - contained expression. - - This class provides a consistent interface for constructing a - node, which is used in tree visitor scripts. - """ - obj = ScalarExpression() - obj.construct() - obj._args_ = values - return obj - - # - # Abstract Interface - # - def set_value(self, expr): """Set the expression on this expression.""" if expr is None or expr.__class__ in native_numeric_types: @@ -235,7 +196,17 @@ def __ipow__(self, other): return numeric_expr._pow_dispatcher[e.__class__, other.__class__](e, other) -class _GeneralExpressionData(_GeneralExpressionDataImpl, ComponentData): +class _ExpressionData(metaclass=RenamedClass): + __renamed__new_class__ = NamedExpressionData + __renamed__version__ = '6.7.2.dev0' + + +class _GeneralExpressionDataImpl(metaclass=RenamedClass): + __renamed__new_class__ = NamedExpressionData + __renamed__version__ = '6.7.2.dev0' + + +class ExpressionData(NamedExpressionData, ComponentData): """ An object that defines an expression that is never cloned @@ -253,12 +224,16 @@ class _GeneralExpressionData(_GeneralExpressionDataImpl, ComponentData): __slots__ = ('_args_',) def __init__(self, expr=None, component=None): - _GeneralExpressionDataImpl.__init__(self, expr) - # Inlining ComponentData.__init__ + self._args_ = (expr,) self._component = weakref_ref(component) if (component is not None) else None self._index = NOTSET +class _GeneralExpressionData(metaclass=RenamedClass): + __renamed__new_class__ = ExpressionData + __renamed__version__ = '6.7.2.dev0' + + @ModelComponentFactory.register( "Named expressions that can be used in other expressions." ) @@ -275,7 +250,7 @@ class Expression(IndexedComponent): doc Text describing this component. """ - _ComponentDataClass = _GeneralExpressionData + _ComponentDataClass = ExpressionData # This seems like a copy-paste error, and should be renamed/removed NoConstraint = IndexedComponent.Skip @@ -402,9 +377,9 @@ def construct(self, data=None): timer.report() -class ScalarExpression(_GeneralExpressionData, Expression): +class ScalarExpression(ExpressionData, Expression): def __init__(self, *args, **kwds): - _GeneralExpressionData.__init__(self, expr=None, component=self) + ExpressionData.__init__(self, expr=None, component=self) Expression.__init__(self, *args, **kwds) self._index = UnindexedComponent_index @@ -427,7 +402,7 @@ def __call__(self, exception=True): def expr(self): """Return expression on this expression.""" if self._constructed: - return _GeneralExpressionData.expr.fget(self) + return ExpressionData.expr.fget(self) raise ValueError( "Accessing the expression of Expression '%s' " "before the Expression has been constructed (there " @@ -445,7 +420,7 @@ def clear(self): def set_value(self, expr): """Set the expression on this expression.""" if self._constructed: - return _GeneralExpressionData.set_value(self, expr) + return ExpressionData.set_value(self, expr) raise ValueError( "Setting the expression of Expression '%s' " "before the Expression has been constructed (there " @@ -455,7 +430,7 @@ def set_value(self, expr): def is_constant(self): """A boolean indicating whether this expression is constant.""" if self._constructed: - return _GeneralExpressionData.is_constant(self) + return ExpressionData.is_constant(self) raise ValueError( "Accessing the is_constant flag of Expression '%s' " "before the Expression has been constructed (there " @@ -465,7 +440,7 @@ def is_constant(self): def is_fixed(self): """A boolean indicating whether this expression is fixed.""" if self._constructed: - return _GeneralExpressionData.is_fixed(self) + return ExpressionData.is_fixed(self) raise ValueError( "Accessing the is_fixed flag of Expression '%s' " "before the Expression has been constructed (there " @@ -509,6 +484,6 @@ def add(self, index, expr): """Add an expression with a given index.""" if (type(expr) is tuple) and (expr == Expression.Skip): return None - cdata = _GeneralExpressionData(expr, component=self) + cdata = ExpressionData(expr, component=self) self._data[index] = cdata return cdata diff --git a/pyomo/core/base/logical_constraint.py b/pyomo/core/base/logical_constraint.py index f32d727931a..9584078307d 100644 --- a/pyomo/core/base/logical_constraint.py +++ b/pyomo/core/base/logical_constraint.py @@ -42,64 +42,7 @@ """ -class _LogicalConstraintData(ActiveComponentData): - """ - This class defines the data for a single logical constraint. - - It functions as a pure interface. - - Constructor arguments: - component The LogicalConstraint object that owns this data. - - Public class attributes: - active A boolean that is true if this statement is - active in the model. - body The Pyomo logical expression for this statement - - Private class attributes: - _component The statement component. - _active A boolean that indicates whether this data is active - """ - - __slots__ = () - - def __init__(self, component=None): - # - # These lines represent in-lining of the - # following constructors: - # - ActiveComponentData - # - ComponentData - self._component = weakref_ref(component) if (component is not None) else None - self._index = NOTSET - self._active = True - - # - # Interface - # - def __call__(self, exception=True): - """Compute the value of the body of this logical constraint.""" - if self.body is None: - return None - return self.body(exception=exception) - - # - # Abstract Interface - # - @property - def expr(self): - """Get the expression on this logical constraint.""" - raise NotImplementedError - - def set_value(self, expr): - """Set the expression on this logical constraint.""" - raise NotImplementedError - - def get_value(self): - """Get the expression on this logical constraint.""" - raise NotImplementedError - - -class _GeneralLogicalConstraintData(_LogicalConstraintData): +class LogicalConstraintData(ActiveComponentData): """ This class defines the data for a single general logical constraint. @@ -123,7 +66,7 @@ def __init__(self, expr=None, component=None): # # These lines represent in-lining of the # following constructors: - # - _LogicalConstraintData, + # - LogicalConstraintData, # - ActiveComponentData # - ComponentData self._component = weakref_ref(component) if (component is not None) else None @@ -134,6 +77,12 @@ def __init__(self, expr=None, component=None): if expr is not None: self.set_value(expr) + def __call__(self, exception=True): + """Compute the value of the body of this logical constraint.""" + if self.body is None: + return None + return self.body(exception=exception) + # # Abstract Interface # @@ -173,6 +122,16 @@ def get_value(self): return self._expr +class _LogicalConstraintData(metaclass=RenamedClass): + __renamed__new_class__ = LogicalConstraintData + __renamed__version__ = '6.7.2.dev0' + + +class _GeneralLogicalConstraintData(metaclass=RenamedClass): + __renamed__new_class__ = LogicalConstraintData + __renamed__version__ = '6.7.2.dev0' + + @ModelComponentFactory.register("General logical constraints.") class LogicalConstraint(ActiveIndexedComponent): """ @@ -215,7 +174,7 @@ class LogicalConstraint(ActiveIndexedComponent): The class type for the derived subclass """ - _ComponentDataClass = _GeneralLogicalConstraintData + _ComponentDataClass = LogicalConstraintData class Infeasible(object): pass @@ -373,7 +332,7 @@ def display(self, prefix="", ostream=None): # # Checks flags like Constraint.Skip, etc. before actually creating a - # constraint object. Returns the _ConstraintData object when it should be + # constraint object. Returns the ConstraintData object when it should be # added to the _data dict; otherwise, None is returned or an exception # is raised. # @@ -409,14 +368,14 @@ def _check_skip_add(self, index, expr): return expr -class ScalarLogicalConstraint(_GeneralLogicalConstraintData, LogicalConstraint): +class ScalarLogicalConstraint(LogicalConstraintData, LogicalConstraint): """ ScalarLogicalConstraint is the implementation representing a single, non-indexed logical constraint. """ def __init__(self, *args, **kwds): - _GeneralLogicalConstraintData.__init__(self, component=self, expr=None) + LogicalConstraintData.__init__(self, component=self, expr=None) LogicalConstraint.__init__(self, *args, **kwds) self._index = UnindexedComponent_index @@ -436,7 +395,7 @@ def body(self): "an expression. There is currently " "nothing to access." % self.name ) - return _GeneralLogicalConstraintData.body.fget(self) + return LogicalConstraintData.body.fget(self) raise ValueError( "Accessing the body of logical constraint '%s' " "before the LogicalConstraint has been constructed (there " @@ -450,7 +409,7 @@ def body(self): # currently in place). So during initialization only, we will # treat them as "indexed" objects where things like # True are managed. But after that they will behave - # like _LogicalConstraintData objects where set_value expects + # like LogicalConstraintData objects where set_value expects # a valid expression or None. # diff --git a/pyomo/core/base/matrix_constraint.py b/pyomo/core/base/matrix_constraint.py index adc9742302e..8dac7c3d24b 100644 --- a/pyomo/core/base/matrix_constraint.py +++ b/pyomo/core/base/matrix_constraint.py @@ -19,7 +19,7 @@ from pyomo.core.expr.numvalue import value from pyomo.core.expr.numeric_expr import LinearExpression from pyomo.core.base.component import ModelComponentFactory -from pyomo.core.base.constraint import IndexedConstraint, _ConstraintData +from pyomo.core.base.constraint import IndexedConstraint, ConstraintData from pyomo.repn.standard_repn import StandardRepn from collections.abc import Mapping @@ -28,7 +28,7 @@ logger = logging.getLogger('pyomo.core') -class _MatrixConstraintData(_ConstraintData): +class _MatrixConstraintData(ConstraintData): """ This class defines the data for a single linear constraint derived from a canonical form Ax=b constraint. @@ -104,7 +104,7 @@ def __init__(self, index, component_ref): # # These lines represent in-lining of the # following constructors: - # - _ConstraintData, + # - ConstraintData, # - ActiveComponentData # - ComponentData self._component = component_ref @@ -209,7 +209,7 @@ def index(self): return self._index # - # Abstract Interface (_ConstraintData) + # Abstract Interface (ConstraintData) # @property diff --git a/pyomo/core/base/objective.py b/pyomo/core/base/objective.py index 10cc853dafb..e388d25aab4 100644 --- a/pyomo/core/base/objective.py +++ b/pyomo/core/base/objective.py @@ -29,7 +29,7 @@ UnindexedComponent_set, rule_wrapper, ) -from pyomo.core.base.expression import _ExpressionData, _GeneralExpressionDataImpl +from pyomo.core.base.expression import NamedExpressionData from pyomo.core.base.set import Set from pyomo.core.base.initializer import ( Initializer, @@ -81,47 +81,7 @@ def O_rule(model, i, j): return rule_wrapper(rule, {None: ObjectiveList.End}) -# -# This class is a pure interface -# - - -class _ObjectiveData(_ExpressionData): - """ - This class defines the data for a single objective. - - Public class attributes: - expr The Pyomo expression for this objective - sense The direction for this objective. - """ - - __slots__ = () - - # - # Interface - # - - def is_minimizing(self): - """Return True if this is a minimization objective.""" - return self.sense == minimize - - # - # Abstract Interface - # - - @property - def sense(self): - """Access sense (direction) of this objective.""" - raise NotImplementedError - - def set_sense(self, sense): - """Set the sense (direction) of this objective.""" - raise NotImplementedError - - -class _GeneralObjectiveData( - _GeneralExpressionDataImpl, _ObjectiveData, ActiveComponentData -): +class ObjectiveData(NamedExpressionData, ActiveComponentData): """ This class defines the data for a single objective. @@ -144,16 +104,21 @@ class _GeneralObjectiveData( _active A boolean that indicates whether this data is active """ - __slots__ = ("_sense", "_args_") + __slots__ = ("_args_", "_sense") def __init__(self, expr=None, sense=minimize, component=None): - _GeneralExpressionDataImpl.__init__(self, expr) + # Inlining NamedExpressionData.__init__ + self._args_ = (expr,) # Inlining ActiveComponentData.__init__ self._component = weakref_ref(component) if (component is not None) else None self._index = NOTSET self._active = True self._sense = ObjectiveSense(sense) + def is_minimizing(self): + """Return True if this is a minimization objective.""" + return self.sense == minimize + def set_value(self, expr): if expr is None: raise ValueError(_rule_returned_none_error % (self.name,)) @@ -178,6 +143,16 @@ def set_sense(self, sense): self._sense = ObjectiveSense(sense) +class _ObjectiveData(metaclass=RenamedClass): + __renamed__new_class__ = ObjectiveData + __renamed__version__ = '6.7.2.dev0' + + +class _GeneralObjectiveData(metaclass=RenamedClass): + __renamed__new_class__ = ObjectiveData + __renamed__version__ = '6.7.2.dev0' + + @ModelComponentFactory.register("Expressions that are minimized or maximized.") class Objective(ActiveIndexedComponent): """ @@ -226,7 +201,7 @@ class Objective(ActiveIndexedComponent): The class type for the derived subclass """ - _ComponentDataClass = _GeneralObjectiveData + _ComponentDataClass = ObjectiveData NoObjective = ActiveIndexedComponent.Skip def __new__(cls, *args, **kwds): @@ -371,14 +346,14 @@ def display(self, prefix="", ostream=None): ) -class ScalarObjective(_GeneralObjectiveData, Objective): +class ScalarObjective(ObjectiveData, Objective): """ ScalarObjective is the implementation representing a single, non-indexed objective. """ def __init__(self, *args, **kwd): - _GeneralObjectiveData.__init__(self, expr=None, component=self) + ObjectiveData.__init__(self, expr=None, component=self) Objective.__init__(self, *args, **kwd) self._index = UnindexedComponent_index @@ -414,7 +389,7 @@ def expr(self): "a sense or expression (there is currently " "no value to return)." % (self.name) ) - return _GeneralObjectiveData.expr.fget(self) + return ObjectiveData.expr.fget(self) raise ValueError( "Accessing the expression of objective '%s' " "before the Objective has been constructed (there " @@ -437,7 +412,7 @@ def sense(self): "a sense or expression (there is currently " "no value to return)." % (self.name) ) - return _GeneralObjectiveData.sense.fget(self) + return ObjectiveData.sense.fget(self) raise ValueError( "Accessing the sense of objective '%s' " "before the Objective has been constructed (there " @@ -456,7 +431,7 @@ def sense(self, sense): # currently in place). So during initialization only, we will # treat them as "indexed" objects where things like # Objective.Skip are managed. But after that they will behave - # like _ObjectiveData objects where set_value does not handle + # like ObjectiveData objects where set_value does not handle # Objective.Skip but expects a valid expression or None # @@ -480,7 +455,7 @@ def set_sense(self, sense): if self._constructed: if len(self._data) == 0: self._data[None] = self - return _GeneralObjectiveData.set_sense(self, sense) + return ObjectiveData.set_sense(self, sense) raise ValueError( "Setting the sense of objective '%s' " "before the Objective has been constructed (there " diff --git a/pyomo/core/base/param.py b/pyomo/core/base/param.py index 5fcaf92b25a..9af6a37de45 100644 --- a/pyomo/core/base/param.py +++ b/pyomo/core/base/param.py @@ -118,7 +118,7 @@ def _parent(self, val): pass -class _ParamData(ComponentData, NumericValue): +class ParamData(ComponentData, NumericValue): """ This class defines the data for a mutable parameter. @@ -252,6 +252,11 @@ def _compute_polynomial_degree(self, result): return 0 +class _ParamData(metaclass=RenamedClass): + __renamed__new_class__ = ParamData + __renamed__version__ = '6.7.2.dev0' + + @ModelComponentFactory.register( "Parameter data that is used to define a model instance." ) @@ -285,7 +290,7 @@ class Param(IndexedComponent, IndexedComponent_NDArrayMixin): """ DefaultMutable = False - _ComponentDataClass = _ParamData + _ComponentDataClass = ParamData class NoValue(object): """A dummy type that is pickle-safe that we can use as the default @@ -523,14 +528,14 @@ def store_values(self, new_values, check=True): # instead of incurring the penalty of checking. for index, new_value in new_values.items(): if index not in self._data: - self._data[index] = _ParamData(self) + self._data[index] = ParamData(self) self._data[index]._value = new_value else: # For scalars, we will choose an approach based on # how "dense" the Param is if not self._data: # empty for index in self._index_set: - p = self._data[index] = _ParamData(self) + p = self._data[index] = ParamData(self) p._value = new_values elif len(self._data) == len(self._index_set): for index in self._index_set: @@ -538,7 +543,7 @@ def store_values(self, new_values, check=True): else: for index in self._index_set: if index not in self._data: - self._data[index] = _ParamData(self) + self._data[index] = ParamData(self) self._data[index]._value = new_values else: # @@ -601,9 +606,9 @@ def _getitem_when_not_present(self, index): # a default value, as long as *solving* a model without # reasonable values produces an informative error. if self._mutable: - # Note: _ParamData defaults to Param.NoValue + # Note: ParamData defaults to Param.NoValue if self.is_indexed(): - ans = self._data[index] = _ParamData(self) + ans = self._data[index] = ParamData(self) else: ans = self._data[index] = self ans._index = index @@ -698,8 +703,8 @@ def _setitem_impl(self, index, obj, value): return obj else: old_value, self._data[index] = self._data[index], value - # Because we do not have a _ParamData, we cannot rely on the - # validation that occurs in _ParamData.set_value() + # Because we do not have a ParamData, we cannot rely on the + # validation that occurs in ParamData.set_value() try: self._validate_value(index, value) return value @@ -736,14 +741,14 @@ def _setitem_when_not_present(self, index, value, _check_domain=True): self._index = UnindexedComponent_index return self elif self._mutable: - obj = self._data[index] = _ParamData(self) + obj = self._data[index] = ParamData(self) obj.set_value(value, index) obj._index = index return obj else: self._data[index] = value - # Because we do not have a _ParamData, we cannot rely on the - # validation that occurs in _ParamData.set_value() + # Because we do not have a ParamData, we cannot rely on the + # validation that occurs in ParamData.set_value() self._validate_value(index, value, _check_domain) return value except: @@ -901,9 +906,9 @@ def _pprint(self): return (headers, self.sparse_iteritems(), ("Value",), dataGen) -class ScalarParam(_ParamData, Param): +class ScalarParam(ParamData, Param): def __init__(self, *args, **kwds): - _ParamData.__init__(self, component=self) + ParamData.__init__(self, component=self) Param.__init__(self, *args, **kwds) self._index = UnindexedComponent_index @@ -996,7 +1001,7 @@ def _create_objects_for_deepcopy(self, memo, component_list): # between potentially variable GetItemExpression objects and # "constant" GetItemExpression objects. That will need to wait for # the expression rework [JDS; Nov 22]. - def __getitem__(self, args) -> _ParamData: + def __getitem__(self, args) -> ParamData: try: return super().__getitem__(args) except: diff --git a/pyomo/core/base/piecewise.py b/pyomo/core/base/piecewise.py index 7817a61b2f2..efe500dbfb1 100644 --- a/pyomo/core/base/piecewise.py +++ b/pyomo/core/base/piecewise.py @@ -40,14 +40,14 @@ import enum from pyomo.common.log import is_debug_set -from pyomo.common.deprecation import deprecation_warning +from pyomo.common.deprecation import RenamedClass, deprecation_warning from pyomo.common.numeric_types import value from pyomo.common.timing import ConstructionTimer -from pyomo.core.base.block import Block, _BlockData +from pyomo.core.base.block import Block, BlockData from pyomo.core.base.component import ModelComponentFactory from pyomo.core.base.constraint import Constraint, ConstraintList from pyomo.core.base.sos import SOSConstraint -from pyomo.core.base.var import Var, _VarData, IndexedVar +from pyomo.core.base.var import Var, VarData, IndexedVar from pyomo.core.base.set_types import PositiveReals, NonNegativeReals, Binary from pyomo.core.base.util import flatten_tuple @@ -214,14 +214,14 @@ def _characterize_function(name, tol, f_rule, model, points, *index): return 0, values, False -class _PiecewiseData(_BlockData): +class PiecewiseData(BlockData): """ This class defines the base class for all linearization and piecewise constraint generators.. """ def __init__(self, parent): - _BlockData.__init__(self, parent) + BlockData.__init__(self, parent) self._constructed = True self._bound_type = None self._domain_pts = None @@ -272,6 +272,11 @@ def __call__(self, x): ) +class _PiecewiseData(metaclass=RenamedClass): + __renamed__new_class__ = PiecewiseData + __renamed__version__ = '6.7.2.dev0' + + class _SimpleSinglePiecewise(object): """ Called when the piecewise points list has only two points @@ -1125,7 +1130,7 @@ def f(model,j,x): not be modified. """ - _ComponentDataClass = _PiecewiseData + _ComponentDataClass = PiecewiseData def __new__(cls, *args, **kwds): if cls != Piecewise: @@ -1235,7 +1240,7 @@ def __init__(self, *args, **kwds): # Check that the variables args are actually Pyomo Vars if not ( - isinstance(self._domain_var, _VarData) + isinstance(self._domain_var, VarData) or isinstance(self._domain_var, IndexedVar) ): msg = ( @@ -1244,7 +1249,7 @@ def __init__(self, *args, **kwds): ) raise TypeError(msg % (repr(self._domain_var),)) if not ( - isinstance(self._range_var, _VarData) + isinstance(self._range_var, VarData) or isinstance(self._range_var, IndexedVar) ): msg = ( @@ -1354,22 +1359,22 @@ def add(self, index, _is_indexed=None): _self_yvar = None _self_domain_pts_index = None if not _is_indexed: - # allows one to mix Var and _VarData as input to + # allows one to mix Var and VarData as input to # non-indexed Piecewise, index would be None in this case - # so for Var elements Var[None] is Var, but _VarData[None] would fail + # so for Var elements Var[None] is Var, but VarData[None] would fail _self_xvar = self._domain_var _self_yvar = self._range_var _self_domain_pts_index = self._domain_points[index] else: - # The following allows one to specify a Var or _VarData + # The following allows one to specify a Var or VarData # object even with an indexed Piecewise component. # The most common situation will most likely be a VarArray, # so we try this first. - if not isinstance(self._domain_var, _VarData): + if not isinstance(self._domain_var, VarData): _self_xvar = self._domain_var[index] else: _self_xvar = self._domain_var - if not isinstance(self._range_var, _VarData): + if not isinstance(self._range_var, VarData): _self_yvar = self._range_var[index] else: _self_yvar = self._range_var @@ -1541,7 +1546,7 @@ def add(self, index, _is_indexed=None): raise ValueError(msg % (self.name, index, self._pw_rep)) if _is_indexed: - comp = _PiecewiseData(self) + comp = PiecewiseData(self) else: comp = self self._data[index] = comp @@ -1551,9 +1556,9 @@ def add(self, index, _is_indexed=None): comp.build_constraints(func, _self_xvar, _self_yvar) -class SimplePiecewise(_PiecewiseData, Piecewise): +class SimplePiecewise(PiecewiseData, Piecewise): def __init__(self, *args, **kwds): - _PiecewiseData.__init__(self, self) + PiecewiseData.__init__(self, self) Piecewise.__init__(self, *args, **kwds) diff --git a/pyomo/core/base/reference.py b/pyomo/core/base/reference.py index 84cccec9749..558ced64f1b 100644 --- a/pyomo/core/base/reference.py +++ b/pyomo/core/base/reference.py @@ -18,7 +18,7 @@ Sequence, ) from pyomo.common.modeling import NOTSET -from pyomo.core.base.set import DeclareGlobalSet, Set, SetOf, OrderedSetOf, _SetDataBase +from pyomo.core.base.set import DeclareGlobalSet, Set, SetOf, OrderedSetOf, SetData from pyomo.core.base.component import Component, ComponentData from pyomo.core.base.global_set import UnindexedComponent_set from pyomo.core.base.enums import SortComponents @@ -774,10 +774,10 @@ def Reference(reference, ctype=NOTSET): # is that within the subsets list, and set is a wildcard set. index = wildcards[0][1] # index is the first wildcard set. - if not isinstance(index, _SetDataBase): + if not isinstance(index, SetData): index = SetOf(index) for lvl, idx in wildcards[1:]: - if not isinstance(idx, _SetDataBase): + if not isinstance(idx, SetData): idx = SetOf(idx) index = index * idx # index is now either a single Set, or a SetProduct of the diff --git a/pyomo/core/base/set.py b/pyomo/core/base/set.py index b3277ab3260..b9a2fe72e1d 100644 --- a/pyomo/core/base/set.py +++ b/pyomo/core/base/set.py @@ -50,7 +50,7 @@ RangeDifferenceError, ) from pyomo.core.base.component import ( - _ComponentBase, + ComponentBase, Component, ComponentData, ModelComponentFactory, @@ -84,10 +84,7 @@ All Sets implement one of the following APIs: -0. `class _SetDataBase(ComponentData)` - *(pure virtual interface)* - -1. `class _SetData(_SetDataBase)` +1. `class SetData(ComponentData)` *(base class for all AML Sets)* 2. `class _FiniteSetMixin(object)` @@ -102,7 +99,7 @@ bounded continuous ranges as well as unbounded discrete ranges). As there are an infinite number of values, iteration is *not* supported. The base class also implements all Python set operations. -Note that `_SetData` does *not* implement `len()`, as Python requires +Note that `SetData` does *not* implement `len()`, as Python requires `len()` to return a positive integer. Finite sets add iteration and support for `len()`. In addition, they @@ -128,7 +125,7 @@ def process_setarg(arg): - if isinstance(arg, _SetDataBase): + if isinstance(arg, SetData): if ( getattr(arg, '_parent', None) is not None or getattr(arg, '_anonymous_sets', None) is GlobalSetBase @@ -140,7 +137,7 @@ def process_setarg(arg): _anonymous.update(arg._anonymous_sets) return arg, _anonymous - elif isinstance(arg, _ComponentBase): + elif isinstance(arg, ComponentBase): if isinstance(arg, IndexedComponent) and arg.is_indexed(): raise TypeError( "Cannot apply a Set operator to an " @@ -512,16 +509,8 @@ class _NotFound(object): pass -# A trivial class that we can use to test if an object is a "legitimate" -# set (either ScalarSet, or a member of an IndexedSet) -class _SetDataBase(ComponentData): - """The base for all objects that can be used as a component indexing set.""" - - __slots__ = () - - -class _SetData(_SetDataBase): - """The base for all Pyomo AML objects that can be used as a component +class SetData(ComponentData): + """The base for all Pyomo objects that can be used as a component indexing set. Derived versions of this class can be used as the Index for any @@ -534,13 +523,13 @@ def __contains__(self, value): ans = self.get(value, _NotFound) except TypeError: # In Python 3.x, Sets are unhashable - if isinstance(value, _SetData): + if isinstance(value, SetData): ans = _NotFound else: raise if ans is _NotFound: - if isinstance(value, _SetData): + if isinstance(value, SetData): deprecation_warning( "Testing for set subsets with 'a in b' is deprecated. " "Use 'a.issubset(b)'.", @@ -894,7 +883,7 @@ def _get_continuous_interval(self): @property @deprecated("The 'virtual' attribute is no longer supported", version='5.7') def virtual(self): - return isinstance(self, (_AnySet, SetOperator, _InfiniteRangeSetData)) + return isinstance(self, (_AnySet, SetOperator, InfiniteRangeSetData)) @virtual.setter def virtual(self, value): @@ -1188,6 +1177,16 @@ def __gt__(self, other): return self >= other and not self == other +class _SetData(metaclass=RenamedClass): + __renamed__new_class__ = SetData + __renamed__version__ = '6.7.2.dev0' + + +class _SetDataBase(metaclass=RenamedClass): + __renamed__new_class__ = SetData + __renamed__version__ = '6.7.2.dev0' + + class _FiniteSetMixin(object): __slots__ = () @@ -1294,14 +1293,14 @@ def ranges(self): yield NonNumericRange(i) -class _FiniteSetData(_FiniteSetMixin, _SetData): +class FiniteSetData(_FiniteSetMixin, SetData): """A general unordered iterable Set""" __slots__ = ('_values', '_domain', '_validate', '_filter', '_dimen') def __init__(self, component): - _SetData.__init__(self, component=component) - # Derived classes (like _OrderedSetData) may want to change the + SetData.__init__(self, component=component) + # Derived classes (like OrderedSetData) may want to change the # storage if not hasattr(self, '_values'): self._values = set() @@ -1470,6 +1469,11 @@ def pop(self): return self._values.pop() +class _FiniteSetData(metaclass=RenamedClass): + __renamed__new_class__ = FiniteSetData + __renamed__version__ = '6.7.2.dev0' + + class _ScalarOrderedSetMixin(object): # This mixin is required because scalar ordered sets implement # __getitem__() as an alias of at() @@ -1630,16 +1634,16 @@ def _to_0_based_index(self, item): ) -class _OrderedSetData(_OrderedSetMixin, _FiniteSetData): +class OrderedSetData(_OrderedSetMixin, FiniteSetData): """ This class defines the base class for an ordered set of concrete data. In older Pyomo terms, this defines a "concrete" ordered set - that is, a set that "owns" the list of set members. While this class actually implements a set ordered by insertion order, we make the "official" - _InsertionOrderSetData an empty derivative class, so that + InsertionOrderSetData an empty derivative class, so that - issubclass(_SortedSetData, _InsertionOrderSetData) == False + issubclass(SortedSetData, InsertionOrderSetData) == False Constructor Arguments: component The Set object that owns this data. @@ -1652,7 +1656,7 @@ class _OrderedSetData(_OrderedSetMixin, _FiniteSetData): def __init__(self, component): self._values = {} self._ordered_values = [] - _FiniteSetData.__init__(self, component=component) + FiniteSetData.__init__(self, component=component) def _iter_impl(self): """ @@ -1730,7 +1734,12 @@ def ord(self, item): raise ValueError("%s.ord(x): x not in %s" % (self.name, self.name)) -class _InsertionOrderSetData(_OrderedSetData): +class _OrderedSetData(metaclass=RenamedClass): + __renamed__new_class__ = OrderedSetData + __renamed__version__ = '6.7.2.dev0' + + +class InsertionOrderSetData(OrderedSetData): """ This class defines the data for a ordered set where the items are ordered in insertion order (similar to Python's OrderedSet. @@ -1751,7 +1760,7 @@ def set_value(self, val): "This WILL potentially lead to nondeterministic behavior " "in Pyomo" % (type(val).__name__,) ) - super(_InsertionOrderSetData, self).set_value(val) + super(InsertionOrderSetData, self).set_value(val) def update(self, values): if type(values) in Set._UnorderedInitializers: @@ -1761,7 +1770,12 @@ def update(self, values): "This WILL potentially lead to nondeterministic behavior " "in Pyomo" % (type(values).__name__,) ) - super(_InsertionOrderSetData, self).update(values) + super(InsertionOrderSetData, self).update(values) + + +class _InsertionOrderSetData(metaclass=RenamedClass): + __renamed__new_class__ = InsertionOrderSetData + __renamed__version__ = '6.7.2.dev0' class _SortedSetMixin(object): @@ -1776,7 +1790,7 @@ def sorted_iter(self): return iter(self) -class _SortedSetData(_SortedSetMixin, _OrderedSetData): +class SortedSetData(_SortedSetMixin, OrderedSetData): """ This class defines the data for a sorted set. @@ -1791,7 +1805,7 @@ class _SortedSetData(_SortedSetMixin, _OrderedSetData): def __init__(self, component): # An empty set is sorted... self._is_sorted = True - _OrderedSetData.__init__(self, component=component) + OrderedSetData.__init__(self, component=component) def _iter_impl(self): """ @@ -1799,12 +1813,12 @@ def _iter_impl(self): """ if not self._is_sorted: self._sort() - return super(_SortedSetData, self)._iter_impl() + return super(SortedSetData, self)._iter_impl() def __reversed__(self): if not self._is_sorted: self._sort() - return super(_SortedSetData, self).__reversed__() + return super(SortedSetData, self).__reversed__() def _add_impl(self, value): # Note that the sorted status has no bearing on insertion, @@ -1818,7 +1832,7 @@ def _add_impl(self, value): # def discard(self, val): def clear(self): - super(_SortedSetData, self).clear() + super(SortedSetData, self).clear() self._is_sorted = True def at(self, index): @@ -1830,7 +1844,7 @@ def at(self, index): """ if not self._is_sorted: self._sort() - return super(_SortedSetData, self).at(index) + return super(SortedSetData, self).at(index) def ord(self, item): """ @@ -1842,7 +1856,7 @@ def ord(self, item): """ if not self._is_sorted: self._sort() - return super(_SortedSetData, self).ord(item) + return super(SortedSetData, self).ord(item) def sorted_data(self): return self.data() @@ -1855,6 +1869,11 @@ def _sort(self): self._is_sorted = True +class _SortedSetData(metaclass=RenamedClass): + __renamed__new_class__ = SortedSetData + __renamed__version__ = '6.7.2.dev0' + + ############################################################################ _SET_API = (('__contains__', 'test membership in'), 'get', 'ranges', 'bounds') @@ -1971,7 +1990,7 @@ class SortedOrder(object): _UnorderedInitializers = {set} @overload - def __new__(cls: Type[Set], *args, **kwds) -> Union[_SetData, IndexedSet]: ... + def __new__(cls: Type[Set], *args, **kwds) -> Union[SetData, IndexedSet]: ... @overload def __new__(cls: Type[OrderedScalarSet], *args, **kwds) -> OrderedScalarSet: ... @@ -1985,7 +2004,7 @@ def __new__(cls, *args, **kwds): # Many things are easier by forcing it to be consistent across # the set (namely, the _ComponentDataClass is constant). # However, it is a bit off that 'ordered' it the only arg NOT - # processed by Initializer. We can mock up a _SortedSetData + # processed by Initializer. We can mock up a SortedSetData # sort function that preserves Insertion Order (lambda x: x), but # the unsorted is harder (it would effectively be insertion # order, but ordered() may not be deterministic based on how the @@ -2030,11 +2049,11 @@ def __new__(cls, *args, **kwds): else: newObj = super(Set, cls).__new__(IndexedSet) if ordered is Set.InsertionOrder: - newObj._ComponentDataClass = _InsertionOrderSetData + newObj._ComponentDataClass = InsertionOrderSetData elif ordered is Set.SortedOrder: - newObj._ComponentDataClass = _SortedSetData + newObj._ComponentDataClass = SortedSetData else: - newObj._ComponentDataClass = _FiniteSetData + newObj._ComponentDataClass = FiniteSetData return newObj @overload @@ -2178,7 +2197,7 @@ def _getitem_when_not_present(self, index): """Returns the default component data value.""" # Because we allow sets within an IndexedSet to have different # dimen, we have moved the tuplization logic from PyomoModel - # into Set (because we cannot know the dimen of a _SetData until + # into Set (because we cannot know the dimen of a SetData until # we are actually constructing that index). This also means # that we need to potentially communicate the dimen to the # (wrapped) value initializer. So, we will get the dimen first, @@ -2338,7 +2357,7 @@ def _pprint(self): # else: # return '{' + str(ans)[1:-1] + "}" - # TBD: In the current design, we force all _SetData within an + # TBD: In the current design, we force all SetData within an # indexed Set to have the same isordered value, so we will only # print it once in the header. Is this a good design? try: @@ -2358,7 +2377,7 @@ def _pprint(self): _ordered = "Sorted" else: _ordered = "{user}" - elif issubclass(_refClass, _InsertionOrderSetData): + elif issubclass(_refClass, InsertionOrderSetData): _ordered = "Insertion" return ( [ @@ -2383,14 +2402,14 @@ def data(self): return {k: v.data() for k, v in self.items()} @overload - def __getitem__(self, index) -> _SetData: ... + def __getitem__(self, index) -> SetData: ... __getitem__ = IndexedComponent.__getitem__ # type: ignore -class FiniteScalarSet(_FiniteSetData, Set): +class FiniteScalarSet(FiniteSetData, Set): def __init__(self, **kwds): - _FiniteSetData.__init__(self, component=self) + FiniteSetData.__init__(self, component=self) Set.__init__(self, **kwds) self._index = UnindexedComponent_index @@ -2400,13 +2419,13 @@ class FiniteSimpleSet(metaclass=RenamedClass): __renamed__version__ = '6.0' -class OrderedScalarSet(_ScalarOrderedSetMixin, _InsertionOrderSetData, Set): +class OrderedScalarSet(_ScalarOrderedSetMixin, InsertionOrderSetData, Set): def __init__(self, **kwds): # In case someone inherits from us, we will provide a rational # default for the "ordered" flag kwds.setdefault('ordered', Set.InsertionOrder) - _InsertionOrderSetData.__init__(self, component=self) + InsertionOrderSetData.__init__(self, component=self) Set.__init__(self, **kwds) @@ -2415,13 +2434,13 @@ class OrderedSimpleSet(metaclass=RenamedClass): __renamed__version__ = '6.0' -class SortedScalarSet(_ScalarOrderedSetMixin, _SortedSetData, Set): +class SortedScalarSet(_ScalarOrderedSetMixin, SortedSetData, Set): def __init__(self, **kwds): # In case someone inherits from us, we will provide a rational # default for the "ordered" flag kwds.setdefault('ordered', Set.SortedOrder) - _SortedSetData.__init__(self, component=self) + SortedSetData.__init__(self, component=self) Set.__init__(self, **kwds) self._index = UnindexedComponent_index @@ -2464,14 +2483,14 @@ class AbstractSortedSimpleSet(metaclass=RenamedClass): ############################################################################ -class SetOf(_SetData, Component): +class SetOf(SetData, Component): """""" def __new__(cls, *args, **kwds): if cls is not SetOf: return super(SetOf, cls).__new__(cls) (reference,) = args - if isinstance(reference, (_SetData, GlobalSetBase)): + if isinstance(reference, (SetData, GlobalSetBase)): if reference.isfinite(): if reference.isordered(): return super(SetOf, cls).__new__(OrderedSetOf) @@ -2485,7 +2504,7 @@ def __new__(cls, *args, **kwds): return super(SetOf, cls).__new__(FiniteSetOf) def __init__(self, reference, **kwds): - _SetData.__init__(self, component=self) + SetData.__init__(self, component=self) kwds.setdefault('ctype', SetOf) Component.__init__(self, **kwds) self._ref = reference @@ -2508,7 +2527,7 @@ def construct(self, data=None): @property def dimen(self): - if isinstance(self._ref, _SetData): + if isinstance(self._ref, SetData): return self._ref.dimen _iter = iter(self) try: @@ -2603,7 +2622,7 @@ def ord(self, item): ############################################################################ -class _InfiniteRangeSetData(_SetData): +class InfiniteRangeSetData(SetData): """Data class for a infinite set. This Set implements an interface to an *infinite set* defined by one @@ -2615,7 +2634,7 @@ class _InfiniteRangeSetData(_SetData): __slots__ = ('_ranges',) def __init__(self, component): - _SetData.__init__(self, component=component) + SetData.__init__(self, component=component) self._ranges = None def get(self, value, default=None): @@ -2648,8 +2667,13 @@ def ranges(self): return iter(self._ranges) -class _FiniteRangeSetData( - _SortedSetMixin, _OrderedSetMixin, _FiniteSetMixin, _InfiniteRangeSetData +class _InfiniteRangeSetData(metaclass=RenamedClass): + __renamed__new_class__ = InfiniteRangeSetData + __renamed__version__ = '6.7.2.dev0' + + +class FiniteRangeSetData( + _SortedSetMixin, _OrderedSetMixin, _FiniteSetMixin, InfiniteRangeSetData ): __slots__ = () @@ -2672,7 +2696,7 @@ def _iter_impl(self): # iterate over it nIters = len(self._ranges) - 1 if not nIters: - yield from _FiniteRangeSetData._range_gen(self._ranges[0]) + yield from FiniteRangeSetData._range_gen(self._ranges[0]) return # The trick here is that we need to remove any duplicates from @@ -2683,7 +2707,7 @@ def _iter_impl(self): for r in self._ranges: # Note: there should always be at least 1 member in each # NumericRange - i = _FiniteRangeSetData._range_gen(r) + i = FiniteRangeSetData._range_gen(r) iters.append([next(i), i]) iters.sort(reverse=True, key=lambda x: x[0]) @@ -2749,11 +2773,16 @@ def ord(self, item): ) # We must redefine ranges(), bounds(), and domain so that we get the - # _InfiniteRangeSetData version and not the one from + # InfiniteRangeSetData version and not the one from # _FiniteSetMixin. - bounds = _InfiniteRangeSetData.bounds - ranges = _InfiniteRangeSetData.ranges - domain = _InfiniteRangeSetData.domain + bounds = InfiniteRangeSetData.bounds + ranges = InfiniteRangeSetData.ranges + domain = InfiniteRangeSetData.domain + + +class _FiniteRangeSetData(metaclass=RenamedClass): + __renamed__new_class__ = FiniteRangeSetData + __renamed__version__ = '6.7.2.dev0' @ModelComponentFactory.register( @@ -3120,7 +3149,7 @@ def construct(self, data=None): old_ranges.reverse() while old_ranges: r = old_ranges.pop() - for i, val in enumerate(_FiniteRangeSetData._range_gen(r)): + for i, val in enumerate(FiniteRangeSetData._range_gen(r)): if not _filter(_block, val): split_r = r.range_difference((NumericRange(val, val, 0),)) if len(split_r) == 2: @@ -3218,9 +3247,9 @@ def _pprint(self): ) -class InfiniteScalarRangeSet(_InfiniteRangeSetData, RangeSet): +class InfiniteScalarRangeSet(InfiniteRangeSetData, RangeSet): def __init__(self, *args, **kwds): - _InfiniteRangeSetData.__init__(self, component=self) + InfiniteRangeSetData.__init__(self, component=self) RangeSet.__init__(self, *args, **kwds) self._index = UnindexedComponent_index @@ -3233,9 +3262,9 @@ class InfiniteSimpleRangeSet(metaclass=RenamedClass): __renamed__version__ = '6.0' -class FiniteScalarRangeSet(_ScalarOrderedSetMixin, _FiniteRangeSetData, RangeSet): +class FiniteScalarRangeSet(_ScalarOrderedSetMixin, FiniteRangeSetData, RangeSet): def __init__(self, *args, **kwds): - _FiniteRangeSetData.__init__(self, component=self) + FiniteRangeSetData.__init__(self, component=self) RangeSet.__init__(self, *args, **kwds) self._index = UnindexedComponent_index @@ -3273,11 +3302,11 @@ class AbstractFiniteSimpleRangeSet(metaclass=RenamedClass): ############################################################################ -class SetOperator(_SetData, Set): +class SetOperator(SetData, Set): __slots__ = ('_sets',) def __init__(self, *args, **kwds): - _SetData.__init__(self, component=self) + SetData.__init__(self, component=self) Set.__init__(self, **kwds) self._sets, _anonymous = zip(*(process_setarg(_set) for _set in args)) _anonymous = tuple(filter(None, _anonymous)) @@ -3461,7 +3490,7 @@ def _domain(self, val): def _checkArgs(*sets): ans = [] for s in sets: - if isinstance(s, _SetDataBase): + if isinstance(s, SetData): ans.append((s.isordered(), s.isfinite())) elif type(s) in {tuple, list}: ans.append((True, True)) @@ -4217,9 +4246,9 @@ def ord(self, item): ############################################################################ -class _AnySet(_SetData, Set): +class _AnySet(SetData, Set): def __init__(self, **kwds): - _SetData.__init__(self, component=self) + SetData.__init__(self, component=self) # There is a chicken-and-egg game here: the SetInitializer uses # Any as part of the processing of the domain/within/bounds # domain restrictions. However, Any has not been declared when @@ -4273,9 +4302,9 @@ def get(self, val, default=None): return super(_AnyWithNoneSet, self).get(val, default) -class _EmptySet(_FiniteSetMixin, _SetData, Set): +class _EmptySet(_FiniteSetMixin, SetData, Set): def __init__(self, **kwds): - _SetData.__init__(self, component=self) + SetData.__init__(self, component=self) Set.__init__(self, **kwds) self.construct() diff --git a/pyomo/core/base/sets.py b/pyomo/core/base/sets.py index ca693cf7d8b..72d49479dd3 100644 --- a/pyomo/core/base/sets.py +++ b/pyomo/core/base/sets.py @@ -18,7 +18,7 @@ set_options, simple_set_rule, _SetDataBase, - _SetData, + SetData, Set, SetOf, IndexedSet, diff --git a/pyomo/core/base/sos.py b/pyomo/core/base/sos.py index 6b8586c9b49..4a8afb05d71 100644 --- a/pyomo/core/base/sos.py +++ b/pyomo/core/base/sos.py @@ -28,7 +28,7 @@ logger = logging.getLogger('pyomo.core') -class _SOSConstraintData(ActiveComponentData): +class SOSConstraintData(ActiveComponentData): """ This class defines the data for a single special ordered set. @@ -101,6 +101,11 @@ def set_items(self, variables, weights): self._weights.append(w) +class _SOSConstraintData(metaclass=RenamedClass): + __renamed__new_class__ = SOSConstraintData + __renamed__version__ = '6.7.2.dev0' + + @ModelComponentFactory.register("SOS constraint expressions.") class SOSConstraint(ActiveIndexedComponent): """ @@ -512,10 +517,10 @@ def add(self, index, variables, weights=None): Add a component data for the specified index. """ if index is None: - # because ScalarSOSConstraint already makes an _SOSConstraintData instance + # because ScalarSOSConstraint already makes an SOSConstraintData instance soscondata = self else: - soscondata = _SOSConstraintData(self) + soscondata = SOSConstraintData(self) self._data[index] = soscondata soscondata._index = index @@ -549,9 +554,9 @@ def pprint(self, ostream=None, verbose=False, prefix=""): ostream.write("\t\t" + str(weight) + ' : ' + var.name + '\n') -class ScalarSOSConstraint(SOSConstraint, _SOSConstraintData): +class ScalarSOSConstraint(SOSConstraint, SOSConstraintData): def __init__(self, *args, **kwd): - _SOSConstraintData.__init__(self, self) + SOSConstraintData.__init__(self, self) SOSConstraint.__init__(self, *args, **kwd) self._index = UnindexedComponent_index diff --git a/pyomo/core/base/var.py b/pyomo/core/base/var.py index 856a2dc0237..8870fc5b09c 100644 --- a/pyomo/core/base/var.py +++ b/pyomo/core/base/var.py @@ -85,241 +85,11 @@ 'value', 'stale', 'fixed', + ('__call__', "access property 'value' on"), ) -class _VarData(ComponentData, NumericValue): - """This class defines the abstract interface for a single variable. - - Note that this "abstract" class is not intended to be directly - instantiated. - - """ - - __slots__ = () - - # - # Interface - # - - def has_lb(self): - """Returns :const:`False` when the lower bound is - :const:`None` or negative infinity""" - return self.lb is not None - - def has_ub(self): - """Returns :const:`False` when the upper bound is - :const:`None` or positive infinity""" - return self.ub is not None - - # TODO: deprecate this? Properties are generally preferred over "set*()" - def setlb(self, val): - """ - Set the lower bound for this variable after validating that - the value is fixed (or None). - """ - self.lower = val - - # TODO: deprecate this? Properties are generally preferred over "set*()" - def setub(self, val): - """ - Set the upper bound for this variable after validating that - the value is fixed (or None). - """ - self.upper = val - - @property - def bounds(self): - """Returns (or set) the tuple (lower bound, upper bound). - - This returns the current (numeric) values of the lower and upper - bounds as a tuple. If there is no bound, returns None (and not - +/-inf) - - """ - return self.lb, self.ub - - @bounds.setter - def bounds(self, val): - self.lower, self.upper = val - - @property - def lb(self): - """Return (or set) the numeric value of the variable lower bound.""" - lb = value(self.lower) - return None if lb == _ninf else lb - - @lb.setter - def lb(self, val): - self.lower = val - - @property - def ub(self): - """Return (or set) the numeric value of the variable upper bound.""" - ub = value(self.upper) - return None if ub == _inf else ub - - @ub.setter - def ub(self, val): - self.upper = val - - def is_integer(self): - """Returns True when the domain is a contiguous integer range.""" - _id = id(self.domain) - if _id in _known_global_real_domains: - return not _known_global_real_domains[_id] - _interval = self.domain.get_interval() - if _interval is None: - return False - # Note: it is not sufficient to just check the step: the - # starting / ending points must be integers (or not specified) - start, stop, step = _interval - return ( - step == 1 - and (start is None or int(start) == start) - and (stop is None or int(stop) == stop) - ) - - def is_binary(self): - """Returns True when the domain is restricted to Binary values.""" - domain = self.domain - if domain is Binary: - return True - if id(domain) in _known_global_real_domains: - return False - return domain.get_interval() == (0, 1, 1) - - def is_continuous(self): - """Returns True when the domain is a continuous real range""" - _id = id(self.domain) - if _id in _known_global_real_domains: - return _known_global_real_domains[_id] - _interval = self.domain.get_interval() - return _interval is not None and _interval[2] == 0 - - def is_fixed(self): - """Returns True if this variable is fixed, otherwise returns False.""" - return self.fixed - - def is_constant(self): - """Returns False because this is not a constant in an expression.""" - return False - - def is_variable_type(self): - """Returns True because this is a variable.""" - return True - - def is_potentially_variable(self): - """Returns True because this is a variable.""" - return True - - def _compute_polynomial_degree(self, result): - """ - If the variable is fixed, it represents a constant - is a polynomial with degree 0. Otherwise, it has - degree 1. This method is used in expressions to - compute polynomial degree. - """ - if self.fixed: - return 0 - return 1 - - def clear(self): - self.value = None - - def __call__(self, exception=True): - """Compute the value of this variable.""" - return self.value - - # - # Abstract Interface - # - - def set_value(self, val, skip_validation=False): - """Set the current variable value.""" - raise NotImplementedError - - @property - def value(self): - """Return (or set) the value for this variable.""" - raise NotImplementedError - - @property - def domain(self): - """Return (or set) the domain for this variable.""" - raise NotImplementedError - - @property - def lower(self): - """Return (or set) an expression for the variable lower bound.""" - raise NotImplementedError - - @property - def upper(self): - """Return (or set) an expression for the variable upper bound.""" - raise NotImplementedError - - @property - def fixed(self): - """Return (or set) the fixed indicator for this variable. - - Alias for :meth:`is_fixed` / :meth:`fix` / :meth:`unfix`. - - """ - raise NotImplementedError - - @property - def stale(self): - """The stale status for this variable. - - Variables are "stale" if their current value was not updated as - part of the most recent model update. A "model update" can be - one of several things: a solver invocation, loading a previous - solution, or manually updating a non-stale :class:`Var` value. - - Returns - ------- - bool - - Notes - ----- - Fixed :class:`Var` objects will be stale after invoking a solver - (as their value was not updated by the solver). - - Updating a stale :class:`Var` value will not cause other - variable values to be come stale. However, updating the first - non-stale :class:`Var` value after a solve or solution load - *will* cause all other variables to be marked as stale - - """ - raise NotImplementedError - - def fix(self, value=NOTSET, skip_validation=False): - """Fix the value of this variable (treat as nonvariable) - - This sets the :attr:`fixed` indicator to True. If ``value`` is - provided, the value (and the ``skip_validation`` flag) are first - passed to :meth:`set_value()`. - - """ - self.fixed = True - if value is not NOTSET: - self.set_value(value, skip_validation) - - def unfix(self): - """Unfix this variable (treat as variable in solver interfaces) - - This sets the :attr:`fixed` indicator to False. - - """ - self.fixed = False - - def free(self): - """Alias for :meth:`unfix`""" - return self.unfix() - - -class _GeneralVarData(_VarData): +class VarData(ComponentData, NumericValue): """This class defines the data for a single variable.""" __slots__ = ('_value', '_lb', '_ub', '_domain', '_fixed', '_stale') @@ -329,7 +99,7 @@ def __init__(self, component=None): # # These lines represent in-lining of the # following constructors: - # - _VarData + # - VarData # - ComponentData # - NumericValue self._component = weakref_ref(component) if (component is not None) else None @@ -360,10 +130,6 @@ def copy(cls, src): self._index = src._index return self - # - # Abstract Interface - # - def set_value(self, val, skip_validation=False): """Set the current variable value. @@ -424,14 +190,20 @@ def set_value(self, val, skip_validation=False): @property def value(self): + """Return (or set) the value for this variable.""" return self._value @value.setter def value(self, val): self.set_value(val) + def __call__(self, exception=True): + """Compute the value of this variable.""" + return self._value + @property def domain(self): + """Return (or set) the domain for this variable.""" return self._domain @domain.setter @@ -448,9 +220,42 @@ def domain(self, domain): ) raise - @_VarData.bounds.getter + def has_lb(self): + """Returns :const:`False` when the lower bound is + :const:`None` or negative infinity""" + return self.lb is not None + + def has_ub(self): + """Returns :const:`False` when the upper bound is + :const:`None` or positive infinity""" + return self.ub is not None + + # TODO: deprecate this? Properties are generally preferred over "set*()" + def setlb(self, val): + """ + Set the lower bound for this variable after validating that + the value is fixed (or None). + """ + self.lower = val + + # TODO: deprecate this? Properties are generally preferred over "set*()" + def setub(self, val): + """ + Set the upper bound for this variable after validating that + the value is fixed (or None). + """ + self.upper = val + + @property def bounds(self): - # Custom implementation of _VarData.bounds to avoid unnecessary + """Returns (or set) the tuple (lower bound, upper bound). + + This returns the current (numeric) values of the lower and upper + bounds as a tuple. If there is no bound, returns None (and not + +/-inf) + + """ + # Custom implementation of lb / ub to avoid unnecessary # expression generation and duplicate calls to domain.bounds() domain_lb, domain_ub = self.domain.bounds() # lb is the tighter of the domain and bounds @@ -491,10 +296,14 @@ def bounds(self): ub = min(ub, domain_ub) return lb, ub - @_VarData.lb.getter + @bounds.setter + def bounds(self, val): + self.lower, self.upper = val + + @property def lb(self): - # Custom implementation of _VarData.lb to avoid unnecessary - # expression generation + """Return (or set) the numeric value of the variable lower bound.""" + # Note: Implementation avoids unnecessary expression generation domain_lb, domain_ub = self.domain.bounds() # lb is the tighter of the domain and bounds lb = self._lb @@ -516,10 +325,14 @@ def lb(self): lb = max(lb, domain_lb) return lb - @_VarData.ub.getter + @lb.setter + def lb(self, val): + self.lower = val + + @property def ub(self): - # Custom implementation of _VarData.ub to avoid unnecessary - # expression generation + """Return (or set) the numeric value of the variable upper bound.""" + # Note: implementation avoids unnecessary expression generation domain_lb, domain_ub = self.domain.bounds() # ub is the tighter of the domain and bounds ub = self._ub @@ -541,6 +354,10 @@ def ub(self): ub = min(ub, domain_ub) return ub + @ub.setter + def ub(self, val): + self.upper = val + @property def lower(self): """Return (or set) an expression for the variable lower bound. @@ -597,8 +414,37 @@ def get_units(self): # component if not scalar return self.parent_component()._units + def fix(self, value=NOTSET, skip_validation=False): + """Fix the value of this variable (treat as nonvariable) + + This sets the :attr:`fixed` indicator to True. If ``value`` is + provided, the value (and the ``skip_validation`` flag) are first + passed to :meth:`set_value()`. + + """ + self.fixed = True + if value is not NOTSET: + self.set_value(value, skip_validation) + + def unfix(self): + """Unfix this variable (treat as variable in solver interfaces) + + This sets the :attr:`fixed` indicator to False. + + """ + self.fixed = False + + def free(self): + """Alias for :meth:`unfix`""" + return self.unfix() + @property def fixed(self): + """Return (or set) the fixed indicator for this variable. + + Alias for :meth:`is_fixed` / :meth:`fix` / :meth:`unfix`. + + """ return self._fixed @fixed.setter @@ -607,6 +453,28 @@ def fixed(self, val): @property def stale(self): + """The stale status for this variable. + + Variables are "stale" if their current value was not updated as + part of the most recent model update. A "model update" can be + one of several things: a solver invocation, loading a previous + solution, or manually updating a non-stale :class:`Var` value. + + Returns + ------- + bool + + Notes + ----- + Fixed :class:`Var` objects will be stale after invoking a solver + (as their value was not updated by the solver). + + Updating a stale :class:`Var` value will not cause other + variable values to be come stale. However, updating the first + non-stale :class:`Var` value after a solve or solution load + *will* cause all other variables to be marked as stale + + """ return StaleFlagManager.is_stale(self._stale) @stale.setter @@ -616,11 +484,70 @@ def stale(self, val): else: self._stale = StaleFlagManager.get_flag(0) - # Note: override the base class definition to avoid a call through a - # property + def is_integer(self): + """Returns True when the domain is a contiguous integer range.""" + _id = id(self.domain) + if _id in _known_global_real_domains: + return not _known_global_real_domains[_id] + _interval = self.domain.get_interval() + if _interval is None: + return False + # Note: it is not sufficient to just check the step: the + # starting / ending points must be integers (or not specified) + start, stop, step = _interval + return ( + step == 1 + and (start is None or int(start) == start) + and (stop is None or int(stop) == stop) + ) + + def is_binary(self): + """Returns True when the domain is restricted to Binary values.""" + domain = self.domain + if domain is Binary: + return True + if id(domain) in _known_global_real_domains: + return False + return domain.get_interval() == (0, 1, 1) + + def is_continuous(self): + """Returns True when the domain is a continuous real range""" + _id = id(self.domain) + if _id in _known_global_real_domains: + return _known_global_real_domains[_id] + _interval = self.domain.get_interval() + return _interval is not None and _interval[2] == 0 + def is_fixed(self): + """Returns True if this variable is fixed, otherwise returns False.""" return self._fixed + def is_constant(self): + """Returns False because this is not a constant in an expression.""" + return False + + def is_variable_type(self): + """Returns True because this is a variable.""" + return True + + def is_potentially_variable(self): + """Returns True because this is a variable.""" + return True + + def clear(self): + self.value = None + + def _compute_polynomial_degree(self, result): + """ + If the variable is fixed, it represents a constant + is a polynomial with degree 0. Otherwise, it has + degree 1. This method is used in expressions to + compute polynomial degree. + """ + if self._fixed: + return 0 + return 1 + def _process_bound(self, val, bound_type): if type(val) in native_numeric_types or val is None: # TODO: warn/error: check if this Var has units: assigning @@ -643,6 +570,16 @@ def _process_bound(self, val, bound_type): return val +class _VarData(metaclass=RenamedClass): + __renamed__new_class__ = VarData + __renamed__version__ = '6.7.2.dev0' + + +class _GeneralVarData(metaclass=RenamedClass): + __renamed__new_class__ = VarData + __renamed__version__ = '6.7.2.dev0' + + @ModelComponentFactory.register("Decision variables.") class Var(IndexedComponent, IndexedComponent_NDArrayMixin): """A numeric variable, which may be defined over an index. @@ -668,7 +605,7 @@ class Var(IndexedComponent, IndexedComponent_NDArrayMixin): doc (str, optional): Text describing this component. """ - _ComponentDataClass = _GeneralVarData + _ComponentDataClass = VarData @overload def __new__(cls: Type[Var], *args, **kwargs) -> Union[ScalarVar, IndexedVar]: ... @@ -775,7 +712,7 @@ def add(self, index): def construct(self, data=None): """ - Construct the _VarData objects for this variable + Construct the VarData objects for this variable """ if self._constructed: return @@ -834,7 +771,7 @@ def construct(self, data=None): # initializers that are constant, we can avoid # re-calling (and re-validating) the inputs in certain # cases. To support this, we will create the first - # _VarData and then use it as a template to initialize + # VarData and then use it as a template to initialize # (constant portions of) every VarData so as to not # repeat all the domain/bounds validation. try: @@ -952,11 +889,11 @@ def _pprint(self): ) -class ScalarVar(_GeneralVarData, Var): +class ScalarVar(VarData, Var): """A single variable.""" def __init__(self, *args, **kwd): - _GeneralVarData.__init__(self, component=self) + VarData.__init__(self, component=self) Var.__init__(self, *args, **kwd) self._index = UnindexedComponent_index @@ -1003,7 +940,7 @@ def fix(self, value=NOTSET, skip_validation=False): def unfix(self): """Unfix all variables in this :class:`IndexedVar` (treat as variable) - This sets the :attr:`_VarData.fixed` indicator to False for + This sets the :attr:`VarData.fixed` indicator to False for every variable in this :class:`IndexedVar`. """ @@ -1057,7 +994,7 @@ def domain(self, domain): # between potentially variable GetItemExpression objects and # "constant" GetItemExpression objects. That will need to wait for # the expression rework [JDS; Nov 22]. - def __getitem__(self, args) -> _GeneralVarData: + def __getitem__(self, args) -> VarData: try: return super().__getitem__(args) except RuntimeError: diff --git a/pyomo/core/beta/dict_objects.py b/pyomo/core/beta/dict_objects.py index a8298b08e63..eedb3c45bf3 100644 --- a/pyomo/core/beta/dict_objects.py +++ b/pyomo/core/beta/dict_objects.py @@ -14,10 +14,10 @@ from pyomo.common.log import is_debug_set from pyomo.core.base.set_types import Any -from pyomo.core.base.var import IndexedVar, _VarData -from pyomo.core.base.constraint import IndexedConstraint, _ConstraintData -from pyomo.core.base.objective import IndexedObjective, _ObjectiveData -from pyomo.core.base.expression import IndexedExpression, _ExpressionData +from pyomo.core.base.var import IndexedVar, VarData +from pyomo.core.base.constraint import IndexedConstraint, ConstraintData +from pyomo.core.base.objective import IndexedObjective, ObjectiveData +from pyomo.core.base.expression import IndexedExpression, ExpressionData from collections.abc import MutableMapping from collections.abc import Mapping @@ -184,7 +184,7 @@ def __init__(self, *args, **kwds): # Constructor for ComponentDict needs to # go last in order to handle any initialization # iterable as an argument - ComponentDict.__init__(self, _VarData, *args, **kwds) + ComponentDict.__init__(self, VarData, *args, **kwds) class ConstraintDict(ComponentDict, IndexedConstraint): @@ -193,7 +193,7 @@ def __init__(self, *args, **kwds): # Constructor for ComponentDict needs to # go last in order to handle any initialization # iterable as an argument - ComponentDict.__init__(self, _ConstraintData, *args, **kwds) + ComponentDict.__init__(self, ConstraintData, *args, **kwds) class ObjectiveDict(ComponentDict, IndexedObjective): @@ -202,7 +202,7 @@ def __init__(self, *args, **kwds): # Constructor for ComponentDict needs to # go last in order to handle any initialization # iterable as an argument - ComponentDict.__init__(self, _ObjectiveData, *args, **kwds) + ComponentDict.__init__(self, ObjectiveData, *args, **kwds) class ExpressionDict(ComponentDict, IndexedExpression): @@ -211,4 +211,4 @@ def __init__(self, *args, **kwds): # Constructor for ComponentDict needs to # go last in order to handle any initialization # iterable as an argument - ComponentDict.__init__(self, _ExpressionData, *args, **kwds) + ComponentDict.__init__(self, ExpressionData, *args, **kwds) diff --git a/pyomo/core/beta/list_objects.py b/pyomo/core/beta/list_objects.py index f53997fed17..005bfc38a1f 100644 --- a/pyomo/core/beta/list_objects.py +++ b/pyomo/core/beta/list_objects.py @@ -14,10 +14,10 @@ from pyomo.common.log import is_debug_set from pyomo.core.base.set_types import Any -from pyomo.core.base.var import IndexedVar, _VarData -from pyomo.core.base.constraint import IndexedConstraint, _ConstraintData -from pyomo.core.base.objective import IndexedObjective, _ObjectiveData -from pyomo.core.base.expression import IndexedExpression, _ExpressionData +from pyomo.core.base.var import IndexedVar, VarData +from pyomo.core.base.constraint import IndexedConstraint, ConstraintData +from pyomo.core.base.objective import IndexedObjective, ObjectiveData +from pyomo.core.base.expression import IndexedExpression, ExpressionData from collections.abc import MutableSequence @@ -232,7 +232,7 @@ def __init__(self, *args, **kwds): # Constructor for ComponentList needs to # go last in order to handle any initialization # iterable as an argument - ComponentList.__init__(self, _VarData, *args, **kwds) + ComponentList.__init__(self, VarData, *args, **kwds) class XConstraintList(ComponentList, IndexedConstraint): @@ -241,7 +241,7 @@ def __init__(self, *args, **kwds): # Constructor for ComponentList needs to # go last in order to handle any initialization # iterable as an argument - ComponentList.__init__(self, _ConstraintData, *args, **kwds) + ComponentList.__init__(self, ConstraintData, *args, **kwds) class XObjectiveList(ComponentList, IndexedObjective): @@ -250,7 +250,7 @@ def __init__(self, *args, **kwds): # Constructor for ComponentList needs to # go last in order to handle any initialization # iterable as an argument - ComponentList.__init__(self, _ObjectiveData, *args, **kwds) + ComponentList.__init__(self, ObjectiveData, *args, **kwds) class XExpressionList(ComponentList, IndexedExpression): @@ -259,4 +259,4 @@ def __init__(self, *args, **kwds): # Constructor for ComponentList needs to # go last in order to handle any initialization # iterable as an argument - ComponentList.__init__(self, _ExpressionData, *args, **kwds) + ComponentList.__init__(self, ExpressionData, *args, **kwds) diff --git a/pyomo/core/expr/calculus/derivatives.py b/pyomo/core/expr/calculus/derivatives.py index ecfdce02fd4..69fe4969938 100644 --- a/pyomo/core/expr/calculus/derivatives.py +++ b/pyomo/core/expr/calculus/derivatives.py @@ -39,11 +39,11 @@ def differentiate(expr, wrt=None, wrt_list=None, mode=Modes.reverse_numeric): ---------- expr: pyomo.core.expr.numeric_expr.NumericExpression The expression to differentiate - wrt: pyomo.core.base.var._GeneralVarData + wrt: pyomo.core.base.var.VarData If specified, this function will return the derivative with - respect to wrt. wrt is normally a _GeneralVarData, but could - also be a _ParamData. wrt and wrt_list cannot both be specified. - wrt_list: list of pyomo.core.base.var._GeneralVarData + respect to wrt. wrt is normally a VarData, but could + also be a ParamData. wrt and wrt_list cannot both be specified. + wrt_list: list of pyomo.core.base.var.VarData If specified, this function will return the derivative with respect to each element in wrt_list. A list will be returned where the values are the derivatives with respect to the diff --git a/pyomo/core/expr/numeric_expr.py b/pyomo/core/expr/numeric_expr.py index 9b624d2b8bd..21896c63219 100644 --- a/pyomo/core/expr/numeric_expr.py +++ b/pyomo/core/expr/numeric_expr.py @@ -722,7 +722,7 @@ def args(self): @deprecated( 'The implicit recasting of a "not potentially variable" ' 'expression node to a potentially variable one is no ' - 'longer supported (this violates that immutability ' + 'longer supported (this violates the immutability ' 'promise for Pyomo5 expression trees).', version='6.4.3', ) @@ -1238,7 +1238,7 @@ class LinearExpression(SumExpression): - not potentially variable (e.g., native types, Params, or NPV expressions) - :py:class:`MonomialTermExpression` - - :py:class:`_VarData` + - :py:class:`VarData` Args: args (tuple): Children nodes diff --git a/pyomo/core/plugins/transform/add_slack_vars.py b/pyomo/core/plugins/transform/add_slack_vars.py index 6b5096d315c..39903384729 100644 --- a/pyomo/core/plugins/transform/add_slack_vars.py +++ b/pyomo/core/plugins/transform/add_slack_vars.py @@ -23,7 +23,6 @@ from pyomo.core.plugins.transform.hierarchy import NonIsomorphicTransformation from pyomo.common.config import ConfigBlock, ConfigValue from pyomo.core.base import ComponentUID -from pyomo.core.base.constraint import _ConstraintData from pyomo.common.deprecation import deprecation_warning @@ -42,7 +41,7 @@ def target_list(x): # [ESJ 07/15/2020] We have to just pass it through because we need the # instance in order to be able to do anything about it... return [x] - elif isinstance(x, (Constraint, _ConstraintData)): + elif getattr(x, 'ctype', None) is Constraint: return [x] elif hasattr(x, '__iter__'): ans = [] @@ -53,7 +52,7 @@ def target_list(x): deprecation_msg = None # same as above... ans.append(i) - elif isinstance(i, (Constraint, _ConstraintData)): + elif getattr(i, 'ctype', None) is Constraint: ans.append(i) else: raise ValueError( diff --git a/pyomo/core/plugins/transform/eliminate_fixed_vars.py b/pyomo/core/plugins/transform/eliminate_fixed_vars.py index 9312035b8c8..934228afd7c 100644 --- a/pyomo/core/plugins/transform/eliminate_fixed_vars.py +++ b/pyomo/core/plugins/transform/eliminate_fixed_vars.py @@ -11,7 +11,7 @@ from pyomo.core.expr import ExpressionBase, as_numeric from pyomo.core import Constraint, Objective, TransformationFactory -from pyomo.core.base.var import Var, _VarData +from pyomo.core.base.var import Var, VarData from pyomo.core.util import sequence from pyomo.core.plugins.transform.hierarchy import IsomorphicTransformation @@ -77,7 +77,7 @@ def _fix_vars(self, expr, model): if isinstance(expr._args[i], ExpressionBase): _args.append(self._fix_vars(expr._args[i], model)) elif ( - isinstance(expr._args[i], Var) or isinstance(expr._args[i], _VarData) + isinstance(expr._args[i], Var) or isinstance(expr._args[i], VarData) ) and expr._args[i].fixed: if expr._args[i].value != 0.0: _args.append(as_numeric(expr._args[i].value)) diff --git a/pyomo/core/plugins/transform/equality_transform.py b/pyomo/core/plugins/transform/equality_transform.py index a1a1b72f146..99291c2227c 100644 --- a/pyomo/core/plugins/transform/equality_transform.py +++ b/pyomo/core/plugins/transform/equality_transform.py @@ -66,7 +66,7 @@ def _create_using(self, model, **kwds): con = equality.__getattribute__(con_name) # - # Get all _ConstraintData objects + # Get all ConstraintData objects # # We need to get the keys ahead of time because we are modifying # con._data on-the-fly. @@ -104,7 +104,7 @@ def _create_using(self, model, **kwds): con.add(ub_name, new_expr) # Since we explicitly `continue` for equality constraints, we - # can safely remove the old _ConstraintData object + # can safely remove the old ConstraintData object del con._data[ndx] return equality.create() diff --git a/pyomo/core/plugins/transform/expand_connectors.py b/pyomo/core/plugins/transform/expand_connectors.py index 8c02f3e5698..82ec546e593 100644 --- a/pyomo/core/plugins/transform/expand_connectors.py +++ b/pyomo/core/plugins/transform/expand_connectors.py @@ -25,7 +25,7 @@ Var, SortComponents, ) -from pyomo.core.base.connector import _ConnectorData, ScalarConnector +from pyomo.core.base.connector import ConnectorData, ScalarConnector @TransformationFactory.register( @@ -69,7 +69,7 @@ def _apply_to(self, instance, **kwds): # The set of connectors found in the current constraint found = ComponentSet() - connector_types = set([ScalarConnector, _ConnectorData]) + connector_types = set([ScalarConnector, ConnectorData]) for constraint in instance.component_data_objects( Constraint, sort=SortComponents.deterministic ): diff --git a/pyomo/core/plugins/transform/logical_to_linear.py b/pyomo/core/plugins/transform/logical_to_linear.py index 7aa541a5fdd..da69ca113bd 100644 --- a/pyomo/core/plugins/transform/logical_to_linear.py +++ b/pyomo/core/plugins/transform/logical_to_linear.py @@ -29,7 +29,7 @@ BooleanVarList, SortComponents, ) -from pyomo.core.base.block import _BlockData +from pyomo.core.base.block import BlockData from pyomo.core.base.boolean_var import _DeprecatedImplicitAssociatedBinaryVariable from pyomo.core.expr.cnf_walker import to_cnf from pyomo.core.expr import ( @@ -100,7 +100,7 @@ def _apply_to(self, model, **kwds): # the GDP will be solved, and it would be wrong to assume that a GDP # will *necessarily* be solved as an algebraic model. The star # example of not doing so being GDPopt.) - if t.ctype is Block or isinstance(t, _BlockData): + if t.ctype is Block or isinstance(t, BlockData): self._transform_block(t, model, new_var_lists, transBlocks) elif t.ctype is LogicalConstraint: if t.is_indexed(): @@ -285,7 +285,7 @@ class CnfToLinearVisitor(StreamBasedExpressionVisitor): """Convert CNF logical constraint to linear constraints. Expected expression node types: AndExpression, OrExpression, NotExpression, - AtLeastExpression, AtMostExpression, ExactlyExpression, _BooleanVarData + AtLeastExpression, AtMostExpression, ExactlyExpression, BooleanVarData """ @@ -372,7 +372,7 @@ def beforeChild(self, node, child, child_idx): if child.is_expression_type(): return True, None - # Only thing left should be _BooleanVarData + # Only thing left should be BooleanVarData # # TODO: After the expr_multiple_dispatch is merged, this should # be switched to using as_numeric. diff --git a/pyomo/core/plugins/transform/model.py b/pyomo/core/plugins/transform/model.py index db8376afd29..7ee268a4292 100644 --- a/pyomo/core/plugins/transform/model.py +++ b/pyomo/core/plugins/transform/model.py @@ -55,8 +55,8 @@ def to_standard_form(self): # N.B. Structure hierarchy: # # active_components: {class: {attr_name: object}} - # object -> Constraint: ._data: {ndx: _ConstraintData} - # _ConstraintData: .lower, .body, .upper + # object -> Constraint: ._data: {ndx: ConstraintData} + # ConstraintData: .lower, .body, .upper # # So, altogether, we access a lower bound via # diff --git a/pyomo/core/plugins/transform/radix_linearization.py b/pyomo/core/plugins/transform/radix_linearization.py index c67e556d60c..92270655f31 100644 --- a/pyomo/core/plugins/transform/radix_linearization.py +++ b/pyomo/core/plugins/transform/radix_linearization.py @@ -21,7 +21,7 @@ Block, RangeSet, ) -from pyomo.core.base.var import _VarData +from pyomo.core.base.var import VarData import logging @@ -268,8 +268,8 @@ def _collect_bilinear(self, expr, bilin, quad): self._collect_bilinear(e, bilin, quad) # No need to check denominator, as this is poly_degree==2 return - if not isinstance(expr._numerator[0], _VarData) or not isinstance( - expr._numerator[1], _VarData + if not isinstance(expr._numerator[0], VarData) or not isinstance( + expr._numerator[1], VarData ): raise RuntimeError("Cannot yet handle complex subexpressions") if expr._numerator[0] is expr._numerator[1]: diff --git a/pyomo/core/plugins/transform/scaling.py b/pyomo/core/plugins/transform/scaling.py index ad894b31fde..11d4ac8c493 100644 --- a/pyomo/core/plugins/transform/scaling.py +++ b/pyomo/core/plugins/transform/scaling.py @@ -10,16 +10,7 @@ # ___________________________________________________________________________ from pyomo.common.collections import ComponentMap -from pyomo.core.base import ( - Block, - Var, - Constraint, - Objective, - _ConstraintData, - _ObjectiveData, - Suffix, - value, -) +from pyomo.core.base import Block, Var, Constraint, Objective, Suffix, value from pyomo.core.plugins.transform.hierarchy import Transformation from pyomo.core.base import TransformationFactory from pyomo.core.base.suffix import SuffixFinder @@ -197,7 +188,7 @@ def _apply_to(self, model, rename=True): already_scaled.add(id(c)) # perform the constraint/objective scaling and variable sub scaling_factor = component_scaling_factor_map[c] - if isinstance(c, _ConstraintData): + if c.ctype is Constraint: body = scaling_factor * replace_expressions( expr=c.body, substitution_map=variable_substitution_dict, @@ -226,7 +217,7 @@ def _apply_to(self, model, rename=True): else: c.set_value((lower, body, upper)) - elif isinstance(c, _ObjectiveData): + elif c.ctype is Objective: c.expr = scaling_factor * replace_expressions( expr=c.expr, substitution_map=variable_substitution_dict, diff --git a/pyomo/core/tests/transform/test_add_slacks.py b/pyomo/core/tests/transform/test_add_slacks.py index a74a9b75c4f..b395237b8e4 100644 --- a/pyomo/core/tests/transform/test_add_slacks.py +++ b/pyomo/core/tests/transform/test_add_slacks.py @@ -330,7 +330,7 @@ def test_error_for_non_constraint_noniterable_target(self): self.assertRaisesRegex( ValueError, "Expected Constraint or list of Constraints.\n\tReceived " - "", + "", TransformationFactory('core.add_slack_variables').apply_to, m, targets=m.indexedVar[1], diff --git a/pyomo/core/tests/unit/test_block.py b/pyomo/core/tests/unit/test_block.py index 71e80d90a73..660f65f1944 100644 --- a/pyomo/core/tests/unit/test_block.py +++ b/pyomo/core/tests/unit/test_block.py @@ -54,7 +54,7 @@ from pyomo.core.base.block import ( ScalarBlock, SubclassOf, - _BlockData, + BlockData, declare_custom_block, ) import pyomo.core.expr as EXPR @@ -851,7 +851,7 @@ class DerivedBlock(ScalarBlock): _Block_reserved_words = None DerivedBlock._Block_reserved_words = ( - set(['a', 'b', 'c']) | _BlockData._Block_reserved_words + set(['a', 'b', 'c']) | BlockData._Block_reserved_words ) m = ConcreteModel() @@ -965,7 +965,7 @@ def __init__(self, *args, **kwds): b.c.d.e = Block() with self.assertRaisesRegex( ValueError, - r'_BlockData.transfer_attributes_from\(\): ' + r'BlockData.transfer_attributes_from\(\): ' r'Cannot set a sub-block \(c.d.e\) to a parent block \(c\):', ): b.c.d.e.transfer_attributes_from(b.c) @@ -974,7 +974,7 @@ def __init__(self, *args, **kwds): b = Block(concrete=True) with self.assertRaisesRegex( ValueError, - r'_BlockData.transfer_attributes_from\(\): expected a Block ' + r'BlockData.transfer_attributes_from\(\): expected a Block ' 'or dict; received str', ): b.transfer_attributes_from('foo') @@ -2977,7 +2977,7 @@ def test_write_exceptions(self): def test_override_pprint(self): @declare_custom_block('TempBlock') - class TempBlockData(_BlockData): + class TempBlockData(BlockData): def pprint(self, ostream=None, verbose=False, prefix=""): ostream.write('Testing pprint of a custom block.') @@ -3052,9 +3052,9 @@ def test_derived_block_construction(self): class ConcreteBlock(Block): pass - class ScalarConcreteBlock(_BlockData, ConcreteBlock): + class ScalarConcreteBlock(BlockData, ConcreteBlock): def __init__(self, *args, **kwds): - _BlockData.__init__(self, component=self) + BlockData.__init__(self, component=self) ConcreteBlock.__init__(self, *args, **kwds) _buf = [] diff --git a/pyomo/core/tests/unit/test_component.py b/pyomo/core/tests/unit/test_component.py index 175c4c47d46..b12db9af047 100644 --- a/pyomo/core/tests/unit/test_component.py +++ b/pyomo/core/tests/unit/test_component.py @@ -66,19 +66,17 @@ def test_getname(self): ) m.b[2]._component = None - self.assertEqual( - m.b[2].getname(fully_qualified=True), "[Unattached _BlockData]" - ) + self.assertEqual(m.b[2].getname(fully_qualified=True), "[Unattached BlockData]") # I think that getname() should do this: # self.assertEqual(m.b[2].c[2,4].getname(fully_qualified=True), - # "[Unattached _BlockData].c[2,4]") + # "[Unattached BlockData].c[2,4]") # but it doesn't match current behavior. I will file a PEP to # propose changing the behavior later and proceed to test # current behavior. self.assertEqual(m.b[2].c[2, 4].getname(fully_qualified=True), "c[2,4]") self.assertEqual( - m.b[2].getname(fully_qualified=False), "[Unattached _BlockData]" + m.b[2].getname(fully_qualified=False), "[Unattached BlockData]" ) self.assertEqual(m.b[2].c[2, 4].getname(fully_qualified=False), "c[2,4]") diff --git a/pyomo/core/tests/unit/test_con.py b/pyomo/core/tests/unit/test_con.py index 6ed19c1bcfd..15f190e281e 100644 --- a/pyomo/core/tests/unit/test_con.py +++ b/pyomo/core/tests/unit/test_con.py @@ -44,7 +44,7 @@ InequalityExpression, RangedExpression, ) -from pyomo.core.base.constraint import _GeneralConstraintData +from pyomo.core.base.constraint import ConstraintData class TestConstraintCreation(unittest.TestCase): @@ -1074,7 +1074,7 @@ def test_setitem(self): m.c[2] = m.x**2 <= 4 self.assertEqual(len(m.c), 1) self.assertEqual(list(m.c.keys()), [2]) - self.assertIsInstance(m.c[2], _GeneralConstraintData) + self.assertIsInstance(m.c[2], ConstraintData) self.assertEqual(m.c[2].upper, 4) m.c[3] = Constraint.Skip @@ -1388,7 +1388,7 @@ def test_empty_singleton(self): # Even though we construct a ScalarConstraint, # if it is not initialized that means it is "empty" # and we should encounter errors when trying to access the - # _ConstraintData interface methods until we assign + # ConstraintData interface methods until we assign # something to the constraint. # self.assertEqual(a._constructed, True) diff --git a/pyomo/core/tests/unit/test_dict_objects.py b/pyomo/core/tests/unit/test_dict_objects.py index 8260f1ae320..ef9f330bfff 100644 --- a/pyomo/core/tests/unit/test_dict_objects.py +++ b/pyomo/core/tests/unit/test_dict_objects.py @@ -17,10 +17,10 @@ ObjectiveDict, ExpressionDict, ) -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.objective import _GeneralObjectiveData -from pyomo.core.base.expression import _GeneralExpressionData +from pyomo.core.base.var import VarData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.objective import ObjectiveData +from pyomo.core.base.expression import ExpressionData class _TestComponentDictBase(object): @@ -348,10 +348,10 @@ def test_active(self): class TestVarDict(_TestComponentDictBase, unittest.TestCase): - # Note: the updated _GeneralVarData class only takes an optional + # Note: the updated VarData class only takes an optional # parent argument (you no longer pass the domain in) _ctype = VarDict - _cdatatype = lambda self, arg: _GeneralVarData() + _cdatatype = lambda self, arg: VarData() def setUp(self): _TestComponentDictBase.setUp(self) @@ -360,7 +360,7 @@ def setUp(self): class TestExpressionDict(_TestComponentDictBase, unittest.TestCase): _ctype = ExpressionDict - _cdatatype = _GeneralExpressionData + _cdatatype = ExpressionData def setUp(self): _TestComponentDictBase.setUp(self) @@ -375,7 +375,7 @@ def setUp(self): class TestConstraintDict(_TestActiveComponentDictBase, unittest.TestCase): _ctype = ConstraintDict - _cdatatype = _GeneralConstraintData + _cdatatype = ConstraintData def setUp(self): _TestComponentDictBase.setUp(self) @@ -384,7 +384,7 @@ def setUp(self): class TestObjectiveDict(_TestActiveComponentDictBase, unittest.TestCase): _ctype = ObjectiveDict - _cdatatype = _GeneralObjectiveData + _cdatatype = ObjectiveData def setUp(self): _TestComponentDictBase.setUp(self) diff --git a/pyomo/core/tests/unit/test_expression.py b/pyomo/core/tests/unit/test_expression.py index 678df4c01a8..eb16f7c6142 100644 --- a/pyomo/core/tests/unit/test_expression.py +++ b/pyomo/core/tests/unit/test_expression.py @@ -29,7 +29,7 @@ value, sum_product, ) -from pyomo.core.base.expression import _GeneralExpressionData +from pyomo.core.base.expression import ExpressionData from pyomo.core.expr.compare import compare_expressions, assertExpressionsEqual from pyomo.common.tee import capture_output @@ -515,10 +515,10 @@ def test_implicit_definition(self): model.E = Expression(model.idx) self.assertEqual(len(model.E), 3) expr = model.E[1] - self.assertIs(type(expr), _GeneralExpressionData) + self.assertIs(type(expr), ExpressionData) model.E[1] = None self.assertIs(expr, model.E[1]) - self.assertIs(type(expr), _GeneralExpressionData) + self.assertIs(type(expr), ExpressionData) self.assertIs(expr.expr, None) model.E[1] = 5 self.assertIs(expr, model.E[1]) @@ -537,7 +537,7 @@ def test_explicit_skip_definition(self): model.E[1] = None expr = model.E[1] - self.assertIs(type(expr), _GeneralExpressionData) + self.assertIs(type(expr), ExpressionData) self.assertIs(expr.expr, None) model.E[1] = 5 self.assertIs(expr, model.E[1]) diff --git a/pyomo/core/tests/unit/test_indexed_slice.py b/pyomo/core/tests/unit/test_indexed_slice.py index babd3f3c46a..40aaad9fec9 100644 --- a/pyomo/core/tests/unit/test_indexed_slice.py +++ b/pyomo/core/tests/unit/test_indexed_slice.py @@ -17,7 +17,7 @@ import pyomo.common.unittest as unittest from pyomo.environ import Var, Block, ConcreteModel, RangeSet, Set, Any -from pyomo.core.base.block import _BlockData +from pyomo.core.base.block import BlockData from pyomo.core.base.indexed_component_slice import IndexedComponent_slice from pyomo.core.base.set import normalize_index @@ -64,7 +64,7 @@ def tearDown(self): self.m = None def test_simple_getitem(self): - self.assertIsInstance(self.m.b[1, 4], _BlockData) + self.assertIsInstance(self.m.b[1, 4], BlockData) def test_simple_getslice(self): _slicer = self.m.b[:, 4] diff --git a/pyomo/core/tests/unit/test_list_objects.py b/pyomo/core/tests/unit/test_list_objects.py index 3eb2e279964..671a8429e06 100644 --- a/pyomo/core/tests/unit/test_list_objects.py +++ b/pyomo/core/tests/unit/test_list_objects.py @@ -17,10 +17,10 @@ XObjectiveList, XExpressionList, ) -from pyomo.core.base.var import _GeneralVarData -from pyomo.core.base.constraint import _GeneralConstraintData -from pyomo.core.base.objective import _GeneralObjectiveData -from pyomo.core.base.expression import _GeneralExpressionData +from pyomo.core.base.var import VarData +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.objective import ObjectiveData +from pyomo.core.base.expression import ExpressionData class _TestComponentListBase(object): @@ -365,10 +365,10 @@ def test_active(self): class TestVarList(_TestComponentListBase, unittest.TestCase): - # Note: the updated _GeneralVarData class only takes an optional + # Note: the updated VarData class only takes an optional # parent argument (you no longer pass the domain in) _ctype = XVarList - _cdatatype = lambda self, arg: _GeneralVarData() + _cdatatype = lambda self, arg: VarData() def setUp(self): _TestComponentListBase.setUp(self) @@ -377,7 +377,7 @@ def setUp(self): class TestExpressionList(_TestComponentListBase, unittest.TestCase): _ctype = XExpressionList - _cdatatype = _GeneralExpressionData + _cdatatype = ExpressionData def setUp(self): _TestComponentListBase.setUp(self) @@ -392,7 +392,7 @@ def setUp(self): class TestConstraintList(_TestActiveComponentListBase, unittest.TestCase): _ctype = XConstraintList - _cdatatype = _GeneralConstraintData + _cdatatype = ConstraintData def setUp(self): _TestComponentListBase.setUp(self) @@ -401,7 +401,7 @@ def setUp(self): class TestObjectiveList(_TestActiveComponentListBase, unittest.TestCase): _ctype = XObjectiveList - _cdatatype = _GeneralObjectiveData + _cdatatype = ObjectiveData def setUp(self): _TestComponentListBase.setUp(self) diff --git a/pyomo/core/tests/unit/test_numeric_expr.py b/pyomo/core/tests/unit/test_numeric_expr.py index 968b3acb6a4..efb01e6d6ce 100644 --- a/pyomo/core/tests/unit/test_numeric_expr.py +++ b/pyomo/core/tests/unit/test_numeric_expr.py @@ -112,7 +112,7 @@ from pyomo.core.base.label import NumericLabeler from pyomo.core.expr.template_expr import IndexTemplate from pyomo.core.expr import expr_common -from pyomo.core.base.var import _GeneralVarData +from pyomo.core.base.var import VarData from pyomo.repn import generate_standard_repn from pyomo.core.expr.numvalue import NumericValue @@ -294,7 +294,7 @@ def value_check(self, exp, val): class TestExpression_EvaluateVarData(TestExpression_EvaluateNumericValue): def create(self, val, domain): - tmp = _GeneralVarData() + tmp = VarData() tmp.domain = domain tmp.value = val return tmp diff --git a/pyomo/core/tests/unit/test_obj.py b/pyomo/core/tests/unit/test_obj.py index 3c8a05f7058..dc2e320e63b 100644 --- a/pyomo/core/tests/unit/test_obj.py +++ b/pyomo/core/tests/unit/test_obj.py @@ -78,7 +78,7 @@ def test_empty_singleton(self): # Even though we construct a ScalarObjective, # if it is not initialized that means it is "empty" # and we should encounter errors when trying to access the - # _ObjectiveData interface methods until we assign + # ObjectiveData interface methods until we assign # something to the objective. # self.assertEqual(a._constructed, True) diff --git a/pyomo/core/tests/unit/test_param.py b/pyomo/core/tests/unit/test_param.py index 9bc0c4b2ad2..f22674b6bf7 100644 --- a/pyomo/core/tests/unit/test_param.py +++ b/pyomo/core/tests/unit/test_param.py @@ -65,8 +65,8 @@ from pyomo.common.errors import PyomoException from pyomo.common.log import LoggingIntercept from pyomo.common.tempfiles import TempfileManager -from pyomo.core.base.param import _ParamData -from pyomo.core.base.set import _SetData +from pyomo.core.base.param import ParamData +from pyomo.core.base.set import SetData from pyomo.core.base.units_container import units, pint_available, UnitsError from io import StringIO @@ -181,7 +181,7 @@ def test_setitem_preexisting(self): idx = sorted(keys)[0] self.assertEqual(value(self.instance.A[idx]), self.data[idx]) if self.instance.A.mutable: - self.assertTrue(isinstance(self.instance.A[idx], _ParamData)) + self.assertTrue(isinstance(self.instance.A[idx], ParamData)) else: self.assertEqual(type(self.instance.A[idx]), float) @@ -190,7 +190,7 @@ def test_setitem_preexisting(self): if not self.instance.A.mutable: self.fail("Expected setitem[%s] to fail for immutable Params" % (idx,)) self.assertEqual(value(self.instance.A[idx]), 4.3) - self.assertTrue(isinstance(self.instance.A[idx], _ParamData)) + self.assertTrue(isinstance(self.instance.A[idx], ParamData)) except TypeError: # immutable Params should raise a TypeError exception if self.instance.A.mutable: @@ -249,7 +249,7 @@ def test_setitem_default_override(self): self.assertEqual(value(self.instance.A[idx]), self.instance.A._default_val) if self.instance.A.mutable: - self.assertIsInstance(self.instance.A[idx], _ParamData) + self.assertIsInstance(self.instance.A[idx], ParamData) else: self.assertEqual( type(self.instance.A[idx]), type(value(self.instance.A._default_val)) @@ -260,7 +260,7 @@ def test_setitem_default_override(self): if not self.instance.A.mutable: self.fail("Expected setitem[%s] to fail for immutable Params" % (idx,)) self.assertEqual(self.instance.A[idx].value, 4.3) - self.assertIsInstance(self.instance.A[idx], _ParamData) + self.assertIsInstance(self.instance.A[idx], ParamData) except TypeError: # immutable Params should raise a TypeError exception if self.instance.A.mutable: @@ -1487,7 +1487,7 @@ def test_domain_set_initializer(self): m.I = Set(initialize=[1, 2, 3]) param_vals = {1: 1, 2: 1, 3: -1} m.p = Param(m.I, initialize=param_vals, domain={-1, 1}) - self.assertIsInstance(m.p.domain, _SetData) + self.assertIsInstance(m.p.domain, SetData) @unittest.skipUnless(pint_available, "units test requires pint module") def test_set_value_units(self): diff --git a/pyomo/core/tests/unit/test_piecewise.py b/pyomo/core/tests/unit/test_piecewise.py index af82ef7c06d..7b8e01e6a45 100644 --- a/pyomo/core/tests/unit/test_piecewise.py +++ b/pyomo/core/tests/unit/test_piecewise.py @@ -104,7 +104,7 @@ def test_indexed_with_nonindexed_vars(self): model.con3 = Piecewise(*args, **keywords) # test that nonindexed Piecewise can handle - # _VarData (e.g model.x[1] + # VarData (e.g model.x[1] def test_nonindexed_with_indexed_vars(self): model = ConcreteModel() model.range = Var([1]) diff --git a/pyomo/core/tests/unit/test_reference.py b/pyomo/core/tests/unit/test_reference.py index cfd9b99f945..7370881612f 100644 --- a/pyomo/core/tests/unit/test_reference.py +++ b/pyomo/core/tests/unit/test_reference.py @@ -800,8 +800,8 @@ def test_reference_indexedcomponent_pprint(self): buf.getvalue(), """r : Size=2, Index={1, 2}, ReferenceTo=x Key : Object - 1 : - 2 : + 1 : + 2 : """, ) m.s = Reference(m.x[:, ...], ctype=IndexedComponent) @@ -811,8 +811,8 @@ def test_reference_indexedcomponent_pprint(self): buf.getvalue(), """s : Size=2, Index={1, 2}, ReferenceTo=x[:, ...] Key : Object - 1 : - 2 : + 1 : + 2 : """, ) @@ -1357,8 +1357,8 @@ def test_pprint_nonfinite_sets_ctypeNone(self): 1 IndexedComponent Declarations ref : Size=2, Index=NonNegativeIntegers, ReferenceTo=v Key : Object - 3 : - 5 : + 3 : + 5 : 2 Declarations: v ref """.strip(), diff --git a/pyomo/core/tests/unit/test_set.py b/pyomo/core/tests/unit/test_set.py index 4bbac6ecaa0..f62589a6873 100644 --- a/pyomo/core/tests/unit/test_set.py +++ b/pyomo/core/tests/unit/test_set.py @@ -60,8 +60,8 @@ FiniteSetOf, InfiniteSetOf, RangeSet, - _FiniteRangeSetData, - _InfiniteRangeSetData, + FiniteRangeSetData, + InfiniteRangeSetData, FiniteScalarRangeSet, InfiniteScalarRangeSet, AbstractFiniteScalarRangeSet, @@ -81,10 +81,10 @@ SetProduct_InfiniteSet, SetProduct_FiniteSet, SetProduct_OrderedSet, - _SetData, - _FiniteSetData, - _InsertionOrderSetData, - _SortedSetData, + SetData, + FiniteSetData, + InsertionOrderSetData, + SortedSetData, _FiniteSetMixin, _OrderedSetMixin, SetInitializer, @@ -1285,19 +1285,19 @@ def test_is_functions(self): self.assertTrue(i.isdiscrete()) self.assertTrue(i.isfinite()) self.assertTrue(i.isordered()) - self.assertIsInstance(i, _FiniteRangeSetData) + self.assertIsInstance(i, FiniteRangeSetData) i = RangeSet(1, 3) self.assertTrue(i.isdiscrete()) self.assertTrue(i.isfinite()) self.assertTrue(i.isordered()) - self.assertIsInstance(i, _FiniteRangeSetData) + self.assertIsInstance(i, FiniteRangeSetData) i = RangeSet(1, 3, 0) self.assertFalse(i.isdiscrete()) self.assertFalse(i.isfinite()) self.assertFalse(i.isordered()) - self.assertIsInstance(i, _InfiniteRangeSetData) + self.assertIsInstance(i, InfiniteRangeSetData) def test_pprint(self): m = ConcreteModel() @@ -4137,9 +4137,9 @@ def test_indexed_set(self): self.assertFalse(m.I[1].isordered()) self.assertFalse(m.I[2].isordered()) self.assertFalse(m.I[3].isordered()) - self.assertIs(type(m.I[1]), _FiniteSetData) - self.assertIs(type(m.I[2]), _FiniteSetData) - self.assertIs(type(m.I[3]), _FiniteSetData) + self.assertIs(type(m.I[1]), FiniteSetData) + self.assertIs(type(m.I[2]), FiniteSetData) + self.assertIs(type(m.I[3]), FiniteSetData) self.assertEqual(m.I.data(), {1: (1,), 2: (2,), 3: (4,)}) # Explicit (constant) construction @@ -4155,9 +4155,9 @@ def test_indexed_set(self): self.assertTrue(m.I[1].isordered()) self.assertTrue(m.I[2].isordered()) self.assertTrue(m.I[3].isordered()) - self.assertIs(type(m.I[1]), _InsertionOrderSetData) - self.assertIs(type(m.I[2]), _InsertionOrderSetData) - self.assertIs(type(m.I[3]), _InsertionOrderSetData) + self.assertIs(type(m.I[1]), InsertionOrderSetData) + self.assertIs(type(m.I[2]), InsertionOrderSetData) + self.assertIs(type(m.I[3]), InsertionOrderSetData) self.assertEqual(m.I.data(), {1: (4, 2, 5), 2: (4, 2, 5), 3: (4, 2, 5)}) # Explicit (constant) construction @@ -4173,9 +4173,9 @@ def test_indexed_set(self): self.assertTrue(m.I[1].isordered()) self.assertTrue(m.I[2].isordered()) self.assertTrue(m.I[3].isordered()) - self.assertIs(type(m.I[1]), _SortedSetData) - self.assertIs(type(m.I[2]), _SortedSetData) - self.assertIs(type(m.I[3]), _SortedSetData) + self.assertIs(type(m.I[1]), SortedSetData) + self.assertIs(type(m.I[2]), SortedSetData) + self.assertIs(type(m.I[3]), SortedSetData) self.assertEqual(m.I.data(), {1: (2, 4, 5), 2: (2, 4, 5), 3: (2, 4, 5)}) # Explicit (procedural) construction @@ -4300,7 +4300,7 @@ def _l_tri(model, i, j): # This tests a filter that matches the dimentionality of the # component. construct() needs to recognize that the filter is # returning a constant in construct() and re-assign it to be the - # _filter for each _SetData + # _filter for each SetData def _lt_3(model, i): self.assertIs(model, m) return i < 3 @@ -5297,15 +5297,15 @@ def test_no_normalize_index(self): class TestAbstractSetAPI(unittest.TestCase): - def test_SetData(self): + def testSetData(self): # This tests an anstract non-finite set API m = ConcreteModel() m.I = Set(initialize=[1]) - s = _SetData(m.I) + s = SetData(m.I) # - # _SetData API + # SetData API # with self.assertRaises(DeveloperError): @@ -5395,7 +5395,7 @@ def test_SetData(self): def test_FiniteMixin(self): # This tests an anstract finite set API - class FiniteMixin(_FiniteSetMixin, _SetData): + class FiniteMixin(_FiniteSetMixin, SetData): pass m = ConcreteModel() @@ -5403,7 +5403,7 @@ class FiniteMixin(_FiniteSetMixin, _SetData): s = FiniteMixin(m.I) # - # _SetData API + # SetData API # with self.assertRaises(DeveloperError): @@ -5520,7 +5520,7 @@ class FiniteMixin(_FiniteSetMixin, _SetData): def test_OrderedMixin(self): # This tests an anstract ordered set API - class OrderedMixin(_OrderedSetMixin, _FiniteSetMixin, _SetData): + class OrderedMixin(_OrderedSetMixin, _FiniteSetMixin, SetData): pass m = ConcreteModel() @@ -5528,7 +5528,7 @@ class OrderedMixin(_OrderedSetMixin, _FiniteSetMixin, _SetData): s = OrderedMixin(m.I) # - # _SetData API + # SetData API # with self.assertRaises(DeveloperError): diff --git a/pyomo/core/tests/unit/test_template_expr.py b/pyomo/core/tests/unit/test_template_expr.py index 4c872e1e11d..80f5d90b60e 100644 --- a/pyomo/core/tests/unit/test_template_expr.py +++ b/pyomo/core/tests/unit/test_template_expr.py @@ -127,7 +127,7 @@ def test_template_scalar_with_set(self): # Note that structural expressions do not implement polynomial_degree with self.assertRaisesRegex( AttributeError, - "'_InsertionOrderSetData' object has " "no attribute 'polynomial_degree'", + "'InsertionOrderSetData' object has " "no attribute 'polynomial_degree'", ): e.polynomial_degree() self.assertEqual(str(e), "s[{I}]") diff --git a/pyomo/core/tests/unit/test_var_set_bounds.py b/pyomo/core/tests/unit/test_var_set_bounds.py index bae89556ce3..1686ba4f1c6 100644 --- a/pyomo/core/tests/unit/test_var_set_bounds.py +++ b/pyomo/core/tests/unit/test_var_set_bounds.py @@ -36,7 +36,7 @@ # GAH: These tests been temporarily disabled. It is no longer the job of Var # to validate its domain at the time of construction. It only needs to # ensure that whatever object is passed as its domain is suitable for -# interacting with the _VarData interface (e.g., has a bounds method) +# interacting with the VarData interface (e.g., has a bounds method) # The plan is to start adding functionality to the solver interfaces # that will support custom domains. diff --git a/pyomo/core/tests/unit/test_visitor.py b/pyomo/core/tests/unit/test_visitor.py index 12fb98d1d19..ac61a3a24c7 100644 --- a/pyomo/core/tests/unit/test_visitor.py +++ b/pyomo/core/tests/unit/test_visitor.py @@ -72,7 +72,7 @@ RECURSION_LIMIT, get_stack_depth, ) -from pyomo.core.base.param import _ParamData, ScalarParam +from pyomo.core.base.param import ParamData, ScalarParam from pyomo.core.expr.template_expr import IndexTemplate from pyomo.common.collections import ComponentSet from pyomo.common.errors import TemplateExpressionError @@ -685,7 +685,7 @@ def __init__(self, model): self.model = model def visiting_potential_leaf(self, node): - if node.__class__ in (_ParamData, ScalarParam): + if node.__class__ in (ParamData, ScalarParam): if id(node) in self.substitute: return True, self.substitute[id(node)] self.substitute[id(node)] = 2 * self.model.w.add() diff --git a/pyomo/core/util.py b/pyomo/core/util.py index f337b487cef..4b6cc8f3320 100644 --- a/pyomo/core/util.py +++ b/pyomo/core/util.py @@ -18,7 +18,7 @@ from pyomo.core.expr.numeric_expr import mutable_expression, NPV_SumExpression from pyomo.core.base.var import Var from pyomo.core.base.expression import Expression -from pyomo.core.base.component import _ComponentBase +from pyomo.core.base.component import ComponentBase import logging logger = logging.getLogger(__name__) @@ -238,12 +238,12 @@ def sequence(*args): def target_list(x): - if isinstance(x, _ComponentBase): + if isinstance(x, ComponentBase): return [x] elif hasattr(x, '__iter__'): ans = [] for i in x: - if isinstance(i, _ComponentBase): + if isinstance(i, ComponentBase): ans.append(i) else: raise ValueError( diff --git a/pyomo/dae/flatten.py b/pyomo/dae/flatten.py index febaf7c10c9..3d90cc443c1 100644 --- a/pyomo/dae/flatten.py +++ b/pyomo/dae/flatten.py @@ -259,7 +259,7 @@ def generate_sliced_components( Parameters ---------- - b: _BlockData + b: BlockData Block whose components will be sliced index_stack: list @@ -267,7 +267,7 @@ def generate_sliced_components( component, that have been sliced. This is necessary to return the sets that have been sliced. - slice_: IndexedComponent_slice or _BlockData + slice_: IndexedComponent_slice or BlockData Slice generated so far. This function will yield extensions to this slice at the current level of the block hierarchy. @@ -443,7 +443,7 @@ def flatten_components_along_sets(m, sets, ctype, indices=None, active=None): Parameters ---------- - m: _BlockData + m: BlockData Block whose components (and their sub-components) will be partitioned @@ -546,7 +546,7 @@ def flatten_dae_components(model, time, ctype, indices=None, active=None): Parameters ---------- - model: _BlockData + model: BlockData Block whose components are partitioned time: Set diff --git a/pyomo/dae/integral.py b/pyomo/dae/integral.py index 41114296a93..8c9512d98dd 100644 --- a/pyomo/dae/integral.py +++ b/pyomo/dae/integral.py @@ -14,7 +14,7 @@ from pyomo.core.base.indexed_component import rule_wrapper from pyomo.core.base.expression import ( Expression, - _GeneralExpressionData, + ExpressionData, ScalarExpression, IndexedExpression, ) @@ -151,7 +151,7 @@ class ScalarIntegral(ScalarExpression, Integral): """ def __init__(self, *args, **kwds): - _GeneralExpressionData.__init__(self, None, component=self) + ExpressionData.__init__(self, None, component=self) Integral.__init__(self, *args, **kwds) def clear(self): diff --git a/pyomo/dae/misc.py b/pyomo/dae/misc.py index 3e09a055577..dcb73f60c9e 100644 --- a/pyomo/dae/misc.py +++ b/pyomo/dae/misc.py @@ -263,7 +263,7 @@ def _update_var(v): # Note: This is not required it is handled by the _default method on # Var (which is now a IndexedComponent). However, it # would be much slower to rely on that method to generate new - # _VarData for a large number of new indices. + # VarData for a large number of new indices. new_indices = set(v.index_set()) - set(v._data.keys()) for index in new_indices: v.add(index) diff --git a/pyomo/gdp/__init__.py b/pyomo/gdp/__init__.py index a18bc03084a..d204369cdba 100644 --- a/pyomo/gdp/__init__.py +++ b/pyomo/gdp/__init__.py @@ -9,7 +9,13 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ -from pyomo.gdp.disjunct import GDP_Error, Disjunct, Disjunction +from pyomo.gdp.disjunct import ( + GDP_Error, + Disjunct, + DisjunctData, + Disjunction, + DisjunctionData, +) # Do not import these files: importing them registers the transformation # plugins with the pyomo script so that they get automatically invoked. diff --git a/pyomo/gdp/disjunct.py b/pyomo/gdp/disjunct.py index d6e5fcfec57..658ead27783 100644 --- a/pyomo/gdp/disjunct.py +++ b/pyomo/gdp/disjunct.py @@ -41,7 +41,7 @@ ComponentData, ) from pyomo.core.base.global_set import UnindexedComponent_index -from pyomo.core.base.block import _BlockData +from pyomo.core.base.block import BlockData from pyomo.core.base.misc import apply_indexed_rule from pyomo.core.base.indexed_component import ActiveIndexedComponent from pyomo.core.expr.expr_common import ExpressionType @@ -412,7 +412,7 @@ def process(arg): return (_Initializer.deferred_value, arg) -class _DisjunctData(_BlockData): +class DisjunctData(BlockData): __autoslot_mappers__ = {'_transformation_block': AutoSlots.weakref_mapper} _Block_reserved_words = set() @@ -424,7 +424,7 @@ def transformation_block(self): ) def __init__(self, component): - _BlockData.__init__(self, component) + BlockData.__init__(self, component) with self._declare_reserved_components(): self.indicator_var = AutoLinkedBooleanVar() self.binary_indicator_var = AutoLinkedBinaryVar(self.indicator_var) @@ -434,23 +434,28 @@ def __init__(self, component): self._transformation_block = None def activate(self): - super(_DisjunctData, self).activate() + super(DisjunctData, self).activate() self.indicator_var.unfix() def deactivate(self): - super(_DisjunctData, self).deactivate() + super(DisjunctData, self).deactivate() self.indicator_var.fix(False) def _deactivate_without_fixing_indicator(self): - super(_DisjunctData, self).deactivate() + super(DisjunctData, self).deactivate() def _activate_without_unfixing_indicator(self): - super(_DisjunctData, self).activate() + super(DisjunctData, self).activate() + + +class _DisjunctData(metaclass=RenamedClass): + __renamed__new_class__ = DisjunctData + __renamed__version__ = '6.7.2.dev0' @ModelComponentFactory.register("Disjunctive blocks.") class Disjunct(Block): - _ComponentDataClass = _DisjunctData + _ComponentDataClass = DisjunctData def __new__(cls, *args, **kwds): if cls != Disjunct: @@ -475,7 +480,7 @@ def __init__(self, *args, **kwargs): # def _deactivate_without_fixing_indicator(self): # # Ideally, this would be a super call from this class. However, # # doing that would trigger a call to deactivate() on all the - # # _DisjunctData objects (exactly what we want to avoid!) + # # DisjunctData objects (exactly what we want to avoid!) # # # # For the time being, we will do something bad and directly call # # the base class method from where we would otherwise want to @@ -484,7 +489,7 @@ def __init__(self, *args, **kwargs): def _activate_without_unfixing_indicator(self): # Ideally, this would be a super call from this class. However, # doing that would trigger a call to deactivate() on all the - # _DisjunctData objects (exactly what we want to avoid!) + # DisjunctData objects (exactly what we want to avoid!) # # For the time being, we will do something bad and directly call # the base class method from where we would otherwise want to @@ -495,15 +500,15 @@ def _activate_without_unfixing_indicator(self): component_data._activate_without_unfixing_indicator() -class ScalarDisjunct(_DisjunctData, Disjunct): +class ScalarDisjunct(DisjunctData, Disjunct): def __init__(self, *args, **kwds): ## FIXME: This is a HACK to get around a chicken-and-egg issue - ## where _BlockData creates the indicator_var *before* + ## where BlockData creates the indicator_var *before* ## Block.__init__ declares the _defer_construction flag. self._defer_construction = True self._suppress_ctypes = set() - _DisjunctData.__init__(self, self) + DisjunctData.__init__(self, self) Disjunct.__init__(self, *args, **kwds) self._data[None] = self self._index = UnindexedComponent_index @@ -524,10 +529,10 @@ def active(self): return any(d.active for d in self._data.values()) -_DisjunctData._Block_reserved_words = set(dir(Disjunct())) +DisjunctData._Block_reserved_words = set(dir(Disjunct())) -class _DisjunctionData(ActiveComponentData): +class DisjunctionData(ActiveComponentData): __slots__ = ('disjuncts', 'xor', '_algebraic_constraint', '_transformation_map') __autoslot_mappers__ = {'_algebraic_constraint': AutoSlots.weakref_mapper} _NoArgument = (0,) @@ -542,7 +547,7 @@ def __init__(self, component=None): # # These lines represent in-lining of the # following constructors: - # - _ConstraintData, + # - ConstraintData, # - ActiveComponentData # - ComponentData self._component = weakref_ref(component) if (component is not None) else None @@ -620,9 +625,14 @@ def set_value(self, expr): self.disjuncts.append(disjunct) +class _DisjunctionData(metaclass=RenamedClass): + __renamed__new_class__ = DisjunctionData + __renamed__version__ = '6.7.2.dev0' + + @ModelComponentFactory.register("Disjunction expressions.") class Disjunction(ActiveIndexedComponent): - _ComponentDataClass = _DisjunctionData + _ComponentDataClass = DisjunctionData def __new__(cls, *args, **kwds): if cls != Disjunction: @@ -763,9 +773,9 @@ def _pprint(self): ) -class ScalarDisjunction(_DisjunctionData, Disjunction): +class ScalarDisjunction(DisjunctionData, Disjunction): def __init__(self, *args, **kwds): - _DisjunctionData.__init__(self, component=self) + DisjunctionData.__init__(self, component=self) Disjunction.__init__(self, *args, **kwds) self._index = UnindexedComponent_index @@ -776,7 +786,7 @@ def __init__(self, *args, **kwds): # currently in place). So during initialization only, we will # treat them as "indexed" objects where things like # Constraint.Skip are managed. But after that they will behave - # like _DisjunctionData objects where set_value does not handle + # like DisjunctionData objects where set_value does not handle # Disjunction.Skip but expects a valid expression or None. # diff --git a/pyomo/gdp/plugins/gdp_var_mover.py b/pyomo/gdp/plugins/gdp_var_mover.py index 5402b576368..7b1df0bb68f 100644 --- a/pyomo/gdp/plugins/gdp_var_mover.py +++ b/pyomo/gdp/plugins/gdp_var_mover.py @@ -115,7 +115,7 @@ def _apply_to(self, instance, **kwds): disjunct_component, Block ) # HACK: activate the block, but do not activate the - # _BlockData objects + # BlockData objects super(ActiveIndexedComponent, disjunct_component).activate() # Deactivate all constraints. Note that we only need to diff --git a/pyomo/gdp/plugins/hull.py b/pyomo/gdp/plugins/hull.py index 5b9d2ad08a9..854366c0cf0 100644 --- a/pyomo/gdp/plugins/hull.py +++ b/pyomo/gdp/plugins/hull.py @@ -42,7 +42,7 @@ Binary, ) from pyomo.gdp import Disjunct, Disjunction, GDP_Error -from pyomo.gdp.disjunct import _DisjunctData +from pyomo.gdp.disjunct import DisjunctData from pyomo.gdp.plugins.gdp_to_mip_transformation import GDP_to_MIP_Transformation from pyomo.gdp.transformed_disjunct import _TransformedDisjunct from pyomo.gdp.util import ( @@ -750,20 +750,20 @@ def _transform_constraint( if obj.is_indexed(): newConstraint.add((name, i, 'eq'), newConsExpr) - # map the _ConstraintDatas (we mapped the container above) + # map the ConstraintDatas (we mapped the container above) constraint_map.transformed_constraints[c].append( newConstraint[name, i, 'eq'] ) constraint_map.src_constraint[newConstraint[name, i, 'eq']] = c else: newConstraint.add((name, 'eq'), newConsExpr) - # map to the _ConstraintData (And yes, for + # map to the ConstraintData (And yes, for # ScalarConstraints, this is overwriting the map to the # container we made above, and that is what I want to # happen. ScalarConstraints will map to lists. For # IndexedConstraints, we can map the container to the # container, but more importantly, we are mapping the - # _ConstraintDatas to each other above) + # ConstraintDatas to each other above) constraint_map.transformed_constraints[c].append( newConstraint[name, 'eq'] ) diff --git a/pyomo/gdp/tests/common_tests.py b/pyomo/gdp/tests/common_tests.py index 5d0d6f6c21b..50bc8b05f86 100644 --- a/pyomo/gdp/tests/common_tests.py +++ b/pyomo/gdp/tests/common_tests.py @@ -30,7 +30,7 @@ from pyomo.gdp import Disjunct, Disjunction, GDP_Error from pyomo.core.expr.compare import assertExpressionsEqual from pyomo.core.base import constraint, ComponentUID -from pyomo.core.base.block import _BlockData +from pyomo.core.base.block import BlockData from pyomo.repn import generate_standard_repn import pyomo.core.expr as EXPR import pyomo.gdp.tests.models as models @@ -952,9 +952,7 @@ def check_disjunction_data_target(self, transformation): transBlock = m.component("_pyomo_gdp_%s_reformulation" % transformation) self.assertIsInstance(transBlock, Block) self.assertIsInstance(transBlock.component("disjunction_xor"), Constraint) - self.assertIsInstance( - transBlock.disjunction_xor[2], constraint._GeneralConstraintData - ) + self.assertIsInstance(transBlock.disjunction_xor[2], constraint.ConstraintData) self.assertIsInstance(transBlock.component("relaxedDisjuncts"), Block) self.assertEqual(len(transBlock.relaxedDisjuncts), 3) @@ -963,7 +961,7 @@ def check_disjunction_data_target(self, transformation): m, targets=[m.disjunction[1]] ) self.assertIsInstance( - m.disjunction[1].algebraic_constraint, constraint._GeneralConstraintData + m.disjunction[1].algebraic_constraint, constraint.ConstraintData ) transBlock = m.component("_pyomo_gdp_%s_reformulation_4" % transformation) self.assertIsInstance(transBlock, Block) @@ -1704,10 +1702,10 @@ def check_all_components_transformed(self, m): # makeNestedDisjunctions_NestedDisjuncts model. self.assertIsInstance(m.disj.algebraic_constraint, Constraint) self.assertIsInstance(m.d1.disj2.algebraic_constraint, Constraint) - self.assertIsInstance(m.d1.transformation_block, _BlockData) - self.assertIsInstance(m.d2.transformation_block, _BlockData) - self.assertIsInstance(m.d1.d3.transformation_block, _BlockData) - self.assertIsInstance(m.d1.d4.transformation_block, _BlockData) + self.assertIsInstance(m.d1.transformation_block, BlockData) + self.assertIsInstance(m.d2.transformation_block, BlockData) + self.assertIsInstance(m.d1.d3.transformation_block, BlockData) + self.assertIsInstance(m.d1.d4.transformation_block, BlockData) def check_transformation_blocks_nestedDisjunctions(self, m, transformation): diff --git a/pyomo/gdp/tests/test_bigm.py b/pyomo/gdp/tests/test_bigm.py index 3174a95292e..c27d7cbe0cb 100644 --- a/pyomo/gdp/tests/test_bigm.py +++ b/pyomo/gdp/tests/test_bigm.py @@ -30,7 +30,7 @@ value, ) from pyomo.gdp import Disjunct, Disjunction, GDP_Error -from pyomo.core.base import constraint, _ConstraintData +from pyomo.core.base import constraint, ConstraintData from pyomo.core.expr.compare import ( assertExpressionsEqual, assertExpressionsStructurallyEqual, @@ -656,14 +656,14 @@ def test_disjunct_and_constraint_maps(self): if src[0]: # equality self.assertEqual(len(transformed), 2) - self.assertIsInstance(transformed[0], _ConstraintData) - self.assertIsInstance(transformed[1], _ConstraintData) + self.assertIsInstance(transformed[0], ConstraintData) + self.assertIsInstance(transformed[1], ConstraintData) self.assertIs(bigm.get_src_constraint(transformed[0]), srcDisjunct.c) self.assertIs(bigm.get_src_constraint(transformed[1]), srcDisjunct.c) else: # >= self.assertEqual(len(transformed), 1) - self.assertIsInstance(transformed[0], _ConstraintData) + self.assertIsInstance(transformed[0], ConstraintData) # check reverse map from the container self.assertIs(bigm.get_src_constraint(transformed[0]), srcDisjunct.c) @@ -1326,8 +1326,8 @@ def test_do_not_transform_deactivated_constraintDatas(self): self.assertEqual(len(cons_list), 2) lb = cons_list[0] ub = cons_list[1] - self.assertIsInstance(lb, constraint._GeneralConstraintData) - self.assertIsInstance(ub, constraint._GeneralConstraintData) + self.assertIsInstance(lb, constraint.ConstraintData) + self.assertIsInstance(ub, constraint.ConstraintData) def checkMs( self, m, disj1c1lb, disj1c1ub, disj1c2lb, disj1c2ub, disj2c1ub, disj2c2ub @@ -2291,7 +2291,7 @@ def test_constraints_not_enforced_when_an_ancestor_indicator_is_False(self): class IndexedDisjunction(unittest.TestCase): # this tests that if the targets are a subset of the - # _DisjunctDatas in an IndexedDisjunction that the xor constraint + # DisjunctDatas in an IndexedDisjunction that the xor constraint # created on the parent block will still be indexed as expected. def test_xor_constraint(self): ct.check_indexed_xor_constraints_with_targets(self, 'bigm') diff --git a/pyomo/gdp/tests/test_hull.py b/pyomo/gdp/tests/test_hull.py index 55edf244731..07876a9d213 100644 --- a/pyomo/gdp/tests/test_hull.py +++ b/pyomo/gdp/tests/test_hull.py @@ -1252,12 +1252,10 @@ def check_second_iteration(self, model): orig = model.component("_pyomo_gdp_hull_reformulation") self.assertIsInstance( - model.disjunctionList[1].algebraic_constraint, - constraint._GeneralConstraintData, + model.disjunctionList[1].algebraic_constraint, constraint.ConstraintData ) self.assertIsInstance( - model.disjunctionList[0].algebraic_constraint, - constraint._GeneralConstraintData, + model.disjunctionList[0].algebraic_constraint, constraint.ConstraintData ) self.assertFalse(model.disjunctionList[1].active) self.assertFalse(model.disjunctionList[0].active) diff --git a/pyomo/gdp/tests/test_util.py b/pyomo/gdp/tests/test_util.py index fd555fc2f59..fa8e953f9f7 100644 --- a/pyomo/gdp/tests/test_util.py +++ b/pyomo/gdp/tests/test_util.py @@ -13,7 +13,7 @@ from pyomo.core import ConcreteModel, Var, Expression, Block, RangeSet, Any import pyomo.core.expr as EXPR -from pyomo.core.base.expression import _ExpressionData +from pyomo.core.base.expression import NamedExpressionData from pyomo.gdp.util import ( clone_without_expression_components, is_child_of, @@ -40,7 +40,7 @@ def test_clone_without_expression_components(self): test = clone_without_expression_components(base, {}) self.assertIsNot(base, test) self.assertEqual(base(), test()) - self.assertIsInstance(base, _ExpressionData) + self.assertIsInstance(base, NamedExpressionData) self.assertIsInstance(test, EXPR.SumExpression) test = clone_without_expression_components(base, {id(m.x): m.y}) self.assertEqual(3**2 + 3 - 1, test()) @@ -51,7 +51,7 @@ def test_clone_without_expression_components(self): self.assertEqual(base(), test()) self.assertIsInstance(base, EXPR.SumExpression) self.assertIsInstance(test, EXPR.SumExpression) - self.assertIsInstance(base.arg(0), _ExpressionData) + self.assertIsInstance(base.arg(0), NamedExpressionData) self.assertIsInstance(test.arg(0), EXPR.SumExpression) test = clone_without_expression_components(base, {id(m.x): m.y}) self.assertEqual(3**2 + 3 - 1 + 3, test()) diff --git a/pyomo/gdp/transformed_disjunct.py b/pyomo/gdp/transformed_disjunct.py index 6cf60abf414..287d5ed1652 100644 --- a/pyomo/gdp/transformed_disjunct.py +++ b/pyomo/gdp/transformed_disjunct.py @@ -10,11 +10,11 @@ # ___________________________________________________________________________ from pyomo.common.autoslots import AutoSlots -from pyomo.core.base.block import _BlockData, IndexedBlock +from pyomo.core.base.block import BlockData, IndexedBlock from pyomo.core.base.global_set import UnindexedComponent_index, UnindexedComponent_set -class _TransformedDisjunctData(_BlockData): +class _TransformedDisjunctData(BlockData): __slots__ = ('_src_disjunct',) __autoslot_mappers__ = {'_src_disjunct': AutoSlots.weakref_mapper} @@ -23,7 +23,7 @@ def src_disjunct(self): return None if self._src_disjunct is None else self._src_disjunct() def __init__(self, component): - _BlockData.__init__(self, component) + BlockData.__init__(self, component) # pointer to the Disjunct whose transformation block this is. self._src_disjunct = None diff --git a/pyomo/gdp/util.py b/pyomo/gdp/util.py index a8c6393f0b3..2fe8e9e1dee 100644 --- a/pyomo/gdp/util.py +++ b/pyomo/gdp/util.py @@ -10,10 +10,9 @@ # ___________________________________________________________________________ from pyomo.gdp import GDP_Error, Disjunction -from pyomo.gdp.disjunct import _DisjunctData, Disjunct +from pyomo.gdp.disjunct import DisjunctData, Disjunct import pyomo.core.expr as EXPR -from pyomo.core.base.component import _ComponentBase from pyomo.core import ( Block, Suffix, @@ -22,7 +21,7 @@ LogicalConstraint, value, ) -from pyomo.core.base.block import _BlockData +from pyomo.core.base.block import BlockData from pyomo.common.collections import ComponentMap, ComponentSet, OrderedSet from pyomo.opt import TerminationCondition, SolverStatus @@ -330,7 +329,7 @@ def get_gdp_tree(targets, instance, knownBlocks=None): "Target '%s' is not a component on instance " "'%s'!" % (t.name, instance.name) ) - if t.ctype is Block or isinstance(t, _BlockData): + if t.ctype is Block or isinstance(t, BlockData): _blocks = t.values() if t.is_indexed() else (t,) for block in _blocks: if not block.active: @@ -387,7 +386,7 @@ def is_child_of(parent, child, knownBlocks=None): if knownBlocks is None: knownBlocks = {} tmp = set() - node = child if isinstance(child, (Block, _BlockData)) else child.parent_block() + node = child if isinstance(child, (Block, BlockData)) else child.parent_block() while True: known = knownBlocks.get(node) if known: @@ -452,7 +451,7 @@ def get_src_disjunct(transBlock): Parameters ---------- - transBlock: _BlockData which is in the relaxedDisjuncts IndexedBlock + transBlock: BlockData which is in the relaxedDisjuncts IndexedBlock on a transformation block. """ if ( @@ -493,7 +492,7 @@ def get_src_constraint(transformedConstraint): def _find_parent_disjunct(constraint): # traverse up until we find the disjunct this constraint lives on parent_disjunct = constraint.parent_block() - while not isinstance(parent_disjunct, _DisjunctData): + while not isinstance(parent_disjunct, DisjunctData): if parent_disjunct is None: raise GDP_Error( "Constraint '%s' is not on a disjunct and so was not " @@ -525,17 +524,17 @@ def get_transformed_constraints(srcConstraint): Parameters ---------- - srcConstraint: ScalarConstraint or _ConstraintData, which must be in + srcConstraint: ScalarConstraint or ConstraintData, which must be in the subtree of a transformed Disjunct """ if srcConstraint.is_indexed(): raise GDP_Error( "Argument to get_transformed_constraint should be " - "a ScalarConstraint or _ConstraintData. (If you " + "a ScalarConstraint or ConstraintData. (If you " "want the container for all transformed constraints " "from an IndexedDisjunction, this is the parent " "component of a transformed constraint originating " - "from any of its _ComponentDatas.)" + "from any of its ComponentDatas.)" ) transBlock = _get_constraint_transBlock(srcConstraint) transformed_constraints = transBlock.private_data( diff --git a/pyomo/mpec/complementarity.py b/pyomo/mpec/complementarity.py index 79f76a9fc34..aa8db922145 100644 --- a/pyomo/mpec/complementarity.py +++ b/pyomo/mpec/complementarity.py @@ -19,7 +19,7 @@ from pyomo.core import Constraint, Var, Block, Set from pyomo.core.base.component import ModelComponentFactory from pyomo.core.base.global_set import UnindexedComponent_index -from pyomo.core.base.block import _BlockData +from pyomo.core.base.block import BlockData from pyomo.core.base.disable_methods import disable_methods from pyomo.core.base.initializer import ( Initializer, @@ -43,7 +43,7 @@ def complements(a, b): return ComplementarityTuple(a, b) -class _ComplementarityData(_BlockData): +class ComplementarityData(BlockData): def _canonical_expression(self, e): # Note: as the complimentarity component maintains references to # the original expression (e), it is NOT safe or valid to bypass @@ -179,9 +179,14 @@ def set_value(self, cc): ) +class _ComplementarityData(metaclass=RenamedClass): + __renamed__new_class__ = ComplementarityData + __renamed__version__ = '6.7.2.dev0' + + @ModelComponentFactory.register("Complementarity conditions.") class Complementarity(Block): - _ComponentDataClass = _ComplementarityData + _ComponentDataClass = ComplementarityData def __new__(cls, *args, **kwds): if cls != Complementarity: @@ -298,9 +303,9 @@ def _conditional_block_printer(ostream, idx, data): ) -class ScalarComplementarity(_ComplementarityData, Complementarity): +class ScalarComplementarity(ComplementarityData, Complementarity): def __init__(self, *args, **kwds): - _ComplementarityData.__init__(self, self) + ComplementarityData.__init__(self, self) Complementarity.__init__(self, *args, **kwds) self._data[None] = self self._index = UnindexedComponent_index diff --git a/pyomo/network/arc.py b/pyomo/network/arc.py index 42b7c6ea075..5e68f181a38 100644 --- a/pyomo/network/arc.py +++ b/pyomo/network/arc.py @@ -52,7 +52,7 @@ def _iterable_to_dict(vals, directed, name): return vals -class _ArcData(ActiveComponentData): +class ArcData(ActiveComponentData): """ This class defines the data for a single Arc @@ -246,6 +246,11 @@ def _validate_ports(self, source, destination, ports): ) +class _ArcData(metaclass=RenamedClass): + __renamed__new_class__ = ArcData + __renamed__version__ = '6.7.2.dev0' + + @ModelComponentFactory.register("Component used for connecting two Ports.") class Arc(ActiveIndexedComponent): """ @@ -267,7 +272,7 @@ class Arc(ActiveIndexedComponent): or a two-member iterable of ports """ - _ComponentDataClass = _ArcData + _ComponentDataClass = ArcData def __new__(cls, *args, **kwds): if cls != Arc: @@ -373,9 +378,9 @@ def _pprint(self): ) -class ScalarArc(_ArcData, Arc): +class ScalarArc(ArcData, Arc): def __init__(self, *args, **kwds): - _ArcData.__init__(self, self) + ArcData.__init__(self, self) Arc.__init__(self, *args, **kwds) self.index = UnindexedComponent_index diff --git a/pyomo/network/port.py b/pyomo/network/port.py index 26822d4fee9..ee5c915d8db 100644 --- a/pyomo/network/port.py +++ b/pyomo/network/port.py @@ -36,7 +36,7 @@ logger = logging.getLogger('pyomo.network') -class _PortData(ComponentData): +class PortData(ComponentData): """ This class defines the data for a single Port @@ -285,6 +285,11 @@ def get_split_fraction(self, arc): return res +class _PortData(metaclass=RenamedClass): + __renamed__new_class__ = PortData + __renamed__version__ = '6.7.2.dev0' + + @ModelComponentFactory.register( "A bundle of variables that can be connected to other ports." ) @@ -339,7 +344,7 @@ def __init__(self, *args, **kwd): # IndexedComponent that support implicit definition def _getitem_when_not_present(self, idx): """Returns the default component data value.""" - tmp = self._data[idx] = _PortData(component=self) + tmp = self._data[idx] = PortData(component=self) tmp._index = idx return tmp @@ -357,7 +362,7 @@ def construct(self, data=None): for _set in self._anonymous_sets: _set.construct() - # Construct _PortData objects for all index values + # Construct PortData objects for all index values if self.is_indexed(): self._initialize_members(self._index_set) else: @@ -763,9 +768,9 @@ def _create_evar(member, name, eblock, index_set): return evar -class ScalarPort(Port, _PortData): +class ScalarPort(Port, PortData): def __init__(self, *args, **kwd): - _PortData.__init__(self, component=self) + PortData.__init__(self, component=self) Port.__init__(self, *args, **kwd) self._index = UnindexedComponent_index diff --git a/pyomo/opt/base/solvers.py b/pyomo/opt/base/solvers.py index f1f9d653a8a..c0698165603 100644 --- a/pyomo/opt/base/solvers.py +++ b/pyomo/opt/base/solvers.py @@ -536,15 +536,15 @@ def solve(self, *args, **kwds): # If the inputs are models, then validate that they have been # constructed! Collect suffix names to try and import from solution. # - from pyomo.core.base.block import _BlockData + from pyomo.core.base.block import BlockData import pyomo.core.base.suffix from pyomo.core.kernel.block import IBlock import pyomo.core.kernel.suffix _model = None for arg in args: - if isinstance(arg, (_BlockData, IBlock)): - if isinstance(arg, _BlockData): + if isinstance(arg, (BlockData, IBlock)): + if isinstance(arg, BlockData): if not arg.is_constructed(): raise RuntimeError( "Attempting to solve model=%s with unconstructed " @@ -553,7 +553,7 @@ def solve(self, *args, **kwds): _model = arg # import suffixes must be on the top-level model - if isinstance(arg, _BlockData): + if isinstance(arg, BlockData): model_suffixes = list( name for ( diff --git a/pyomo/repn/beta/matrix.py b/pyomo/repn/beta/matrix.py index 916b0daf755..0201c46eb18 100644 --- a/pyomo/repn/beta/matrix.py +++ b/pyomo/repn/beta/matrix.py @@ -24,7 +24,7 @@ Constraint, IndexedConstraint, ScalarConstraint, - _ConstraintData, + ConstraintData, ) from pyomo.core.expr.numvalue import native_numeric_types from pyomo.repn import generate_standard_repn @@ -247,7 +247,7 @@ def _get_bound(exp): constraint_containers_removed += 1 for constraint, index in constraint_data_to_remove: # Note that this del is not needed: assigning Constraint.Skip - # above removes the _ConstraintData from the _data dict. + # above removes the ConstraintData from the _data dict. # del constraint[index] constraints_removed += 1 for block, constraint in constraint_containers_to_remove: @@ -348,12 +348,12 @@ def _get_bound(exp): ) -# class _LinearConstraintData(_ConstraintData,LinearCanonicalRepn): +# class _LinearConstraintData(ConstraintData,LinearCanonicalRepn): # # This change breaks this class, but it's unclear whether this # is being used... # -class _LinearConstraintData(_ConstraintData): +class _LinearConstraintData(ConstraintData): """ This class defines the data for a single linear constraint in canonical form. @@ -393,7 +393,7 @@ def __init__(self, index, component=None): # # These lines represent in-lining of the # following constructors: - # - _ConstraintData, + # - ConstraintData, # - ActiveComponentData # - ComponentData self._component = weakref_ref(component) if (component is not None) else None @@ -442,7 +442,7 @@ def __init__(self, index, component=None): # These lines represent in-lining of the # following constructors: # - _LinearConstraintData - # - _ConstraintData, + # - ConstraintData, # - ActiveComponentData # - ComponentData self._component = weakref_ref(component) if (component is not None) else None @@ -584,7 +584,7 @@ def constant(self): return sum(terms) # - # Abstract Interface (_ConstraintData) + # Abstract Interface (ConstraintData) # @property diff --git a/pyomo/repn/plugins/ampl/ampl_.py b/pyomo/repn/plugins/ampl/ampl_.py index f422a085a3c..cc99e9cfdae 100644 --- a/pyomo/repn/plugins/ampl/ampl_.py +++ b/pyomo/repn/plugins/ampl/ampl_.py @@ -33,7 +33,7 @@ from pyomo.core.base import ( SymbolMap, NameLabeler, - _ExpressionData, + NamedExpressionData, SortComponents, var, param, @@ -168,11 +168,11 @@ def _build_op_template(): _op_template[EXPR.EqualityExpression] = "o24{C}\n" _op_comment[EXPR.EqualityExpression] = "\t#eq" - _op_template[var._VarData] = "v%d{C}\n" - _op_comment[var._VarData] = "\t#%s" + _op_template[var.VarData] = "v%d{C}\n" + _op_comment[var.VarData] = "\t#%s" - _op_template[param._ParamData] = "n%r{C}\n" - _op_comment[param._ParamData] = "" + _op_template[param.ParamData] = "n%r{C}\n" + _op_comment[param.ParamData] = "" _op_template[NumericConstant] = "n%r{C}\n" _op_comment[NumericConstant] = "" @@ -724,7 +724,7 @@ def _print_nonlinear_terms_NL(self, exp): self._print_nonlinear_terms_NL(exp.arg(0)) self._print_nonlinear_terms_NL(exp.arg(1)) - elif isinstance(exp, (_ExpressionData, IIdentityExpression)): + elif isinstance(exp, (NamedExpressionData, IIdentityExpression)): self._print_nonlinear_terms_NL(exp.expr) else: @@ -733,24 +733,24 @@ def _print_nonlinear_terms_NL(self, exp): % (exp_type) ) - elif isinstance(exp, (var._VarData, IVariable)) and (not exp.is_fixed()): + elif isinstance(exp, (var.VarData, IVariable)) and (not exp.is_fixed()): # (self._output_fixed_variable_bounds or if not self._symbolic_solver_labels: OUTPUT.write( - self._op_string[var._VarData] + self._op_string[var.VarData] % (self.ampl_var_id[self._varID_map[id(exp)]]) ) else: OUTPUT.write( - self._op_string[var._VarData] + self._op_string[var.VarData] % ( self.ampl_var_id[self._varID_map[id(exp)]], self._name_labeler(exp), ) ) - elif isinstance(exp, param._ParamData): - OUTPUT.write(self._op_string[param._ParamData] % (value(exp))) + elif isinstance(exp, param.ParamData): + OUTPUT.write(self._op_string[param.ParamData] % (value(exp))) elif isinstance(exp, NumericConstant) or exp.is_fixed(): OUTPUT.write(self._op_string[NumericConstant] % (value(exp))) diff --git a/pyomo/repn/plugins/cpxlp.py b/pyomo/repn/plugins/cpxlp.py index 46e6b6d5265..45f4279f8fe 100644 --- a/pyomo/repn/plugins/cpxlp.py +++ b/pyomo/repn/plugins/cpxlp.py @@ -60,7 +60,7 @@ def __init__(self): # The LP writer tracks which variables are # referenced in constraints, so that a user does not end up with a # zillion "unreferenced variables" warning messages. - # This dictionary maps id(_VarData) -> _VarData. + # This dictionary maps id(VarData) -> VarData. self._referenced_variable_ids = {} # Per ticket #4319, we are using %.17g, which mocks the @@ -374,7 +374,7 @@ def _print_expr_canonical( def printSOS(self, symbol_map, labeler, variable_symbol_map, soscondata, output): """ - Prints the SOS constraint associated with the _SOSConstraintData object + Prints the SOS constraint associated with the SOSConstraintData object """ sos_template_string = self.sos_template_string diff --git a/pyomo/repn/plugins/mps.py b/pyomo/repn/plugins/mps.py index ba26783eea1..e1a0d2187fc 100644 --- a/pyomo/repn/plugins/mps.py +++ b/pyomo/repn/plugins/mps.py @@ -62,7 +62,7 @@ def __init__(self, int_marker=False): # referenced in constraints, so that one doesn't end up with a # zillion "unreferenced variables" warning messages. stored at # the object level to avoid additional method arguments. - # dictionary of id(_VarData)->_VarData. + # dictionary of id(VarData)->VarData. self._referenced_variable_ids = {} # Keven Hunter made a nice point about using %.16g in his attachment diff --git a/pyomo/repn/plugins/nl_writer.py b/pyomo/repn/plugins/nl_writer.py index 86da2a3622b..644fd26987b 100644 --- a/pyomo/repn/plugins/nl_writer.py +++ b/pyomo/repn/plugins/nl_writer.py @@ -69,15 +69,11 @@ minimize, ) from pyomo.core.base.component import ActiveComponent -from pyomo.core.base.constraint import _ConstraintData -from pyomo.core.base.expression import ScalarExpression, _GeneralExpressionData -from pyomo.core.base.objective import ( - ScalarObjective, - _GeneralObjectiveData, - _ObjectiveData, -) +from pyomo.core.base.constraint import ConstraintData +from pyomo.core.base.expression import ScalarExpression, ExpressionData +from pyomo.core.base.objective import ScalarObjective, ObjectiveData from pyomo.core.base.suffix import SuffixFinder -from pyomo.core.base.var import _VarData +from pyomo.core.base.var import VarData import pyomo.core.kernel as kernel from pyomo.core.pyomoobject import PyomoObject from pyomo.opt import WriterFactory @@ -130,17 +126,17 @@ class NLWriterInfo(object): Attributes ---------- - variables: List[_VarData] + variables: List[VarData] The list of (unfixed) Pyomo model variables in the order written to the NL file - constraints: List[_ConstraintData] + constraints: List[ConstraintData] The list of (active) Pyomo model constraints in the order written to the NL file - objectives: List[_ObjectiveData] + objectives: List[ObjectiveData] The list of (active) Pyomo model objectives in the order written to the NL file @@ -163,10 +159,10 @@ class NLWriterInfo(object): file in the same order as the :py:attr:`variables` and generated .col file. - eliminated_vars: List[Tuple[_VarData, NumericExpression]] + eliminated_vars: List[Tuple[VarData, NumericExpression]] The list of variables in the model that were eliminated by the - presolve. Each entry is a 2-tuple of (:py:class:`_VarData`, + presolve. Each entry is a 2-tuple of (:py:class:`VarData`, :py:class`NumericExpression`|`float`). The list is in the necessary order for correct evaluation (i.e., all variables appearing in the expression must either have been sent to the @@ -442,6 +438,7 @@ def store(self, obj, val): self.values[obj] = val def compile(self, column_order, row_order, obj_order, model_id): + var_con_obj = {Var, Constraint, Objective} missing_component_data = ComponentSet() unknown_data = ComponentSet() queue = [self.values.items()] @@ -467,18 +464,20 @@ def compile(self, column_order, row_order, obj_order, model_id): self.obj[obj_order[_id]] = val elif _id == model_id: self.prob[0] = val - elif isinstance(obj, (_VarData, _ConstraintData, _ObjectiveData)): - missing_component_data.add(obj) - elif isinstance(obj, (Var, Constraint, Objective)): - # Expand this indexed component to store the - # individual ComponentDatas, but ONLY if the - # component data is not in the original dictionary - # of values that we extracted from the Suffixes - queue.append( - product( - filterfalse(self.values.__contains__, obj.values()), (val,) + elif getattr(obj, 'ctype', None) in var_con_obj: + if obj.is_indexed(): + # Expand this indexed component to store the + # individual ComponentDatas, but ONLY if the + # component data is not in the original dictionary + # of values that we extracted from the Suffixes + queue.append( + product( + filterfalse(self.values.__contains__, obj.values()), + (val,), + ) ) - ) + else: + missing_component_data.add(obj) else: unknown_data.add(obj) if missing_component_data: diff --git a/pyomo/repn/plugins/standard_form.py b/pyomo/repn/plugins/standard_form.py index ea7b6a6a9e6..315b2160d37 100644 --- a/pyomo/repn/plugins/standard_form.py +++ b/pyomo/repn/plugins/standard_form.py @@ -76,25 +76,25 @@ class LinearStandardFormInfo(object): The constraint right-hand sides. - rows : List[Tuple[_ConstraintData, int]] + rows : List[Tuple[ConstraintData, int]] The list of Pyomo constraint objects corresponding to the rows in `A`. Each element in the list is a 2-tuple of - (_ConstraintData, row_multiplier). The `row_multiplier` will be + (ConstraintData, row_multiplier). The `row_multiplier` will be +/- 1 indicating if the row was multiplied by -1 (corresponding to a constraint lower bound) or +1 (upper bound). - columns : List[_VarData] + columns : List[VarData] The list of Pyomo variable objects corresponding to columns in the `A` and `c` matrices. - eliminated_vars: List[Tuple[_VarData, NumericExpression]] + eliminated_vars: List[Tuple[VarData, NumericExpression]] The list of variables from the original model that do not appear in the standard form (usually because they were replaced by nonnegative variables). Each entry is a 2-tuple of - (:py:class:`_VarData`, :py:class`NumericExpression`|`float`). + (:py:class:`VarData`, :py:class`NumericExpression`|`float`). The list is in the necessary order for correct evaluation (i.e., all variables appearing in the expression must either have appeared in the standard form, or appear *earlier* in this list. diff --git a/pyomo/repn/standard_repn.py b/pyomo/repn/standard_repn.py index 8600a8a50f6..b767ab727af 100644 --- a/pyomo/repn/standard_repn.py +++ b/pyomo/repn/standard_repn.py @@ -19,11 +19,15 @@ import pyomo.core.expr as EXPR from pyomo.core.expr.numvalue import NumericConstant -from pyomo.core.base.objective import _GeneralObjectiveData, ScalarObjective -from pyomo.core.base import _ExpressionData, Expression -from pyomo.core.base.expression import ScalarExpression, _GeneralExpressionData -from pyomo.core.base.var import ScalarVar, Var, _GeneralVarData, value -from pyomo.core.base.param import ScalarParam, _ParamData +from pyomo.core.base.objective import ObjectiveData, ScalarObjective +from pyomo.core.base import Expression +from pyomo.core.base.expression import ( + ScalarExpression, + NamedExpressionData, + ExpressionData, +) +from pyomo.core.base.var import ScalarVar, Var, VarData, value +from pyomo.core.base.param import ScalarParam, ParamData from pyomo.core.kernel.expression import expression, noclone from pyomo.core.kernel.variable import IVariable, variable from pyomo.core.kernel.objective import objective @@ -1136,25 +1140,25 @@ def _collect_external_fn(exp, multiplier, idMap, compute_values, verbose, quadra EXPR.RangedExpression: _collect_comparison, EXPR.EqualityExpression: _collect_comparison, EXPR.ExternalFunctionExpression: _collect_external_fn, - # _ConnectorData : _collect_linear_connector, + # ConnectorData : _collect_linear_connector, # ScalarConnector : _collect_linear_connector, - _ParamData: _collect_const, + ParamData: _collect_const, ScalarParam: _collect_const, # param.Param : _collect_linear_const, # parameter : _collect_linear_const, NumericConstant: _collect_const, - _GeneralVarData: _collect_var, + VarData: _collect_var, ScalarVar: _collect_var, Var: _collect_var, variable: _collect_var, IVariable: _collect_var, - _GeneralExpressionData: _collect_identity, + ExpressionData: _collect_identity, ScalarExpression: _collect_identity, expression: _collect_identity, noclone: _collect_identity, - _ExpressionData: _collect_identity, + NamedExpressionData: _collect_identity, Expression: _collect_identity, - _GeneralObjectiveData: _collect_identity, + ObjectiveData: _collect_identity, ScalarObjective: _collect_identity, objective: _collect_identity, } @@ -1536,24 +1540,24 @@ def _linear_collect_pow(exp, multiplier, idMap, compute_values, verbose, coef): #EXPR.EqualityExpression : _linear_collect_comparison, #EXPR.ExternalFunctionExpression : _linear_collect_external_fn, ##EXPR.LinearSumExpression : _collect_linear_sum, - ##_ConnectorData : _collect_linear_connector, + ##ConnectorData : _collect_linear_connector, ##ScalarConnector : _collect_linear_connector, - ##param._ParamData : _collect_linear_const, + ##param.ParamData : _collect_linear_const, ##param.ScalarParam : _collect_linear_const, ##param.Param : _collect_linear_const, ##parameter : _collect_linear_const, - _GeneralVarData : _linear_collect_var, + VarData : _linear_collect_var, ScalarVar : _linear_collect_var, Var : _linear_collect_var, variable : _linear_collect_var, IVariable : _linear_collect_var, - _GeneralExpressionData : _linear_collect_identity, + ExpressionData : _linear_collect_identity, ScalarExpression : _linear_collect_identity, expression : _linear_collect_identity, noclone : _linear_collect_identity, - _ExpressionData : _linear_collect_identity, + NamedExpressionData : _linear_collect_identity, Expression : _linear_collect_identity, - _GeneralObjectiveData : _linear_collect_identity, + ObjectiveData : _linear_collect_identity, ScalarObjective : _linear_collect_identity, objective : _linear_collect_identity, } diff --git a/pyomo/repn/util.py b/pyomo/repn/util.py index 1b3056738bf..8d902d0f99a 100644 --- a/pyomo/repn/util.py +++ b/pyomo/repn/util.py @@ -40,7 +40,7 @@ SortComponents, ) from pyomo.core.base.component import ActiveComponent -from pyomo.core.base.expression import _ExpressionData +from pyomo.core.base.expression import NamedExpressionData from pyomo.core.expr.numvalue import is_fixed, value import pyomo.core.expr as EXPR import pyomo.core.kernel as kernel @@ -55,7 +55,7 @@ EXPR.NPV_SumExpression, } _named_subexpression_types = ( - _ExpressionData, + NamedExpressionData, kernel.expression.expression, kernel.objective.objective, ) @@ -495,7 +495,7 @@ def categorize_valid_components( Parameters ---------- - model: _BlockData + model: BlockData The model tree to walk active: True or None @@ -516,7 +516,7 @@ def categorize_valid_components( Returns ------- - component_map: Dict[type, List[_BlockData]] + component_map: Dict[type, List[BlockData]] A dict mapping component type to a list of block data objects that contain declared component of that type. diff --git a/pyomo/solvers/plugins/solvers/cplex_persistent.py b/pyomo/solvers/plugins/solvers/cplex_persistent.py index fd396a8c87f..754dadc09e2 100644 --- a/pyomo/solvers/plugins/solvers/cplex_persistent.py +++ b/pyomo/solvers/plugins/solvers/cplex_persistent.py @@ -82,7 +82,7 @@ def update_var(self, var): Parameters ---------- - var: Var (scalar Var or single _VarData) + var: Var (scalar Var or single VarData) """ # see PR #366 for discussion about handling indexed @@ -130,7 +130,7 @@ def _add_column(self, var, obj_coef, constraints, coefficients): Parameters ---------- - var: Var (scalar Var or single _VarData) + var: Var (scalar Var or single VarData) obj_coef: float constraints: list of solver constraints coefficients: list of coefficients to put on var in the associated constraint diff --git a/pyomo/solvers/plugins/solvers/direct_or_persistent_solver.py b/pyomo/solvers/plugins/solvers/direct_or_persistent_solver.py index c131b8ad10a..de38a0372d0 100644 --- a/pyomo/solvers/plugins/solvers/direct_or_persistent_solver.py +++ b/pyomo/solvers/plugins/solvers/direct_or_persistent_solver.py @@ -10,7 +10,7 @@ # ___________________________________________________________________________ from pyomo.core.base.PyomoModel import Model -from pyomo.core.base.block import Block, _BlockData +from pyomo.core.base.block import Block, BlockData from pyomo.core.kernel.block import IBlock from pyomo.opt.base.solvers import OptSolver from pyomo.core.base import SymbolMap, NumericLabeler, TextLabeler @@ -177,7 +177,7 @@ def _postsolve(self): """ This method should be implemented by subclasses.""" def _set_instance(self, model, kwds={}): - if not isinstance(model, (Model, IBlock, Block, _BlockData)): + if not isinstance(model, (Model, IBlock, Block, BlockData)): msg = ( "The problem instance supplied to the {0} plugin " "'_presolve' method must be a Model or a Block".format(type(self)) diff --git a/pyomo/solvers/plugins/solvers/direct_solver.py b/pyomo/solvers/plugins/solvers/direct_solver.py index 3eab658391c..609a81b2018 100644 --- a/pyomo/solvers/plugins/solvers/direct_solver.py +++ b/pyomo/solvers/plugins/solvers/direct_solver.py @@ -15,7 +15,7 @@ from pyomo.solvers.plugins.solvers.direct_or_persistent_solver import ( DirectOrPersistentSolver, ) -from pyomo.core.base.block import _BlockData +from pyomo.core.base.block import BlockData from pyomo.core.kernel.block import IBlock from pyomo.core.base.suffix import active_import_suffix_generator from pyomo.core.kernel.suffix import import_suffix_generator @@ -79,8 +79,8 @@ def solve(self, *args, **kwds): # _model = None for arg in args: - if isinstance(arg, (_BlockData, IBlock)): - if isinstance(arg, _BlockData): + if isinstance(arg, (BlockData, IBlock)): + if isinstance(arg, BlockData): if not arg.is_constructed(): raise RuntimeError( "Attempting to solve model=%s with unconstructed " @@ -89,7 +89,7 @@ def solve(self, *args, **kwds): _model = arg # import suffixes must be on the top-level model - if isinstance(arg, _BlockData): + if isinstance(arg, BlockData): model_suffixes = list( name for (name, comp) in active_import_suffix_generator(arg) ) diff --git a/pyomo/solvers/plugins/solvers/gurobi_persistent.py b/pyomo/solvers/plugins/solvers/gurobi_persistent.py index 4522a2151c3..94a2ac6b734 100644 --- a/pyomo/solvers/plugins/solvers/gurobi_persistent.py +++ b/pyomo/solvers/plugins/solvers/gurobi_persistent.py @@ -111,7 +111,7 @@ def update_var(self, var): Parameters ---------- - var: Var (scalar Var or single _VarData) + var: Var (scalar Var or single VarData) """ # see PR #366 for discussion about handling indexed @@ -157,7 +157,7 @@ def set_linear_constraint_attr(self, con, attr, val): Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The pyomo constraint for which the corresponding gurobi constraint attribute should be modified. attr: str @@ -192,7 +192,7 @@ def set_var_attr(self, var, attr, val): Parameters ---------- - con: pyomo.core.base.var._GeneralVarData + con: pyomo.core.base.var.VarData The pyomo var for which the corresponding gurobi var attribute should be modified. attr: str @@ -342,7 +342,7 @@ def get_var_attr(self, var, attr): Parameters ---------- - var: pyomo.core.base.var._GeneralVarData + var: pyomo.core.base.var.VarData The pyomo var for which the corresponding gurobi var attribute should be retrieved. attr: str @@ -384,7 +384,7 @@ def get_linear_constraint_attr(self, con, attr): Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The pyomo constraint for which the corresponding gurobi constraint attribute should be retrieved. attr: str @@ -413,7 +413,7 @@ def get_sos_attr(self, con, attr): Parameters ---------- - con: pyomo.core.base.sos._SOSConstraintData + con: pyomo.core.base.sos.SOSConstraintData The pyomo SOS constraint for which the corresponding gurobi SOS constraint attribute should be retrieved. attr: str @@ -431,7 +431,7 @@ def get_quadratic_constraint_attr(self, con, attr): Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The pyomo constraint for which the corresponding gurobi constraint attribute should be retrieved. attr: str @@ -569,7 +569,7 @@ def cbCut(self, con): Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The cut to add """ if not con.active: @@ -647,7 +647,7 @@ def cbLazy(self, con): """ Parameters ---------- - con: pyomo.core.base.constraint._GeneralConstraintData + con: pyomo.core.base.constraint.ConstraintData The lazy constraint to add """ if not con.active: @@ -710,7 +710,7 @@ def _add_column(self, var, obj_coef, constraints, coefficients): Parameters ---------- - var: Var (scalar Var or single _VarData) + var: Var (scalar Var or single VarData) obj_coef: float constraints: list of solver constraints coefficients: list of coefficients to put on var in the associated constraint diff --git a/pyomo/solvers/plugins/solvers/mosek_direct.py b/pyomo/solvers/plugins/solvers/mosek_direct.py index f4225651907..025c71d36f0 100644 --- a/pyomo/solvers/plugins/solvers/mosek_direct.py +++ b/pyomo/solvers/plugins/solvers/mosek_direct.py @@ -555,7 +555,7 @@ def _add_block(self, block): Parameters ---------- - block: Block (scalar Block or single _BlockData) + block: Block (scalar Block or single BlockData) """ var_seq = tuple( block.component_data_objects( diff --git a/pyomo/solvers/plugins/solvers/mosek_persistent.py b/pyomo/solvers/plugins/solvers/mosek_persistent.py index 97f88e0cb9a..efcbb7dd9dd 100644 --- a/pyomo/solvers/plugins/solvers/mosek_persistent.py +++ b/pyomo/solvers/plugins/solvers/mosek_persistent.py @@ -85,7 +85,7 @@ def add_constraints(self, con_seq): Parameters ---------- - con_seq: tuple/list of Constraint (scalar Constraint or single _ConstraintData) + con_seq: tuple/list of Constraint (scalar Constraint or single ConstraintData) """ self._add_constraints(con_seq) @@ -95,7 +95,7 @@ def remove_var(self, solver_var): This will keep any other model components intact. Parameters ---------- - solver_var: Var (scalar Var or single _VarData) + solver_var: Var (scalar Var or single VarData) """ self.remove_vars(solver_var) @@ -106,7 +106,7 @@ def remove_vars(self, *solver_vars): This will keep any other model components intact. Parameters ---------- - *solver_var: Var (scalar Var or single _VarData) + *solver_var: Var (scalar Var or single VarData) """ try: var_ids = [] @@ -137,7 +137,7 @@ def remove_constraint(self, solver_con): To remove a conic-domain, you should use the remove_block method. Parameters ---------- - solver_con: Constraint (scalar Constraint or single _ConstraintData) + solver_con: Constraint (scalar Constraint or single ConstraintData) """ self.remove_constraints(solver_con) @@ -151,7 +151,7 @@ def remove_constraints(self, *solver_cons): Parameters ---------- - *solver_cons: Constraint (scalar Constraint or single _ConstraintData) + *solver_cons: Constraint (scalar Constraint or single ConstraintData) """ lq_cons = tuple( itertools.filterfalse(lambda x: isinstance(x, _ConicBase), solver_cons) @@ -205,7 +205,7 @@ def update_vars(self, *solver_vars): changing variable types and bounds. Parameters ---------- - *solver_var: Constraint (scalar Constraint or single _ConstraintData) + *solver_var: Constraint (scalar Constraint or single ConstraintData) """ try: var_ids = [] diff --git a/pyomo/solvers/plugins/solvers/persistent_solver.py b/pyomo/solvers/plugins/solvers/persistent_solver.py index 29aa3f2bbf5..3c2a9e52eab 100644 --- a/pyomo/solvers/plugins/solvers/persistent_solver.py +++ b/pyomo/solvers/plugins/solvers/persistent_solver.py @@ -12,7 +12,7 @@ from pyomo.solvers.plugins.solvers.direct_or_persistent_solver import ( DirectOrPersistentSolver, ) -from pyomo.core.base.block import _BlockData +from pyomo.core.base.block import BlockData from pyomo.core.kernel.block import IBlock from pyomo.core.base.suffix import active_import_suffix_generator from pyomo.core.kernel.suffix import import_suffix_generator @@ -96,7 +96,7 @@ def add_block(self, block): Parameters ---------- - block: Block (scalar Block or single _BlockData) + block: Block (scalar Block or single BlockData) """ if self._pyomo_model is None: @@ -132,7 +132,7 @@ def add_constraint(self, con): Parameters ---------- - con: Constraint (scalar Constraint or single _ConstraintData) + con: Constraint (scalar Constraint or single ConstraintData) """ if self._pyomo_model is None: @@ -206,9 +206,9 @@ def add_column(self, model, var, obj_coef, constraints, coefficients): Parameters ---------- model: pyomo ConcreteModel to which the column will be added - var: Var (scalar Var or single _VarData) + var: Var (scalar Var or single VarData) obj_coef: float, pyo.Param - constraints: list of scalar Constraints of single _ConstraintDatas + constraints: list of scalar Constraints of single ConstraintDatas coefficients: list of the coefficient to put on var in the associated constraint """ @@ -295,7 +295,7 @@ def remove_block(self, block): Parameters ---------- - block: Block (scalar Block or a single _BlockData) + block: Block (scalar Block or a single BlockData) """ # see PR #366 for discussion about handling indexed @@ -328,7 +328,7 @@ def remove_constraint(self, con): Parameters ---------- - con: Constraint (scalar Constraint or single _ConstraintData) + con: Constraint (scalar Constraint or single ConstraintData) """ # see PR #366 for discussion about handling indexed @@ -380,7 +380,7 @@ def remove_var(self, var): Parameters ---------- - var: Var (scalar Var or single _VarData) + var: Var (scalar Var or single VarData) """ # see PR #366 for discussion about handling indexed @@ -455,7 +455,7 @@ def solve(self, *args, **kwds): self.available(exception_flag=True) # Collect suffix names to try and import from solution. - if isinstance(self._pyomo_model, _BlockData): + if isinstance(self._pyomo_model, BlockData): model_suffixes = list( name for (name, comp) in active_import_suffix_generator(self._pyomo_model) diff --git a/pyomo/solvers/plugins/solvers/xpress_persistent.py b/pyomo/solvers/plugins/solvers/xpress_persistent.py index 513a7fbc257..fbdc2866dcf 100644 --- a/pyomo/solvers/plugins/solvers/xpress_persistent.py +++ b/pyomo/solvers/plugins/solvers/xpress_persistent.py @@ -90,7 +90,7 @@ def update_var(self, var): Parameters ---------- - var: Var (scalar Var or single _VarData) + var: Var (scalar Var or single VarData) """ # see PR #366 for discussion about handling indexed @@ -124,7 +124,7 @@ def _add_column(self, var, obj_coef, constraints, coefficients): Parameters ---------- - var: Var (scalar Var or single _VarData) + var: Var (scalar Var or single VarData) obj_coef: float constraints: list of solver constraints coefficients: list of coefficients to put on var in the associated constraint diff --git a/pyomo/solvers/tests/checks/test_CPLEXPersistent.py b/pyomo/solvers/tests/checks/test_CPLEXPersistent.py index 91a60eee9dd..442212d4fbb 100644 --- a/pyomo/solvers/tests/checks/test_CPLEXPersistent.py +++ b/pyomo/solvers/tests/checks/test_CPLEXPersistent.py @@ -101,7 +101,7 @@ def test_add_column_exceptions(self): # add indexed constraint self.assertRaises(AttributeError, opt.add_column, m, m.y, -2, [m.ci], [1]) - # add something not a _ConstraintData + # add something not a ConstraintData self.assertRaises(AttributeError, opt.add_column, m, m.y, -2, [m.x], [1]) # constraint not on solver model diff --git a/pyomo/solvers/tests/checks/test_gurobi_persistent.py b/pyomo/solvers/tests/checks/test_gurobi_persistent.py index a2c089207e5..812390c23a4 100644 --- a/pyomo/solvers/tests/checks/test_gurobi_persistent.py +++ b/pyomo/solvers/tests/checks/test_gurobi_persistent.py @@ -382,7 +382,7 @@ def test_add_column_exceptions(self): # add indexed constraint self.assertRaises(AttributeError, opt.add_column, m, m.y, -2, [m.ci], [1]) - # add something not a _ConstraintData + # add something not a ConstraintData self.assertRaises(AttributeError, opt.add_column, m, m.y, -2, [m.x], [1]) # constraint not on solver model diff --git a/pyomo/solvers/tests/checks/test_xpress_persistent.py b/pyomo/solvers/tests/checks/test_xpress_persistent.py index ddae860cd92..dcd36780f62 100644 --- a/pyomo/solvers/tests/checks/test_xpress_persistent.py +++ b/pyomo/solvers/tests/checks/test_xpress_persistent.py @@ -262,7 +262,7 @@ def test_add_column_exceptions(self): # add indexed constraint self.assertRaises(AttributeError, opt.add_column, m, m.y, -2, [m.ci], [1]) - # add something not a _ConstraintData + # add something not a ConstraintData self.assertRaises(AttributeError, opt.add_column, m, m.y, -2, [m.x], [1]) # constraint not on solver model diff --git a/pyomo/util/calc_var_value.py b/pyomo/util/calc_var_value.py index b5e620fea07..42ee3119361 100644 --- a/pyomo/util/calc_var_value.py +++ b/pyomo/util/calc_var_value.py @@ -12,7 +12,7 @@ from pyomo.common.errors import IterationLimitError from pyomo.common.numeric_types import native_numeric_types, native_complex_types, value from pyomo.core.expr.calculus.derivatives import differentiate -from pyomo.core.base.constraint import Constraint, _ConstraintData +from pyomo.core.base.constraint import Constraint import logging @@ -53,9 +53,9 @@ def calculate_variable_from_constraint( Parameters: ----------- - variable: :py:class:`_VarData` + variable: :py:class:`VarData` The variable to solve for - constraint: :py:class:`_ConstraintData` or relational expression or `tuple` + constraint: :py:class:`ConstraintData` or relational expression or `tuple` The equality constraint to use to solve for the variable value. May be a `ConstraintData` object or any valid argument for ``Constraint(expr=<>)`` (i.e., a relational expression or 2- or @@ -81,10 +81,17 @@ def calculate_variable_from_constraint( """ # Leverage all the Constraint logic to process the incoming tuple/expression - if not isinstance(constraint, _ConstraintData): + if not getattr(constraint, 'ctype', None) is Constraint: constraint = Constraint(expr=constraint, name=type(constraint).__name__) constraint.construct() + if constraint.is_indexed(): + raise ValueError( + 'calculate_variable_from_constraint(): constraint must be a ' + 'scalar constraint or a single ConstraintData. Received ' + f'{constraint.__class__.__name__} ("{constraint.name}")' + ) + body = constraint.body lower = constraint.lb upper = constraint.ub diff --git a/pyomo/util/report_scaling.py b/pyomo/util/report_scaling.py index 201319ea92a..02b3710c334 100644 --- a/pyomo/util/report_scaling.py +++ b/pyomo/util/report_scaling.py @@ -11,9 +11,9 @@ import pyomo.environ as pyo import math -from pyomo.core.base.block import _BlockData +from pyomo.core.base.block import BlockData from pyomo.common.collections import ComponentSet -from pyomo.core.base.var import _GeneralVarData +from pyomo.core.base.var import Var from pyomo.contrib.fbbt.fbbt import compute_bounds_on_expr from pyomo.core.expr.calculus.diff_with_pyomo import reverse_sd import logging @@ -42,7 +42,7 @@ def _print_var_set(var_set): return s -def _check_var_bounds(m: _BlockData, too_large: float): +def _check_var_bounds(m: BlockData, too_large: float): vars_without_bounds = ComponentSet() vars_with_large_bounds = ComponentSet() for v in m.component_data_objects(pyo.Var, descend_into=True): @@ -73,7 +73,7 @@ def _check_coefficients( ): ders = reverse_sd(expr) for _v, _der in ders.items(): - if isinstance(_v, _GeneralVarData): + if getattr(_v, 'ctype', None) is Var: if _v.is_fixed(): continue der_lb, der_ub = compute_bounds_on_expr(_der) @@ -90,7 +90,7 @@ def _check_coefficients( def report_scaling( - m: _BlockData, too_large: float = 5e4, too_small: float = 1e-6 + m: BlockData, too_large: float = 5e4, too_small: float = 1e-6 ) -> bool: """ This function logs potentially poorly scaled parts of the model. @@ -107,7 +107,7 @@ def report_scaling( Parameters ---------- - m: _BlockData + m: BlockData The pyomo model or block too_large: float Values above too_large will generate a log entry diff --git a/pyomo/util/slices.py b/pyomo/util/slices.py index 53f6d364219..d85aa3fa926 100644 --- a/pyomo/util/slices.py +++ b/pyomo/util/slices.py @@ -98,7 +98,7 @@ def slice_component_along_sets(comp, sets, context=None): sets: `pyomo.common.collections.ComponentSet` Contains the sets to replace with slices context: `pyomo.core.base.block.Block` or - `pyomo.core.base.block._BlockData` + `pyomo.core.base.block.BlockData` Block below which to search for sets Returns: diff --git a/pyomo/util/tests/test_calc_var_value.py b/pyomo/util/tests/test_calc_var_value.py index a02d7a7d838..4bed4d5c843 100644 --- a/pyomo/util/tests/test_calc_var_value.py +++ b/pyomo/util/tests/test_calc_var_value.py @@ -101,6 +101,15 @@ def test_initialize_value(self): ): calculate_variable_from_constraint(m.x, m.lt) + m.indexed = Constraint([1, 2], rule=lambda m, i: m.x <= i) + with self.assertRaisesRegex( + ValueError, + r"calculate_variable_from_constraint\(\): constraint must be a scalar " + r"constraint or a single ConstraintData. Received IndexedConstraint " + r'\("indexed"\)', + ): + calculate_variable_from_constraint(m.x, m.indexed) + def test_linear(self): m = ConcreteModel() m.x = Var()