/* * Copyright (C) 2022 Dominik Klumpp (klumpp@informatik.uni-freiburg.de) * Copyright (C) 2022 University of Freiburg * * This file is part of the ULTIMATE Automata Library. * * The ULTIMATE Automata Library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The ULTIMATE Automata Library 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the ULTIMATE Automata Library. If not, see . * * Additional permission under GNU GPL version 3 section 7: * If you modify the ULTIMATE Automata Library, or any covered work, by linking * or combining it with Eclipse RCP (or a modified version of Eclipse RCP), * containing parts covered by the terms of the Eclipse Public License, the * licensors of the ULTIMATE Automata Library grant you additional permission * to convey the resulting work. */ package de.uni_freiburg.informatik.ultimate.automata.petrinet; import java.util.ArrayList; import java.util.List; import java.util.Spliterator; import java.util.Spliterators; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; import de.uni_freiburg.informatik.ultimate.automata.Word; import de.uni_freiburg.informatik.ultimate.automata.petrinet.netdatastructures.Transition; import de.uni_freiburg.informatik.ultimate.util.BFSIterator; import de.uni_freiburg.informatik.ultimate.util.datastructures.ImmutableList; import de.uni_freiburg.informatik.ultimate.util.datastructures.ImmutableSet; import de.uni_freiburg.informatik.ultimate.util.datastructures.relation.Pair; /** * Enumerates all accepting runs of a given Petri net, in increasing length. * * @author Dominik Klumpp (klumpp@informatik.uni-freiburg.de) * */ public class EnumerateRuns { public static Iterable> enumerate(final IPetriNet net) { return () -> new RunEnumerator<>(net); } public static Stream> stream(final IPetriNet net) { return StreamSupport.stream(Spliterators.spliteratorUnknownSize(new RunEnumerator<>(net), Spliterator.ORDERED | Spliterator.IMMUTABLE), false); } private static class RunEnumerator extends BFSIterator, Transition, PetriNetRun> { private final IPetriNet mNet; public RunEnumerator(final IPetriNet net) { super(List.of(getInitialMarking(net))); mNet = net; } private static

Marking

getInitialMarking(final IPetriNet net) { return new Marking<>(ImmutableSet.copyOf(net.getInitialPlaces())); } @Override protected Iterable> getOutgoing(final Marking

marking) { return mNet.getTransitions().stream().filter(marking::isTransitionEnabled).collect(Collectors.toList()); } @Override protected Marking

getSuccessor(final Marking

marking, final Transition transition) { try { return marking.fireTransition(transition); } catch (final PetriNetNot1SafeException e) { throw new IllegalStateException(e); } } @Override protected boolean isTarget(final Marking

marking) { return mNet.isAccepting(marking); } @Override protected PetriNetRun finish(final ImmutableList, Transition>> stack, final Marking

finalMarking) { final L[] letters = (L[]) new Object[stack.size()]; final var markings = new ArrayList>(); final var transitions = new ArrayList>(); markings.add(finalMarking); int i = stack.size() - 1; for (final var frame : stack) { letters[i] = frame.getSecond().getSymbol(); transitions.add(0, frame.getSecond()); markings.add(0, frame.getFirst()); i--; } return new PetriNetRun(markings, new Word<>(letters), transitions); } } }