Skip to content

Commit

Permalink
Karp-Miller Tree is implemented to check boundedness
Browse files Browse the repository at this point in the history
  • Loading branch information
akalenkova committed Jan 27, 2021
1 parent 3e62564 commit 3de15d1
Show file tree
Hide file tree
Showing 13 changed files with 300 additions and 21 deletions.
276 changes: 276 additions & 0 deletions jbpt-petri/src/main/java/org/jbpt/petri/mc/PetriNetChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
package org.jbpt.petri.mc;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import org.jbpt.petri.Flow;
import org.jbpt.petri.INetSystem;
import org.jbpt.petri.Marking;
import org.jbpt.petri.Node;
import org.jbpt.petri.Place;
import org.jbpt.petri.Transition;

/**
* Checking boundedness of Petri net
*
* @author Anna Kalenkova
*/
public class PetriNetChecker implements IModelChecker<Flow,Node,Place,Transition,Marking> {

public static class KarpMillerTree {
private Node root;

public KarpMillerTree(Marking rootData) {
root = new Node(rootData);
}

public static class Node {
private Marking data;
private Node parent;

public Node(Marking data) {

this.data = data;

}
public Node getParent() {

return parent;
}
public Marking getData() {

return data;
}
public void setParent(Node parent) {

this.parent=parent;
}

}
public Node getRoot() {

return root;
}
}

private INetSystem<Flow,Node,Place,Transition,Marking> net;

public PetriNetChecker (INetSystem<Flow,Node,Place,Transition,Marking> net) {

this.net = net;
}

public boolean isBounded() {

if (net == null)
return false;

return isBoundedKarpMiller();
}

private boolean isBoundedKarpMiller() {


Marking initialMarking = new Marking(net);
initialMarking.fromMultiSet(net.getMarking().toMultiSet());

Marking startMarking = new Marking(net);
startMarking.fromMultiSet(net.getMarking().toMultiSet());

KarpMillerTree tree = new KarpMillerTree(startMarking);

Set<KarpMillerTree.Node> newNodes = new HashSet<KarpMillerTree.Node>();
newNodes.add(tree.getRoot());

while(!newNodes.isEmpty()) {
KarpMillerTree.Node curNode = newNodes.iterator().next();

Set<Transition> enabledTransitions = findEnabledTransitions(curNode.getData());
Marking currentMarking = curNode.getData();
// Add new markings to the tree
for(Transition enabledTransition: enabledTransitions) {

net.loadMarking(currentMarking);
net.fire(enabledTransition);
Marking newMarking = new Marking(net);
newMarking.fromMultiSet(net.getMarking().toMultiSet());
KarpMillerTree.Node newNode = new KarpMillerTree.Node(newMarking);

Set<KarpMillerTree.Node> parents = findParents(curNode);
// If this node is identical to one of the parents, skip it
if(belongsTo(newNode, parents)) {
continue;
}

// If marking dominates one of the parents' markings, the net is not bounded, return false
if(dominates(newNode, parents)) {
return false;
}

// Add new node
newNode.setParent(curNode);
newNodes.add(newNode);
}
newNodes.remove(curNode);
}
// Restore marking
net.loadMarking(initialMarking);
return true;
}

private boolean dominates(KarpMillerTree.Node node, Set<KarpMillerTree.Node> otherNodes) {

Marking nodeMarking = node.getData();

for(KarpMillerTree.Node otherNode : otherNodes) {
Marking otherNodeMarking = otherNode.getData();
if(nodeMarking.toMultiSet().containsAll(otherNodeMarking.toMultiSet())) {
return true;
}
}
return false;
}

private Set findEnabledTransitions (Marking marking) {

Set enabledTransitions = new HashSet();

for (Transition t : net.getTransitions()) {
Collection<Flow> incomingEdges = net.getIncomingEdges(t);
boolean enabled = true;
for (Flow incomingEdge : incomingEdges) {
Place place = (Place)incomingEdge.getSource();
if(!marking.toMultiSet().contains(place)) {
enabled = false;
}
}
if(enabled) {
enabledTransitions.add(t);
}
}

return enabledTransitions;
}

private boolean belongsTo(KarpMillerTree.Node node, Set<KarpMillerTree.Node> setOfNodes) {

for (KarpMillerTree.Node nodeFromTheSet : setOfNodes) {
if (nodeFromTheSet.getData().toMultiSet().equals(node.getData().toMultiSet())) {
return true;
}
}

return false;
}

private Set<KarpMillerTree.Node> findParents(KarpMillerTree.Node node) {
Set<KarpMillerTree.Node> parents = new HashSet<KarpMillerTree.Node>();
KarpMillerTree.Node curNode = node;

while (curNode.getParent()!= null) {
parents.add(curNode.getParent());
curNode = curNode.getParent();
}
return parents;
}


@Override
public boolean isLive(INetSystem<Flow,Node,Place,Transition,Marking> sys, Transition t) {
// TODO Auto-generated method stub
return false;
}


@Override
public void setLoLAActive(boolean active) {
// TODO Auto-generated method stub

}

@Override
public AtomicBoolean isLoLAActive() {
// TODO Auto-generated method stub
return null;
}


@Override
public boolean isLive(INetSystem<Flow, org.jbpt.petri.Node, Place, Transition, Marking> sys) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean isReachable(INetSystem<Flow, org.jbpt.petri.Node, Place, Transition, Marking> sys,
Collection<Place> marking) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean isBounded(INetSystem<Flow, org.jbpt.petri.Node, Place, Transition, Marking> sys, Place p) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean isBounded(INetSystem<Flow, org.jbpt.petri.Node, Place, Transition, Marking> sys) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean isSoundWorkflowNet(INetSystem<Flow, org.jbpt.petri.Node, Place, Transition, Marking> sys) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean canReachMarkingWithAtLeastOneTokenAtEachPlace(
INetSystem<Flow, org.jbpt.petri.Node, Place, Transition, Marking> sys, Set<Place> places) {
// TODO Auto-generated method stub
return false;
}

@Override
public StateSpaceStatistics getStateSpaceStatistics(
INetSystem<Flow, org.jbpt.petri.Node, Place, Transition, Marking> sys) {
// TODO Auto-generated method stub
return null;
}

@Override
public boolean check(INetSystem<Flow, org.jbpt.petri.Node, Place, Transition, Marking> sys, String property) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean canReachMarkingWithAtLeastOneTokenAtEachPlace(
INetSystem<Flow, org.jbpt.petri.Node, Place, Transition, Marking> sys, Set<Place> places, Set<Process> p) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean isReachable(INetSystem<Flow, org.jbpt.petri.Node, Place, Transition, Marking> sys,
Collection<Place> marking, Set<Process> p) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean isIndexable(INetSystem<Flow, org.jbpt.petri.Node, Place, Transition, Marking> sys) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean isIndexable(INetSystem<Flow, org.jbpt.petri.Node, Place, Transition, Marking> sys, Set<Process> p) {
// TODO Auto-generated method stub
return false;
}
}
Binary file modified jbpt-pm/entropia/jbpt-pm-entropia-1.5.jar
Binary file not shown.
6 changes: 3 additions & 3 deletions jbpt-pm/install.bat
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
call mvn -f ../jbpt-core/pom.xml install
call mvn -f ../jbpt-deco/pom.xml install
call mvn -f ../jbpt-petri/pom.xml install
call mvn -f ../jbpt-core/pom.xml clean install
call mvn -f ../jbpt-deco/pom.xml clean install
call mvn -f ../jbpt-petri/pom.xml clean install
call mvn install:install-file -Dfile=${project.basedir}/lib/eigen-measure.jar -DrepositoryLayout=default -DgroupId=org.processmining.eigenvalue -DartifactId=eigenvalue -Dversion=0.1.1 -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=${project.basedir}/lib/StochasticAwareEntropy.jar -DrepositoryLayout=default -DgroupId=org.processmining.stochasticawareconformancechecking -DartifactId=stochastic -Dversion=0.0.1 -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=${project.basedir}/lib/jbpt-pm-relevance-1.0-SNAPSHOT-jdk1.8.jar -DpomFile=${project.basedir}/lib/relevance-pom.xml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import org.deckfour.xes.model.XLog;
import org.jbpt.petri.NetSystem;
import org.jbpt.petri.mc.LoLA2ModelChecker;
import org.jbpt.petri.mc.PetriNetChecker;
import org.jbpt.pm.utils.Utils;

import dk.brics.automaton.Automaton;
Expand Down Expand Up @@ -90,10 +90,12 @@ public boolean checkLimitations() {
private boolean checkBounded(Object model) {
if (model instanceof NetSystem) {
NetSystem sys = (NetSystem) model;
sys.loadNaturalMarking();
LoLA2ModelChecker lola = new LoLA2ModelChecker("./lola2/win/lola");
boolean result = lola.isBounded(sys);
return result;
PetriNetChecker netChecker = new PetriNetChecker(sys);
return netChecker.isBounded();
// sys.loadNaturalMarking();
// LoLA2ModelChecker lola = new LoLA2ModelChecker("./lola2/win/lola");
// boolean result = lola.isBounded(sys);
// return result;
}
return true;
}
Expand All @@ -106,8 +108,7 @@ private boolean checkBounded(Object model) {
*/
public double computeMeasure() throws Exception {

if (limitationsHold==null) this.checkLimitations();
if (limitationsHold==null || !limitationsHold.booleanValue()) {
if (limitationsHold!=null && !limitationsHold.booleanValue()) {
throw new Exception(String.format("Limitation(s): %s of %s measure are not fulfilled", violetedLimitations, this.getClass().getName()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import org.apache.commons.math3.util.Pair;
import org.deckfour.xes.model.XLog;
import org.jbpt.petri.NetSystem;
import org.jbpt.petri.mc.LoLA2ModelChecker;
import org.jbpt.petri.mc.PetriNetChecker;
import org.jbpt.pm.utils.Utils;

import dk.brics.automaton.Automaton;
Expand Down Expand Up @@ -112,10 +112,12 @@ public boolean checkLimitations() {
public static boolean checkBounded(Object model) {
if (model instanceof NetSystem) {
NetSystem sys = (NetSystem) model;
sys.loadNaturalMarking();
LoLA2ModelChecker lola = new LoLA2ModelChecker("./lola2/win/lola");
boolean result = lola.isBounded(sys);
return result;
PetriNetChecker netChecker = new PetriNetChecker(sys);
return netChecker.isBounded();
// sys.loadNaturalMarking();
// LoLA2ModelChecker lola = new LoLA2ModelChecker("./lola2/win/lola");
// boolean result = lola.isBounded(sys);
// return result;
}
return true;
}
Expand All @@ -128,8 +130,7 @@ public static boolean checkBounded(Object model) {
*/
public Pair<Double, Double> computeMeasure() throws Exception {

if (limitationsHold==null) this.checkLimitations();
if (limitationsHold==null || !limitationsHold.booleanValue()) {
if (limitationsHold!=null && !limitationsHold.booleanValue()) {
throw new Exception(String.format("Limitation(s): %s of %s measure are not fulfilled", violetedLimitations, this.getClass().getName()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.commons.math3.util.Pair;
import org.deckfour.xes.in.XesXmlParser;
import org.deckfour.xes.model.XLog;
import org.jbpt.petri.NetSystem;
import org.jbpt.petri.io.PNMLSerializer;
import org.jbpt.pm.models.FDAGraph;
import org.jbpt.pm.models.SAutomaton;
Expand Down
1 change: 0 additions & 1 deletion jbpt-pm/src/main/java/org/jbpt/pm/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public static Automaton constructAutomatonFromNetSystem(NetSystem ns, TObjectSho

// Construct initial state
Collection<Place> initialMarking = ns.getMarking().toMultiSet();
// System.out.println("Initial marking = " + initialMarking);

// Derive final marking
Collection<Place> finalMarking = deriveFinalMarking(ns);
Expand Down
1 change: 1 addition & 0 deletions jbpt-pm/target/examples/model2.pnml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<text>true</text>
</tokenCaseSensitive>
</toolspecific>
<initialMarking><text>1</text></initialMarking>
</place>
<place id="pl2">
<graphics>
Expand Down
6 changes: 3 additions & 3 deletions jbpt-pm/target/install.bat
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
call mvn -f ../jbpt-core/pom.xml install
call mvn -f ../jbpt-deco/pom.xml install
call mvn -f ../jbpt-petri/pom.xml install
call mvn -f ../jbpt-core/pom.xml clean install
call mvn -f ../jbpt-deco/pom.xml clean install
call mvn -f ../jbpt-petri/pom.xml clean install
call mvn install:install-file -Dfile=${project.basedir}/lib/eigen-measure.jar -DrepositoryLayout=default -DgroupId=org.processmining.eigenvalue -DartifactId=eigenvalue -Dversion=0.1.1 -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=${project.basedir}/lib/StochasticAwareEntropy.jar -DrepositoryLayout=default -DgroupId=org.processmining.stochasticawareconformancechecking -DartifactId=stochastic -Dversion=0.0.1 -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=${project.basedir}/lib/jbpt-pm-relevance-1.0-SNAPSHOT-jdk1.8.jar -DpomFile=${project.basedir}/lib/relevance-pom.xml
Expand Down
Binary file modified jbpt-pm/target/jbpt-pm-entropia-1.5.jar
Binary file not shown.
Binary file modified jbpt-pm/target/lib/jbpt-core-0.3.2.jar
Binary file not shown.
Binary file modified jbpt-pm/target/lib/jbpt-deco-0.3.2.jar
Binary file not shown.
Binary file modified jbpt-pm/target/lib/jbpt-petri-0.3.2.jar
Binary file not shown.

0 comments on commit 3de15d1

Please sign in to comment.