Petri nets are useful tools for modeling systems with control flow. In particular they aid in modeling systems with concurrency, and parallelism. A set of routines have been developed at UWO to serve as the basis for a manufacturing simulation. The routines will support a number of various Petri net functions. The basic operation of the Petri net may be simulated. As well the EOR transitions will also be modeled. An attempt has been made to add ‘colors’ to the tokens, but at the present there is insufficient information (i.e., no references) to verify the implementation.
The routines have been written in a user friendly way to allow simple application interface. Places and Transitions are specified with textual names. A brief theory of petri nets follows.
There are four basic elements in a petri net; places, transitions, arcs, and tokens. If we are to think in terms of a factory, tokens are equivalent to work parts. Arcs are the paths the work will follow through the factory. Places are buffers where parts are stored temporarily, and transitions are equivalent to machines where the parts are used to make new parts.
The basic operation is that tokens are introduced to the network, and then transitions are fired in different orders, and thus tokens are created and destroyed at the transitions. The example below follows the petri net for a few cycles. The first figure shows the Petri Net with the initial markings.
The reader should note that there are a few interesting properties found in Petri nets.
Transitions are fired when all of their inputs are satisfied, and the user specifies that transition.
Most analysis of petri nets uses random firings of the transitions to obtain statistical performance.
Other basic references to the petri net theory are available in Peterson [1981] and Reisig [1985].
The subroutines are applied in a methodical manner. Before the user can integrate the subroutines into their program, they must draw out the petri net, and label all places and transitions. The example given above is illustrated below.
After these labels are determined, they are defined using the petri net subroutines. The arcs in the petri net are also defined in the program. There are defined with respect to the transitions. That is to say that an arc is an input to, or output from a transition. After the petri net structure has been defined, tokens may be placed in the places of the net. The tokens are as given in the previous example.
The transitions are then selectively fired in the net, by function calls in the program. This program also has calls to functions which print the petri net structure after each transition. The code is show below for the example above.
* BASIC TEST NET (Peterson book, 1981, pg. 19)
static int p1, p2, p3, p4, p5;
t1 = petri_transition(&net, “t1”);
t2 = petri_transition(&net, “t2”);
t3 = petri_transition(&net, “t3”);
t4 = petri_transition(&net, “t4”);
petri_output(&net, p2, t1, 1);
petri_output(&net, p3, t1, 1);
petri_output(&net, p4, t1, 1);
petri_output(&net, p4, t1, 1);
petri_output(&net, p2, t2, 1);
petri_output(&net, p5, t3, 1);
petri_output(&net, p3, t4, 1);
petri_output(&net, p4, t4, 1);
petri_add_tokens(&net, p1, 1);
petri_add_tokens(&net, p4, 2);
petri_add_tokens(&net, p5, 1);
As can be seen this method of implementation is very simple. The user is able to define a number of nets, and refer to transitions and places by name.
In some cases we want to prevent a transition from firing. To do this, the idea of inhibiting inputs has been proposed. If a transition has an inhibiting input from a place, that has any tokens in it, then the transition cannot fire. Otherwise the transition may fire normally. A sample net has been devised for this case, it is seen below.
The program below shows that the inhibiting input is simply defined when the arc is defined.
* INHIBITED TEST NET (Peterson book, 1981, pg. 196)
static int p1, p2, p3, p4, p5, p6;
t1 = petri_transition(&net, “t1”);
t2 = petri_transition(&net, “t2”);
t3 = petri_transition(&net, “t3”);
t4 = petri_transition(&net, “t4”);
petri_input(&net, p3, t4, INHIBIT);
petri_output(&net, p1, t1, 1);
petri_output(&net, p3, t1, 1);
petri_output(&net, p2, t2, 1);
petri_output(&net, p4, t3, 1);
petri_output(&net, p5, t3, 1);
petri_output(&net, p6, t4, 1);
petri_add_tokens(&net, p1, 1);
petri_add_tokens(&net, p2, 1);
petri_add_tokens(&net, p5, 1);
petri_add_tokens(&net, p6, 1);
The inhibitory inputs are complimentary to the exclusive or function. Thus another research proposed an Exclusive or transition which will fire when one (and only one) input is from a place with tokens. An example of a problem using this, a ring shift register was modeled. This net is modeled as shown below.
In this example the EOR transition is marked with a plus in a circle (at ‘t7’). When run, a token will appear in p1, p3, and p5 in a repeating cycle. The program to set this up is seen below.
* EOR TEST NET (Peterson book, 1981, discussed pg. 190)
* This is for a single bit shifter
static int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
static int t1, t2, t3, t4, t5, t6, t7;
p10 = petri_place(&net, “p10”);
t1 = petri_transition(&net, “t1”);
t2 = petri_transition(&net, “t2”);
t3 = petri_transition(&net, “t3”);
t4 = petri_transition(&net, “t4”);
t5 = petri_transition(&net, “t5”);
t6 = petri_transition(&net, “t6”);
t7 = petri_transition(&net, “t7”);
petri_input(&net, p10, t7, 1);
petri_output(&net, p1, t1, 1);
petri_output(&net, p3, t2, 1);
petri_output(&net, p5, t3, 1);
petri_output(&net, p2, t4, 1);
petri_output(&net, p8, t4, 1);
petri_output(&net, p4, t5, 1);
petri_output(&net, p9, t5, 1);
petri_output(&net, p6, t6, 1);
petri_output(&net, p10, t6, 1);
petri_output(&net, p7, t7, 1);
petri_type_transition(&net, t7, EOR);
petri_add_tokens(&net, p1, 1);
This section should be considered incorrect. The theory has not been found, although the approach should adhere to the concept. The concept is that each token may now have a color, and a second bit of private information. If a transition is specified to be colored, it will only fire if tokens of the specified color are available at the inputs. The subroutines will then require that the user supply a new set of instance information so that new tokens may be issued.
The net used has tokens of mixed colors in it, an is seen below.
The code is shown below. The reader should note that a second subroutine is used. This is done because there is a bit of code which would be repeated for each update of tokens at the transition.
* COLOR TEST NET (Assumed for now)
* Two consumers of different colors and one input. The instances of tokens
static int color1 = 1, color2 = 2;
static int instance[20], instance_pnt;
t1 = petri_transition(&net, “t1”);
t2 = petri_transition(&net, “t2”);
petri_output(&net, p1, t1, 1);
petri_output(&net, p2, t2, 1);
petri_type_transition(&net, t1, COLORED);
petri_type_transition(&net, t2, COLORED);
for(i = 0; i < 20; i++) instance[i] = i;
petri_add_color_token(&net, p1, color1, instance[instance_pnt]);
petri_add_color_token(&net, p2, color2, instance[instance_pnt]);
petri_add_color_token(&net, p3, color1, instance[instance_pnt]);
petri_add_color_token(&net, p3, color2, instance[instance_pnt]);
sub4(&net, t2, color1, instance, &instance_pnt);
sub4(&net, t1, color1, instance, &instance_pnt);
sub4(&net, t1, color1, instance, &instance_pnt);
sub4(&net, t2, color2, instance, &instance_pnt);
int sub4(net, transition, color, instance, instance_pnt)
int transition, color, *instance, *instance_pnt;
static int error, i, list[20], n, outputs;
if(petri_in_event(net, transition, color) == NO_ERROR){
if(petri_get_consumed(net, transition, &color, list, &n, &outputs) == NO_ERROR){
for(i = 0; i <= n; i++) instance[list[i]] = -1000;
if(petri_set_produced(net, transition, &(instance[*instance_pnt]),outputs) == NO_ERROR){
error = petri_out_event(net, transition);
Relational nets will use various firing rules for each transition. This is by far the most useful for varied manufacturing conditions. An example is seen below.
This may be seen in the fifth test subroutine in the program.
At present there is one data structure used which holds structures for Places and for Transitions. Arc information is stored (redundantly) in both. These are defined when a Place or Transition number is requested for one that does not exist. Each place and transition have reference numbers, which are used by all other net functions.
The software is still undergoing development, and testing, thus a list of functions would be premature.
3.1 Peterson, J.L., “Petri Net Theory and the Modelling of Systems”, Prentice-Hall, Inc., N.J., U.S.A., 1981.
3.2 Reisig, W., “Petri Nets; An Introduction”, Springer-Verlag, 1985.
if(argv[1][0] == '1') test1();
if(argv[1][0] == '2') test2();
if(argv[1][0] == '3') test3();
if(argv[1][0] == '4') test4();
if(argv[1][0] == '5') test5();
* BASIC TEST NET (Peterson book, 1981, pg. 21)
static int p1, p2, p3, p4, p5;
t1 = petri_transition(&net, "t1");
t2 = petri_transition(&net, "t2");
t3 = petri_transition(&net, "t3");
t4 = petri_transition(&net, "t4");
petri_input(&net, p1, t1, 1, NO_COLOR, NO_RULE);
petri_input(&net, p2, t2, 1, NO_COLOR, NO_RULE);
petri_input(&net, p3, t2, 1, NO_COLOR, NO_RULE);
petri_input(&net, p4, t2, 1, NO_COLOR, NO_RULE);
petri_input(&net, p4, t3, 2, NO_COLOR, NO_RULE);
petri_input(&net, p5, t4, 1, NO_COLOR, NO_RULE);
petri_output(&net, t1, p2, 1, NO_COLOR, NO_RULE);
petri_output(&net, t1, p3, 1, NO_COLOR, NO_RULE);
petri_output(&net, t1, p4, 2, NO_COLOR, NO_RULE);
petri_output(&net, t2, p2, 1, NO_COLOR, NO_RULE);
petri_output(&net, t3, p5, 1, NO_COLOR, NO_RULE);
petri_output(&net, t4, p3, 1, NO_COLOR, NO_RULE);
petri_output(&net, t4, p4, 1, NO_COLOR, NO_RULE);
petri_add_tokens(&net, p1, 1);
petri_add_tokens(&net, p4, 2);
petri_add_tokens(&net, p5, 1);
* INHIBITED TEST NET (Peterson book, 1981, pg. 196)
static int p1, p2, p3, p4, p5, p6;
t1 = petri_transition(&net, "t1");
t2 = petri_transition(&net, "t2");
t3 = petri_transition(&net, "t3");
t4 = petri_transition(&net, "t4");
petri_input(&net, p1, t1, 1, NO_COLOR, NO_RULE);
petri_input(&net, p2, t2, 1, NO_COLOR, NO_RULE);
petri_input(&net, p3, t2, 1, NO_COLOR, NO_RULE);
petri_input(&net, p5, t3, 1, NO_COLOR, NO_RULE);
petri_input(&net, p3, t4, INHIBIT, NO_COLOR, NO_RULE);
petri_input(&net, p4, t4, 1, NO_COLOR, NO_RULE);
petri_input(&net, p6, t4, 1, NO_COLOR, NO_RULE);
petri_output(&net, t1, p1, 1, NO_COLOR, NO_RULE);
petri_output(&net, t1, p3, 1, NO_COLOR, NO_RULE);
petri_output(&net, t2, p2, 1, NO_COLOR, NO_RULE);
petri_output(&net, t3, p4, 1, NO_COLOR, NO_RULE);
petri_output(&net, t3, p5, 1, NO_COLOR, NO_RULE);
petri_output(&net, t4, p6, 1, NO_COLOR, NO_RULE);
petri_add_tokens(&net, p1, 1);
petri_add_tokens(&net, p2, 1);
petri_add_tokens(&net, p5, 1);
petri_add_tokens(&net, p6, 1);
* EOR TEST NET (Peterson book, 1981, discussed pg. 190)
* This is for a single bit shifter
static int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
static int t1, t2, t3, t4, t5, t6, t7;
p10 = petri_place(&net, "p10");
t1 = petri_transition(&net, "t1");
t2 = petri_transition(&net, "t2");
t3 = petri_transition(&net, "t3");
t4 = petri_transition(&net, "t4");
t5 = petri_transition(&net, "t5");
t6 = petri_transition(&net, "t6");
t7 = petri_transition(&net, "t7");
petri_input(&net, p6, t1, 1, NO_COLOR, NO_RULE);
petri_input(&net, p7, t1, 1, NO_COLOR, NO_RULE);
petri_input(&net, p2, t2, 1, NO_COLOR, NO_RULE);
petri_input(&net, p7, t2, 1, NO_COLOR, NO_RULE);
petri_input(&net, p4, t3, 1, NO_COLOR, NO_RULE);
petri_input(&net, p7, t3, 1, NO_COLOR, NO_RULE);
petri_input(&net, p1, t4, 1, NO_COLOR, NO_RULE);
petri_input(&net, p3, t5, 1, NO_COLOR, NO_RULE);
petri_input(&net, p5, t6, 1, NO_COLOR, NO_RULE);
petri_input(&net, p8, t7, 1, NO_COLOR, NO_RULE);
petri_input(&net, p9, t7, 1, NO_COLOR, NO_RULE);
petri_input(&net, p10, t7, 1, NO_COLOR, NO_RULE);
petri_output(&net, t1, p1, 1, NO_COLOR, NO_RULE);
petri_output(&net, t2, p3, 1, NO_COLOR, NO_RULE);
petri_output(&net, t3, p5, 1, NO_COLOR, NO_RULE);
petri_output(&net, t4, p2, 1, NO_COLOR, NO_RULE);
petri_output(&net, t4, p8, 1, NO_COLOR, NO_RULE);
petri_output(&net, t5, p4, 1, NO_COLOR, NO_RULE);
petri_output(&net, t5, p9, 1, NO_COLOR, NO_RULE);
petri_output(&net, t6, p6, 1, NO_COLOR, NO_RULE);
petri_output(&net, t6, p10, 1, NO_COLOR, NO_RULE);
petri_output(&net, t7, p7, 1, NO_COLOR, NO_RULE);
petri_type_transition(&net, t7, EOR);
petri_add_tokens(&net, p1, 1);
* COLOR TEST NET (Assumed for now)
* Two consumers of different colors and one input. The instances of tokens
static int color1 = 1, color2 = 2;
static int instance[20], instance_pnt;
t1 = petri_transition(&net, "t1");
t2 = petri_transition(&net, "t2");
petri_input(&net, p1, t1, 1, color1, NO_RULE);
petri_input(&net, p3, t1, 1, color1, NO_RULE);
petri_input(&net, p2, t2, 1, color2, NO_RULE);
petri_input(&net, p3, t2, 1, color2, NO_RULE);
petri_output(&net, p1, t1, 1, color1, NO_RULE);
petri_output(&net, p2, t2, 1, color2, NO_RULE);
for(i = 0; i < 20; i++) instance[i] = i;
petri_add_color_token(&net, p1, color1, instance[instance_pnt]);
petri_add_color_token(&net, p2, color2, instance[instance_pnt]);
petri_add_color_token(&net, p3, color1, instance[instance_pnt]);
petri_add_color_token(&net, p3, color2, instance[instance_pnt]);
sub4(&net, t2, color1, instance, &instance_pnt);
sub4(&net, t1, color1, instance, &instance_pnt);
sub4(&net, t1, color1, instance, &instance_pnt);
sub4(&net, t2, color2, instance, &instance_pnt);
int sub4(net, transition, color, instance, instance_pnt)
int transition, color, *instance, *instance_pnt;
static int error, i, list[20], n, outs[20], places[20], outputs;
if(petri_in_event(net, transition, NO_RULE) == NO_ERROR){
if(petri_get_consumed(net, transition, &color, list, &n, outs, places, &outputs) == NO_ERROR){
for(i = 0; i <= n; i++) instance[list[i]] = -1000;
if(petri_set_produced(net, transition, &(instance[*instance_pnt]), outputs) == NO_ERROR){
error = petri_out_event(net, transition);
* This is based on an example on pg. 125 of Reisig [1985]
static int color_a = 1, color_b = 2;
static int rule_a = 1, rule_b = 2;
static int instance[20], instance_pnt;
t1 = petri_transition(&net, "t1");
petri_input(&net, p1, t1, 2, color_a, rule_a);
petri_input(&net, p1, t1, 1, color_b, rule_a);
petri_input(&net, p2, t1, 1, color_a, rule_a);
petri_input(&net, p2, t1, 1, color_b, rule_a);
petri_output(&net, t1, p3, 1, color_b, rule_a);
petri_output(&net, t1, p4, 2, color_a, rule_a);
petri_output(&net, t1, p4, 2, color_b, rule_a);
petri_input(&net, p1, t1, 1, color_a, rule_b);
petri_input(&net, p1, t1, 2, color_b, rule_b);
petri_input(&net, p2, t1, 2, color_a, rule_b);
petri_input(&net, p2, t1, 2, color_b, rule_b);
petri_output(&net, t1, p3, 2, color_a, rule_b);
petri_output(&net, t1, p3, 3, color_b, rule_b);
petri_output(&net, t1, p4, 2, color_a, rule_b);
petri_output(&net, t1, p4, 2, color_b, rule_b);
for(i = 0; i < 20; i++) instance[i] = i;
petri_add_color_token(&net, p1, color_a, instance[instance_pnt]);
petri_add_color_token(&net, p1, color_a, instance[instance_pnt]);
petri_add_color_token(&net, p1, color_b, instance[instance_pnt]);
petri_add_color_token(&net, p1, color_b, instance[instance_pnt]);
petri_add_color_token(&net, p2, color_a, instance[instance_pnt]);
petri_add_color_token(&net, p2, color_a, instance[instance_pnt]);
petri_add_color_token(&net, p2, color_b, instance[instance_pnt]);
petri_add_color_token(&net, p2, color_b, instance[instance_pnt]);
petri_add_color_token(&net, p2, color_b, instance[instance_pnt]);
petri_add_color_token(&net, p3, color_a, instance[instance_pnt]);
petri_add_color_token(&net, p4, color_b, instance[instance_pnt]);
sub5(&net, t1, rule_a, instance, &instance_pnt);
sub5(&net, t1, rule_b, instance, &instance_pnt);
int sub5(net, transition, rule, instance, instance_pnt)
int transition, rule, *instance, *instance_pnt;
static int error, i, list[20], n, outs[20], places[20], outputs;
if(petri_in_event(net, transition, rule) == NO_ERROR){
if(petri_get_consumed(net, transition, &rule, list, &n, outs, places, &outputs) == NO_ERROR){
for(i = 0; i <= n; i++) instance[list[i]] = -1000;
if(petri_set_produced(net, transition, &(instance[*instance_pnt]), outputs) == NO_ERROR){
error = petri_out_event(net, transition);
#define MAX_NUMBER_TRANSITIONS 20
int color_instance[MAX_NUMBER_COLORS];
int output[MAX_NUMBER_COLORS];
int instance[MAX_NUMBER_INPUTS];
int to_color[MAX_NUMBER_OUTPUTS];
int to_place[MAX_NUMBER_OUTPUTS];
int to_instance[MAX_NUMBER_OUTPUTS];
} transition[MAX_NUMBER_TRANSITIONS];
struct arc precondition[MAX_NUMBER_RULES];
struct arc event[MAX_NUMBER_RULES];
* NOTE: In this software the view is that arcs are inputs and outputs from
* transitions (not places as in some textbooks). Therefore an INPUT is going
* into a transition. An OUTPUT is coming out of a transition.
* This petri net simulator allows the transitions to be set in various ways.
* BASIC allows the transactions to fire when all of the inputs have tokens.
* EOR allows the transaction to fire when only one input is set.
* COLORED transactions will only fire when tokens of the same color are
* When an input to a transition is set to INHIBIT, the transition cannot fire
* while a token is present in the input place.
for(i = 0; i < MAX_NUMBER_PLACES; i++){
for(i = 0; i < MAX_NUMBER_TRANSITIONS; i++){
net->transition[i].status = EMPTY;
int petri_transition(net, name)
for(i = 0; (i < MAX_NUMBER_TRANSITIONS)
&& (strcmp(name, net->transition[i].name) != 0); i++);
if(i < MAX_NUMBER_TRANSITIONS){
for(i = 0; (i < MAX_NUMBER_TRANSITIONS)
&& (net->transition[i].status != EMPTY); i++);
if(i < MAX_NUMBER_TRANSITIONS){
net->transition[number].status = USED;
strcpy(net->transition[number].name, name);
net->transition[number].color_pnt = -1;
net->transition[number].ready_to_fire = FALSE;
net->transition[number].fire_time = 0.0;
net->transition[number].type = COLORED;
int petri_type_transition(net, transition, type)
if(net->transition[transition].status == USED){
if((type == EOR) || (type == COLORED)){
net->transition[transition].type = type;
for(i = 0; (i < MAX_NUMBER_PLACES)
&& (strcmp(name, net->place[i].name) != 0); i++);
for(i = 0; (i < MAX_NUMBER_PLACES)
&& (net->place[i].status != EMPTY); i++);
net->place[number].status = USED;
strcpy(net->place[number].name, name);
net->place[number].tokens = 0;
net->place[number].color_pnt = -1;
int petri_color_find(net, transition, color)
static int number, i, end_pnt;
end_pnt = net->transition[transition].color_pnt;
for(i = 0; (i <= end_pnt) &&(net->transition[transition].color[i] != color);i++);
net->transition[transition].color_pnt = i;
net->transition[transition].color[i] = color;
net->transition[transition].input[i] = -1;
net->transition[transition].output[i] = -1;
int petri_add_relation(list, point, end_point, place, number, color)
int *point, *end_point, place, number, color;
* Add a relationship to the list of preconditions or events
static int error, list_pnt, current_pnt;
if((*point >= 0) && (*point < MAX_NUMBER_RULES)){
while((current_pnt == -1) && (error == NO_ERROR)){
if((list[list_pnt].place == place)
&& (list[list_pnt].color == color)){
} else if(list[list_pnt].next_point < 0){
if(*end_point < (MAX_NUMBER_RULES - 1)){
list[current_pnt].color = color;
list[current_pnt].place = place;
list[current_pnt].next_point = -1;
list[list_pnt].next_point = *end_point;
list_pnt = list[list_pnt].next_point;
if(*end_point < (MAX_NUMBER_RULES - 1)){
if((current_pnt >= 0) && (error == NO_ERROR)){
list[current_pnt].number += number;
int petri_get_list(list, point, place, number, color, n)
int point, *place, *number, *color, *n;
* Get a list of preconditions or events
static int error, i, list_pnt;
if((point >= 0) && (point < MAX_NUMBER_RULES)){
while((list_pnt != -1) && (error == NO_ERROR)){
place[*n] = list[list_pnt].place;
number[*n] = list[list_pnt].number;
color[*n] = list[list_pnt].color;
list_pnt = list[list_pnt].next_point;
int petri_input(net, from_place, to_transition, number, color, rule)
int from_place, to_transition;
* Set a relational input to a transition
static int error, i, color_pnt;
if((net->place[from_place].status != EMPTY)
&& (net->transition[to_transition].status != EMPTY)){
color_pnt = petri_color_find(net, to_transition, rule);
error = petri_add_relation(net->precondition,
&(net->transition[to_transition].input[color_pnt]),
int petri_output(net, from_transition, to_place, number, color, rule)
int to_place, from_transition;
* Set relational output from transition
static int error, i, color_pnt;
if((net->place[to_place].status != EMPTY)
&& (net->transition[from_transition].status != EMPTY)){
color_pnt = petri_color_find(net, from_transition, rule);
error = petri_add_relation(net->event,
&(net->transition[from_transition].output[color_pnt]),
int petri_add_tokens(net, place, number)
* Add or subtract tokens from a place
if(net->place[place].status == USED){
net->place[place].tokens += number;
if(net->place[place].tokens < 0){
net->place[place].tokens -= number;
int petri_add_color_token(net, place, color, instance)
* Add an instance of a colored token to a place
if((net->place[place].status == USED)
&& (net->place[place].color_pnt < (MAX_NUMBER_COLORS - 1))){
net->place[place].tokens += 1;
net->place[place].color_pnt += 1;
list_pnt = net->place[place].color_pnt;
net->place[place].color[list_pnt] = color;
net->place[place].color_instance[list_pnt] = instance;
* Get a count of tokens in a place
if(net->place[place].status == USED){
number = net->place[place].tokens;
int petri_color_tokens(net, place, list_color, list_instance)
int place, *list_color, *list_instance;
* get a list of colored tokens in a place
if(net->place[place].status == USED){
number = net->place[place].color_pnt;
list_color[i] = net->place[place].color[i];
list_instance[i] = net->place[place].color_instance[i];
int petri_number_tokens(net, place, color)
* Get the number of tokens of one color
if(net->place[place].status == USED){
number = net->place[place].tokens;
for(i = 0; i <= net->place[place].color_pnt; i++){
if(color == net->place[place].color[i])
int petri_remove_tokens(net, place, color, number, instance)
int place, color, number, *instance;
* Remove a number of tokens from a place
static int error, i, j, temp_cnt, temp_pnt;
if((net->place[place].status == USED) && (color >= 0)){
temp_pnt = net->place[place].color_pnt;
for(j = temp_pnt; j >= 0; j--){
if((net->place[place].color[j] == color)
net->place[place].color_instance[j];
net->place[place].color[temp_pnt];
net->place[place].color_instance[j] =
net->place[place].color_instance[temp_pnt];
net->place[place].color_pnt = temp_pnt;
} else if((net->place[place].status == USED) && (color == NO_COLOR)){
net->place[place].tokens -= number;
int petri_in_event(net, transition, rule)
static int error, i, color_pnt, type, count, eor_pnt, tokens, inhibit,
static int place[MAX_NUMBER_INPUTS],
if((net->transition[transition].status == USED)
&& (net->transition[transition].ready_to_fire != TRUE)){
type = net->transition[transition].type;
color_pnt = petri_color_find(net, transition, rule);
petri_get_list(net->precondition, net->transition[transition].input[color_pnt],
if((tokens > 0) && (number[i] < 0)){
} else if(tokens >= number[i]){
if((type == EOR) && (count == 0)){
} else if((type != EOR) && (count == n)){
net->transition[transition].fire_color
net->transition[transition].ready_to_fire
for(i = i_start; i <= i_end; i++){
&(net->transition[transition].instance[count]));
net->transition[transition].instance_pnt
int petri_output_prepare(net, transition, rule)
* Create an output list for a transition
static int error, i, j, count, list_pnt, color_pnt;
static int plc[MAX_NUMBER_OUTPUTS],
color_pnt = petri_color_find(net, transition, rule);
petri_get_list(net->event, net->transition[transition].output[color_pnt], plc, num, col, &pnt);
net->transition[transition].to_place[j+count]
net->transition[transition].to_color[j+count]
net->transition[transition].to_pnt = count - 1;
int petri_get_consumed(net, transition, rule, list, n, color_out, place, n_produced)
int transition, *rule, *list, *n, *color_out, *place, *n_produced;
static int error, i, j, count;
static int plc[MAX_NUMBER_OUTPUTS],
if(net->transition[transition].ready_to_fire == TRUE){
*rule = net->transition[transition].fire_color;
*n = net->transition[transition].instance_pnt;
list[i] = net->transition[transition].instance[i];
if(petri_output_prepare(net, transition, *rule) != ERROR){
*n_produced = net->transition[transition].to_pnt;
for(i = 0; i <= *n_produced; i++){
int petri_set_produced(net, transition, list, n)
* Add a new list of instances to the transition before firing
if(net->transition[transition].ready_to_fire == TRUE){
net->transition[transition].to_instance[i] = list[i];
int petri_out_event(net, transition)
static int error, place, number, i, j, color, instance, point;
if((net->transition[transition].status == USED)
&& (net->transition[transition].ready_to_fire == TRUE)){
for(i = 0; i <= net->transition[transition].to_pnt; i++){
color = net->transition[transition].to_color[i];
net->transition[transition].to_place[i], 1);
net->transition[transition].to_place[i],
net->transition[transition].to_color[i],
net->transition[transition].to_instance[i]);
net->transition[transition].ready_to_fire = FALSE;
int petri_event(net, transition)
error = petri_in_event(net, transition, NO_COLOR, NO_RULE);
if(error == NO_ERROR) error = petri_output_prepare(net, transition, NO_RULE);
if(error == NO_ERROR) error = petri_out_event(net, transition);
static int error, i, j, k, place[MAX_NUMBER_RULES],
color[MAX_NUMBER_RULES], number[MAX_NUMBER_RULES], end_pnt;
printf("\n\nPLACES -------------------------- \n");
for(i = 0; i < MAX_NUMBER_PLACES; i++){
if(net->place[i].status == USED){
printf("# %d -- %30s -- %d tokens\n", i,
for(j = 0; j <= net->place[i].color_pnt; j++){
printf(" color token %d -- instance %d\n",
net->place[i].color_instance[j]);
* Print the list of transitions
printf("\n\nTRANSITIONS ---------------------\n");
for(i = 0; i < MAX_NUMBER_TRANSITIONS; i++){
if(net->transition[i].status == USED){
printf("# %d -- %30s -- %d fire(?) -- %d color -- %f time -- %d type\n", i,
net->transition[i].ready_to_fire,
net->transition[i].fire_color,
for(j = 0; j <= net->transition[i].color_pnt; j++){
printf(" Rule %d -> color %d \n", j,
petri_get_list(net->precondition,
place, number, color, &end_pnt);
for(k = 0; k <= end_pnt; k++){
printf(" Input %d -- place %d -- color %d -- number %d\n", k,
place[k], color[k], number[k]);
place, number, color, &end_pnt);
for(k = 0; k <= end_pnt; k++){
printf(" Output %d -- place %d -- color %d -- number %d\n", k,
place[k], color[k], number[k]);
for(k = 0; k <= net->transition[i].instance_pnt; k++){
printf(" instance consumed %d is %d\n",
k, net->transition[i].instance[k]);
for(k = 0; k <= net->transition[i].to_pnt; k++){
printf(" token out %d is %d, %d, %d\n",
k, net->transition[i].to_color[k],
net->transition[i].to_place[k],
net->transition[i].to_instance[k]);
printf("\n\n PRECONDITIONS \n");
for(i = 0; i <= net->precondition_pnt; i++){
printf(" %d --> color %d -> number %d -> place %d -> point %d\n", i,
net->precondition[i].next_point);
for(i = 0; i <= net->event_pnt; i++){
printf(" %d --> color %d -> number %d -> place %d -> point %d\n", i,