// From "Design and validation of a controller", Laure Petrucci, SCI 2000
// http://www.lsv.ens-cachan.fr/Publis/PAPERS/Pet-sci2000.ps

// Normally, Maria reports 836 states, 2644 arcs
// #define MIN // for canonical initial markings (512 states, 1600 arcs)
// #define MAX // for worst possible initial markings (898 states, 2819 arcs)
// #define OPT // optimised model (no intermediate states)

/* The MIN option unfires the following local transitions, transforming
 * the initial marking to a situation where no local actions have been
 * performed after synchronisations:
 *  t1, t7..t6, t8, t45..t44, t50
 */

/* The MAX option fires the following local transitions, transforming
 * the initial marking to a situation where only synchronisation actions
 * are enabled:
 *  t9, t16, t31, t32, t53, t25..t30, t11..t12, t35..t38, t51..t52
 */

#ifdef MODULAR
trans :t2;

subnet
{
#endif // MODULAR

#ifndef OPT
  place i12 (1) bool:
# ifdef MIN
    true
# else // MIN
    false
# endif //MIN
    ;
  trans i12_t1 in { place i12: true; } out { place i12: false; };
#endif // !OPT

#ifdef MODULAR
  trans i12_t2:trans t2
#else // MODULAR
  trans :i12_t2
#endif // MODULAR
#ifndef OPT
  in { place i12: false; } out { place i12: true; }
#endif // !OPT
  ;
#ifdef MODULAR
};

trans :t5;

subnet
{
#endif // MODULAR

#ifdef OPT
  place a (1) bool: false;
#else // OPT
  place a (1) unsigned (1..6):
# ifdef MIN
    4
# else // MIN
    6
# endif // MIN
    ;

  trans a_t in { place a: a; } out { place a: +a; }
  gate a != 6, a != 3;
#endif // OPT

#ifdef MODULAR
  trans a_t2:trans t2
#else // MODULAR
  trans :a_t2
#endif // MODULAR
#ifdef OPT
  in { place a: false; } out { place a: true; };
#else // OPT
  in { place a: 6; } out { place a: 1; };
#endif // OPT
#ifdef MODULAR
  trans a_t5:trans t5
#else // MODULAR
  trans :a_t5
#endif // MODULAR
#ifdef OPT
  in { place a: true; } out { place a: false; };
#else // OPT
  in { place a: 3; } out { place a: 4; };
#endif // OPT
#ifdef MODULAR
};

trans :t10;

subnet
{
#endif // MODULAR

#ifdef OPT
  place w1 (1) bool: false;
#else // OPT
  place w1 (1) unsigned (11..14):
# ifdef MAX
    13
# else // MAX
#  ifdef MIN
    11
#  else // MIN
    12
#  endif // MIN
# endif // MAX
    ;

  trans w1_t in { place w1: w; } out { place w1: +w; }
  gate w != 13, w != 14;
#endif // OPT

#ifdef MODULAR
  trans w1_t5:trans t5
#else // MODULAR
  trans :w1_t5
#endif // MODULAR
#ifdef OPT
  in { place w1: true; } out { place w1: false; };
#else // OPT
  in { place w1: 14; } out { place w1: 11; };
#endif // OPT
#ifdef MODULAR
  trans w1_t10:trans t10
#else // MODULAR
  trans :w1_t10
#endif // MODULAR
#ifdef OPT
  in { place w1: false; } out { place w1: true; };
#else // OPT
  in { place w1: 13; } out { place w1: 14; };
#endif // OPT
#ifdef MODULAR
};

trans :t17;

subnet
{
#endif // MODULAR

#ifndef OPT
  place i34 (1) bool:
# ifdef MAX
    false
# else // MAX
    true
# endif // MAX
    ;

  trans i34_t16 in { place i34: true; } out { place i34: false; };
#endif // !OPT

#ifdef MODULAR
  trans i34_t17:trans t17
#else // MODULAR
  trans :i34_t17
#endif // MODULAR
#ifndef OPT
  in { place i34: false; } out { place i34: true; }
#endif // !OPT
  ;
#ifdef MODULAR
};

trans :t13;
trans :t33;
trans :t34;

subnet
{
#endif // MODULAR

#ifdef OPT
  place w (1) bool: false;
  place w3 (1) bool: false;
#else // OPT
  place w (1) unsigned (33..36):
# ifdef MAX
    36
# else // MAX
    33
# endif // MAX
    ;
  place w3 (0..1) unsigned (31..32)
# ifdef MAX
# else // MAX
    : 32
# endif // MAX
    ;

  trans w3_t31 in { place w3: 32; place w: 33; } out { place w: 34; };
  trans w3_t32 in { place w: 34; } out { place w: 36; };
#endif // OPT

#ifdef MODULAR
  trans w3_t13:trans t13
#else // MODULAR
  trans :w3_t13
#endif // MODULAR
#ifdef OPT
  in { place w3: true; } out { place w3: false; };
#else // OPT
  in { place w3: 31; } out { place w3: 32; };
#endif // OPT
#ifdef MODULAR
  trans w3_t34:trans t34
#else // MODULAR
  trans :w3_t34
#endif // MODULAR
#ifdef OPT
  in { place w: true; } out { place w: false; };
#else // OPT
  in { place w: 35; } out { place w: 33; };
#endif // OPT
#ifdef MODULAR
  trans w3_t33:trans t33
#else // MODULAR
  trans :w3_t33
#endif // MODULAR
#ifdef OPT
  in { place w3: false; place w: false; }
  out { place w3: true; place w: true; };
#else // OPT
  in { place w: 36; } out { place w3: 31; place w: 35; };
#endif // OPT
#ifdef MODULAR
};

trans :t24;
trans :t39;

subnet
{
#endif // MODULAR

#ifdef OPT
  place w2 (1) bool: false;
#else // OPT
  place w2 (1) unsigned (21..24):
# ifdef MIN
    21
# else // MIN
    23
# endif // MIN
    ;

  trans w2_t in { place w2: w; } out { place w2: +w; }
  gate w != 23, w != 24;
#endif // OPT

#ifdef MODULAR
  trans w2_t24:trans t24
#else // MODULAR
  trans :w2_t24
#endif // MODULAR
#ifdef OPT
  in { place w2: true; } out { place w2: false; };
#else // OPT
  in { place w2: 24; } out { place w2: 21; };
#endif // OPT
#ifdef MODULAR
  trans w2_t39:trans t39
#else // MODULAR
  trans :w2_t39
#endif // MODULAR
#ifdef OPT
  in { place w2: false; } out { place w2: true; };
#else // OPT
  in { place w2: 23; } out { place w2: 24; };
#endif // OPT
#ifdef MODULAR
};

trans :t49;

subnet
{
#endif // MODULAR

#ifndef OPT
  place o (1) bool:
#ifdef MAX
    false
#else
    true
#endif
    ;
  trans o_t53 in { place o: true; } out { place o: false; };
#endif // !OPT

#ifdef MODULAR
  trans o_t49:trans t49
#else // MODULAR
  trans :o_t49
#endif // MODULAR
#ifndef OPT
  in { place o: false; } out { place o: true; }
#endif // !OPT
  ;
#ifdef MODULAR
};

subnet
{
#endif // MODULAR

#ifdef OPT
  place b (1) bool: false;
#else // OPT
  place b (1) unsigned (1..14):
# ifdef MAX
    14
# else // MAX
    8
# endif // MAX
    ;
  trans b in { place b: b; } out { place b: +b; }
  gate b != 7, b != 14;
#endif // OPT

#ifdef MODULAR
  trans t24:trans t24
#else // MODULAR
  trans :t24
#endif // MODULAR
#ifdef OPT
  in { place b: true; } out { place b: false; };
#else // OPT
  in { place b: 7; } out { place b: 8; };
#endif // OPT
#ifdef MODULAR
  trans t17:trans t17
#else // MODULAR
  trans :t17
#endif // MODULAR
#ifdef OPT
  in { place b: false; } out { place b: true; };
#else // OPT
  in { place b: 14; } out { place b: 1; };
#endif // OPT
#ifdef MODULAR
};

subnet
{
#endif // MODULAR

#ifdef OPT
  place d (1) bool: false;
#else // OPT
  place d (1) unsigned (1..6):
# ifdef MAX
    6
# else // MAX
    4
# endif // MAX
    ;

  trans d in { place d: d; } out { place d: +d; }
  gate d != 3, d != 6;
#endif // OPT

#ifdef MODULAR
  trans t10:trans t10
#else // MODULAR
  trans :t10
#endif // MODULAR
#ifdef OPT
  in { place d: true; } out { place d: false; };
#else // OPT
  in { place d: 3; } out { place d: 4; };
#endif // OPT
#ifdef MODULAR
  trans t13:trans t13
#else // MODULAR
  trans :t13
#endif // MODULAR
#ifdef OPT
  in { place d: false; } out { place d: true; };
#else // OPT
  in { place d: 6; } out { place d: 1; };
#endif // OPT
#ifdef MODULAR
};

subnet
{
#endif // MODULAR

#ifdef OPT
  place e (1) bool: false;
#else // OPT
  place e (1) unsigned (1..10):
# ifdef MAX
    5
# else // MAX
    1
# endif // MAX
    ;

  trans e in { place e: e; } out { place e: +e; }
  gate e != 5, e != 10;
#endif // OPT

#ifdef MODULAR
  trans t39:trans t39
#else // MODULAR
  trans :t39
#endif // MODULAR
#ifdef OPT
  in { place e: false; } out { place e: true; };
#else // OPT
  in { place e: 5; } out { place e: 6; };
#endif // OPT
#ifdef MODULAR
  trans t34:trans t34
#else // MODULAR
  trans :t34
#endif // MODULAR
#ifdef OPT
  in { place e: true; } out { place e: false; };
#else // OPT
  in { place e: 10; } out { place e: 1; };
#endif // OPT
#ifdef MODULAR
};

subnet
{
#endif // MODULAR

#ifdef OPT
  place f (1) bool: false;
#else // OPT
  place f (1) unsigned (1..8):
# ifdef MAX
    8
# else // MAX
#  ifdef MIN
    5
#  else // MIN
    6
#  endif // MIN
# endif // MAX
    ;

  trans f in { place f: f; } out { place f: +f; }
  gate f != 4, f != 8;
#endif // OPT

#ifdef MODULAR
  trans t49:trans t49
#else // MODULAR
  trans :t49
#endif // MODULAR
#ifdef OPT
  in { place f: true; } out { place f: false; };
#else // OPT
  in { place f: 4; } out { place f: 5; };
#endif // OPT
#ifdef MODULAR
  trans t33:trans t33
#else // MODULAR
  trans :t33
#endif // MODULAR
#ifdef OPT
  in { place f: false; } out { place f: true; };
#else // OPT
  in { place f: 8; } out { place f: 1; };
#endif // OPT
#ifdef MODULAR
};
#else // MODULAR
trans t2:trans i12_t2:trans a_t2;
trans t5:trans a_t5:trans w1_t5;
trans t10:trans w1_t10:trans t10;
trans t17:trans i34_t17:trans t17;
trans t13:trans w3_t13:trans t13;
trans t33:trans w3_t33:trans t33;
trans t34:trans w3_t34:trans t34;
trans t24:trans w2_t24:trans t24;
trans t39:trans w2_t39:trans t39;
trans t49:trans o_t49:trans t49;
#endif // MODULAR
