diff --git a/src/omlt/base/var.py b/src/omlt/base/var.py index e1f7e6bc..d2cc0928 100644 --- a/src/omlt/base/var.py +++ b/src/omlt/base/var.py @@ -67,23 +67,6 @@ def tanh(self): class OmltVar(ABC): - # @abstractmethod - # def construct(self, data): - # """Construct the variable.""" - - # @abstractmethod - # def is_constructed(self): - # """Return True if the variable has been constructed.""" - - # @abstractmethod - # def fix(self, value, *, skip_validation=False): - # """Fix the value of the variable.""" - - # @property - # @abstractmethod - # def ctype(self): - # """Return the type of the variable.""" - @property @abstractmethod def name(self): @@ -112,17 +95,6 @@ def __init__(self, binary=False): # noqa: ARG002, FBT002 def is_indexed(self): return False - # Bound-setting interface for scalar variables: - # @property - # @abstractmethod - # def bounds(self): - # """Return a tuple with the lower and upper bounds.""" - - # @bounds.setter - # @abstractmethod - # def bounds(self, val): - # """Set lower and upper bounds to the given tuple.""" - @property @abstractmethod def lb(self): @@ -213,20 +185,6 @@ class OmltIndexed(OmltVar): def is_indexed(self): return True - # @property - # @abstractmethod - # def index_set(self): - # """Return the index set for the variable.""" - - # # Bound-setting interface for indexed variables: - # @abstractmethod - # def setub(self, value): - # """Set upper bounds on all component variables.""" - - # @abstractmethod - # def setlb(self, value): - # """Set lower bounds on all component variables.""" - # Interface: act as a dict for the sub-variables. @abstractmethod def __getitem__(self, item): diff --git a/src/omlt/block.py b/src/omlt/block.py index 0a3f0e10..2cefb87f 100644 --- a/src/omlt/block.py +++ b/src/omlt/block.py @@ -94,6 +94,12 @@ def build_formulation(self, formulation, lang=None): if lang is not None: self._format = lang + if self._format != DEFAULT_MODELING_LANGUAGE and formulation.pyomo_only: + msg = ( + f"OMLT does not support building {formulation} with modeling languages" + " other than Pyomo." + ) + self._setup_inputs_outputs( input_indexes=list(formulation.input_indexes), output_indexes=list(formulation.output_indexes), diff --git a/src/omlt/formulation.py b/src/omlt/formulation.py index 6d1161f4..6211627b 100644 --- a/src/omlt/formulation.py +++ b/src/omlt/formulation.py @@ -55,6 +55,16 @@ def _build_formulation(self): corresponding mathematical formulation of the model. """ + @property + @abc.abstractmethod + def pyomo_only(self): + """Pyomo Only. + + Return True if this formulation can only be built on a Pyomo + block, and False if it can be built on blocks using other + modeling languages. + """ + class _PyomoFormulation(_PyomoFormulationInterface): """Pyomo Formulation. diff --git a/src/omlt/gbt/gbt_formulation.py b/src/omlt/gbt/gbt_formulation.py index e126e4b8..905343d4 100644 --- a/src/omlt/gbt/gbt_formulation.py +++ b/src/omlt/gbt/gbt_formulation.py @@ -62,6 +62,9 @@ def _build_formulation(self): output_vars=self.block.scaled_outputs, ) + @property + def pyomo_only(self): + return True def add_formulation_to_block(block, model_definition, input_vars, output_vars): # noqa: C901, PLR0912, PLR0915 r"""Adds the gradient-boosted trees formulation to the given Pyomo block. diff --git a/src/omlt/linear_tree/lt_formulation.py b/src/omlt/linear_tree/lt_formulation.py index 581719e4..4ac1cd1c 100644 --- a/src/omlt/linear_tree/lt_formulation.py +++ b/src/omlt/linear_tree/lt_formulation.py @@ -109,6 +109,10 @@ def _build_formulation(self): include_leaf_equalities=True, ) + @property + def pyomo_only(self): + return True + class LinearTreeHybridBigMFormulation(_PyomoFormulation): r"""Class to add a Linear Tree Hybrid Big-M formulation to OmltBlock. @@ -165,6 +169,10 @@ def output_indexes(self): """The indexes of the formulation output.""" return list(range(self.model_definition.n_outputs)) + @property + def pyomo_only(self): + return True + def _build_formulation(self): """Build formulation. diff --git a/src/omlt/neuralnet/nn_formulation.py b/src/omlt/neuralnet/nn_formulation.py index 406467dc..98460bf7 100644 --- a/src/omlt/neuralnet/nn_formulation.py +++ b/src/omlt/neuralnet/nn_formulation.py @@ -140,6 +140,10 @@ def output_indexes(self): raise ValueError(MULTI_OUTPUTS_UNSUPPORTED) return network_outputs[0].output_indexes + @property + def pyomo_only(self): + return False + def _build_neural_network_formulation( # noqa: C901,PLR0912,PLR0915 block, network_structure, layer_constraints, activation_constraints @@ -325,6 +329,10 @@ def _supported_default_activation_constraints(self): "relu": ComplementarityReLUActivation(), } + @property + def pyomo_only(self): + return True + class ReducedSpaceNNFormulation(_PyomoFormulation): """Reduced Space Neural Network Formulation. @@ -475,6 +483,10 @@ def output_indexes(self): raise ValueError(MULTI_OUTPUTS_UNSUPPORTED) return network_outputs[0].output_indexes + @property + def pyomo_only(self): + return False + class ReducedSpaceSmoothNNFormulation(ReducedSpaceNNFormulation): """Reduced Space Smooth Neural Network Formulation. @@ -659,3 +671,7 @@ def output_indexes(self): if len(network_outputs) != 1: raise ValueError(MULTI_OUTPUTS_UNSUPPORTED) return network_outputs[0].output_indexes + + @property + def pyomo_only(self): + return False