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

org.jbpt.petri.unfolding.AbstractBranchingProcess 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.algo.ListCombinationGenerator;
import org.jbpt.algo.MultiSetUtils;
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;

/**
 * Abstract implementation of a branching process of a net system.
 * 
 * @author Artem Polyvyanyy
 */
public abstract class AbstractBranchingProcess, C extends ICondition, E extends IEvent, 
												F extends IFlow, N extends INode, P extends IPlace, T extends ITransition, M extends IMarking> 
		implements IBranchingProcess 
{
	// originative net system
	protected INetSystem sys = null;
	
	protected List log = null;
	
	protected Set events	= null;	
	protected Set conds	= null;
	protected ICut iniBP = null;
	
	// causality: maps node of unfolding to a set of preceding nodes
	protected Map> ca = null;
	// concurrency: maps node of unfolding to a set of concurrent nodes
	protected Map> co = null;
	
	// indexes for conflict and concurrency relations 
	private Map> EX    = null;
	private Map> notEX = null;
	private Map> CO    = null;
	private Map> notCO = null;
	
	protected AbstractBranchingProcess() {
		this.initialize();
	}
	
	protected AbstractBranchingProcess(INetSystem sys) {
		this.setNetSystem(sys);
	}
	
	protected void initialize() {
		this.log = new ArrayList();
		this.events	= new HashSet();
		this.conds	= new HashSet();
		this.iniBP	= this.createCut();
		this.ca		= new HashMap>();
		this.co		= new HashMap>();
		this.EX		= new HashMap>();
		this.notEX	= new HashMap>();
		this.CO		= new HashMap>();
		this.notCO	= new HashMap>();
	}

	@Override
	public void constructInitialBranchingProcess() {
		if (!this.conds.isEmpty()) return;
		for (P p : this.sys.getMarking().toMultiSet()) {
			C c = this.createCondition(p,null);
			this.appendCondition(c);
			this.iniBP.add(c);
		}
	}

	@Override
	public Set getConditions() {
		return this.conds;
	}

	@Override
	public Set getConditions(P place) {
		Set result = new HashSet();
		for (C c : this.conds) {
			if (c.getPlace().equals(place))
				result.add(c);
		}
		return result;
	}

	@Override
	public Set getEvents() {
		return this.events;
	}

	@Override
	public Set getEvents(T transition) {
		Set result = new HashSet();
		for (E e : this.events) {
			if (e.getTransition().equals(transition))
				result.add(e);
		}
		return result;
	}

	@Override
	public INetSystem getOriginativeNetSystem() {
		return this.sys;
	}

	@Override
	public boolean areCausal(BPN n1, BPN n2) {
		if (this.ca.get(n2)==null) {
			if (n2 instanceof AbstractEvent) {
				@SuppressWarnings("unchecked")
				E e = (E) n2;
				if (e.getPreConditions().contains(n1)) return true;
				for (C c : e.getPreConditions())
					if (this.ca.get(c).contains(n1))
						return true;
				
				return false;
			}
			else {
				@SuppressWarnings("unchecked")
				C c = (C) n2;
				if (c.getPreEvent().equals(n1)) return true;
				if (this.ca.get(c.getPreEvent()).contains(n1)) return true;
				
				return false;
			}
		}
		
		return this.ca.get(n2).contains(n1);
	}

	@Override
	public boolean areInverseCausal(BPN n1, BPN n2) {
		return this.areCausal(n2,n1);
	}

	@Override
	public boolean areConcurrent(BPN n1, BPN n2) {
		Set co = this.CO.get(n1);
		if (co!=null)
			if (co.contains(n2)) return true;
		
		Set notCo = this.notCO.get(n1);
		if (notCo!=null)
			if (notCo.contains(n2)) return false;
		
		boolean result = !this.areCausal(n1,n2) && !this.areInverseCausal(n1,n2) && !this.areInConflict(n1,n2);
		
		if (result)
			this.index(this.CO,n1,n2);
		else
			this.index(this.notCO,n1,n2);
		
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean areInConflict(BPN n1, BPN n2) {
		Set ex = this.EX.get(n1);
		if (ex!=null)
			if (ex.contains(n2)) return true;
		
		Set notEx = this.notEX.get(n1);
		if (notEx!=null)
			if (notEx.contains(n2)) return false;
		
		if (n1.equals(n2)) {
			this.index(this.notEX,n1,n2);
			return false;
		}
		
		Set ca1 = new HashSet(this.ca.get(n1));
		ca1.add(n1);
		Set ca2 = new HashSet(this.ca.get(n2));
		ca2.add(n2);
		
		for (BPN nn1 : ca1) {
			if (nn1.isCondition()) continue;
			E e1 = (E) nn1;
			for (BPN nn2 : ca2) {
				if (nn2.isCondition()) continue;
				E e2 = (E) nn2;
				if (e1.equals(e2)) continue;				
				if (!this.overlap(e1.getPreConditions(),e2.getPreConditions())) continue;
				
				this.index(this.EX,n1,n2);
				return true;
			}
		}
		
		this.index(this.notEX,n1,n2);
		return false;
	}

	@Override
	public OrderingRelationType getOrderingRelation(BPN n1, BPN 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;
	}

	@SuppressWarnings("unchecked")
	@Override
	public C createCondition(P place, E event) {
		C c = null;
		try {
			c = (C) Condition.class.newInstance();
			c.setPlace(place);
			c.setPreEvent(event);
			return c;
		} catch (InstantiationException exception) {
			exception.printStackTrace();
		} catch (IllegalAccessException exception) {
			exception.printStackTrace();
		}
		
		return c;
	}

	@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);
			return e;
		} catch (InstantiationException exception) {
			exception.printStackTrace();
		} catch (IllegalAccessException exception) {
			exception.printStackTrace();
		}
		
		return e;
	}
	
	@Override
	public boolean appendCondition(C condition) {
		this.conds.add(condition);
		this.updateCausalityCondition(condition);
		
		return true;
	}
		
	@SuppressWarnings("unchecked")
	protected void updateCausalityCondition(C c) {
		if (this.ca.get(c)==null)
			this.ca.put((BPN)c,new HashSet());
		
		E e = c.getPreEvent();
		if (e==null) return;
		
		this.ca.get(c).addAll(this.ca.get(e));
		this.ca.get(c).add((BPN)e);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public boolean appendEvent(E event) {
		this.events.add(event);		
		this.updateCausalityEvent(event);
		
		// add conditions that correspond to post-places of transition that corresponds to new event
		ICoSet postConditions = null;
		try {
			postConditions = (ICoSet) AbstractCoSet.class.newInstance();
		} catch (InstantiationException e1) {
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			e1.printStackTrace();
		}
		
		for (P s : this.sys.getPostset(event.getTransition())) {
			C c = this.createCondition(s,event);
			postConditions.add(c);
			this.appendCondition(c);
		}
		event.setPostConditions(postConditions);

		this.log.add(event);
		return true;
	}
	
	@Override
	public boolean appendTransition(T transition) {
		ICoSet preset = this.createCoSet();
		
		Set max = this.getMax();
		for (P p : this.getOriginativeNetSystem().getPreset(transition)) {
			boolean flag = false;
			for (C c : this.getMax()) {
				if (c.getPlace().equals(p) && max.contains(c)) {
					preset.add(c);
					max.remove(c);
					flag = true;
				}
			}
			
			if (!flag) return false;
		}
		
		E e = this.createEvent(transition, preset);
		return this.appendEvent(e);
	}
	
	@SuppressWarnings("unchecked")
	private void updateCausalityEvent(E e) {
		if (this.ca.get(e)==null)
			this.ca.put((BPN)e, new HashSet());
		
		for (C c : e.getPreConditions()) {
			this.ca.get(e).addAll(this.ca.get(c));
		}
		
		for (C c : e.getPreConditions())
			this.ca.get(e).add((BPN)c);
	}
	
	private void index(Map> map, BPN n1, BPN n2) {
		Set s1 = map.get(n1);
		if (s1==null) {
			Set ss1 = new HashSet();
			ss1.add(n2);
			map.put(n1,ss1);
		}
		else
			s1.add(n2);
		
		Set s2 = map.get(n2);
		if (s2==null) {
			Set ss2 = new HashSet();
			ss2.add(n1);
			map.put(n2,ss2);
		}
		else
			s2.add(n1);
	}
	
	private boolean overlap(ICoSet s1, ICoSet s2) {
		for (C n : s1)
			if (s2.contains(n))
				return true;
		
		return false;
	}

	@Override
	public ICut getInitialCut() {
		return this.iniBP;
	}

	@SuppressWarnings("unchecked")
	@Override
	public ICoSet createCoSet() {
		try {
			return (ICoSet) CoSet.class.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
			return null;
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public ICut createCut() {
		try {
			return (ICut) Cut.class.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
			return null;
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public Set getCausalPredecessors(BPN node) {
		return this.ca.get(node);
	}

	@Override
	public boolean isConflictFree() {
		Map c2e = new HashMap();
		for (E e : this.events) {
			for (C c : e.getPreConditions()) {
				if (c2e.get(c)!=null) return false;
				c2e.put(c,e);
			}
		}
		
		return true;
	}
	
	@Override
	public void setNetSystem(INetSystem system) {
		if (system==null) return;
		this.sys = system;
		this.initialize();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public boolean isSafe() {
		for (C c1 : this.conds) {
			for (C c2 : this.conds) {
				if (c1.equals(c2)) continue;
				if (c1.getPlace().equals(c2.getPlace()) && this.areConcurrent((BPN)c1,(BPN)c2))
					return false;
			}	
		}
		return true;
	}
	
	@Override
	public Set getMin() {
		return this.iniBP;
	}

	@Override
	public Set getMax() {
		Set result = new HashSet(this.conds);
		for (E e : this.events) {
			result.removeAll(e.getPreConditions());
		}
		return result;
	}
	
	@Override
	public Set

getPlaces(Collection conditions) { Set

result = new HashSet

(); if (conditions==null) return result; for (C c : conditions) { result.add(c.getPlace()); } return result; } @Override public Set getTransitions(Collection events) { Set result = new HashSet(); if (events==null) return result; for (E e : events) { result.add(e.getTransition()); } return result; } @Override public IOccurrenceNet getOccurrenceNet() { try { @SuppressWarnings("unchecked") IOccurrenceNet occ = (IOccurrenceNet) OccurrenceNet.class.newInstance(); occ.setBranchingProcess(this); return occ; } catch (InstantiationException e) { e.printStackTrace(); return null; } catch (IllegalAccessException e) { e.printStackTrace(); return null; } } @SuppressWarnings("unchecked") @Override public IBranchingProcess clone() { IBranchingProcess clone = null; try { clone = (IBranchingProcess)BranchingProcess.class.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } clone.setNetSystem(this.sys); for (C c : this.conds) { if (c.getPreEvent()!=null) continue; C newC = this.createCondition(c.getPlace(), null); clone.appendCondition(newC); } for (E e : this.log) { E newE = this.createEvent(e.getTransition(), null); ICoSet preset = this.createCoSet(); Set max = new HashSet(clone.getMax()); for (C c2 : e.getPreConditions()) { for (C c1 : max) { if (c1.getPlace().equals(c2.getPlace())) { preset.add(c1); max.remove(c1); break; } } } newE.setPreConditions(preset); clone.appendEvent(newE); } return clone; } @SuppressWarnings("unchecked") @Override public boolean isCut(Collection conditions) { for (C c1 : conditions) { Collection cs = new ArrayList(conditions); cs.remove(c1); for (C c2 : cs) { if (c1.equals(c2)) return false; if (!this.areConcurrent((BPN)c1,(BPN)c2)) return false; } } for (C c : this.getConditions()) { if (conditions.contains(c)) continue; boolean flag = true; for (C cc : conditions) { if (!this.areConcurrent((BPN)c,(BPN)cc)) { flag = false; break; } } if (flag) return false; } return true; } @Override // TODO optimize public boolean areMutuallyConcurrent(Collection conditions) { for (C c1 : conditions) { for (C c2 : conditions) { if (c1.equals(c2)) continue; boolean result = this.areConcurrent((BPN)c1,(BPN)c2); if (!result) return false; } } return true; } @Override public Set> getCuts(Collection

places) { Set> result = new HashSet>(); List> conds = new ArrayList>(); for (P p : places) { conds.add(new ArrayList(this.getConditions(p))); } ListCombinationGenerator lcg = new ListCombinationGenerator(conds); while(lcg.hasMoreCombinations()) { List cs = lcg.getNextCombination(); if (!MultiSetUtils.isSet(cs)) continue; if (this.isCut(cs)) { ICut cut = this.createCut(); cut.addAll(cs); result.add(cut); } } return result; } @Override public List getLog() { return this.log; } /*protected boolean appendEvent2(Event e) { this.events.add(e); this.updateCausalityEvent(e); if (t2es.get(e.getTransition())!=null) t2es.get(e.getTransition()).add(e); else { Set es = new HashSet(); es.add(e); t2es.put(e.getTransition(), es); } // add conditions that correspond to post-places of transition that corresponds to new event CoSet postConds = new CoSet(this.sys); // collection of new post conditions for (Place s : this.sys.getPostset(e.getTransition())) { // iterate over places in the postset Condition c = new Condition(s,e); // construct new condition postConds.add(c); this.addCondition(c); // add condition to unfolding } e.setPostConditions(postConds); // set post conditions of event // compute new cuts of unfolding for (Cut cut : c2cut.get(e.getPreConditions().iterator().next())) { if (contains(cut,e.getPreConditions())) { Cut newCut = new Cut(this.sys,cut); newCut.removeAll(e.getPreConditions()); newCut.addAll(postConds); if (!this.addCut(newCut)) return false; } } this.countEvents++; return true; }*/ }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy