Last active
August 6, 2021 08:54
-
-
Save mzaks/d23981c8b1d12003a7b9025860839e81 to your computer and use it in GitHub Desktop.
Simple Petri net implementation in C with a couple examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <libc.h> | |
typedef struct { | |
int *marking; | |
int *takes; | |
int *puts; | |
int transition_count; | |
int place_count; | |
} PetriNet; | |
typedef struct { | |
int *array; | |
size_t count; | |
size_t cap; | |
} vec; | |
void vec_init(vec *a, size_t initialSize) { | |
a->array = malloc(initialSize * sizeof(int)); | |
a->count = 0; | |
a->cap = initialSize; | |
} | |
void vec_append(vec *a, int element) { | |
if (a->count == a->cap) { | |
a->cap *= 2; | |
a->array = realloc(a->array, a->cap * sizeof(int)); | |
} | |
a->array[a->count++] = element; | |
} | |
void vec_drop_last(vec *a) { | |
a->count--; | |
} | |
void vec_free(vec *a) { | |
free(a->array); | |
a->array = NULL; | |
a->count = a->cap = 0; | |
} | |
void vec_print(vec a) { | |
for (int i = 0; i < a.count; ++i) { | |
printf("%i", a.array[i]); | |
if (i < a.count - 1) { | |
printf(", "); | |
} | |
} | |
printf("\n"); | |
} | |
boolean_t marking_equals_goal(const PetriNet *net, const int *goal) { | |
for (int i = 0; i < net->place_count; ++i) { | |
if (goal[i] != 0 && net->marking[i] != goal[i]) { | |
return FALSE; | |
} | |
} | |
return TRUE; | |
} | |
boolean_t fire_transition(PetriNet *net, int t_id) { | |
if (net->transition_count <= t_id) { | |
return FALSE; | |
} | |
int *marking = net->marking; | |
for (int p = 0; p < net->place_count; ++p) { | |
if (marking[p] < net->takes[t_id *net-> place_count + p]) { | |
return FALSE; | |
} | |
} | |
for (int p = 0; p < net->place_count; ++p) { | |
marking[p] -= net->takes[t_id *net-> place_count + p]; | |
} | |
for (int p = 0; p < net->place_count; ++p) { | |
marking[p] += net->puts[t_id *net-> place_count + p]; | |
} | |
return TRUE; | |
} | |
void undo_transition(PetriNet *net, int t_id) { | |
int *marking = net->marking; | |
for (int p = 0; p < net->place_count; ++p) { | |
marking[p] += net->takes[t_id *net-> place_count + p]; | |
} | |
for (int p = 0; p < net->place_count; ++p) { | |
marking[p] -= net->puts[t_id *net-> place_count + p]; | |
} | |
} | |
boolean_t find_path(PetriNet *net, vec *result, int* goal, int max_depth) { | |
if (marking_equals_goal(net, goal)) { | |
return TRUE; | |
} | |
if (result->count == max_depth) { | |
return FALSE; | |
} | |
for (int t = 0; t < net->transition_count; ++t) { | |
if (!fire_transition(net, t)) { | |
continue; | |
} | |
vec_append(result, t); | |
if (find_path(net, result, goal, max_depth)) { | |
// rollback the net | |
undo_transition(net, t); | |
return TRUE; | |
} | |
undo_transition(net, t); | |
vec_drop_last(result); | |
} | |
return FALSE; | |
} | |
void swap(int *xp, int *yp) | |
{ | |
int temp = *xp; | |
*xp = *yp; | |
*yp = temp; | |
} | |
boolean_t find_path_with_distance_function(PetriNet *net, vec *result, int* goal, int max_depth, int (*distance_func)(int, int*, int*)) { | |
if (marking_equals_goal(net, goal)) { | |
return TRUE; | |
} | |
if (result->count == max_depth) { | |
return FALSE; | |
} | |
// Compute distances for all transitions | |
int distance[net->transition_count]; | |
int transitions[net->transition_count]; | |
for (int t = 0; t < net->transition_count; ++t) { | |
boolean_t alive = fire_transition(net, t); | |
distance[t] = distance_func(net->place_count, net->marking, goal); | |
transitions[t] = t; | |
if (alive) { | |
undo_transition(net, t); | |
} | |
} | |
{ // Selection sort | |
int n = net->transition_count; | |
int i, j, min_idx; | |
// One by one move boundary of unsorted subarray | |
for (i = 0; i < n-1; i++) | |
{ | |
// Find the minimum element in unsorted array | |
min_idx = i; | |
for (j = i+1; j < n; j++) | |
if (distance[j] < distance[min_idx]) | |
min_idx = j; | |
// Swap the found minimum element with the first element | |
swap(&distance[min_idx], &distance[i]); | |
swap(&transitions[min_idx], &transitions[i]); | |
} | |
} | |
for (int i = 0; i < net->transition_count; ++i) { | |
int t = transitions[i]; | |
if (!fire_transition(net, t)) { | |
continue; | |
} | |
vec_append(result, t); | |
if (find_path_with_distance_function(net, result, goal, max_depth, distance_func)) { | |
// rollback the net | |
undo_transition(net, t); | |
return TRUE; | |
} | |
undo_transition(net, t); | |
vec_drop_last(result); | |
} | |
return FALSE; | |
} | |
void print_marking(PetriNet net) { | |
for (int i = 0; i < net.place_count; ++i) { | |
printf("%i", net.marking[i]); | |
if (i < net.place_count - 1) { | |
printf(", "); | |
} | |
} | |
printf("\n"); | |
} | |
int manhattan_distance(int count, int* source, int* target) { | |
int result = 0; | |
for (int i = 0; i < count; ++i) { | |
if (target[i] != 0) { | |
result += abs(source[i] - target[i]); | |
} | |
} | |
return result; | |
} | |
void light_test() { | |
enum Places { | |
on, off, places_count | |
}; | |
enum Transitions { | |
_turn_on, _turn_off, transitions_count | |
}; | |
int m[places_count] = {[off] = 1}; | |
int take[transitions_count][places_count] = { | |
[_turn_on] = { | |
[off] = 1 | |
}, | |
[_turn_off] = { | |
[on] = 1 | |
} | |
}; | |
int put[transitions_count][places_count] = { | |
[_turn_on] = { | |
[on] = 1 | |
}, | |
[_turn_off] = { | |
[off] = 1 | |
} | |
}; | |
PetriNet net1 = { | |
.marking = m, | |
.puts = (int *) put, | |
.takes = (int *) take, | |
.place_count = places_count, | |
.transition_count = transitions_count | |
}; | |
printf("--------\n"); | |
print_marking(net1); | |
fire_transition(&net1, _turn_on); | |
print_marking(net1); | |
fire_transition(&net1, _turn_on); | |
print_marking(net1); | |
fire_transition(&net1, _turn_off); | |
print_marking(net1); | |
vec path; | |
vec_init(&path, 10); | |
int goal[places_count] = {[on] = 1}; | |
find_path(&net1, &path, goal, 3); | |
vec_print(path); | |
vec_free(&path); | |
printf("--------\n"); | |
} | |
void count_test() { | |
enum Places { | |
count, places_count | |
}; | |
enum Transitions { | |
increase, decrease, transition_count | |
}; | |
int marking2[places_count] = { | |
[count] = 7 | |
}; | |
int takes[transition_count][places_count] = { | |
[increase] = { | |
[count] = 0 | |
}, | |
[decrease] = { | |
[count] = 1 | |
} | |
}; | |
int puts[transition_count][places_count] = { | |
[increase] = { | |
[count] = 1 | |
}, | |
[decrease] = { | |
[count] = 0 | |
} | |
}; | |
PetriNet n1 = { | |
.marking = marking2, | |
.takes = (int *) takes, | |
.puts = (int *) puts, | |
.place_count = places_count, | |
.transition_count = transition_count | |
}; | |
int goal[places_count] = {[count] = 4}; | |
vec res; | |
vec_init(&res, 10); | |
boolean_t found = find_path(&n1, &res, goal, 10); | |
vec_print(res); | |
vec_free(&res); | |
printf("search with distance function:\n"); | |
vec res2; | |
vec_init(&res2, 10); | |
find_path_with_distance_function(&n1, &res2, goal, 10, manhattan_distance); | |
vec_print(res2); | |
} | |
void bar_bell_test() { | |
enum Places { | |
total_weight_in_gram, | |
bar_bell_selected, bar_bell_not_selected, | |
bar_bell_10_kg, bar_bell_15_kg, bar_bell_20_kg, | |
plate_0_5_kg, plate_1_kg, plate_1_25_kg, plate_2_kg, plate_2_5_kg, | |
plate_3_kg, plate_5_kg, plate_10_kg, plate_15_kg, plate_20_kg, plate_25_kg, | |
places_count | |
}; | |
enum Transitions { | |
pick_10_kg_bar_bell, pick_15_kg_bar_bell, pick_20_kg_bar_bell, | |
pick_0_5_kg_plates, pick_1_kg_plates, pick_1_25_kg_plates, pick_2_kg_plates, pick_2_5_kg_plates, | |
pick_3_kg_plates, pick_5_kg_plates, pick_10_kg_plates, pick_15_kg_plates, pick_20_kg_plates, pick_25_kg_plates, | |
transition_count | |
}; | |
int marking[places_count] = { | |
[bar_bell_not_selected] = 1, | |
[bar_bell_10_kg] = 1, [bar_bell_15_kg] = 1, [bar_bell_20_kg] = 1, | |
[plate_0_5_kg] = 4, [plate_1_kg] = 4, [plate_1_25_kg] = 4, [plate_2_kg] = 4, [plate_2_5_kg] = 4, | |
[plate_3_kg] = 4, [plate_5_kg] = 4, [plate_10_kg] = 4, [plate_15_kg] = 4, [plate_20_kg] = 4, [plate_25_kg] = 4 | |
}; | |
int takes[transition_count][places_count] = { | |
[pick_10_kg_bar_bell] = {[bar_bell_10_kg] = 1, [bar_bell_not_selected] = 1}, | |
[pick_15_kg_bar_bell] = {[bar_bell_15_kg] = 1, [bar_bell_not_selected] = 1}, | |
[pick_20_kg_bar_bell] = {[bar_bell_20_kg] = 1, [bar_bell_not_selected] = 1}, | |
[pick_0_5_kg_plates] = {[bar_bell_selected] = 1, [plate_0_5_kg] = 2}, | |
[pick_1_kg_plates] = {[bar_bell_selected] = 1, [plate_1_kg] = 2}, | |
[pick_1_25_kg_plates] = {[bar_bell_selected] = 1, [plate_1_25_kg] = 2}, | |
[pick_2_kg_plates] = {[bar_bell_selected] = 1, [plate_2_kg] = 2}, | |
[pick_2_5_kg_plates] = {[bar_bell_selected] = 1, [plate_2_5_kg] = 2}, | |
[pick_3_kg_plates] = {[bar_bell_selected] = 1, [plate_3_kg] = 2}, | |
[pick_5_kg_plates] = {[bar_bell_selected] = 1, [plate_5_kg] = 2}, | |
[pick_10_kg_plates] = {[bar_bell_selected] = 1, [plate_10_kg] = 2}, | |
[pick_15_kg_plates] = {[bar_bell_selected] = 1, [plate_15_kg] = 2}, | |
[pick_20_kg_plates] = {[bar_bell_selected] = 1, [plate_20_kg] = 2}, | |
[pick_25_kg_plates] = {[bar_bell_selected] = 1, [plate_25_kg] = 2}, | |
}; | |
int puts[transition_count][places_count] = { | |
[pick_10_kg_bar_bell] = {[total_weight_in_gram] = 10000, [bar_bell_selected] = 1}, | |
[pick_15_kg_bar_bell] = {[total_weight_in_gram] = 15000, [bar_bell_selected] = 1}, | |
[pick_20_kg_bar_bell] = {[total_weight_in_gram] = 20000, [bar_bell_selected] = 1}, | |
[pick_0_5_kg_plates] = {[total_weight_in_gram] = 1000, [bar_bell_selected] = 1}, | |
[pick_1_kg_plates] = {[total_weight_in_gram] = 2000, [bar_bell_selected] = 1}, | |
[pick_1_25_kg_plates] = {[total_weight_in_gram] = 2500, [bar_bell_selected] = 1}, | |
[pick_2_kg_plates] = {[total_weight_in_gram] = 4000, [bar_bell_selected] = 1}, | |
[pick_2_5_kg_plates] = {[total_weight_in_gram] = 5000, [bar_bell_selected] = 1}, | |
[pick_3_kg_plates] = {[total_weight_in_gram] = 6000, [bar_bell_selected] = 1}, | |
[pick_5_kg_plates] = {[total_weight_in_gram] = 10000, [bar_bell_selected] = 1}, | |
[pick_10_kg_plates] = {[total_weight_in_gram] = 20000, [bar_bell_selected] = 1}, | |
[pick_15_kg_plates] = {[total_weight_in_gram] = 30000, [bar_bell_selected] = 1}, | |
[pick_20_kg_plates] = {[total_weight_in_gram] = 40000, [bar_bell_selected] = 1}, | |
[pick_25_kg_plates] = {[total_weight_in_gram] = 50000, [bar_bell_selected] = 1}, | |
}; | |
PetriNet net = { | |
.place_count = places_count, | |
.transition_count = transition_count, | |
.marking = marking, | |
.takes = (int *) takes, | |
.puts = (int *) puts | |
}; | |
int goal[places_count] = { [total_weight_in_gram] = 70500}; | |
vec result; | |
vec_init(&result, 3); | |
printf("-----------Bar Bell----------- \n"); | |
int success = find_path(&net, &result, goal, 5); | |
printf("Success: %i \n", success); | |
vec_print(result); | |
print_marking(net); | |
printf("----------- \n"); | |
vec_free(&result); | |
// find solution after 20 kg bar bell is picked | |
fire_transition(&net, pick_20_kg_bar_bell); | |
print_marking(net); | |
vec result2; | |
vec_init(&result2, 3); | |
int success2 = find_path(&net, &result2, goal, 4); | |
printf("Success: %i \n", success2); | |
vec_print(result2); | |
vec_free(&result2); | |
printf("-----------With distance function----------- \n"); | |
print_marking(net); | |
vec result3; | |
vec_init(&result2, 3); | |
int success3 = find_path_with_distance_function(&net, &result3, goal, 5, manhattan_distance); | |
printf("Success: %i \n", success3); | |
vec_print(result3); | |
printf("----------- \n"); | |
vec_free(&result3); | |
} | |
void test_towers_of_hanoi() { | |
enum Places { | |
a___, a__1, a__2, a__3, a_12, a_13, a_23, a123, | |
b___, b__1, b__2, b__3, b_12, b_13, b_23, b123, | |
c___, c__1, c__2, c__3, c_12, c_13, c_23, c123, | |
places_count | |
}; | |
enum Transitions { | |
a123_to_b___, a123_to_c___, | |
a_23_to_b___, a_23_to_c___, | |
a_12_to_b___, a_12_to_c___, a_12_to_b__3, a_12_to_c__3, | |
a__3_to_b___, a__3_to_c___, | |
a__2_to_b___, a__2_to_c___, a__2_to_b__3, a__2_to_c__3, | |
a__1_to_b___, a__1_to_c___, a__1_to_b__2, a__1_to_c__2, a__1_to_b__3, a__1_to_c__3, a__1_to_b_23, a__1_to_c_23, | |
b123_to_a___, b123_to_c___, | |
b_23_to_a___, b_23_to_c___, | |
b_12_to_a___, b_12_to_c___, b_12_to_a__3, b_12_to_c__3, | |
b__3_to_a___, b__3_to_c___, | |
b__2_to_a___, b__2_to_c___, b__2_to_a__3, b__2_to_c__3, | |
b__1_to_a___, b__1_to_c___, b__1_to_a__2, b__1_to_c__2, b__1_to_a__3, b__1_to_c__3, b__1_to_a_23, b__1_to_c_23, | |
c123_to_b___, c123_to_a___, | |
c_23_to_b___, c_23_to_a___, | |
c_12_to_b___, c_12_to_a___, c_12_to_b__3, c_12_to_a__3, | |
c__3_to_b___, c__3_to_a___, | |
c__2_to_b___, c__2_to_a___, c__2_to_b__3, c__2_to_a__3, | |
c__1_to_b___, c__1_to_a___, c__1_to_b__2, c__1_to_a__2, c__1_to_b__3, c__1_to_a__3, c__1_to_b_23, c__1_to_a_23, | |
transitions_count | |
}; | |
int marking[places_count] = { | |
[a123] = 1, | |
[b___] = 1, | |
[c___] = 1 | |
}; | |
int takes[transitions_count][places_count] = { | |
[a123_to_b___] = {[a123] = 1, [b___] = 1}, | |
[a123_to_c___] = {[a123] = 1, [c___] = 1}, | |
[a_23_to_b___] = {[a_23] = 1, [b___] = 1}, | |
[a_23_to_c___] = {[a_23] = 1, [c___] = 1}, | |
[a_12_to_b___] = {[a_12] = 1, [b___] = 1}, | |
[a_12_to_c___] = {[a_12] = 1, [c___] = 1}, | |
[a_12_to_b__3] = {[a_12] = 1, [b__3] = 1}, | |
[a_12_to_c__3] = {[a_12] = 1, [c__3] = 1}, | |
[a__3_to_b___] = {[a__3] = 1, [b___] = 1}, | |
[a__3_to_c___] = {[a__3] = 1, [c___] = 1}, | |
[a__2_to_b___] = {[a__2] = 1, [b___] = 1}, | |
[a__2_to_c___] = {[a__2] = 1, [c___] = 1}, | |
[a__2_to_b__3] = {[a__2] = 1, [b__3] = 1}, | |
[a__2_to_c__3] = {[a__2] = 1, [c__3] = 1}, | |
[a__1_to_b___] = {[a__1] = 1, [b___] = 1}, | |
[a__1_to_c___] = {[a__1] = 1, [c___] = 1}, | |
[a__1_to_b__2] = {[a__1] = 1, [b__2] = 1}, | |
[a__1_to_c__2] = {[a__1] = 1, [c__2] = 1}, | |
[a__1_to_b__3] = {[a__1] = 1, [b__3] = 1}, | |
[a__1_to_c__3] = {[a__1] = 1, [c__3] = 1}, | |
[a__1_to_b_23] = {[a__1] = 1, [b_23] = 1}, | |
[a__1_to_c_23] = {[a__1] = 1, [c_23] = 1}, | |
[b123_to_a___] = {[b123] = 1, [a___] = 1}, | |
[b123_to_c___] = {[b123] = 1, [c___] = 1}, | |
[b_23_to_a___] = {[b_23] = 1, [a___] = 1}, | |
[b_23_to_c___] = {[b_23] = 1, [c___] = 1}, | |
[b_12_to_a___] = {[b_12] = 1, [a___] = 1}, | |
[b_12_to_c___] = {[b_12] = 1, [c___] = 1}, | |
[b_12_to_a__3] = {[b_12] = 1, [a__3] = 1}, | |
[b_12_to_c__3] = {[b_12] = 1, [c__3] = 1}, | |
[b__3_to_a___] = {[b__3] = 1, [a___] = 1}, | |
[b__3_to_c___] = {[b__3] = 1, [c___] = 1}, | |
[b__2_to_a___] = {[b__2] = 1, [a___] = 1}, | |
[b__2_to_c___] = {[b__2] = 1, [c___] = 1}, | |
[b__2_to_a__3] = {[b__2] = 1, [a__3] = 1}, | |
[b__2_to_c__3] = {[b__2] = 1, [c__3] = 1}, | |
[b__1_to_a___] = {[b__1] = 1, [a___] = 1}, | |
[b__1_to_c___] = {[b__1] = 1, [c___] = 1}, | |
[b__1_to_a__2] = {[b__1] = 1, [a__2] = 1}, | |
[b__1_to_c__2] = {[b__1] = 1, [c__2] = 1}, | |
[b__1_to_a__3] = {[b__1] = 1, [a__3] = 1}, | |
[b__1_to_c__3] = {[b__1] = 1, [c__3] = 1}, | |
[b__1_to_a_23] = {[b__1] = 1, [a_23] = 1}, | |
[b__1_to_c_23] = {[b__1] = 1, [c_23] = 1}, | |
[c123_to_b___] = {[c123] = 1, [b___] = 1}, | |
[c123_to_a___] = {[c123] = 1, [a___] = 1}, | |
[c_23_to_b___] = {[c_23] = 1, [b___] = 1}, | |
[c_23_to_a___] = {[c_23] = 1, [a___] = 1}, | |
[c_12_to_b___] = {[c_12] = 1, [b___] = 1}, | |
[c_12_to_a___] = {[c_12] = 1, [a___] = 1}, | |
[c_12_to_b__3] = {[c_12] = 1, [b__3] = 1}, | |
[c_12_to_a__3] = {[c_12] = 1, [a__3] = 1}, | |
[c__3_to_b___] = {[c__3] = 1, [b___] = 1}, | |
[c__3_to_a___] = {[c__3] = 1, [a___] = 1}, | |
[c__2_to_b___] = {[c__2] = 1, [b___] = 1}, | |
[c__2_to_a___] = {[c__2] = 1, [a___] = 1}, | |
[c__2_to_b__3] = {[c__2] = 1, [b__3] = 1}, | |
[c__2_to_a__3] = {[c__2] = 1, [a__3] = 1}, | |
[c__1_to_b___] = {[c__1] = 1, [b___] = 1}, | |
[c__1_to_a___] = {[c__1] = 1, [a___] = 1}, | |
[c__1_to_b__2] = {[c__1] = 1, [b__2] = 1}, | |
[c__1_to_a__2] = {[c__1] = 1, [a__2] = 1}, | |
[c__1_to_b__3] = {[c__1] = 1, [b__3] = 1}, | |
[c__1_to_a__3] = {[c__1] = 1, [a__3] = 1}, | |
[c__1_to_b_23] = {[c__1] = 1, [b_23] = 1}, | |
[c__1_to_a_23] = {[c__1] = 1, [a_23] = 1}, | |
}; | |
int puts[transitions_count][places_count] = { | |
[a123_to_b___] = {[a_23] = 1, [b__1] = 1}, | |
[a123_to_c___] = {[a_23] = 1, [c__1] = 1}, | |
[a_23_to_b___] = {[a__3] = 1, [b__2] = 1}, | |
[a_23_to_c___] = {[a__3] = 1, [c__2] = 1}, | |
[a_12_to_b___] = {[a__2] = 1, [b__1] = 1}, | |
[a_12_to_c___] = {[a__2] = 1, [c__1] = 1}, | |
[a_12_to_b__3] = {[a__2] = 1, [b_13] = 1}, | |
[a_12_to_c__3] = {[a__2] = 1, [c_13] = 1}, | |
[a__3_to_b___] = {[a___] = 1, [b__3] = 1}, | |
[a__3_to_c___] = {[a___] = 1, [c__3] = 1}, | |
[a__2_to_b___] = {[a___] = 1, [b__2] = 1}, | |
[a__2_to_c___] = {[a___] = 1, [c__2] = 1}, | |
[a__2_to_b__3] = {[a___] = 1, [b_23] = 1}, | |
[a__2_to_c__3] = {[a___] = 1, [c_23] = 1}, | |
[a__1_to_b___] = {[a___] = 1, [b__1] = 1}, | |
[a__1_to_c___] = {[a___] = 1, [c__1] = 1}, | |
[a__1_to_b__2] = {[a___] = 1, [b_12] = 1}, | |
[a__1_to_c__2] = {[a___] = 1, [c_12] = 1}, | |
[a__1_to_b__3] = {[a___] = 1, [b_13] = 1}, | |
[a__1_to_c__3] = {[a___] = 1, [c_13] = 1}, | |
[a__1_to_b_23] = {[a___] = 1, [b123] = 1}, | |
[a__1_to_c_23] = {[a___] = 1, [c123] = 1}, | |
[b123_to_a___] = {[b_23] = 1, [a__1] = 1}, | |
[b123_to_c___] = {[b_23] = 1, [c__1] = 1}, | |
[b_23_to_a___] = {[b__3] = 1, [a__2] = 1}, | |
[b_23_to_c___] = {[b__3] = 1, [c__2] = 1}, | |
[b_12_to_a___] = {[b__2] = 1, [a__1] = 1}, | |
[b_12_to_c___] = {[b__2] = 1, [c__1] = 1}, | |
[b_12_to_a__3] = {[b__2] = 1, [a_13] = 1}, | |
[b_12_to_c__3] = {[b__2] = 1, [c_13] = 1}, | |
[b__3_to_a___] = {[b___] = 1, [a__3] = 1}, | |
[b__3_to_c___] = {[b___] = 1, [c__3] = 1}, | |
[b__2_to_a___] = {[b___] = 1, [a__2] = 1}, | |
[b__2_to_c___] = {[b___] = 1, [c__2] = 1}, | |
[b__2_to_a__3] = {[b___] = 1, [a_23] = 1}, | |
[b__2_to_c__3] = {[b___] = 1, [c_23] = 1}, | |
[b__1_to_a___] = {[b___] = 1, [a__1] = 1}, | |
[b__1_to_c___] = {[b___] = 1, [c__1] = 1}, | |
[b__1_to_a__2] = {[b___] = 1, [a_12] = 1}, | |
[b__1_to_c__2] = {[b___] = 1, [c_12] = 1}, | |
[b__1_to_a__3] = {[b___] = 1, [a_13] = 1}, | |
[b__1_to_c__3] = {[b___] = 1, [c_13] = 1}, | |
[b__1_to_a_23] = {[b___] = 1, [a123] = 1}, | |
[b__1_to_c_23] = {[b___] = 1, [c123] = 1}, | |
[c123_to_b___] = {[c_23] = 1, [b__1] = 1}, | |
[c123_to_a___] = {[c_23] = 1, [a__1] = 1}, | |
[c_23_to_b___] = {[c__3] = 1, [b__2] = 1}, | |
[c_23_to_a___] = {[c__3] = 1, [a__2] = 1}, | |
[c_12_to_b___] = {[c__2] = 1, [b__1] = 1}, | |
[c_12_to_a___] = {[c__2] = 1, [a__1] = 1}, | |
[c_12_to_b__3] = {[c__2] = 1, [b_13] = 1}, | |
[c_12_to_a__3] = {[c__2] = 1, [a_13] = 1}, | |
[c__3_to_b___] = {[c___] = 1, [b__3] = 1}, | |
[c__3_to_a___] = {[c___] = 1, [a__3] = 1}, | |
[c__2_to_b___] = {[c___] = 1, [b__2] = 1}, | |
[c__2_to_a___] = {[c___] = 1, [a__2] = 1}, | |
[c__2_to_b__3] = {[c___] = 1, [b_23] = 1}, | |
[c__2_to_a__3] = {[c___] = 1, [a_23] = 1}, | |
[c__1_to_b___] = {[c___] = 1, [b__1] = 1}, | |
[c__1_to_a___] = {[c___] = 1, [a__1] = 1}, | |
[c__1_to_b__2] = {[c___] = 1, [b_12] = 1}, | |
[c__1_to_a__2] = {[c___] = 1, [a_12] = 1}, | |
[c__1_to_b__3] = {[c___] = 1, [b_13] = 1}, | |
[c__1_to_a__3] = {[c___] = 1, [a_13] = 1}, | |
[c__1_to_b_23] = {[c___] = 1, [b123] = 1}, | |
[c__1_to_a_23] = {[c___] = 1, [a123] = 1}, | |
}; | |
PetriNet net = { | |
.marking = marking, | |
.place_count = places_count, | |
.transition_count = transitions_count, | |
.puts = (int *) puts, | |
.takes = (int *) takes | |
}; | |
int goal[places_count] = { [c123] = 1}; | |
vec result; | |
vec_init(&result, 3); | |
printf("-----------Towers of hanoi----------- \n"); | |
int success = find_path(&net, &result, goal, 7); | |
printf("Success: %i \n", success); | |
vec_print(result); | |
print_marking(net); | |
printf("----------- \n"); | |
} | |
int main() { | |
printf("Hello, World!\n"); | |
light_test(); | |
count_test(); | |
bar_bell_test(); | |
test_towers_of_hanoi(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment