1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
|
// Transition class -*- c++ -*-
#ifndef TRANSITION_H_
# define TRANSITION_H_
# ifdef __GNUC__
# pragma interface
# endif // __GNUC__
# include <string.h>
# include <assert.h>
# include <map>
# include <list>
# include "util.h"
# include "Error.h"
/** @file Transition.h
* Transition in an algebraic system net
*/
/* Copyright 1998-2003,2005 Marko Mkel (msmakela@tcs.hut.fi).
This file is part of MARIA, a reachability analyzer and model checker
for high-level Petri nets.
MARIA is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
MARIA is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
/** Transition class */
class Transition
{
public:
/** Kind of the transition */
enum Kind {
tNormal = 0, //< Regular transition
tUndefined, //< A safety assertion that does not abort analysis
tFatal //< A safety assertion that aborts the analysis
};
/** Actions for unifiability test */
enum Unif {
uNormal = 0,//< Report variables that cannot be unified
uIgnore, //< Ignore gates and outputs
uRemove //< Remove gates depending on un-unifiable variables
};
/** List of gate expressions */
typedef std::list<class Expression*> GateList;
/** Map from names to variables defined in the transition */
typedef std::map<const char*,class VariableDefinition*,
struct ltstr> VariableMap;
/** Iterator to the variable name map */
typedef VariableMap::iterator iterator;
/** Constant iterator to the variable name map */
typedef VariableMap::const_iterator const_iterator;
/** Map from names to functions defined in the transition */
typedef std::map<const char*,class Function*,struct ltstr> FunctionMap;
/** Constructor for anonymous transitions */
Transition ();
/** Constructor
* @param net the net this transition belongs to
* @param i index number of the transition (in the net)
* @param name name of the transition
*/
Transition (class Net& net,
unsigned i,
char* name);
private:
/** Copy constructor */
Transition (const class Transition& old);
/** Assignment operator */
class Transition& operator= (const class Transition& old);
public:
/** Destructor */
~Transition ();
/** Get the net of the transition */
const class Net* getNet () const { return myNet; }
/** Get the index number of the transition in the local net */
unsigned getLocalIndex () const { return myLocalIndex; }
/** Get the index number of the transition in the root net */
unsigned getRootIndex () const { return myRootIndex; }
/** Set the index number of the transition in the root net */
void setRootIndex (unsigned root) { myRootIndex = root; }
/** Get the name of the transition */
const char* getName () const { return myName; }
/** Get the number of parents (0 if this is not a sync transition) */
unsigned getNumParents () const { return myNumParents; }
/** Get a parent of this transition by index number */
const class Transition& getParent (unsigned i) const {
assert (i < myNumParents);
return *myParents[i];
}
# ifndef NDEBUG
/** Determine whether the transition has a specific parent
* @param parent parent transition to look for
*/
bool hasParent (const class Transition& parent) const;
/** Determine whether the transition has a specific child
* @param child child transition to look for
*/
bool hasChild (const class Transition& child) const;
# endif // NDEBUG
/** Change the parent transition to indicate synchronisation label
* @param old the old parent transition
* @param fused the new (fused) parent transition
*/
void changeParent (const class Transition& old,
const class Transition& fused);
/** Get the number of children the transition has */
unsigned getNumChildren () const { return myNumChildren; }
/** Get a child transition by index number */
const class Transition& getChild (unsigned i) const {
assert (i < myNumChildren);
return *myChildren[i];
}
/** Register a sync transition in a child net
* @param child the child transition
*/
void addChild (class Transition& child);
/** Get the priority level (0=none) */
unsigned getPriority () const { return myPriority; }
/** Set the priority level (0=none) */
void setPriority (unsigned priority) { myPriority = priority; }
/** Get the kind of the transition */
enum Kind getKind () const { return myKind; }
/** Flag the transition an assertion
* @param fatal flag: is this a fatal assertion?
*/
void setAssertion (bool fatal);
/** Determine if a transition instance should be hidden
* @param valuation the valuation
*/
bool isHidden (const class Valuation& valuation) const;
/** Add an enabling condition (conjunct with existing condition)
* @param gate the enabling condition
*/
void addGate (class Expression& gate);
/** Add a hide condition (disjunct with existing condition)
* @param qualifier the hiding condition
*/
void addHide (class Expression& qualifier);
/** Add a fairness constraint
* @param qualifier transition instance qualifier expression
* @param id identifier of the fairness set
* @param isStrong flag: is this a strong fairness constraint
* @return number of fairness constraints
*/
unsigned addFairness (class Expression& qualifier,
unsigned id,
bool isStrong);
/** Add an enabledness constraint
* @param qualifier transition instance qualifier expression
* @param id identifier of the enabledness set
* @return number of fairness constraints
*/
unsigned addEnabledness (class Expression& qualifier,
unsigned id);
/** Get a variable by name
* @param name Name of the variable
* @return the VariableDefinition object; NULL if there is none
*/
const class VariableDefinition* getVariable (const char* name) const {
const_iterator i = myVariables.find (name);
return i != myVariables.end () ? i->second : NULL;
}
/** Determine whether a variable is present on any of the input arcs
* @param variable variable to look for (NULL=PlaceContents)
* @return true if it is an input variable
*/
bool isInput (const class VariableDefinition* variable) const;
/** Determine whether a variable is present on any of the output arcs
* @param variable variable to look for (NULL=PlaceContents)
* @return true if it is an output variable
*/
bool isOutput (const class VariableDefinition* variable) const;
/** Determine whether a variable is present on a gate expression
* @param variable variable to look for (NULL=PlaceContents)
* @return true if the variable is used in a gate expression
*/
bool isGate (const class VariableDefinition* variable) const;
/** @name Accessors to the variable map */
/*@{*/
const_iterator begin () const { return myVariables.begin (); }
const_iterator end () const { return myVariables.end (); }
iterator begin () { return myVariables.begin (); }
iterator end () { return myVariables.end (); }
size_t size () const { return myVariables.size (); }
/*@}*/
/** @name Accessors to the gate expression list */
/*@{*/
GateList::const_iterator beginG () const { return myGates.begin (); }
GateList::const_iterator endG () const { return myGates.end (); }
/*@}*/
/** Add an output variable
* @param type Type of the variable
* @param name Name of the variable (may be NULL)
* @param expr Condition expression for the quantification
* @return reference to the VariableDefinition object
*/
const class VariableDefinition& addOutputVariable (const class Type& type,
char* name,
class Expression* expr);
/** Get the quantifier list for the output variables of the transition */
const class QuantifierList* getOutputVariables () const {
return myOutputVariables;
}
/** Add a variable
* @param name Name of the variable
* @param type Type of the variable
* @param aggregate flag: is this an output variable (quantifier)?
* @param hidden flag: should the variable be hidden?
* @return reference to the VariableDefinition object
*/
const class VariableDefinition& addVariable (char* name,
const class Type& type,
bool aggregate,
bool hidden);
/** Get a function definition by name
* @param name Name of the function
* @return The function definition
*/
class Function* getFunction (const char* name) {
FunctionMap::const_iterator i = myFunctions.find (name);
return i == myFunctions.end () ? NULL : i->second;
}
/** Add a function definition
* @param function The function
*/
void addFunction (class Function& function);
/** Check the gates
* @param valuation Valuation for evaluating the gate expressions
* @param err error code to accept (typically errVar or errNone)
* @return true if the gates allow the transition to be fired
*/
bool checkGates (const class Valuation& valuation,
enum Error err = errVar) const;
/** Add an arc
* @param arc The arc to be added
*/
void addArc (class Arc& arc);
/** Determine whether the transition has an arc from/to a place
* @param output specifies the type of arcs to look for
* @param place identifies the place
* @return the arc, or NULL
*/
class Arc* getArc (bool output, const class Place& place);
/** Determine whether the transition has input arcs */
bool hasInputs () const { return myNumInputs != 0; }
/** Determine whether the transition has output arcs */
bool hasOutputs () const { return myNumOutputs != 0; }
/** Determine the number of input arcs */
unsigned getNumInputs () const { return myNumInputs; }
/** Determine the number of output arcs */
unsigned getNumOutputs () const { return myNumOutputs; }
/** Get an input arc
* @param i index number of the arc
*/
const class Arc& getInput (unsigned i) const {
assert (i < myNumInputs); return *myInputs[i];
}
/** Get an output arc
* @param i index number of the arc
*/
const class Arc& getOutput (unsigned i) const {
assert (i < myNumOutputs); return *myOutputs[i];
}
/** Determine the number of weak fairness sets the transition belongs to */
unsigned getNumWeaklyFair () const { return myNumWeaklyFair; }
/** Determine the number of strong fairness sets the transition belongs to */
unsigned getNumStronglyFair () const { return myNumStronglyFair; }
/** Determine the number of enabledness sets the transition belongs to */
unsigned getNumEnabled () const { return myNumEnabled; }
/** Add a constant
* @param name name of the constant
* @param constant the constant
* @return true if the constant had a unique name
*/
bool addConstant (char* name, class Constant& constant);
/** Retrieve a constant by name
* @param name name of the constant
* @return the constant, or NULL if none found
*/
const class Constant* getConstant (const char* name) const;
/** Get the number of constants */
unsigned getNumConstants () const { return myNumConstants; }
/** Get the name of a constant
* @param i index number of the constant
* @return the name of the constant
*/
const char* getConstantName (unsigned i) const {
assert (i < myNumConstants);
return myConstantNames[i];
}
/** Get a constant
* @param i index number of the constant
* @return the constant
*/
const class Constant& getConstant (unsigned i) const {
assert (i < myNumConstants);
return *myConstants[i];
}
/** Fuse a callee transition to this one
* @param callee the transition to be fused
* @param printer the printer object for diagnostics
* @param warn flag: issue warnings
* @return true if the operation was successful
*/
bool fuse (const class Transition& callee,
const class Printer& printer,
bool warn);
/** Determine whether the transition can be unified
* @param action additional actions to take
* @param printer the printer object for diagnostics
* @return true if the transition can be unified
*/
bool isUnifiable (enum Unif action,
const class Printer& printer);
/** Determine all enabled instances of the transition for a marking
* @param m the marking to be analyzed
* @param reporter the interface for reporting successors or errors
*/
void analyze (class GlobalMarking& m,
class StateReporter& reporter) const;
/** Report a rejected successor state
* @param valuation the transition binding
* @param marking the erroneous successor state
* @param reason reason for failure (optional)
* @param place the place whose marking could not be encoded (optional)
* @param printer the output stream for the message
*/
void report (const class Valuation& valuation,
const class GlobalMarking& marking,
const char* reason,
const class Place* place,
const class Printer& printer) const;
/** Display an edge to a successor state
* @param valuation the transition binding
* @param marking the successor state
* @param printer the output stream for the message
*/
void displayEdge (const class Valuation& valuation,
const class GlobalMarking& marking,
const class Printer& printer) const;
/** Unfold the transition with the help of a coverable marking
* @param cover (input/output) the coverable marking
* @param lnet the low-level net being generated
* @param reporter the reporting interface
*/
void unfold (class GlobalMarking& cover,
class LNet& lnet,
class DummyReporter& reporter) const;
/** Unfold the transition by iterating the variable domains
* @param lnet the low-level net being generated
* @param reporter the reporting interface
*/
void unfold (class LNet& lnet,
class DummyReporter& reporter) const;
/** Determine which weak fairness sets a transition instance belongs to
* @param valuation variable substitutions
* @param sets (output) sets[1..*sets]: weak fairness sets
*/
void computeWeaklyFair (const class Valuation& valuation,
unsigned* sets) const;
/** Determine which strong fairness sets a transition instance belongs to
* @param valuation variable substitutions
* @param sets (output) sets[1..*sets]: strong fairness sets
*/
void computeStronglyFair (const class Valuation& valuation,
unsigned* sets) const;
/** Log the enabled enabledness sets
* @param valuation variable substitutions
* @param log the enabledness sets
*/
void logEnabled (const class Valuation& valuation,
char* log) const;
# ifdef EXPR_COMPILE
private:
/** Compile transition instance analysis
* @param cexpr compilation output
* @param inputPlaces the input places
* @param numOptVars number of optional variables
*/
void compileAnalysis (class CExpression& cexpr,
const std::list<const class Place*>& inputPlaces,
unsigned numOptVars) const;
public:
/** Compile the expressions of the transition
* @param out the output stream
*/
void compile (class StringBuffer& out) const;
# endif // EXPR_COMPILE
/** Display the transition definition
* @param printer the printer object
*/
void display (const class Printer& printer) const;
private:
/** The net this transition belongs to */
class Net* myNet;
/** Index number of the transition in myNet */
unsigned myLocalIndex;
/** Index number of the transition in the root net */
unsigned myRootIndex;
/** Name of the transition */
char* myName;
/** Number of parent transitions */
unsigned myNumParents;
/** Parent transitions (for transitions in child nets) */
const class Transition** myParents;
/** Number of child transitions */
unsigned myNumChildren;
/** Child transitions in child nets */
const class Transition** myChildren;
/** Priority level (0=none) */
unsigned myPriority;
/** Kind of the transition */
enum Kind myKind;
/** Number of input arcs */
unsigned myNumInputs;
/** Input arcs */
class Arc** myInputs;
/** Number of output arcs */
unsigned myNumOutputs;
/** Output arcs */
class Arc** myOutputs;
/** Flag: do the outputs depend on the input marking? */
bool myOutputMarking;
/** List of tokens to be unified */
struct unif* myUnif;
/** Number of weak fairness sets */
unsigned myNumWeaklyFair;
/** Number of strong fairness sets */
unsigned myNumStronglyFair;
/** Number of enabledness sets */
unsigned myNumEnabled;
/** Weak fairness conditions */
class Expression** myWeaklyFairCond;
/** Strong fairness conditions */
class Expression** myStronglyFairCond;
/** Enabledness conditions */
class Expression** myEnabledCond;
/** Weak fairness sets */
unsigned* myWeaklyFairSet;
/** Strong fairness sets */
unsigned* myStronglyFairSet;
/** Enabledness sets */
unsigned* myEnabledSet;
/** Gate expressions */
GateList myGates;
/** Hiding condition */
class Expression* myHide;
/** Output variables */
class QuantifierList* myOutputVariables;
/** Transition variables indexed by name */
VariableMap myVariables;
/** Functions indexed by name */
FunctionMap myFunctions;
/** Number of constants */
unsigned myNumConstants;
/** Names of constants */
char** myConstantNames;
/** Constants */
class Constant** myConstants;
};
#endif // TRANSITION_H_
|