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

Revision 2194, 23.0 KB checked in by wehart, 5 years ago (diff) |
---|

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 | |

13 | from numvalue import * |

14 | from numvalue import create_name |

15 | from expr import * |

16 | from plugin import ComponentRegistration |

17 | import pyomo |

18 | from var import Var, _VarValue |

19 | from indexed_component import IndexedComponent |

20 | from sets import _BaseSet |

21 | import pyutilib.misc |

22 | import pyutilib.math |

23 | from numtypes import * |

24 | import sys |

25 | from set_types import * |

26 | |

27 | |

28 | class 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 | |

49 | class 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 | |

189 | class 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 | |

215 | class 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 | |

601 | ComponentRegistration("Objective", Objective, "Expressions that are minimized or maximized in a model.") |

602 | ComponentRegistration("Constraint", Constraint, "Constraint expressions a model.") |

**Note:**See TracBrowser for help on using the repository browser.