All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jbpt.petri.unfolding.AbstractCompletePrefixUnfolding Maven / Gradle / Ivy

Go to download

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.unfolding;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

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.ITransition;
import org.jbpt.petri.unfolding.order.EsparzaAdequateOrderForArbitrarySystems;
import org.jbpt.petri.unfolding.order.EsparzaAdequateTotalOrderForSafeSystems;
import org.jbpt.petri.unfolding.order.IAdequateOrder;
import org.jbpt.petri.unfolding.order.McMillanAdequateOrder;
import org.jbpt.petri.unfolding.order.UnfoldingAdequateOrder;


/**
 * (An abstract) implementation of a complete prefix unfloding of a net system.

* * This class implements techniques described in: * - Javier Esparza, Stefan Roemer, Walter Vogler: An Improvement of McMillan's Unfolding Algorithm. Formal Methods in System Design (FMSD) 20(3):285-310 (2002). * - Victor Khomenko: Model Checking Based on Prefixes of Petri Net Unfoldings. PhD Thesis. February (2003). * * @author Artem Polyvyanyy */ public class AbstractCompletePrefixUnfolding, C extends ICondition, E extends IEvent, F extends IFlow, N extends INode, P extends IPlace, T extends ITransition, M extends IMarking> extends AbstractBranchingProcess implements ICompletePrefixUnfolding { // setup to use when constructing this complete prefix unfolding protected CompletePrefixUnfoldingSetup setup = null; // map of cutoff events to corresponding events protected Map cutoff2corr = new HashMap(); // set of possible extensions updates private Set UPE = null; // total order used to construct this complete prefix unfolding protected List totalOrderTs = null; // adequate order used to construct this complete prefix unfolding protected IAdequateOrder ADEQUATE_ORDER = null; /** * Empty constructor. */ protected AbstractCompletePrefixUnfolding(){} /** * Constructor with default setup. * * @param sys Net system to construct complete prefix unfolding for. */ public AbstractCompletePrefixUnfolding(INetSystem sys) { this(sys, new CompletePrefixUnfoldingSetup()); } /** * Constructor with specified setup. * * @param sys Net system to construct complete prefix unfolding for. * @param setup Setup to use when constructing complete prefix unfolding. */ public AbstractCompletePrefixUnfolding(INetSystem sys, CompletePrefixUnfoldingSetup setup) { super(sys); // net system must be different from null if (this.sys==null) return; // initial branching process must not be empty this.constructInitialBranchingProcess(); if (this.iniBP.isEmpty()) return; // initialise this.totalOrderTs = new ArrayList(sys.getTransitions()); this.setup = setup; switch (this.setup.ADEQUATE_ORDER) { case ESPARZA_FOR_ARBITRARY_SYSTEMS: this.ADEQUATE_ORDER = new EsparzaAdequateOrderForArbitrarySystems(); break; case ESPARZA_FOR_SAFE_SYSTEMS: this.ADEQUATE_ORDER = new EsparzaAdequateTotalOrderForSafeSystems(); break; case MCMILLAN: this.ADEQUATE_ORDER = new McMillanAdequateOrder(); break; case UNFOLDING: this.ADEQUATE_ORDER = new UnfoldingAdequateOrder(); break; default: this.ADEQUATE_ORDER = new EsparzaAdequateTotalOrderForSafeSystems(); break; } // construct unfolding if (this.setup.SAFE_OPTIMIZATION) this.constructSafe(); else this.constructSafe(); } protected void constructSafe() { IPossibleExtensions pe = getInitialPossibleExtensions(); // get possible extensions of the initial branching process while (!pe.isEmpty()) { // while extensions exist if (this.events.size() >= this.setup.MAX_EVENTS) return; // track number of events in unfolding E e = pe.getMinimal(); // event to use for extending unfolding pe.remove(e); // remove 'e' from the set of possible extensions if (!this.appendEvent(e)) return; // add event 'e' to unfolding E corr = this.checkCutoffA(e); // check if 'e' is a cutoff event if (corr!=null) this.addCutoff(e,corr); // record cutoff else pe.addAll(this.updatePossibleExtensions(e)); // update the set of possible extensions } } // map a condition to a set of cuts that contain the condition //protected Map>> c2cut = new HashMap>>(); // maps of transitions/places to sets of events/conditions (occurrences of transitions/places) //protected Map> t2es = new HashMap>(); //protected Map> p2cs = new HashMap>(); /** * Construct unfolding. * * This method closely follows the algorithm described in: * Javier Esparza, Stefan Roemer, Walter Vogler: An Improvement of McMillan's Unfolding Algorithm. Formal Methods in System Design (FMSD) 20(3):285-310 (2002). */ /*protected void construct() { if (this.sys==null) return; // CONSTRUCT INITIAL BRANCHING PROCESS M M0 = this.sys.getMarking(); for (P p : this.sys.getMarking().toMultiSet()) { C c = this.createCondition(p,null); this.addCondition(c); this.initialBranchingProcess.add(c); } if (!this.addCut(initialBranchingProcess)) return; // Event cutoffIni = null; Event corrIni = null; // for special handling of events that induce initial markings // CONSTRUCT UNFOLDING Set pe = getPossibleExtensionsA(); // get possible extensions of initial branching process while (!pe.isEmpty()) { // while extensions exist if (this.countEvents>=this.setup.MAX_EVENTS) return; // track number of events in unfolding Event e = this.setup.ADEQUATE_ORDER.getMinimal(pe); // event to use for extending unfolding if (!this.overlap(cutoff2corr.keySet(),e.getLocalConfiguration())) { if (!this.addEvent(e)) return; // add event to unfolding Event corr = this.checkCutoffA(e); // check for cutoff event if (corr!=null) this.addCutoff(e,corr); // e is cutoff event // The following functionality is not captured by Esparza's algorithm !!! // The code handles situation when there exist a cutoff event which induces initial marking // The identification of such cutoff was postponed to the point until second event which induces initial marking is identified //if (corrIni == null) { //boolean isCutoffIni = e.getLocalConfiguration().getMarking().equals(this.net.getMarking()); //if (cutoffIni == null && isCutoffIni) cutoffIni = e; //else if (cutoffIni != null && corrIni == null && isCutoffIni) { //corrIni = e; //this.cutoff2corr.put(cutoffIni, corrIni); //} //} pe = getPossibleExtensionsA(); // get possible extensions of branching process } else { pe.remove(e); } } }*/ protected IPossibleExtensions getInitialPossibleExtensions() { IPossibleExtensions result = new AbstractPossibleExtensions(this.ADEQUATE_ORDER); for (T t : this.sys.getTransitions()) { ICoSet coset = this.containsPlaces(this.getInitialCut(),this.sys.getPreset(t)); if (coset!=null) { // if there exists such a co-set result.add(this.createEvent(t,coset)); } } return result; } private Set updatePossibleExtensions(E e) { this.UPE = new HashSet(); T u = e.getTransition(); Set upp = new HashSet(this.sys.getPostsetTransitions(this.sys.getPostset(u))); Set

pu = new HashSet

(this.sys.getPreset(u)); pu.removeAll(this.sys.getPostset(u)); upp.removeAll(this.sys.getPostsetTransitions(pu)); for (T t : upp) { ICoSet preset = this.createCoSet(); for (C b : e.getPostConditions()) { if (this.sys.getPreset(t).contains(b.getPlace())) preset.add(b); } Set C = this.getConcurrentConditions(e); this.cover(C,t,preset); } return this.UPE; } @SuppressWarnings("unchecked") private void cover(Set CC, T t, ICoSet preset) { if (this.sys.getPreset(t).size()==preset.size()) { this.UPE.add(this.createEvent(t, preset)); } else { Set

pre = new HashSet

(this.sys.getPreset(t)); pre.removeAll(this.getPlaces(preset)); P p = pre.iterator().next(); for (C d : CC) { if (d.getPlace().equals(p)) { Set C2 = new HashSet(); for (C dd : CC) if (this.areConcurrent((BPN)d,(BPN)dd)) C2.add(dd); ICoSet preset2 = this.createCoSet(); preset2.addAll(preset); preset2.add(d); this.cover(C2,t,preset2); } } } } private Set

getPlaces(ICoSet coset) { Set

result = new HashSet

(); for (C c : coset) result.add(c.getPlace()); return result; } @SuppressWarnings("unchecked") private Set getConcurrentConditions(E e) { Set result = new HashSet(); for (C c : this.getConditions()) { if (this.areConcurrent((BPN)e,(BPN)c)) result.add(c); } return result; } protected ICoSet containsPlaces(ICoSet coset, Collection

places) { ICoSet result = this.createCoSet(); for (P p : places) { boolean flag = false; for (C c : coset) { if (c.getPlace().equals(p)) { flag = true; result.add(c); break; } } if (!flag) return null; } return result; } protected E checkCutoffA(E cutoff) { ILocalConfiguration lce = cutoff.getLocalConfiguration(); for (E f : this.getEvents()) { if (f.equals(cutoff)) continue; ILocalConfiguration lcf = f.getLocalConfiguration(); if (lce.getMarking().equals(lcf.getMarking()) && this.ADEQUATE_ORDER.isSmaller(lcf, lce)) return this.checkCutoffB(cutoff,f); // check cutoff extended conditions } return null; } protected E checkCutoffB(E cutoff, E corr) { return corr; } protected void addCutoff(E e, E corr) { this.cutoff2corr.put(e,corr); } @Override public Set getCutoffEvents() { return this.cutoff2corr.keySet(); } @Override public boolean isCutoffEvent(E event) { return this.cutoff2corr.containsKey(event); } @Override public E getCorrespondingEvent(E event) { return this.cutoff2corr.get(event); } @Override public List getTotalOrderOfTransitions() { return this.totalOrderTs; } @Override public IOccurrenceNet getOccurrenceNet() { try { @SuppressWarnings("unchecked") IOccurrenceNet occ = (IOccurrenceNet) OccurrenceNet.class.newInstance(); occ.setCompletePrefixUnfolding(this); return occ; } catch (InstantiationException e) { e.printStackTrace(); return null; } catch (IllegalAccessException e) { e.printStackTrace(); return null; } } /*protected Set getPossibleExtensionsA() { Set result = new HashSet(); // iterate over all transitions of the originative net for (Transition t : this.sys.getTransitions()) { // iterate over all places in the preset Collection pre = this.sys.getPreset(t); Place p = pre.iterator().next(); // get cuts that contain conditions that correspond to the place Collection cuts = this.getCutsWithPlace(p); // iterate over cuts for (Cut cut : cuts) { // get co-set of conditions that correspond to places in the preset (contained in the cut) CoSet coset = this.containsPlaces(cut,pre); if (coset!=null) { // if there exists such a co-set // check if there already exists an event that corresponds to the transition with the preset of conditions which equals to coset boolean flag = false; if (t2es.get(t)!=null) { for (IEvent e : t2es.get(t)) { //if (this.areEqual(e.getPreConditions(),coset)) { if (coset.equals(e.getPreConditions())) { flag = true; break; } } } if (!flag) { // we found possible extension !!! Event e = new Event(this,t,coset); result.add(e); } } } } result.addAll(this.getPossibleExtensionsB(result)); return result; }*/ /*protected Set getPossibleExtensionsB(Set pe) { return new HashSet(); }*/ /*private void updateConcurrency(Cut cut) { for (Condition c1 : cut) { if (this.co.get(c1)==null) this.co.put(c1, new HashSet()); Event e1 = c1.getPreEvent(); if (e1 != null && this.co.get(e1)==null) this.co.put(e1, new HashSet()); for (Condition c2 : cut) { if (this.co.get(c2)==null) this.co.put(c2, new HashSet()); this.co.get(c1).add(c2); Event e2 = c2.getPreEvent(); if (e1!=null && e2!=null && !this.ca.get(e1).contains(e2) && !this.ca.get(e2).contains(e1)) this.co.get(e1).add(e2); if (!c1.equals(c2) && e1!=null && !this.ca.get(c2).contains(e1) && !this.ca.get(e1).contains(c2)) { this.co.get(c2).add(e1); this.co.get(e1).add(c2); } } } }*/ /*protected Set getCutsWithPlace(Place p) { Set result = new HashSet(); Collection cs = p2cs.get(p); if (cs==null) return result; for (ICondition c : cs) { Collection cuts = c2cut.get(c); if (cuts!=null) result.addAll(cuts); } return result; }*/ /*protected boolean contains(Collection cs1, Collection cs2) { for (ICondition c1 : cs2) { boolean flag = false; for (ICondition c2 : cs1) { if (c1.equals(c2)) { flag = true; break; } } if (!flag) return false; } return true; }*/ /*protected boolean addCut(ICut cut) { this.updateConcurrency(cut); Map p2i = new HashMap(); for (Condition c : cut) { // check bound Integer i = p2i.get(c.getPlace()); if (i==null) p2i.put(c.getPlace(),1); else { if (i == this.setup.MAX_BOUND) return false; else p2i.put(c.getPlace(),i+1); } if (c2cut.get(c)!=null) c2cut.get(c).add(cut); else { Collection cuts = new ArrayList(); cuts.add(cut); c2cut.put(c,cuts); } } return true; }*/ /*@Override public CompletePrefixUnfoldingSetup getSetup() { return this.setup; }*/ /*@Override public OrderingRelationType getOrderingRelation(BPNode n1, BPNode n2) { if (this.areCausal(n1,n2)) return OrderingRelationType.CAUSAL; if (this.areInverseCausal(n1,n2)) return OrderingRelationType.INVERSE_CAUSAL; if (this.areInConflict(n1,n2)) return OrderingRelationType.CONFLICT; return OrderingRelationType.CONCURRENT; }*/ /*@Override public IOccurrenceNet getOccurrenceNet() { this.occNet = new OccurrenceNet(this); return this.occNet; }*/ /*public void printOrderingRelations() { List ns = new ArrayList(); ns.addAll(this.getConditions()); ns.addAll(this.getEvents()); System.out.println(" \t"); for (BPNode n : ns) System.out.print("\t"+n.getName()); System.out.println(); for (BPNode n1 : ns) { System.out.print(n1.getName()+"\t"); for (BPNode n2 : ns) { String rel = ""; if (this.areCausal(n1,n2)) rel = ">"; if (this.areInverseCausal(n1,n2)) rel = "<"; if (this.areConcurrent(n1,n2)) rel = "@"; if (this.areInConflict(n1,n2)) rel = "#"; System.out.print(rel + "\t"); } System.out.println(); } }*/ /*@Override public Set getCutoffEvents() { return this.cutoff2corr.keySet(); }*/ /*@Override public boolean isCutoffEvent(IEvent e) { return this.cutoff2corr.containsKey(e); }*/ /*@Override public IEvent getCorrespondingEvent(IEvent e) { return this.cutoff2corr.get(e); }*/ /*@Override public Set getConditions(P place) { // TODO Auto-generated method stub return null; }*/ /*@Override public Set getEvents(T transition) { // TODO Auto-generated method stub return null; }*/ @SuppressWarnings("unchecked") @Override public E createEvent(T transition, ICoSet preConditions) { E e = null; try { e = (E) Event.class.newInstance(); e.setTransition(transition); e.setPreConditions(preConditions); e.setCompletePrefixUnfolding(this); return e; } catch (InstantiationException exception) { exception.printStackTrace(); return e; } catch (IllegalAccessException exception) { exception.printStackTrace(); return e; } } @Override public boolean isHealthyCutoffEvent(E event) { E corr = this.getCorrespondingEvent(event); if (corr==null) return false; Set ecs = new HashSet(event.getLocalConfiguration().getCut()); Set ccs = new HashSet(corr.getLocalConfiguration().getCut()); ecs.removeAll(event.getPostConditions()); ccs.removeAll(corr.getPostConditions()); if (ecs.equals(ccs)) return true; return false; } @Override public boolean isProper() { for (E e : this.getEvents()) { E corr = this.getCorrespondingEvent(e); if (corr==null) continue; if (!this.isHealthyCutoffEvent(e)) return false; } return true; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy