File: Transition.h

package info (click to toggle)
maria 1.3.5-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 3,980 kB
  • ctags: 5,458
  • sloc: cpp: 43,402; yacc: 8,080; ansic: 436; sh: 404; lisp: 395; makefile: 291; perl: 21
file content (524 lines) | stat: -rw-r--r-- 18,007 bytes parent folder | download | duplicates (5)
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_