+++ /dev/null
-package de.yasc.example.petrinet;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-import java.util.stream.Collectors;
-
-public final class PetriNet {
-
- private static final class Place {
-
- int tokens;
-
- boolean empty() {
- return tokens <= 0;
- }
-
- void dec() {
- assert tokens > 0;
- tokens--;
- }
-
- void inc() {
- tokens++;
- }
- }
-
- private static final class Transition {
-
- final List<Place> preset;
- final List<Place> postset;
-
- public Transition(List<Place> preset, List<Place> postset) {
- this.preset = preset;
- this.postset = postset;
- }
-
- boolean enabled() {
- return preset.stream().noneMatch(Place::empty);
- }
-
- void fire() {
- preset.forEach(Place::dec);
- postset.forEach(Place::inc);
- }
- }
-
- final private Random prng = new Random();
- final private Place[] places;
- final private List<Transition> transitions;
-
- public PetriNet(int places) {
- this.places = new Place[places];
- for (int i = 0 ; i < places ; i++)
- this.places[i] = new Place();
- transitions = new ArrayList<>();
- }
-
- public void addTransistion(Integer[] preset, Integer[] postset) {
- transitions.add(new Transition(
- Arrays.stream(preset).map((i) -> places[i]).collect(Collectors.toList()),
- Arrays.stream(postset).map((i) -> places[i]).collect(Collectors.toList())
- ));
- }
-
- public void addMarking(Integer ... marking) {
- Arrays.stream(marking).forEach((i) -> places[i].inc());
- }
-
- public boolean step() {
- var enabledTransitions = transitions.stream().filter(Transition::enabled).collect(Collectors.toList());
- if (enabledTransitions.isEmpty()) {
- return false;
- } else {
- transitions.get(prng.nextInt(enabledTransitions.size())).fire();
- return true;
- }
- }
-
- public int step(int k) {
- int i = 0;
- while (i < k) {
- if (!step())
- return i;
- ++i;
- }
- return i;
- }
-
- public Integer[] getMarking() {
- final var marking = new ArrayList<Integer>();
- for (int p = 0 ; p < places.length ; p++) {
- Collections.nCopies(places[p].tokens, p).forEach(marking::add);
- }
- return marking.toArray(new Integer[0]);
- }
-}