/*
* Copyright (C) 2012-2015 Matthias Heizmann (heizmann@informatik.uni-freiburg.de)
* Copyright (C) 2009-2015 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.petruchio;
import java.util.ArrayList;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.Map;
import de.uni_freiburg.informatik.ultimate.automata.AutomataLibraryException;
import de.uni_freiburg.informatik.ultimate.automata.AutomataLibraryServices;
import de.uni_freiburg.informatik.ultimate.automata.nestedword.NestedRun;
import de.uni_freiburg.informatik.ultimate.automata.nestedword.NestedWord;
import de.uni_freiburg.informatik.ultimate.automata.nestedword.operations.IsEmpty;
import de.uni_freiburg.informatik.ultimate.automata.petrinet.IPetriNet;
import de.uni_freiburg.informatik.ultimate.automata.petrinet.UnaryNetOperation;
import de.uni_freiburg.informatik.ultimate.automata.petrinet.netdatastructures.BoundedPetriNet;
import de.uni_freiburg.informatik.ultimate.automata.petrinet.operations.Accepts;
import de.uni_freiburg.informatik.ultimate.automata.petrinet.operations.PetriNet2FiniteAutomaton;
import de.uni_freiburg.informatik.ultimate.automata.statefactory.IPetriNet2FiniteAutomatonStateFactory;
import petruchio.cov.Backward;
import petruchio.cov.SimpleList;
import petruchio.interfaces.petrinet.Place;
import petruchio.interfaces.petrinet.Transition;
/**
* Check if a BoundedPetriNet has an accepting run. The emptiness check uses Tim Strazny's Petruchio. A marking of a
* BoundedPetriNet is accepting if the marking contains an accepting place. EmptinessPetruchio checks if any (singleton)
* marking {p} such that p is an accepting place can be covered.
*
* @author Matthias Heizmann (heizmann@informatik.uni-freiburg.de)
* @param
* Type of alphabet symbols
* @param
* Type of place labeling
*/
public final class EmptinessPetruchio
extends UnaryNetOperation> {
private final PetruchioWrapper mPetruchio;
private final BoundedPetriNet mBoundedNet;
private final NestedRun mAcceptedRun;
/**
* Constructor.
*
* @param services
* Ultimate services
* @param net
* Petri net
*/
public EmptinessPetruchio(final AutomataLibraryServices services, final BoundedPetriNet net) {
super(services);
mBoundedNet = net;
if (mLogger.isInfoEnabled()) {
mLogger.info(startMessage());
}
mPetruchio = new PetruchioWrapper<>(mServices, net);
mAcceptedRun = constructAcceptingRun();
if (mLogger.isInfoEnabled()) {
mLogger.info(exitMessage());
}
}
/**
* @return Some accepting run if the Petri net has an accepting run, null otherwise. Note: A run should be an
* interleaved sequence of markings and symbols. Here each marking will be null instead.
*/
private NestedRun constructAcceptingRun() {
if (mLogger.isDebugEnabled()) {
mLogger.debug("Net has " + mBoundedNet.getPlaces().size() + " Places");
mLogger.debug("Net has " + mBoundedNet.getTransitions().size() + " Transitions");
}
final Integer one = Integer.valueOf(1);
// construct single invariant p_1 + ... + p_n where p_i \in places
/*
* TODO Christian 2017-02-06: Sonar rightly complains that this variable is never actually used. It was used
* further below once because there is a commented occurrence of it.
*/
final Collection