package deadlock.analyser.detection; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.TreeSet; import org.stringtemplate.v4.misc.STNoSuchAttributeException; import deadlock.analyser.factory.Contract; import deadlock.analyser.factory.GroupName; import deadlock.analyser.factory.MainMethodContract; import deadlock.analyser.factory.MethodContract; import deadlock.analyser.factory.MethodInterface; import deadlock.analyser.factory.IRecord; import com.gzoumix.semisolver.term.Term; // a BigLam is a quadruple <methodName, methodContract, Lam w, Lam wPrime> // and it contains the set of variable bTilde (new fresh name created in the method) and the set of variable aTilde (formal parameter of a method) public class BigLam { String methodName; Term methodContract; Set<GroupName> bTilde; Set<GroupName> aTilde; VarSubstitution lastBFresh; Lam w; Lam wPrime; // constructor from methodName and methodContract public BigLam(String method, MainMethodContract methodContractInferred){ this.methodName = method; this.methodContract = methodContractInferred; this.lastBFresh = new VarSubstitution(); this.w = new Lam(); this.wPrime = new Lam(); this.bTilde = new TreeSet<GroupName>(); this.aTilde = new TreeSet<GroupName>(); } // constructor from methodName and methodContract public BigLam(String method, Term methodContractInferred){ //initialize the lam for the method MethodName, and use this MethodContract obtained form inference algorithm to produce //bTilde this.methodName = method; this.methodContract = methodContractInferred; this.lastBFresh = new VarSubstitution(); this.w = new Lam(); this.wPrime = new Lam(); if(methodContractInferred instanceof MethodContract){ MethodInterface methodInterface = ((MethodContract) methodContractInferred).getMethodInterface(); Contract contractP = ((MethodContract) methodContractInferred).getContractPresent(); Contract contractF = ((MethodContract) methodContractInferred).getContractPresent(); IRecord _this = methodInterface.getThis(); IRecord ret = methodInterface.getResult(); List<IRecord> args = methodInterface.getParameters(); Set<GroupName> bTildeTemp = contractP.fn(); bTildeTemp.addAll(contractF.fn()); this.bTilde = bTildeTemp; this.bTilde.addAll(ret.fn()); this.bTilde.removeAll(_this.fn()); this.aTilde = new TreeSet<GroupName>(); this.aTilde.addAll(_this.fn()); for(IRecord t : args){ this.bTilde.removeAll(t.fn()); this.aTilde.addAll(t.fn()); } } else { this.bTilde = new TreeSet<GroupName>(); this.aTilde = new TreeSet<GroupName>(); } } //Getter and Setter for Lam public Lam getFirst(){ return this.w; } public Lam getSecond(){ return this.wPrime; } public void setFirst(Lam l){ Lam l2 = l.minimize(); this.w = l2; } public void setSecond(Lam l){ Lam l2 = l.minimize(); this.wPrime = l2; } //Getter for aTilde and bTilde public Set<GroupName> getbTilde(){ return this.bTilde; } public Set<GroupName> getaTilde(){ return this.aTilde; } //Getter for lastBFresh used for saturation public VarSubstitution getLastBFresh(){ return this.lastBFresh; } public void setLastBFresh(VarSubstitution sub){ this.lastBFresh = sub; } //Getter for methodName and methodContract public String getMethodName(){ return this.methodName; } public Term getMethodContract(){ return this.methodContract; } //Return the freeVariable of a BigLamp public Set<GroupName> fv(){ Set<GroupName> fv = new TreeSet<GroupName>(); fv.addAll(this.w.fv()); fv.addAll(this.wPrime.fv()); return fv; } //check for Cycle public Boolean hasCycle(){ //there is a Cycle when one of the two cycle types is present return w.hasCycle() || wPrime.hasCycle(); } //check just for Get Cycle public Boolean hasCycleGet(){ //it has cycle if any of the two lamps is cyclic return w.hasCycleGet() || wPrime.hasCycleGet(); } //check just for Await Cycle public Boolean hasCycleAwait(){ //it has cycle if any of the two lamps is cyclic return w.hasCycleAwait() || wPrime.hasCycleAwait(); } //toString method public String toString(){ return "< \n" + this.w.toString() + " , \n" + this.wPrime.toString() + ">"; } //According to version2 of the fix point algorithm this method adds the missing dependencies from the transitive closure //of the dependencies of not new names and removes all dependencies with new names public void expandAndClean() { w.expandAndClean(); wPrime.expandAndClean(); } public Boolean hasReflexiveState() { // TODO Auto-generated method stub return w.hasReflexiveState() || wPrime.hasReflexiveState(); } public LinkedList<State> getReflexiveStates(){ LinkedList<State> res = new LinkedList<>(); res.addAll(w.getReflexiveStates()); res.addAll(wPrime.getReflexiveStates()); return res; } }