/* * Copyright (C) 2019 Elisabeth Schanno * Copyright (C) 2019 Dominik Klumpp (klumpp@informatik.uni-freiburg.de) * Copyright (C) 2019 Matthias Heizmann (heizmann@informatik.uni-freiburg.de) * Copyright (C) 2019 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.partialorder; import java.util.Collection; import java.util.Set; import de.uni_freiburg.informatik.ultimate.automata.AutomataLibraryServices; import de.uni_freiburg.informatik.ultimate.automata.AutomataOperationCanceledException; import de.uni_freiburg.informatik.ultimate.automata.petrinet.IPetriNet; import de.uni_freiburg.informatik.ultimate.automata.petrinet.PetriNetNot1SafeException; import de.uni_freiburg.informatik.ultimate.automata.petrinet.unfolding.BranchingProcess; import de.uni_freiburg.informatik.ultimate.automata.petrinet.unfolding.Event; import de.uni_freiburg.informatik.ultimate.automata.petrinet.unfolding.FinitePrefix; import de.uni_freiburg.informatik.ultimate.automata.petrinet.unfolding.ICoRelation; import de.uni_freiburg.informatik.ultimate.util.datastructures.relation.HashRelation; /** * Relates letters labeling transitions in a Petri net. Two letters are coenabled if there exists a reachable marking * where transitions labelled with these letters can fire independently (i.e., without one disabling the other). * * @author Dominik Klumpp (klumpp@informatik.uni-freiburg.de) * * @param * The type of letters labeling Petri net transitions. */ public final class CoenabledRelation { private final HashRelation mRelation; private CoenabledRelation(final HashRelation relation) { mRelation = relation; } /** * Creates a new instance by computing the relation from the given Petri net. * * @param services * Automata library services to be used in the computation * @param petriNet * The net whose coenabled-relation shall be computed. * * @return A new relation computed from the finite unfolding prefix of the given net. * * @throws AutomataOperationCanceledException * if the computation is canceled * @throws PetriNetNot1SafeException * if the given net is not 1-safe */ public static CoenabledRelation fromPetriNet(final AutomataLibraryServices services, final IPetriNet petriNet) throws AutomataOperationCanceledException, PetriNetNot1SafeException { final BranchingProcess bp = new FinitePrefix<>(services, petriNet).getResult(); return new CoenabledRelation<>(computeFromBranchingProcess(bp)); } private static HashRelation computeFromBranchingProcess(final BranchingProcess bp) { final HashRelation hashRelation = new HashRelation<>(); final ICoRelation coRelation = bp.getCoRelation(); final Collection> events = bp.getEvents(); for (final Event event1 : events) { if (bp.getDummyRoot() != event1) { final Set> coRelatedEvents = coRelation.computeCoRelatatedEvents(event1); for (final Event coRelatedEvent : coRelatedEvents) { hashRelation.addPair(event1.getTransition().getSymbol(), coRelatedEvent.getTransition().getSymbol()); } } } return hashRelation; } /** * Determines the size of the relation. * * @return The number of pairs of letters that are in the relation. */ public int size() { return mRelation.size(); } /** * Computes the set of all coenabled letters. * * @param element * The letter whose coenabled letters shall be computed. * @return The set of all letters b, such that the pair (element, b) is in the relation. */ public Set getImage(final LETTER element) { return mRelation.getImage(element); } /** * For each pair in the relation involving a given letter, creates a new corresponding pair involving the other * letter. The original pairs are not removed, they remain in the relation. */ public void copyRelationships(final LETTER from, final LETTER to) { for (final LETTER t3 : mRelation.getImage(from)) { mRelation.addPair(to, t3); } for (final LETTER t3 : mRelation.getDomain()) { if (mRelation.containsPair(t3, from)) { mRelation.addPair(t3, to); } } } /** * Removes all pairs involving the given letter from the relation. */ public void deleteElement(final LETTER letter) { mRelation.removeDomainElement(letter); mRelation.removeRangeElement(letter); } }