source: coopr.pyomo/stable/2.2/coopr/pyomo/base/constraint.py @ 2194

Revision 2194, 23.0 KB checked in by wehart, 4 years ago (diff)

Merged revisions 2112-2193 via svnmerge from
 https://software.sandia.gov/svn/public/coopr/coopr.pyomo/trunk

........

r2122 | wehart | 2010-01-02 23:44:52 -0700 (Sat, 02 Jan 2010) | 2 lines


Adding methods to clear objective/constraint data.

........

r2125 | wehart | 2010-01-03 17:00:33 -0700 (Sun, 03 Jan 2010) | 10 lines


Extended collection of linear terms to ignore identity expressions in a
ProductExpression?.


Misc documentation update in Pyomo.


If there is no rule, then Constraint.construct() does _not_ clear the constraint
set. This had the unfortunate side-effect that user-added constraints are
cleared!

........

r2128 | wehart | 2010-01-03 23:59:03 -0700 (Sun, 03 Jan 2010) | 4 lines


Adding the @set_options decorator, which can be used
to specify options for temporary sets that are defined by
index functions.

........

r2129 | jwatson | 2010-01-04 15:41:02 -0700 (Mon, 04 Jan 2010) | 7 lines


I have changed the setitem interface for the variable base class to allow invocations of the following form:


var[None] = some_value


In cases where the variable Var is a singleton, i.e., non-indexed. This slight abuse of syntax is extremely useful in PH (and anywhere else where we have automated manipulation of variable values), as it avoids the needs for around 15 if-then statements.

........

r2130 | jwatson | 2010-01-04 16:03:42 -0700 (Mon, 04 Jan 2010) | 3 lines


Mirroring previous commit for singleton (non-indexed) parameters, allowing set via param[None].

........

r2133 | wehart | 2010-01-07 08:03:46 -0700 (Thu, 07 Jan 2010) | 2 lines


A draft implementation of expressions for intrinsic functions.

........

r2142 | wehart | 2010-01-11 18:47:07 -0700 (Mon, 11 Jan 2010) | 2 lines


Bug fix. Parameter indices do not have a keys() attribute.

........

r2145 | wehart | 2010-01-11 22:03:47 -0700 (Mon, 11 Jan 2010) | 6 lines


A stab at refactoring the pyomo command-line script, to make
it easier to write related scripts.


Unfortunately, I started doing this with a Jython installation, which
has some issues running PyUtilib?. Thus, this is not well-tested.

........

r2146 | wehart | 2010-01-11 22:19:42 -0700 (Mon, 11 Jan 2010) | 2 lines


Other updates from my laptop...

........

r2147 | wehart | 2010-01-11 22:44:35 -0700 (Mon, 11 Jan 2010) | 2 lines


Fixing bugs

........

r2148 | wehart | 2010-01-11 23:16:37 -0700 (Mon, 11 Jan 2010) | 2 lines


Bug fixes and pyomo command tests.

........

r2159 | wehart | 2010-01-13 14:59:23 -0700 (Wed, 13 Jan 2010) | 2 lines


Updates to reconfigure how files are written out by Pyomo.

........

r2160 | wehart | 2010-01-13 16:09:28 -0700 (Wed, 13 Jan 2010) | 6 lines


Adding the pyomo2lp and pyomo2nl commands.
Setting up the convert.py module, which is used in these commands.
Various fixes to scripting utilities: fixed management of
traceback functions, and reworked the processing of the save_model
option.

........

r2161 | jwatson | 2010-01-13 22:38:15 -0700 (Wed, 13 Jan 2010) | 3 lines


Cut the run-time of the PyomoModel? _load_solution method by 2/3 - it's still taking too long, but even this improvement is noticeable.

........

r2163 | wehart | 2010-01-19 22:08:40 -0700 (Tue, 19 Jan 2010) | 2 lines


Adding diagnostic output.

........

r2166 | jwatson | 2010-01-24 13:51:15 -0700 (Sun, 24 Jan 2010) | 5 lines


Allowing PyomoModel? to load a solver results object with a status equal to "Warning" - the old version threw an exception if the solver status wasn't OK.


The new version does print a warning message indicating that you are loading a solver with a warning, and that the user should take a look.

........

r2170 | wehart | 2010-01-25 16:35:49 -0700 (Mon, 25 Jan 2010) | 6 lines


A rework of the NL/LP file writers. This now uses the
canonical expression representation. I'm pretty sure that the LP writer
is OK, but much less sure about the NL writer. Also, it's clear that we don't
have adequate tests of the writers to ensure that all different types of
models are written correctly.

........

Line 
1#  _________________________________________________________________________
2#
3#  Coopr: A COmmon Optimization Python Repository
4#  Copyright (c) 2008 Sandia Corporation.
5#  This software is distributed under the BSD License.
6#  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
7#  the U.S. Government retains certain rights in this software.
8#  For more information, see the Coopr README.txt file.
9#  _________________________________________________________________________
10
11__all__ = ['Objective', 'Constraint']
12
13from numvalue import *
14from numvalue import create_name
15from expr import *
16from plugin import ComponentRegistration
17import pyomo
18from var import Var, _VarValue
19from indexed_component import IndexedComponent
20from sets import _BaseSet
21import pyutilib.misc
22import pyutilib.math
23from numtypes import *
24import sys
25from set_types import *
26
27
28class ObjectiveData(NumericValue):
29
30    def __init__(self, expr=None, name=None):
31        NumericValue.__init__(self,name=name,domain=Reals)
32        self.expr = expr
33        self.label = None
34        self.id = -1
35        self.active = True
36
37    def __call__(self, exception=True):
38        if self.expr is None:
39            return None
40        return self.expr()
41
42    def activate(self):
43        self.active=True
44
45    def deactivate(self):
46        self.active=False
47
48
49class Objective(NumericValue, IndexedComponent):
50    """An object that defines a objective expression"""
51
52    def __init__(self, *args, **kwd):
53        """Construct an objective expression with rule to construct the
54           expression
55        """
56        tkwd = {'ctype':Objective}
57        IndexedComponent.__init__(self, *args, **tkwd)
58        tmpname="unknown"
59        tmpsense = minimize
60        tmprule = None
61        self._data = {}
62        if args == ():
63           self._data[None] = ObjectiveData()
64        self._quad_subexpr = None # this is a hack for now; we eventually want a "QuadraticObjective" class.       
65        for key in kwd.keys():
66          if key == "name":
67             tmpname=kwd[key]
68          elif key == "doc":
69             self.doc=kwd[key]
70          elif key == "rule":
71             tmprule = kwd[key]
72          elif key == "sense":
73             tmpsense = kwd[key]
74          else:
75             raise ValueError, "Objective constructor: unknown keyword - "+key
76        NumericValue.__init__(self,name=tmpname)
77        if None in self._data:
78            self._data[None].name = tmpname
79        self.sense = tmpsense
80        self.rule = tmprule
81        self.trivial=False
82
83    def clear(self):
84        self._data = {}
85       
86    def __call__(self, exception=True):
87        if len(self._data) == 0:
88            return None
89        if None in self._data:
90            if self._data[None].expr is None:
91                return None
92            return self._data[None].expr()
93        if exception:
94            raise ValueError, "Cannot compute the value of an array of objectives"
95
96    def dim(self):
97        return self._ndim
98
99    def __len__(self):
100        return len(self._data.keys())
101
102    def keys(self):
103        return self._data.keys()
104        #return self._index
105
106    def __contains__(self,ndx):
107        return ndx in self._data
108        #return ndx in self._index
109
110    def __getitem__(self,ndx):
111        """This method returns a ObjectiveData object.  This object can be
112           coerced to a numeric value using the value() function, or using
113           explicity coercion with float().
114        """
115        if ndx in self._data:
116           return self._data[ndx]
117        raise KeyError, "Unknown index " + str(ndx) + " in objective " + self.name
118
119    def __iter__(self):
120        return self._data.keys().__iter__()
121        #return self._index.__iter__()
122
123    def _apply_rule(self,arg,ndx):
124        tmp = self.rule(*arg)
125        if tmp is None:
126           return None
127        if type(tmp) in [bool,int,long,float]:
128           return NumericConstant(value=tmp)
129        return tmp
130
131    def construct(self, data=None):
132        if self.rule is not None:
133           if self._ndim==0:
134              tmp = self._apply_rule((self.model,),None)
135              if not tmp is None and not (type(tmp) in [int,long,float] and tmp == 0):
136                 self._data[None].expr = tmp
137           else:
138              _name=self.name
139              for val in self._index:
140                if type(val) is tuple:
141                   tmp = list(val)
142                else:
143                   tmp = [val]
144                tmp.append(self.model)
145                tmp = tuple(tmp)
146                tmp = self._apply_rule(tmp,val)
147                if not tmp is None and not (type(tmp) in [int,long,float] and tmp == 0):
148                   self._data[val] = ObjectiveData(expr=tmp, name=create_name(_name,val))
149           #self._index = self._data.keys()
150               
151        for val in self._data:
152            if self._data[val].expr is not None:
153                self._data[val].expr = self._data[val].expr.simplify(self.model)
154
155    def pprint(self, ostream=None):
156        if ostream is None:
157           ostream = sys.stdout
158        print >>ostream, "  ",self.name,":",
159        print >>ostream, "\tSize="+str(len(self._data.keys())),
160        if isinstance(self._index,_BaseSet):
161           print >>ostream, "\tIndex=",self._index.name
162        else:
163           print >>ostream,""
164        for key in self._data:
165          if not self._data[key].expr is None:
166                print >>ostream, "\t",
167                self._data[key].expr.pprint(ostream)
168                print >>ostream, ""
169        if self._quad_subexpr is not None:
170           print >>ostream, "\tQuadratic sub-expression: ",
171           self._quad_subexpr.pprint(ostream)         
172           print >>ostream, ""
173
174    def display(self, prefix="", ostream=None):
175        if ostream is None:
176           ostream = sys.stdout
177        print >>ostream, prefix+"Objective "+self.name,":",
178        print >>ostream, "  Size="+str(len(self))
179        if None in self._data:
180           print >>ostream, prefix+"  Value="+pyutilib.misc.format_io(self._data[None].expr(exception=False))
181        else:
182           for key in self._data:
183             if not self._data[key].active:
184                continue
185             val = self._data[key].expr(exception=False)
186             print >>ostream, prefix+"  "+str(key)+" : "+str(val)
187
188
189class ConstraintData(NumericValue):
190
191    def __init__(self, name=None):
192        NumericValue.__init__(self,name=name,domain=Reals)
193        self._equality = False
194        self.lower = None
195        self.lower_ineq_strict = None
196        self.body = None
197        self.upper = None
198        self.upper_ineq_strict = None
199        self.label = None
200        self.id = None
201        self.active = True
202
203    def __call__(self, exception=True):
204        if self.body is None:
205            return None
206        return self.body()
207
208    def activate(self):
209        self.active=True
210
211    def deactivate(self):
212        self.active=False
213
214
215class Constraint(NumericValue, IndexedComponent):
216    """An object that defines a objective expression"""
217
218    def __init__(self, *args, **kwd):
219        """Construct an objective expression with rule to construct the
220           expression
221        """
222        tkwd = {'ctype':Constraint}
223        IndexedComponent.__init__(self, *args, **tkwd)
224        tmpname="unknown"
225        tmprule=None
226        self._data = {}
227        #if args == ():
228        #   self._data[None]=ConstraintData()
229        for key in kwd.keys():
230          if key == "name":
231             tmpname=kwd[key]
232          elif key == "doc":
233             self.doc=kwd[key]
234          elif key == "rule":
235             tmprule = kwd[key]
236          else:
237             raise ValueError, "Constraint constructor: unknown keyword - "+key
238        NumericValue.__init__(self,name=tmpname)
239        if None in self._data:
240            self._data[None].name=tmpname
241        self.rule = tmprule
242        self.trivial=False
243
244    def clear(self):
245        self._data = {}
246
247    def __call__(self, exception=True):
248        if len(self._data) == 0:
249            return None
250        if None in self._data:
251            if self._data[None].body is None:
252                return None
253            return self._data[None].body()
254        if exception:
255            raise ValueError, "Cannot compute the value of an array of constraints"
256
257    def dim(self):
258        return self._ndim
259
260    def __len__(self):
261        return len(self._data.keys())
262
263    def keys(self):
264        return self._data.keys()
265        #return self._index
266
267    def __contains__(self,ndx):
268        return ndx in self._data
269        #return ndx in self._index
270
271    def __getitem__(self,ndx):
272        """This method returns a ConstraintData object.  This object can be
273           coerced to a numeric value using the value() function, or using
274           explicity coercion with float().
275        """
276        if ndx in self._data:
277           return self._data[ndx]
278        raise KeyError, "Unknown index " + str(ndx) + " in constraint " + self.name
279
280    def __iter__(self):
281        return self._data.keys().__iter__()
282
283    def construct(self, data=None):
284
285        if pyomo.debug("verbose") or pyomo.debug("normal"):     #pragma:nocover
286           print "Construcing constraint "+self.name
287        if self.rule is None:
288           return
289        #
290        # Local variables for code optimization
291        #
292        _self_rule = self.rule
293        #
294        if not None in self._index and len(self._index) > 0 and _self_rule.func_code.co_argcount == 1:
295            if pyomo.debug("verbose"):                            #pragma:nocover
296                print "   Constructing constraint indices with rule that returns a dictionary"
297            constraints = _self_rule(self.model)
298            for val in constraints:
299                if val not in self._index:
300                    raise IndexError, "The index "+str(val)+" generated by the constructor rule is not valid"
301                ##constructed_indices.append(val)
302                self.add(val, constraints[val])
303        else:
304            for val in self._index:
305                if pyomo.debug("verbose"):                            #pragma:nocover
306                    print "   Constructing constraint index "+str(val)
307                if val is None:
308                    expr = _self_rule(self.model)
309                    if expr is None or (type(expr) in [int,long,float] and expr == 0):
310                        continue
311                else:
312                    if type(val) is tuple:
313                        tmp=list(val)
314                    else:
315                        tmp=[val]
316                    tmp.append(self.model)
317                    tmp=tuple(tmp)
318                    expr = _self_rule(*tmp)
319                    if expr is None or (type(expr) in [int,long,float] and expr == 0):
320                        continue
321                ##constructed_indices.append(val)
322                self.add(val, expr)
323        #self._index=constructed_indices
324
325    def add(self, index, expr):
326        # index: the constraint index (should probably be renamed)
327        # expr: the constraint expression
328        # model: the parent model
329
330        #
331        # Ignore an 'empty' constraint
332        #
333        if expr is None:
334            return
335        #
336        # Verify that the user actually provided an expression or tuple/list - they can (and have)
337        # specified odd expressions that evaluate to unexpected values, e.g., True or False.
338        #
339        if isinstance(expr,Expression) is False and isinstance(expr,tuple) is False and isinstance(expr, list) is False:
340           raise ValueError, "Non-expression object of "+str(type(expr))+" supplied to initialize constraint="+self.name+", index="+str(index)
341           
342        #
343        #
344        # Local variables to optimize runtime performance
345        #
346        _self_data = self._data
347        _self_data[index] = ConstraintData(name=create_name(self.name,index))
348        if not type(expr) in [tuple,list]:
349            _expr_args0 = expr._args[0]
350            _expr_args1 = expr._args[1]
351
352            #_expr_args0.pprint()
353            #print "HERE", is_constant(_expr_args0)
354            #_expr_args1.pprint()
355            #print "HERE", is_constant(_expr_args1)
356        #
357        # If the constructor rule returns an equality expression, then
358        # convert to a 3-tuple
359        #
360        if isinstance(expr,_EqualToExpression):
361            _self_data[index]._equality = True
362            if is_constant(_expr_args1):
363                tpl = [ _expr_args1,_expr_args0,_expr_args1, False, False ]
364            elif is_constant(_expr_args1):
365                tpl = [ _expr_args0,_expr_args1,_expr_args0, False, False ]
366            else:
367                tpl = [ 0.0 , _expr_args0 - _expr_args1, 0.0, False, False ]
368        #
369        # If the constructor rule returns a greater-than expression, then
370        # convert to a 3-tuple
371        #
372        elif isinstance(expr,_GreaterThanExpression) or\
373                isinstance(expr,_GreaterThanOrEqualExpression):
374
375            if isinstance(_expr_args0,_GreaterThanExpression) or\
376                    isinstance(_expr_args0,_GreaterThanOrEqualExpression):
377                tpl = [ _expr_args1, _expr_args0._args[1], _expr_args0._args[0],
378                        isinstance(expr,_GreaterThanExpression), isinstance(_expr_args0,_GreaterThanExpression) ]
379
380            elif isinstance(_expr_args0,_LessThanExpression) or\
381                    isinstance(_expr_args0,_LessThanOrEqualExpression):
382                tpl = [ _expr_args1, _expr_args0._args[0], _expr_args0._args[1],
383                        isinstance(expr,_GreaterThanExpression), isinstance(_expr_args0,_LessThanExpression) ]
384
385            elif isinstance(_expr_args1,_GreaterThanExpression) or\
386                    isinstance(_expr_args1,_GreaterThanOrEqualExpression):
387                tpl = [ _expr_args1._args[1], _expr_args1._args[0], _expr_args0,
388                        isinstance(_expr_args1,_GreaterThanExpression), isinstance(expr,_GreaterThanExpression) ]
389
390            elif isinstance(_expr_args1,_LessThanExpression) or\
391                    isinstance(_expr_args1,_LessThanOrEqualExpression):
392                tpl = [ _expr_args1._args[0], _expr_args1._args[1], _expr_args0, 
393                        isinstance(_expr_args1,_LessThanExpression), isinstance(expr,_GreaterThanExpression) ]
394
395            elif isinstance(_expr_args0,_EqualToExpression) or\
396                    isinstance(_expr_args1,_EqualToExpression):
397                raise ValueError, "Bound error: > expression used with an = expression."
398
399            elif _expr_args0.is_constant():
400                tpl = [ None, _expr_args1, _expr_args0,
401                        True, isinstance(expr,_GreaterThanExpression) ]
402            elif _expr_args1.is_constant():
403                tpl = [ _expr_args1, _expr_args0, None,
404                        isinstance(expr,_GreaterThanExpression), True]
405            else:
406                tpl = [ 0.0, _expr_args0-_expr_args1, None,
407                        isinstance(expr,_GreaterThanExpression), True ]
408
409        #
410        # If the constructor rule returns a less-than expression, then
411        # convert to a 3-tuple
412        #
413        elif isinstance(expr,_LessThanExpression) or\
414                isinstance(expr,_LessThanOrEqualExpression):
415
416            if isinstance(_expr_args0,_LessThanExpression) or\
417                    isinstance(_expr_args0,_LessThanOrEqualExpression):
418                tpl = [ _expr_args0._args[0],_expr_args0._args[1],_expr_args1,
419                        isinstance(_expr_args0,_LessThanExpression), isinstance(expr,_LessThanExpression) ]
420
421            elif isinstance(_expr_args0,_GreaterThanExpression) or\
422                    isinstance(_expr_args0,_GreaterThanOrEqualExpression):
423                tpl = [ _expr_args0._args[1],_expr_args0._args[0],_expr_args1,
424                        isinstance(_expr_args0,_GreaterThanExpression), isinstance(expr,_LessThanExpression) ]
425
426            elif isinstance(_expr_args1,_LessThanExpression) or\
427                    isinstance(_expr_args1,_LessThanOrEqualExpression):
428                tpl = [ _expr_args0,_expr_args1._args[0],_expr_args1._args[1],
429                        isinstance(expr,_LessThanExpression), isinstance(_expr_args1,_LessThanExpression) ]
430
431            elif isinstance(_expr_args1,_GreaterThanExpression) or\
432                    isinstance(_expr_args1,_GreaterThanOrEqualExpression):
433                tpl = [ _expr_args0,_expr_args1._args[1],_expr_args1._args[0],
434                        isinstance(expr,_LessThanExpression), isinstance(_expr_args1,_GreaterThanExpression) ]
435
436            elif isinstance(_expr_args0,_EqualToExpression) or\
437                    isinstance(_expr_args1,_EqualToExpression):
438                raise ValueError, "Bound error: < expression used with an = expression."+str(expr)+str(expr._args)
439
440            elif _expr_args0.is_constant():
441                tpl = [ _expr_args0, _expr_args1, None,
442                        isinstance(expr,_LessThanExpression), True ]
443            elif _expr_args1.is_constant():
444                tpl = [ None, _expr_args0, _expr_args1,
445                        True, isinstance(expr,_LessThanExpression) ]
446            else:
447                tpl = [ 0.0, _expr_args1 - _expr_args0, None,
448                        isinstance(expr,_LessThanExpression), True ]
449        #
450        # If the constructor rule returns a tuple or list, then convert
451        # it into a canonical form
452        #
453        elif type(expr) in [tuple,list]:
454            #
455            # Convert tuples to list
456            #
457            if type(expr) is tuple:
458                expr = list(expr)
459            #
460            # Form equality expression
461            #
462            if len(expr) == 2:
463                _self_data[index]._equality = True
464                if is_constant(expr[1]):
465                    tpl = [ expr[1], expr[0], expr[1], False, False ]
466                else:
467                    tpl = [ expr[0], expr[1], expr[0], False, False ]
468            #
469            # Form inequality expression
470            #
471            elif len(expr) == 3:
472                tpl=list(expr)+[expr[0] is None, expr[2] is None]
473            else:
474                raise ValueError, "Constructor rule for constraint "+self.name+" returned a tuple of length "+str(len(expr))
475        #
476        # Unrecognized constraint values
477        #
478        else:
479            raise ValueError, "Constraint \"" + self.name + "\" does not have a proper value:" + str(expr)
480        #
481        # Replace numeric bound values with a NumericConstant object,
482        # and reset the values to 'None' if they are 'infinite'
483        #
484        if type(tpl[0]) in [bool,int,long,float]:
485            if pyutilib.math.is_finite(tpl[0]):
486                tpl[0] = NumericConstant(value=float(tpl[0]))
487            else:
488                tpl[0] = None
489        elif type(tpl[0]) is NumericConstant and not pyutilib.math.is_finite(tpl[0]()):
490                tpl[0] = None
491        if type(tpl[1]) in [bool,int,long,float]:
492            raise ValueError, "Constraint \""+self.name+"\" has a numeric body.  Expecting Expression instance."
493        if _self_data[index]._equality:
494            tpl[2] = tpl[0]
495        elif type(tpl[2]) in [bool,int,long,float]:
496            if pyutilib.math.is_finite(tpl[2]):
497                tpl[2] = NumericConstant(value=float(tpl[2]))
498            else:
499                tpl[2] = None
500        elif type(tpl[2]) is NumericConstant and not pyutilib.math.is_finite(tpl[2]()):
501                tpl[2] = None
502        #
503        # Error check, to ensure that we don't have an equality constraint with
504        # 'infinite' RHS
505        #
506        if (tpl[0] is None or tpl[2] is None) and _self_data[index]._equality:
507            raise ValueError, "Equality constraint "+self.name+" defined with infinity RHS"
508        #
509        # Setup identity expressions
510        #
511        if tpl[0] is not None:
512            if not isinstance(tpl[0],Expression):
513                tpl[0] = _IdentityExpression(tpl[0])
514            tpl[0] = tpl[0].simplify(self.model)
515        if tpl[1] is not None:
516            if not isinstance(tpl[1],Expression):
517                tpl[1] = _IdentityExpression(tpl[1])
518            tpl[1] = tpl[1].simplify(self.model)
519        if tpl[2] is not None:
520            if not isinstance(tpl[2],Expression):
521                tpl[2] = _IdentityExpression(tpl[2])
522            tpl[2] = tpl[2].simplify(self.model)
523        #
524        # Finally, setup the data
525        #
526        _self_data[index].lower = tpl[0]
527        _self_data[index].lower_ineq_strict = tpl[3]
528        _self_data[index].body = tpl[1]
529        _self_data[index].upper = tpl[2]
530        _self_data[index].upper_ineq_strict = tpl[4]
531
532
533    def pprint(self, ostream=None):
534        if ostream is None:
535           ostream = sys.stdout
536        print >>ostream, "  ",self.name,":",
537        print >>ostream, "\tSize="+str(len(self._data.keys())),
538        if isinstance(self._index,_BaseSet):
539           print >>ostream, "\tIndex=",self._index.name
540        else:
541           print >>ostream,""
542        for val in self._data:
543          if not val is None:
544             print >>ostream, "\t"+`val`
545          if self._data[val].lower is not None:
546             print >>ostream, "\t\t",
547             self._data[val].lower.pprint(ostream)
548          else:
549             print >>ostream, "\t\t-Inf"
550          if self._data[val].lower_ineq_strict:
551             print >>ostream, "\t\t<"
552          else:
553             print >>ostream, "\t\t<="
554          if self._data[val].body is not None:
555             print >>ostream, "\t\t",
556             self._data[val].body.pprint(ostream)
557          #else:                         #pragma:nocover
558             #raise ValueError, "Unexpected empty constraint body"
559          if self._data[val].upper_ineq_strict:
560             print >>ostream, "\t\t<"
561          else:
562             print >>ostream, "\t\t<="
563          if self._data[val].upper is not None:
564             print >>ostream, "\t\t",
565             self._data[val].upper.pprint(ostream)
566          elif self._data[val]._equality:
567             print >>ostream, "\t\t",
568             self._data[val].lower.pprint(ostream)
569          else:
570             print >>ostream, "\t\tInf"
571
572    def display(self, prefix="", ostream=None):
573        if ostream is None:
574           ostream = sys.stdout
575        print >>ostream, prefix+"Constraint "+self.name,":",
576        print >>ostream, "  Size="+str(len(self))
577        if None in self._data:
578           print >>ostream, prefix+"  Value="+pyutilib.misc.format_io(self._data[None].body())
579        else:
580           flag=True
581           for key in self._data:
582             if not self._data[key].active:
583                continue
584             if flag:
585                print >>ostream, prefix+"        \tLower\tBody\t\tUpper"
586                flag=False
587             if self._data[key].lower is not None:
588                lval = str(self._data[key].lower())
589             else:
590                lval = "-Infinity"
591             val = str(self._data[key].body())
592             if self._data[key].upper is not None:
593                uval = str(self._data[key].upper())
594             else:
595                uval = "Infinity"
596             print >>ostream, prefix+"  "+str(key)+" :\t"+lval+"\t"+val+"\t"+uval
597           if flag:
598                print >>ostream, prefix+"  None active"
599
600
601ComponentRegistration("Objective", Objective, "Expressions that are minimized or maximized in a model.")
602ComponentRegistration("Constraint", Constraint, "Constraint expressions a model.")
Note: See TracBrowser for help on using the repository browser.