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

org.jbpt.petri.untangling.AbstractReductionBasedRepresentativeUntangling 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.untangling;

import java.util.ArrayList;
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.IRun;
import org.jbpt.petri.IStep;
import org.jbpt.petri.ITransition;
import org.jbpt.petri.unfolding.IBPNode;
import org.jbpt.petri.unfolding.ICondition;
import org.jbpt.petri.unfolding.IEvent;

/**
 * An abstract implementation of the reduction-based algorithm for computing representative untanglings of net systems ({@link INetSystem}).
 * 
 * @author Artem Polyvyanyy
 */
public class AbstractReductionBasedRepresentativeUntangling, C extends ICondition, E extends IEvent, 
													F extends IFlow, N extends INode, P extends IPlace, T extends ITransition, M extends IMarking> 
		extends AbstractBaselineRepresentativeUntangling
{

	private Map> abs = null;
	private Map map = null;
	private Map map2 = null;
	
	/**
	 * Constructor of a representative untangling.
	 * 
	 * @param sys A net system to untangle.
	 */
	public AbstractReductionBasedRepresentativeUntangling(INetSystem sys) {
		super(sys);
	}
	
	public AbstractReductionBasedRepresentativeUntangling(INetSystem sys, UntanglingSetup setup) {
		super(sys, setup);
	}
	
	@Override
	protected void constructRuns(INetSystem system) {
		map2 = new HashMap();
		this.reducedSys = system.clone(map2);
		
		map = new HashMap();
		for (Map.Entry entry : map2.entrySet())
			map.put(entry.getValue(), entry.getKey());
		
		try {		
			abs = this.reduce(this.reducedSys);
		}
		catch(Exception e) {
			System.err.println(e.getMessage());
		}
		
		super.constructRuns(this.reducedSys);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	protected void constructProcesses() {
		// construct reduced processes
		this.reducedProcesses = new ArrayList>();
		for (IRun run : this.runs) {
			IProcess pi = this.createProcess(this.reducedSys);	

			for (IStep step : run) {
				pi.appendTransition(step.getTransition());
			}
			
			this.reducedProcesses.add(pi);
		}
		
		// construct processes of the original net
		this.processes = new ArrayList>();
		for (IRun run : this.runs) {
			IProcess pi = this.createProcess(this.sys);	

			for (IStep step : run) {
				// process preset
				for (P p : step.getInputMarking().toMultiSet()) {
					List list = this.getAbstractedNodes((N)p,(N)step.getTransition());
					if (list!=null) {
						for (int i=0; i list = this.getAbstractedNodes((N)step.getTransition(),(N)p);
					if (list!=null) {
						for (int i=1; i list = this.abs.get(f);
						for (int i=0; i getAbstractedNodes(N n1, N n2) {
		for (Map.Entry> entry : this.abs.entrySet()) {
			F f = entry.getKey();
			if (f.getSource().equals(n1) && f.getTarget().equals(n2))
				return entry.getValue();
		}
		
		return null;
	}

	@SuppressWarnings({ "unchecked" })
	protected Map> reduce(INetSystem system) {
		Map> result = new HashMap>();
		
		// compute maximal sequences of trivial fragments
		List> maxSequences = new ArrayList>();
		Set flow = new HashSet(system.getFlow());
		List seq = new ArrayList();
		boolean flag = false;
		N entry = null;
		N exit = null;
		while (!flow.isEmpty()) {
			if (!flag) {
				F f = flow.iterator().next();
				flow.remove(f);
				seq.add(f);
				entry = f.getSource();
				exit = f.getTarget();
				flag = true;
			}
			else {
				boolean done = true;
				
				P p = null; if (entry instanceof IPlace) p = (P) entry;
				if (system.getDirectPredecessors(entry).size()==1  && system.getDirectSuccessors(entry).size()==1 && (p==null || system.getTokens(p)==0)) {
					F nf = system.getFirstIncomingEdge(entry);
					seq.add(0,nf);
					entry = nf.getSource();
					done = false;
					flow.remove(nf);
				}
				
				p = null; if (exit instanceof IPlace) p = (P) exit;
				if (system.getDirectPredecessors(exit).size()==1  && system.getDirectSuccessors(exit).size()==1 && (p==null || system.getTokens(p)==0)) {
					F nf = system.getFirstOutgoingEdge(exit);
					seq.add(nf);
					exit = nf.getTarget();
					done = false;
					flow.remove(nf);
				}
				
				if (done) {
					flag = false;
					maxSequences.add(new ArrayList(seq));
					seq = new ArrayList();
					entry = null;
					exit = null;
				}
			}
		}
		maxSequences.add(seq);
				
		// reduce maximal sequences
		for (List sequence : maxSequences) {
			if (sequence.size()<3) continue;
			N start	= sequence.get(0).getSource();
			N end	= sequence.get(sequence.size()-1).getTarget();
			
			if (start instanceof IPlace) {
				if (end instanceof IPlace) { // O->...->O
					P en = (P) start;
					List list = this.getOrderedNodes(sequence);
					T last = (T) list.get(list.size()-1);
					list.remove(list.size()-1);
					system.removeNodes(list);
					F f = system.addFlow(en, last);
					result.put(f,list);
				}
				else { // O->...->[]
					P en	= (P) start;
					T ex	= (T) end;
					
					F f = null;
					boolean safe = system.getPostset(en).size()==1 || system.getPreset(ex).size()==1; // cannot introduce deadlock
					
					if (safe) {
						f = system.addFlow(en,ex);
						if (f!=null) {
							List list = this.getOrderedNodes(sequence);
							system.removeNodes(list);
							result.put(f,list);	
						}
					}
					
					if (!safe && f==null) {
						if (sequence.size()<5) continue;
						List list = this.getOrderedNodes(sequence);
						T last = (T) list.get(list.size()-2);
						list.remove(list.size()-1);
						list.remove(list.size()-1);
						system.removeNodes(list);
						f = system.addFlow(en, last);
						result.put(f,list);
					}
				}
			}
			else {
				if (end instanceof IPlace) { // []->...->O
					T en	= (T) start;
					P ex	= (P) end;
					
					F f = system.addFlow(en, ex);
					if (f==null) { // edge already exists
						if (sequence.size()<5) continue;
						List list = this.getOrderedNodes(sequence);
						P last = (P) list.get(list.size()-2);
						list.remove(list.size()-1);
						list.remove(list.size()-1);
						system.removeNodes(list);
						f = system.addFlow(en, last);
						result.put(f,list);
					}
					else {
						List list = this.getOrderedNodes(sequence);
						system.removeNodes(list);
						result.put(f,list);
					}
				}
				else { // []->...->[]
					T en = (T) start;
					List list = this.getOrderedNodes(sequence);
					P last = (P) list.get(list.size()-1);
					list.remove(list.size()-1);
					system.removeNodes(list);
					F f = system.addFlow(en, last);
					result.put(f,list);
				}
			}
		}
		
		return result;
	}
	
	private List getOrderedNodes(List polygon) {
		List result = new ArrayList();
				
		for (int i=1; i run : this.runs) {
			if (run.isEmpty()) return false;
			
			IStep step = run.get(run.size()-1);
			if (this.reducedSys.getEnabledTransitionsAtMarking(step.getOutputMarking()).isEmpty()) {
				for (P p : step.getOutputMarking().toMultiSet()) {
					if (!this.reducedSys.getPostset(p).isEmpty())
						return false;
				}
			}
		}
		
		return true;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy