Parent Directory | Revision Log

Revision **2244** -
(**hide annotations**)
(**download**)
(**as text**)

*Mon Aug 2 01:05:11 2010 UTC*
(10 years, 7 months ago)
by *jpye*

File MIME type: text/x-ascend

File size: 19401 byte(s)

File MIME type: text/x-ascend

File size: 19401 byte(s)

Fix bug with 'RUN default', need to use Initialize(GetSimulationRoot(sim),...) for running methods!

1 | johnpye | 1293 | (* ASCEND modelling environment |

2 | Copyright (C) 1998, 2007 Carnegie Mellon University | ||

3 | |||

4 | This program is free software; you can redistribute it and/or modify | ||

5 | it under the terms of the GNU General Public License as published by | ||

6 | the Free Software Foundation; either version 2, or (at your option) | ||

7 | any later version. | ||

8 | |||

9 | This program is distributed in the hope that it will be useful, | ||

10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||

11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||

12 | GNU General Public License for more details. | ||

13 | |||

14 | You should have received a copy of the GNU General Public License | ||

15 | along with this program; if not, write to the Free Software | ||

16 | Foundation, Inc., 59 Temple Place - Suite 330, | ||

17 | Boston, MA 02111-1307, USA. | ||

18 | *) | ||

19 | aw0a | 1 | PROVIDE "basemodel.a4l"; |

20 | (* | ||

21 | johnpye | 1293 | basemodel.a4l, by Benjamin A. Allan 03/98 - Original Code |

22 | aw0a | 1 | |

23 | johnpye | 1293 | Basic definitions cmu libraries and standard methods. |

24 | This file is necessary for all other CMU authored ASCEND models to work | ||

25 | in ASCEND IV. | ||

26 | *) | ||

27 | aw0a | 1 | |

28 | MODEL catch_Word_model (* Bill Gates sacrificial goat *); | ||

29 | (* This MODEL does nothing. | ||

30 | * Normally catch_Word_model just gets parsed and ignored. | ||

31 | * | ||

32 | * If the user has tried to read a Microsoft Word binary file, Tcl file, | ||

33 | * or some other piece of junk as if it were an ASCEND MODEL | ||

34 | * source file, then catch_Word_model will die on an unknown | ||

35 | * syntax error. | ||

36 | * While catch_Word_model is dying the parser returns a good | ||

37 | * starting condition. | ||

38 | * | ||

39 | * Here is the message of recovery when this MODEL fails: | ||

40 | Asc-Error: Model definition "catch_Word_model" abandoned due to syntax errors. | ||

41 | Asc-Error: Rejected "catch_Word_model" at line basemodel.a4l:62. | ||

42 | johnpye | 1293 | |

43 | @TODO document how this works | ||

44 | aw0a | 1 | *) |

45 | END catch_Word_model; | ||

46 | |||

47 | (* First define the standard methods, or stand-ins which will tell | ||

48 | * us when a standard method has not been written. | ||

49 | *) | ||

50 | ADD METHODS IN DEFINITION MODEL; | ||

51 | |||

52 | METHOD ClearAll; | ||

53 | |||

54 | NOTES 'purpose' SELF { | ||

55 | This method finds anything that is a solver_var and changes | ||

56 | the .fixed flag on the var to FALSE. | ||

57 | |||

58 | This method does not change .included flags on relations | ||

59 | or return boolean, integer, or symbol variables to a | ||

60 | default value. | ||

61 | } END NOTES; | ||

62 | |||

63 | EXTERNAL asc_free_all_variables(SELF); | ||

64 | END ClearAll; | ||

65 | |||

66 | (* | ||

67 | * Geniuses make more mistakes than anyone else -- because they | ||

68 | * try more things that anyone else. Part (perhaps a very large | ||

69 | * part) of what makes a genius different from the rest of | ||

70 | * humanity is that they quickly recognize their own mistakes | ||

71 | * and move on to try something else before anyone notices | ||

72 | * they screwed up! Solving a problem as far and as fast as you | ||

73 | * can, then going back to criticize every aspect of the solution | ||

74 | * with an eye to improving it is how you usually discover right answers. | ||

75 | * | ||

76 | * The authors of ASCEND (geniuses or not we'll | ||

77 | * leave to our users to decide) have found that it is | ||

78 | * best to do things such as writing mathematical MODELs and | ||

79 | * writing mathematical modeling software in ways which | ||

80 | * makes our mistakes (or your mistakes) very easy to detect. | ||

81 | * | ||

82 | * Below we describe a methodology (pun intended) which can | ||

83 | * help make anyone who can solve a quadratic equation | ||

84 | * a mathematical modeling expert. This methodology helps | ||

85 | * you to avoid screwing up and to find out about it when you have. | ||

86 | * | ||

87 | * The ASCEND system will not force you to write standard | ||

88 | * methods in your models. :-( METHODs of the sort we advocate | ||

89 | * here make your MODELs much easier to use and | ||

90 | * much more reliable. They pay off in the short run as well | ||

91 | * as the long run. These are _guidelines_, not _laws_: real | ||

92 | * genius requires knowing when to color outside the lines. :-) | ||

93 | * | ||

94 | * If you do not write the standard methods, your MODEL will | ||

95 | * inherit the ones given here. The "ClearAll" and "reset" | ||

96 | * methods here will work for you if you followed the guidelines. | ||

97 | * The other methods contain STOP statements which will warn you | ||

98 | * that you have skipped something important, should you accidentally | ||

99 | * end up calling one of them. | ||

100 | * | ||

101 | * The following methods should be redefined by each | ||

102 | * reusable library MODEL that REFINES this root MODEL. | ||

103 | * Models that do not supply proper versions of these | ||

104 | * (and possibly other) methods are very hard to reuse. | ||

105 | * | ||

106 | * The premise of this method design is that we can | ||

107 | * write the _self methods incrementally, building on the | ||

108 | * already tested methods of previous MODEL parts we are | ||

109 | * reusing. In this way we never have to write a single huge method | ||

110 | * that directly checks 100s of variables in a hierarchy. | ||

111 | * | ||

112 | * The _all methods are methods which simply "top off" the | ||

113 | * _self methods. With an _all method, you can treat | ||

114 | * just a part of a larger simulation already built | ||

115 | * as a self-contained simulation. | ||

116 | * | ||

117 | *) | ||

118 | |||

119 | (* | ||

120 | * Usually discovery of the information you need to write the methods | ||

121 | * proceeds in the order that they appear below: | ||

122 | * check, default, specify, bound, scale. | ||

123 | *) | ||

124 | |||

125 | METHOD check_self; | ||

126 | NOTES 'purpose' SELF { | ||

127 | This method should be written first, though it is run | ||

128 | last. Just like they taught you in elementary school, | ||

129 | always check your work. Start by defining criteria for a | ||

130 | successful solution that will not be included in the | ||

131 | equations solved and then computing those in this method. | ||

132 | As you develop your MODEL, you should expect to revise the | ||

133 | check method from time to time, if you are learning | ||

134 | anything about the MODEL. We frequently change our | ||

135 | definition of success. | ||

136 | |||

137 | When a mathematical MODEL is solved, the assumptions that | ||

138 | went into writing (deriving) the equations should be | ||

139 | checked. Usually there are redundant equations available | ||

140 | (more than one way to state the physical MODEL | ||

141 | mathematically). These should be used to check the | ||

142 | particularly tricky bits of the MODEL. | ||

143 | |||

144 | Check that the physical or intuitive (qualitative) | ||

145 | relationships among variables ch you expect to hold are | ||

146 | TRUE, especially if you have not written such relationships | ||

147 | in terms of inequalities in the MODEL equations. | ||

148 | |||

149 | In some models, checking the variable values against | ||

150 | absolute physical limits (temperature > 0{K} and | ||

151 | temperature < Tcritical for example) may be all that is | ||

152 | necessary or possible. Do not check variable values against | ||

153 | their .lower_bound or .upper_bound, as any decent algebraic | ||

154 | solver or modeling system will do this for you. | ||

155 | |||

156 | If a check fails, use a STOP or ERROR statement to notify | ||

157 | yourself (or you MODEL using customer) that the solution | ||

158 | may be bogus. | ||

159 | |||

160 | Currently only STOP is implemented. | ||

161 | STOP raises an error signal and issues an error message; | ||

162 | STOP normally also stops further execution of the method | ||

163 | and returns control to a higher level, though there are | ||

164 | interactive tools to force method execution to continue. | ||

165 | STOP does not crash the ASCEND system. | ||

166 | |||

167 | } END NOTES; | ||

168 | |||

169 | johnpye | 1290 | (* STOP {Error! Standard method "check_self" called but not written in MODEL.}; *) |

170 | aw0a | 1 | |

171 | END check_self; | ||

172 | |||

173 | METHOD check_all; | ||

174 | |||

175 | NOTES 'purpose' SELF { | ||

176 | When solving only a part of a simulation, it is necessary to check | ||

177 | the models and variables passed into the part as well as the | ||

178 | locally defined parts and variables. This method should check | ||

179 | all the received models and variables, then check the local | ||

180 | stuff. | ||

181 | } END NOTES; | ||

182 | |||

183 | johnpye | 1290 | (* STOP {Error! Standard method "check_all" called but not written in MODEL.}; *) |

184 | aw0a | 1 | RUN check_self; (* intentionally _second_ *) |

185 | |||

186 | END check_all; | ||

187 | |||

188 | METHOD defaults; | ||

189 | (* | ||

190 | * This is a kluge for interfaces that still think of | ||

191 | * 'defaults' as the standard method. | ||

192 | *) | ||

193 | RUN default_self; | ||

194 | STOP {GUI (or somebody) called non-standard method defaults. Call forwarded to default_self before stopping here.}; | ||

195 | END defaults; | ||

196 | |||

197 | johnpye | 669 | METHOD on_load; |

198 | NOTES 'purpose' SELF { | ||

199 | This method adds improved ability to perform stuff when a model is first loaded. | ||

200 | By default, just 'default_self' will be run (this was the previous behaviour). | ||

201 | Any model that has an on_load method can override this behaviour however. | ||

202 | Note that this behaviour applies only in the C++/python interface at this stage. | ||

203 | } END NOTES; | ||

204 | johnpye | 1290 | RUN default_all; |

205 | johnpye | 669 | END on_load; |

206 | |||

207 | johnpye | 1290 | METHOD default; |

208 | NOTES 'purpose' SELF { | ||

209 | This method exists for the purpose ofOVERRIDING atom defaults in the local | ||

210 | MODEL. Hopefully this approach can replace the current practise of writing | ||

211 | johnpye | 1293 | 'default_self' methods for most MODELs. It should be superior, since using |

212 | johnpye | 1290 | 'default' instead of 'default_self' will always result in ALL variables in a |

213 | model being reset to default values, rather than only those explicitly stated | ||

214 | by the modeller. | ||

215 | } END NOTES; | ||

216 | jpye | 2244 | (*STOP {it works!};*) |

217 | johnpye | 1290 | (* nothing here *) |

218 | END default; | ||

219 | |||

220 | aw0a | 1 | METHOD default_self; |

221 | NOTES 'purpose' SELF { | ||

222 | This method should set default values for any variables | ||

223 | declared locally (IS_A) to the MODEL. It should run | ||

224 | default_self on _all_ the models that are declared locally | ||

225 | (with IS_A) in the MODEL also. If the atoms you use to | ||

226 | define your variables have a suitable default already, then | ||

227 | you do not need to assign them a default in this method. | ||

228 | |||

229 | This method should not run any methods on MODEL parts that | ||

230 | come via WILL_BE in the definition's parameter list. This | ||

231 | method also should not change the values of variables that | ||

232 | are passed in through the parameter list. | ||

233 | |||

234 | Sometimes there will be nothing for this method to do. | ||

235 | Define it anyway, leaving it empty. | ||

236 | |||

237 | When a top-level simulation is built by the compiler, this | ||

238 | method will be run at the end of compilation by the | ||

239 | johnpye | 1293 | compiler. See notes in on_load method for new behaviour in |

240 | the PyGTK GUI. | ||

241 | aw0a | 1 | } END NOTES; |

242 | jpye | 1372 | EXTERNAL defaultself_visit_childatoms(SELF); |

243 | EXTERNAL defaultself_visit_submodels(SELF); (* overwrite ATOM defaults explicit nested code if needed *) | ||

244 | jpye | 2244 | RUN default; (* local overrides *) |

245 | aw0a | 1 | END default_self; |

246 | |||

247 | METHOD default_all; | ||

248 | NOTES 'purpose' SELF { | ||

249 | This method assumes that the arguments to the MODEL | ||

250 | instance have not been properly initialized, as is | ||

251 | frequently the case in one-off modeling efforts. This | ||

252 | method should run the default_self method on each of the | ||

253 | parts received through the parameter list and should give | ||

254 | appropriate default values to any variables received | ||

255 | through the parameter list. After these have been done, it | ||

256 | should then call default_self to take care of all locally | ||

257 | declared default needs. | ||

258 | } END NOTES; | ||

259 | jpye | 1372 | (* INITIALISATION OF PARAMETERS IS NOT IMPLEMENTED YET *) |

260 | aw0a | 1 | RUN default_self; |

261 | END default_all; | ||

262 | |||

263 | METHOD specify; | ||

264 | NOTES 'purpose' SELF { | ||

265 | * Assuming ClearAll has been run on the MODEL, this method | ||

266 | * should get the MODEL to a condition called 'square': | ||

267 | * the case where there are as many variables with .fixed == FALSE | ||

268 | * as there equations available to compute them. | ||

269 | * This is one of the hardest tasks ever invented by mathematicians | ||

270 | * if you go about it in the wrong way. We think we know the right way. | ||

271 | * | ||

272 | * Actually, 'square' is a bit trickier to achieve | ||

273 | * than simply counting equations and variables. | ||

274 | * Solver, such as QRSlv in ASCEND, may help greatly with the bookkeeping. | ||

275 | * | ||

276 | The general approach is to: | ||

277 | |||

278 | (1) Run "specify" for all the parts (both passed in and locally defined) | ||

279 | that are not passed on into other parts. | ||

280 | |||

281 | (2) Fix up (by tweaking .fixed flags on variables) any difficulties | ||

282 | that arise when parts compete to calculate the same variable. | ||

283 | |||

284 | (3) Use the remaining new local variables to take care of any leftover | ||

285 | equations among the parts and any new equations written locally. | ||

286 | |||

287 | At all steps 1-3 | ||

288 | Pay special attention to indexed variables used in | ||

289 | indexed equations; frequently you must fix or free N or | ||

290 | N-1 variables of a set sized N, if there are N matching equations. | ||

291 | In general, if you think you have specify correctly written, change | ||

292 | the sizes of all the sets in your MODEL by one and then by two | ||

293 | members. If your specify method still works, you are using sets | ||

294 | correctly. | ||

295 | |||

296 | When writing models that combine parts which do not share | ||

297 | very well, or which both try to compute the same variable | ||

298 | in different ways, it may even be necessary to write a WHEN | ||

299 | statement to selectively TURN OFF the conflicting equations | ||

300 | or MODEL fragments. An object or equation USEd in a WHEN | ||

301 | statement is turned off by default and becomes a part of | ||

302 | the solved MODEL only when the conditions of some CASE | ||

303 | which refers to that object are matched. | ||

304 | |||

305 | The setting of boolean, integer, and symbol variables which | ||

306 | are controlling conditions of WHEN and SWITCH statements | ||

307 | should be taken care of in the specify method. | ||

308 | |||

309 | There is no 'one perfect "specify"' for all purposes. This | ||

310 | routine should merely define a reasonably useful base | ||

311 | configuration of the MODEL. | ||

312 | |||

313 | Other specify_whatElseYouWant methods can (should) also be | ||

314 | written. | ||

315 | |||

316 | The name of a method is a communication tool. Please use | ||

317 | meaningful names as long as necessary to tell what the | ||

318 | method does. Avoid cryptic abbreviations and hyper- | ||

319 | specialized jargon known only to you and your three friends | ||

320 | when you are naming methods; however, do not shy away from | ||

321 | technical terms common to the engineering domain in which | ||

322 | you are modeling. | ||

323 | |||

324 | } END NOTES; | ||

325 | |||

326 | johnpye | 1290 | (* STOP {Error! Standard method "specify" called but not written in MODEL.}; *) |

327 | aw0a | 1 | |

328 | END specify; | ||

329 | |||

330 | METHOD reset; | ||

331 | NOTES 'purpose' SELF { | ||

332 | This method gets the MODEL to some standard starting state, | ||

333 | though not necessarily the most useful starting state for a | ||

334 | particular application. In Chem. Eng. terms, this method | ||

335 | establishes a base case. | ||

336 | |||

337 | There is no 'one perfect "reset"' for all purposes. This | ||

338 | routine should merely define a reasonably useful base | ||

339 | configuration of the MODEL. | ||

340 | |||

341 | Other reset_whatElseYouWant methods can (should) also be | ||

342 | written. | ||

343 | |||

344 | Normally you do not need to write this method: your models | ||

345 | will inherit this one unless you override it (redefine it) | ||

346 | in your MODEL. | ||

347 | } | ||

348 | END NOTES; | ||

349 | |||

350 | RUN ClearAll; | ||

351 | RUN specify; | ||

352 | |||

353 | END reset; | ||

354 | |||

355 | jpye | 1373 | METHOD values; |

356 | END values; | ||

357 | |||

358 | aw0a | 1 | METHOD bound_self; |

359 | NOTES 'purpose' SELF { | ||

360 | Much of the art of nonlinear physical modeling is in | ||

361 | bounding the solution. | ||

362 | |||

363 | This method should update the bounds on _locally_ defined | ||

364 | (IS_A) variables and IS_A defined MODEL parts. Updating | ||

365 | bounds requires some care. For example, the bounds on | ||

366 | fractions frequently don't need updating. | ||

367 | |||

368 | A common formula for updating bounds is to define a region | ||

369 | around the current value of the variable. A linear region | ||

370 | size formula, as an example, would be: | ||

371 | |||

372 | v.upper_bound := v + boundwidth * v.nominal; | ||

373 | v.lower_bound := v - boundwidth * v.nominal; | ||

374 | |||

375 | Care must be taken that such a formula does not move the | ||

376 | bounds (particularly lower bounds) out so far as to allow | ||

377 | non-physical solutions. Logarithmic bounding regions are | ||

378 | also simple to calculate. | ||

379 | |||

380 | Here boundwidth IS_A bound_width; | ||

381 | boundwidth is a real variable (but not a solver_var) or a | ||

382 | value you can use to determine how much "wiggle-room" you | ||

383 | want to give a solver. Small powers of 4 and 10 are usually | ||

384 | good values of boundwidth. | ||

385 | |||

386 | Too small a boundwidth can cut off the portion of number | ||

387 | space where the solution is found. Too large a bound width | ||

388 | can allow solvers to wander for great distances in | ||

389 | uninteresting regions of the number space. | ||

390 | |||

391 | This method should not bound variables passed into the | ||

392 | MODEL definition or parts passed into the definition. | ||

393 | } END NOTES; | ||

394 | |||

395 | johnpye | 1290 | (* STOP {Error! Standard method "bound_self" called but not written in MODEL.}; *) |

396 | aw0a | 1 | END bound_self; |

397 | |||

398 | METHOD bound_all; | ||

399 | NOTES 'purpose' SELF { | ||

400 | This method should be like bound_self except that it bounds the | ||

401 | passed in variables and calls bound_self on the passed in parts. | ||

402 | It should then call bound_self. | ||

403 | } END NOTES; | ||

404 | |||

405 | johnpye | 1290 | (* STOP {Error! Standard method "bound_all" called but not written in MODEL.}; *) |

406 | aw0a | 1 | RUN bound_self; |

407 | END bound_all; | ||

408 | |||

409 | METHOD scale_self; | ||

410 | NOTES 'purpose' SELF { | ||

411 | Most nonlinear (and many linear) models cannot be solved without | ||

412 | proper scaling of the variables. | ||

413 | |||

414 | This method should reset the .nominal value on every real | ||

415 | variable in need of scaling. It should then call the | ||

416 | scale_self method on all the locally defined (IS_A) parts | ||

417 | of the MODEL. 0.0 is the worst possible nominal value. A | ||

418 | proper nominal is one such that you expect at the solution | ||

419 | the quantity | ||

420 | |||

421 | abs(variable/(variable.nominal)) | ||

422 | |||

423 | to be around 1 (in the range of [0.1..10] or [0.01..100]). | ||

424 | |||

425 | Variables (like fractions) bounded such that they cannot be | ||

426 | too far away from 1.0 in magnitude probably don't need scaling | ||

427 | most of the time if they are also bounded away from 0.0. | ||

428 | |||

429 | Some solvers, but not all, will attempt to scale the | ||

430 | equations and variables by heuristic matrix-based methods. | ||

431 | This works, but inconsistently; user-defined scaling is | ||

432 | generaly much superior. | ||

433 | |||

434 | ASCEND makes it easy to do. You scale the variables, which | ||

435 | can only be done well by knowing something about where the | ||

436 | solution is going to be found (by being an engineer, for | ||

437 | example.) Then ASCEND can calculate an appropriate | ||

438 | equation-scaling by efficient symbolic methods. | ||

439 | |||

440 | This method should not change the scaling of models and | ||

441 | variables that are received through the parameter list of | ||

442 | the MODEL. | ||

443 | } END NOTES; | ||

444 | |||

445 | johnpye | 1290 | (* STOP {Error! Standard method "scale_self" called but not written in MODEL.}; *) |

446 | aw0a | 1 | END scale_self; |

447 | |||

448 | METHOD scale_all; | ||

449 | NOTES 'purpose' SELF { | ||

450 | This method should be like scale_self above except that it also | ||

451 | should scale the variables and models received through the | ||

452 | parameter list. It should then call scale_self to take care of | ||

453 | the local variables and models. | ||

454 | } END NOTES; | ||

455 | |||

456 | johnpye | 1290 | (* STOP {Error! Standard method "scale_all" called but not written in MODEL.}; *) |

457 | aw0a | 1 | RUN scale_self; |

458 | END scale_all; | ||

459 | END METHODS; | ||

460 | |||

461 | MODEL cmumodel(); | ||

462 | NOTES | ||

463 | 'purpose' SELF { | ||

464 | This MODEL does nothing except provide a root | ||

465 | for a collection of loosely related models. | ||

466 | If it happens to reveal a few bugs in the software, | ||

467 | and perhaps masks others, well, what me worry? | ||

468 | BAA, 8/97. | ||

469 | } | ||

470 | 'methods' SELF { | ||

471 | This MODEL also provides a hook to put in candidates for | ||

472 | becoming ascBuiltin global methods. Global methods may be | ||

473 | overridden by local definitions. | ||

474 | BAA, 3/98. | ||

475 | } | ||

476 | END NOTES; | ||

477 | |||

478 | END cmumodel; | ||

479 | |||

480 | MODEL testcmumodel(); | ||

481 | (* | ||

482 | * All CMU test models, of whatever sort should ultimately be | ||

483 | * rooted here or be a final refinement of a reusable MODEL. | ||

484 | *) | ||

485 | METHODS | ||

486 | jpye | 1372 | METHOD values; |

487 | (* | ||

488 | * In a final application MODEL, you should record at least one set of | ||

489 | * input values (values of the fixed variables and guesses of key | ||

490 | * solved-for variables) that leads to a good solution. | ||

491 | * Do this so noone need reinvent that set the next time | ||

492 | * you use the MODEL or someone picks the MODEL up after you. | ||

493 | *) | ||

494 | (* STOP {Error! Standard method "values" called but not written in MODEL.}; *) | ||

495 | END values; | ||

496 | aw0a | 1 | |

497 | jpye | 1372 | METHOD specify; |

498 | (* STOP {Error! Standard method "specify" called but not written in test MODEL.}; *) | ||

499 | END specify; | ||

500 | aw0a | 1 | |

501 | jpye | 1372 | METHOD ClearAll; |

502 | EXTERNAL asc_free_all_variables(SELF); | ||

503 | END ClearAll; | ||

504 | |||

505 | METHOD reset; | ||

506 | (* This method gets the MODEL to some standard starting state, | ||

507 | * though not necessarily the most useful starting state for | ||

508 | * a particular application. In Chem. Eng. terms, this method | ||

509 | * establishes a base case. | ||

510 | * There is no 'one perfect "reset"' for all purposes. This | ||

511 | * routine should merely define a reasonably useful base configuration | ||

512 | * of the MODEL. | ||

513 | * Other reset_whatElseYouWant methods can (should) also be | ||

514 | * written. | ||

515 | * | ||

516 | * Normally you do not need to write this method: your models | ||

517 | * will inherit this one unless you override it (redefine it) | ||

518 | * in your MODEL. | ||

519 | *) | ||

520 | RUN ClearAll; | ||

521 | RUN specify; | ||

522 | END reset; | ||

523 | aw0a | 1 | END testcmumodel; |

524 | |||

525 | MODEL your_site_models(); | ||

526 | (* if you create a library to share with the net which is | ||

527 | * not just an end application of Carnegie Mellon models, | ||

528 | * please create an empy root MODEL such as this and use | ||

529 | * it as the origin of your library in the same way that | ||

530 | * we use cmumodel as the origin of our libraries. | ||

531 | * Thank you. | ||

532 | *) | ||

533 | END your_site_models; |

john.pye@anu.edu.au | ViewVC Help |

Powered by ViewVC 1.1.22 |