def test_potentially_variable(self): p = parameter() self.assertEqual(p.is_potentially_variable(), False) self.assertEqual(potentially_variable(p), False) p.value = 1.0 self.assertEqual(p.is_potentially_variable(), False) self.assertEqual(potentially_variable(p), False)
def test_potentially_variable(self): v = variable() self.assertEqual(v.is_potentially_variable(), True) self.assertEqual(potentially_variable(v), True) self.assertEqual(v.fixed, False) self.assertEqual(v.value, None) v.value = 1.0 self.assertEqual(v.is_potentially_variable(), True) self.assertEqual(potentially_variable(v), True) self.assertEqual(v.fixed, False) self.assertEqual(v.value, 1.0) v.fix() self.assertEqual(v.is_potentially_variable(), True) self.assertEqual(potentially_variable(v), True) self.assertEqual(v.fixed, True) self.assertEqual(v.value, 1.0) v.value = None self.assertEqual(v.is_potentially_variable(), True) self.assertEqual(potentially_variable(v), True) self.assertEqual(v.fixed, True) self.assertEqual(v.value, None) v.free() self.assertEqual(v.is_potentially_variable(), True) self.assertEqual(potentially_variable(v), True) self.assertEqual(v.fixed, False) self.assertEqual(v.value, None)
def testis_potentially_variable(self): e = noclone(variable()) self.assertEqual(e.is_potentially_variable(), True) self.assertEqual(potentially_variable(e), True) e = noclone(parameter()) self.assertEqual(e.is_potentially_variable(), False) self.assertEqual(potentially_variable(e), False) e = noclone(expression()) self.assertEqual(e.is_potentially_variable(), True) self.assertEqual(potentially_variable(e), True) e = noclone(data_expression()) self.assertEqual(e.is_potentially_variable(), False) self.assertEqual(potentially_variable(e), False)
def testis_potentially_variable(self): e = self._ctype_factory() self.assertEqual(e.is_potentially_variable(), True) self.assertEqual(potentially_variable(e), True) e.expr = 1 self.assertEqual(e.is_potentially_variable(), True) self.assertEqual(potentially_variable(e), True) v = variable() v.value = 2 e.expr = v + 1 self.assertEqual(e.is_potentially_variable(), True) self.assertEqual(potentially_variable(e), True) v.fix() e.expr = v + 1 self.assertEqual(e.is_potentially_variable(), True) self.assertEqual(potentially_variable(e), True) self.assertEqual(e(), 3)
def testis_potentially_variable(self): e = self._ctype_factory() self.assertEqual(e.is_potentially_variable(), False) self.assertEqual(potentially_variable(e), False) e.expr = 1 self.assertEqual(e.is_potentially_variable(), False) self.assertEqual(potentially_variable(e), False) p = parameter() e.expr = p**2 self.assertEqual(e.is_potentially_variable(), False) self.assertEqual(potentially_variable(e), False) a = self._ctype_factory() e.expr = (a * p)**2 / (p + 5) self.assertEqual(e.is_potentially_variable(), False) self.assertEqual(potentially_variable(e), False) a.expr = 2.0 p.value = 5.0 self.assertEqual(e.is_potentially_variable(), False) self.assertEqual(potentially_variable(e), False) self.assertEqual(e(), 10.0) v = variable() with self.assertRaises(ValueError): e.expr = v + 1
def __init__(self, variables, weights=None, level=1): self._parent = None self._active = True self._variables = tuple(variables) self._weights = None self._level = level if weights is None: self._weights = tuple(range(1, len(self._variables) + 1)) else: self._weights = tuple(weights) for w in self._weights: if potentially_variable(w): raise ValueError( "Weights for Special Ordered Sets must be " "expressions restricted to data") assert len(self._variables) == len(self._weights) assert self._level >= 1
def expr(self, expr): self._equality = False if expr is None: self.body = None self.lb = None self.ub = None return _expr_type = expr.__class__ if _expr_type is tuple: # # Form equality expression # if len(expr) == 2: arg0 = expr[0] if arg0 is not None: arg0 = as_numeric(arg0) arg1 = expr[1] if arg1 is not None: arg1 = as_numeric(arg1) # assigning to the rhs property # will set the equality flag to True if (arg1 is None) or (not arg1.is_potentially_variable()): self.rhs = arg1 self.body = arg0 elif (arg0 is None) or (not arg0.is_potentially_variable()): self.rhs = arg0 self.body = arg1 else: self.rhs = ZeroConstant self.body = arg0 self.body -= arg1 # # Form inequality expression # elif len(expr) == 3: arg0 = expr[0] if arg0 is not None: if potentially_variable(arg0): raise ValueError( "Constraint '%s' found a 3-tuple (lower," " expression, upper) but the lower " "value was not data or an expression " "restricted to storage of data." % (self.name)) arg1 = expr[1] if arg1 is not None: arg1 = as_numeric(arg1) arg2 = expr[2] if arg2 is not None: if potentially_variable(arg2): raise ValueError( "Constraint '%s' found a 3-tuple (lower," " expression, upper) but the upper " "value was not data or an expression " "restricted to storage of data." % (self.name)) self.lb = arg0 self.body = arg1 self.ub = arg2 else: raise ValueError( "Constraint '%s' assigned a tuple " "of length %d. Expecting a tuple of " "length 2 or 3:\n" "Equality: (body, rhs)\n" "Inequality: (lb, body, ub)" % (self.name, len(expr))) relational_expr = False else: try: relational_expr = expr.is_relational() if not relational_expr: raise ValueError( "Constraint '%s' does not have a proper " "value. Found '%s'\nExpecting a tuple or " "equation. Examples:" "\n sum_product(model.costs) == model.income" "\n (0, model.price[item], 50)" % (self.name, str(expr))) except AttributeError: msg = ("Constraint '%s' does not have a proper " "value. Found '%s'\nExpecting a tuple or " "equation. Examples:" "\n sum_product(model.costs) == model.income" "\n (0, model.price[item], 50)" % (self.name, str(expr))) if type(expr) is bool: msg += ("\nNote: constant Boolean expressions " "are not valid constraint expressions. " "Some apparently non-constant compound " "inequalities (e.g. 'expr >= 0 <= 1') " "can return boolean values; the proper " "form for compound inequalities is " "always 'lb <= expr <= ub'.") raise ValueError(msg) # # Special check for chainedInequality errors like "if var < # 1:" within rules. Catching them here allows us to provide # the user with better (and more immediate) debugging # information. We don't want to check earlier because we # want to provide a specific debugging message if the # construction rule returned True/False; for example, if the # user did ( var < 1 > 0 ) (which also results in a non-None # chainedInequality value) # if EXPR._using_chained_inequality and \ (EXPR._chainedInequality.prev is not None): raise TypeError(EXPR._chainedInequality.error_message()) # # Process relational expressions # (i.e. explicit '==', '<', and '<=') # if relational_expr: if _expr_type is EXPR.EqualityExpression: # assigning to the rhs property # will set the equality flag to True if not potentially_variable(expr.arg(1)): self.rhs = expr.arg(1) self.body = expr.arg(0) elif not potentially_variable(expr.arg(0)): self.rhs = expr.arg(0) self.body = expr.arg(1) else: self.rhs = ZeroConstant self.body = expr.arg(0) self.body -= expr.arg(1) elif _expr_type is EXPR.InequalityExpression: if expr._strict: raise ValueError( "Constraint '%s' encountered a strict " "inequality expression ('>' or '<'). All" " constraints must be formulated using " "using '<=', '>=', or '=='." % (self.name)) if not potentially_variable(expr.arg(1)): self.lb = None self.body = expr.arg(0) self.ub = expr.arg(1) elif not potentially_variable(expr.arg(0)): self.lb = expr.arg(0) self.body = expr.arg(1) self.ub = None else: self.lb = None self.body = expr.arg(0) self.body -= expr.arg(1) self.ub = ZeroConstant else: # RangedExpression if any(expr._strict): raise ValueError( "Constraint '%s' encountered a strict " "inequality expression ('>' or '<'). All" " constraints must be formulated using " "using '<=', '>=', or '=='." % (self.name)) if potentially_variable(expr.arg(0)): raise ValueError( "Constraint '%s' found a double-sided " "inequality expression (lower <= " "expression <= upper) but the lower " "bound was not data or an expression " "restricted to storage of data." % (self.name)) if potentially_variable(expr.arg(2)): raise ValueError( "Constraint '%s' found a double-sided "\ "inequality expression (lower <= " "expression <= upper) but the upper " "bound was not data or an expression " "restricted to storage of data." % (self.name)) self.lb = expr.arg(0) self.body = expr.arg(1) self.ub = expr.arg(2) # # Error check, to ensure that we don't have an equality # constraint with 'infinite' RHS # assert not (self.equality and (self.lb is None)) assert (not self.equality) or (self.lb is self.ub)
def is_potentially_variable(self): """A boolean indicating whether this expression can reference variables.""" return potentially_variable(self._expr)
def expr(self, expr): if potentially_variable(expr): raise ValueError("Expression is not restricted to data.") self._expr = expr