home *** CD-ROM | disk | FTP | other *** search
- /*
- * Production.C - methods for L-System productions.
- *
- * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
- * University of Berne, Switzerland
- * All rights reserved.
- *
- * This software may be freely copied, modified, and redistributed
- * provided that this copyright notice is preserved on all copies.
- *
- * You may not distribute this software, in whole or in part, as part of
- * any commercial product without the express consent of the authors.
- *
- * There is no warranty or other guarantee of fitness of this software
- * for any purpose. It is provided solely "as is".
- *
- */
-
- #include <stdlib.h>
- #include "Production.h"
- #include "Error.h"
-
- implementList(ProductionList, ProductionPtr);
-
- //___________________________________________________________ Production
-
- Production::Production(Predecessor* p, Expression* c, SuccessorList* s)
- : _name(p->name), predecessor(p), condition(c), successors(s)
- {
- arg_count = (p->formalParam) ? (int)p->formalParam->count()
- : 0;
- stochastic = (successors->count() > 1);
- }
-
- Production::~Production()
- {
- delete predecessor;
- if (condition) delete condition;
-
- for (long i=0; i<successors->count(); i++)
- delete successors->item(i);
- delete successors;
- }
-
- // choose a successor out of the successor list and clone it
- ModuleList* Production::cloneSuccessor()
- {
- // if we have more than one successor, choose by random
- if (stochastic) {
- double p = drand48();
- for (register long i=0; i<successors->count(); i++)
- if (p <= successors->item(i)->probability())
- return successors->item(i)->clone();
-
- // No successor choosen. VERY, VERY BAD!
- Error(ERR_PANIC, "cloneSuccessor: no successor choosen");
- return NULL;
- }
- else
- return successors->item(0)->clone();
- }
-
- // The probabilities of the successor must cumulate to 1. In addition
- // a preprocessing is done, e.g.:
- // A -> (0.5) B => A -> (0.5) B
- // -> (0.5) C -> (1.0) C
- // => no arithmetic operation has to be performed will choosing a
- // successor
- int Production::cumulateProbability()
- {
- double sum = 0.0;
-
- for (long i=0; i<successors->count(); i++) {
- sum += successors->item(i)->probability();
- successors->item(i)->probability() = sum;
- }
- return ((sum > 1.01) ? 1 : 0);
- }
-
- int Production::hashValue()
- {
- extern unsigned int modHash(const char*, long);
- return modHash((const char*)_name, (long)arg_count);
- }
-
- ostream& operator<<(ostream& os, Production& p)
- {
- long i;
-
- os << p.predecessor->name;
- if (p.predecessor->formalParam) {
- os << '(';
- for (i=0; i<p.predecessor->formalParam->count()-1; i++)
- os << *p.predecessor->formalParam->item(i) << ", ";
- os << *p.predecessor->formalParam->item(i) << ")";
- }
- if (p.condition) os << " : " << *p.condition << ' ';
-
- for (i=0; i<p.successors->count()-1; i++)
- os << *p.successors->item(i) << "\n\t";
- os << *p.successors->item(i) << '\n';
-
- return os;
- }
-