org.jbpt.petri.untangling.AbstractBaselineRepresentativeUntangling Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jbpt-petri Show documentation
Show all versions of jbpt-petri Show documentation
The jBPT code library is a compendium of technologies that support research on design, execution, and evaluation of business processes.
The newest version!
package org.jbpt.petri.untangling;
import java.util.ArrayList;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.jbpt.algo.graph.DirectedGraphAlgorithms;
import org.jbpt.petri.IFlow;
import org.jbpt.petri.IMarking;
import org.jbpt.petri.INetSystem;
import org.jbpt.petri.INode;
import org.jbpt.petri.IPlace;
import org.jbpt.petri.IRun;
import org.jbpt.petri.ITransition;
import org.jbpt.petri.structure.PetriNetStructuralChecks;
import org.jbpt.petri.unfolding.IBPNode;
import org.jbpt.petri.unfolding.ICondition;
import org.jbpt.petri.unfolding.IEvent;
/**
* An abstract implementation of the baseline algorithm for computing representative untanglings of net systems ({@link INetSystem}).
*
* @author Artem Polyvyanyy
*/
public class AbstractBaselineRepresentativeUntangling, C extends ICondition, E extends IEvent,
F extends IFlow, N extends INode, P extends IPlace, T extends ITransition, M extends IMarking>
extends AbstractRepresentativeUntangling
{
public AbstractBaselineRepresentativeUntangling(INetSystem sys, UntanglingSetup setup) {
super(sys, setup);
}
/**
* Constructor of a representative untangling.
*
* @param sys Net system to untangle.
*/
public AbstractBaselineRepresentativeUntangling(INetSystem sys) {
super(sys);
}
@Override
protected void constructRuns(INetSystem system) {
switch (this.setup.SIGNIFICANCE_CHECK) {
case EXHAUSTIVE:
this.constructRunsExhaustive(system);
break;
case HASHMAP_BASED:
this.constructRunsHashmapBased(system);
break;
case TREE_OF_RUNS:
this.constructRunsTreeOfRuns(system);
break;
default:
this.constructRunsExhaustive(system);
}
}
private void constructRunsExhaustive(INetSystem system) {
Queue> queue = new ConcurrentLinkedQueue>();
IRun ini = this.createRun(system);
// if system has no conflicts and is acyclic its untangling is trivial
PetriNetStructuralChecks sc = new PetriNetStructuralChecks();
DirectedGraphAlgorithms dga = new DirectedGraphAlgorithms();
if (sc.isConflictFree(system) && dga.isAcyclic(system)) {
Set PE = ini.getPossibleExtensions();
while (!PE.isEmpty()) {
ini.append(PE.iterator().next());
}
this.significantRunCounter++;
this.runs.add(ini);
return;
}
// perform complex stuff
queue.add(ini);
this.significantRunCounter++;
while (!queue.isEmpty()) {
if (queue.size() % 1000 == 0)
System.out.println(queue.size());
IRun run = queue.poll();
// safeness check (extra)
if (this.safe && run.size()>0 && !run.get(run.size()-1).getOutputMarking().isSafe()) {
this.safe = false;
//return;
}
// get possible extensions of the run
Set PE = run.getPossibleExtensions();
if (PE.isEmpty()) {
if (setup.REDUCE) this.prune(run);
this.runs.add(run);
if (this.runs.size() % 1000 == 0) System.err.println(this.runs.size());
}
else {
boolean allExtensionsInsignificant = true;
for (T t : PE) {
IRun freshRun = run.clone();
freshRun.append(t);
if (this.isSignificant(freshRun)) {
queue.add(freshRun);
this.significantRunCounter++;
allExtensionsInsignificant = false;
}
}
if (allExtensionsInsignificant) {
if (setup.REDUCE) this.prune(run);
this.runs.add(run);
if (this.runs.size() % 1000 == 0) System.err.println(this.runs.size());
}
}
}
System.out.println("FINISHED WHILE LOOP");
System.out.println(this.runs.size());
if (setup.REDUCE) {
System.err.println("REDUCING PROCESSES");
this.reduceSubruns();
}
}
private void constructRunsHashmapBased(INetSystem system) {
Queue> queue = new ConcurrentLinkedQueue>();
IUntanglingRun ini = this.createUntanglingRun(system);
// if system has no conflicts and is acyclic its untangling is trivial
PetriNetStructuralChecks sc = new PetriNetStructuralChecks();
DirectedGraphAlgorithms dga = new DirectedGraphAlgorithms();
if (sc.isConflictFree(system) && dga.isAcyclic(system)) {
Set PE = ini.getPossibleExtensions();
while (!PE.isEmpty()) {
ini.append(PE.iterator().next());
}
this.significantRunCounter++;
this.runs.add(ini);
return;
}
// perform complex stuff
queue.add(ini);
this.significantRunCounter++;
while (!queue.isEmpty()) {
IUntanglingRun run = queue.poll();
// safeness check (extra)
if (run.size()>0 && !run.get(run.size()-1).getOutputMarking().isSafe()) {
this.safe = false;
return;
}
// get possible extensions of the run
Set PE = run.getPossibleExtensions();
if (PE.isEmpty()) {
if (setup.REDUCE) this.prune(run);
this.runs.add(run);
}
else {
boolean allExtensionsInsignificant = true;
for (T t : PE) {
IUntanglingRun freshRun = run.clone();
freshRun.append(t);
if (freshRun.isSignificant()) {
queue.add(freshRun);
this.significantRunCounter++;
allExtensionsInsignificant = false;
}
}
if (allExtensionsInsignificant) {
if (setup.REDUCE) this.prune(run);
this.runs.add(run);
}
}
}
if (setup.REDUCE) {
this.reduceSubruns();
}
}
@SuppressWarnings("unchecked")
private void constructRunsTreeOfRuns(INetSystem system) {
this.torRoot = new TreeStep(system,null,null,null,(M)system.getMarking().clone(),0);
this.torRoot.index = new TreeStepIndex();
this.torLeaves = new ArrayList>();
Queue> queue = new ConcurrentLinkedQueue>();
// if system has no conflicts and is acyclic its untangling is trivial
PetriNetStructuralChecks sc = new PetriNetStructuralChecks();
DirectedGraphAlgorithms dga = new DirectedGraphAlgorithms();
if (sc.isConflictFree(system) && dga.isAcyclic(system)) {
IRun ini = this.createRun(system);
Set PE = ini.getPossibleExtensions();
while (!PE.isEmpty()) {
ini.append(PE.iterator().next());
}
this.significantRunCounter++;
this.runs.add(ini);
return;
}
// perform complex stuff
if (!this.torRoot.isSafe()) {
this.safe = false;
return;
}
queue.add(this.torRoot);
this.significantRunCounter++;
while (!queue.isEmpty()) {
TreeStep curr = queue.poll();
Set> PE = curr.getPossibleExtensions();
if (PE.isEmpty())
this.torLeaves.add(curr);
else {
boolean allExtensionsInsignificant = true;
for (TreeStep ext : PE) {
if (ext.isSignificant()) {
if (!ext.isSafe()) {
this.safe = false;
return;
}
allExtensionsInsignificant = false;
queue.add(ext);
this.significantRunCounter++;
}
}
if (allExtensionsInsignificant)
this.torLeaves.add(curr);
}
}
}
}