/// <summary> /// Return transition where source states are in states /// [ REFS: 'result', DEREFS:states] /// </summary> /// <param name="states">source state of transition</param> /// <param name="transitions">transitions[0]: normal transitions, transitions[1]: priority transition</param> /// <returns></returns> private CUDDNode TransitionsBySourceStates(CUDDNode states, List <List <CUDDNode> > transitions) { CUDDNode successors; if (transitions.Count > 1) { CUDD.Ref(states); CUDD.Ref(transitions[1]); CUDDNode temp = CUDD.Function.And(states, transitions[1]); if (!temp.Equals(CUDD.ZERO)) { CUDD.Deref(states); successors = temp; } else { CUDD.Deref(temp); CUDD.Ref(transitions[0]); successors = CUDD.Function.And(states, transitions[0]); } } else { CUDD.Ref(transitions[0]); successors = CUDD.Function.And(states, transitions[0]); } return(successors); }
/// <summary> /// Can support array of array /// </summary> /// <param name="model"></param> /// <returns></returns> private ExpressionBDDEncoding TranslateArrayExpression(Model model) { if (this.Argument2 is IntConstant) { int indexValue = ((IntConstant)this.Argument2).Value; if (Operator == ARRAY) { return(new Variable(this.Argument1 + Model.NAME_SEPERATOR + indexValue).TranslateIntExpToBDD(model)); } else { return(new VariablePrime(this.Argument1 + Model.NAME_SEPERATOR + indexValue).TranslateIntExpToBDD(model)); } } ExpressionBDDEncoding indexBddEncoding = this.Argument2.TranslateIntExpToBDD(model); //Get the array range int min = model.GetArrayRange(this.Argument1.ExpressionID)[0]; int max = model.GetArrayRange(this.Argument1.ExpressionID)[1]; ExpressionBDDEncoding result = new ExpressionBDDEncoding(); //a[i] for (int i = min; i <= max; i++) { for (int j = 0; j < indexBddEncoding.Count(); j++) { //index = i & guard of index CUDD.Ref(indexBddEncoding.ExpressionDDs[j], indexBddEncoding.GuardDDs[j]); CUDDNode guard = CUDD.Function.And(CUDD.Function.Equal(indexBddEncoding.ExpressionDDs[j], CUDD.Constant(i)), indexBddEncoding.GuardDDs[j]); if (guard != CUDD.ZERO) { //a[i] result.GuardDDs.Add(guard); Expression arrayExpression; if (Operator == ARRAY) { arrayExpression = new Variable(this.Argument1.ExpressionID + Model.NAME_SEPERATOR + i); } else { arrayExpression = new VariablePrime(this.Argument1.ExpressionID + Model.NAME_SEPERATOR + i); } result.ExpressionDDs.Add(arrayExpression.TranslateIntExpToBDD(model).ExpressionDDs[0]); } else { CUDD.Deref(guard); } } } //dereference later because 2 loops above indexBddEncoding.DeRef(); return(result); }
/// <summary> /// return all states reachable from start and Start /// P ◦ R* /// [ REFS: 'result', DEREFS:start] /// </summary> /// <param name="start"></param> /// <param name="transition"></param> /// <returns></returns> public CUDDNode SuccessorsStart(CUDDNode start, List <CUDDNode> transition) { CUDD.Ref(start); CUDDNode allReachableStates = start; CUDDNode currentStep = start; while (true) { currentStep = Successors(currentStep, transition); CUDD.Ref(allReachableStates, currentStep); CUDDNode allReachableTemp = CUDD.Function.Or(allReachableStates, currentStep); if (allReachableTemp.Equals(allReachableStates)) { CUDD.Deref(currentStep, allReachableTemp); return(allReachableStates); } else { currentStep = CUDD.Function.Different(currentStep, allReachableStates); allReachableStates = allReachableTemp; } } }
public override void Execute() { CUDDNode precondition = _context.emptyOrPreGD().ToPrecondition(_predicateDict, _assignment); if (!precondition.Equals(CUDD.ZERO)) { Observation observation = new Observation(_context, precondition, _eventDict, _scanArray, _assignment); _observationDict.Add(observation.FullName, observation); foreach (var pair in _agentDict) { int startIndex = observation.FullName.IndexOf('('); int startIndexAddOne = observation.FullName.IndexOf(pair.Key); //Console.WriteLine("observation name: {0}, agent name: {1}, isContains: {2}", observation.FullName, pair.Key, startIndex == startIndexAddOne - 1); //Console.ReadLine(); if (startIndex == startIndexAddOne - 1) { pair.Value.AddObservation(observation); break; } } } else { CUDD.Deref(precondition); } }
/// <summary> /// Check whethere the goal can be reachable from the initial state of automataBDD /// [ REFS: traces, DEREFS: ] /// </summary> /// <param name="automataBDD"></param> /// <param name="goal"></param> /// <param name="model"></param> public void MCForTA(AutomataBDD automataBDD, Expression goal, Model model) { //Clear the old data this.traces.Clear(); ExpressionBDDEncoding goalBddEncoding = goal.TranslateBoolExpToBDD(model); ExpressionBDDEncoding initEncoding = automataBDD.initExpression.TranslateBoolExpToBDD(model); if (initEncoding.GuardDDs.Count == 0) { VerificationOutput.VerificationResult = VerificationResultType.INVALID; } else { CUDDNode initDD = CUDD.Function.Or(initEncoding.GuardDDs); CUDDNode goalDD = CUDD.Function.Or(goalBddEncoding.GuardDDs); CUDD.Ref(automataBDD.transitionBDD); List <CUDDNode> discreteTrans = CUDD.Abstract.ThereExists(automataBDD.transitionBDD, model.GetAllEventVars()); CUDD.Ref(automataBDD.Ticks); List <CUDDNode> tickTrans = CUDD.Abstract.ThereExists(automataBDD.Ticks, model.GetAllEventVars()); bool reachable = model.PathForTA(initDD, goalDD, discreteTrans, tickTrans, automataBDD.SimulationRel, SelectedEngineName); CUDD.Deref(discreteTrans, tickTrans); CUDD.Deref(initDD, goalDD); VerificationOutput.VerificationResult = (reachable) ? VerificationResultType.VALID : VerificationResultType.INVALID; } }
/// <summary> /// Return AutomataBDD of the hiding process /// [ REFS: 'none', DEREFS: 'hidingEvent, tauEvent, P1' ] /// </summary> /// <param name="hidingEvent">CUDDNode of hiding events</param> /// <param name="tauEvent">CUDDNode of tau event</param> /// <param name="P1">AutomataBDD of the process P1</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Hiding(CUDDNode hidingEvent, CUDDNode tauEvent, AutomataBDD P1, Model model) { CUDD.Ref(P1.transitionBDD); CUDD.Ref(hidingEvent); List <CUDDNode> hidingTransition = CUDD.Function.And(P1.transitionBDD, hidingEvent); hidingTransition = CUDD.Abstract.ThereExists(hidingTransition, model.GetEventColVars()); CUDD.Ref(tauEvent); hidingTransition = CUDD.Function.And(hidingTransition, tauEvent); // CUDD.Ref(P1.transitionBDD); CUDD.Ref(hidingEvent); List <CUDDNode> notHidingTransition = CUDD.Function.And(P1.transitionBDD, CUDD.Function.Not(hidingEvent)); // CUDD.Deref(hidingEvent, tauEvent); CUDD.Deref(P1.transitionBDD); P1.transitionBDD.Clear(); P1.transitionBDD.AddRange(hidingTransition); P1.transitionBDD.AddRange(notHidingTransition); return(P1); }
/// <summary> /// [ REFS: '', DEREFS: 'processes.transitionBDD'] /// </summary> /// <param name="processes"></param> /// <param name="model"></param> /// <param name="result"></param> private static void SyncTerminateTrans(List <AutomataBDD> processes, Model model, AutomataBDD result) { CUDDNode syncTerminateTrans = GetTerminationTransEncoding(model); foreach (var process in processes) { List <CUDDNode> allTransitions = new List <CUDDNode>(); allTransitions.AddRange(process.transitionBDD); allTransitions.AddRange(process.priorityTransitionsBDD); if (syncTerminateTrans.Equals(CUDD.ZERO)) { CUDD.Deref(allTransitions); } else { syncTerminateTrans = CUDD.Function.And(syncTerminateTrans, allTransitions); } } if (syncTerminateTrans != CUDD.ZERO) { result.transitionBDD.Add(syncTerminateTrans); } else { CUDD.Deref(syncTerminateTrans); } }
/// <summary> /// Forward search, check destination is reachable from source /// [ REFS: '', DEREFS:] /// </summary> /// <param name="source"></param> /// <param name="destination"></param> /// <param name="transitions">transitions[0]: normal transitions, transitions[1]: priority transition</param> /// <returns></returns> public bool PathForward(CUDDNode source, CUDDNode destination, List <List <CUDDNode> > transitions) { CUDD.Ref(source, destination); CUDDNode temp = CUDD.Function.And(source, destination); //In case source already satisfies destination if (!temp.Equals(CUDD.ZERO)) { CUDD.Deref(temp); return(true); } // bool reachable = false; CUDDNode allReachableFromInit, currentReachableFromInit; CUDD.Ref(source, source); allReachableFromInit = currentReachableFromInit = source; CUDDNode commonNode = CUDD.Constant(0); do { //forward currentReachableFromInit = this.Successors(currentReachableFromInit, transitions); //Check 2 directions have intersection CUDD.Ref(destination, currentReachableFromInit); CUDD.Deref(commonNode); commonNode = CUDD.Function.And(destination, currentReachableFromInit); if (!commonNode.Equals(CUDD.ZERO)) { reachable = true; break; } //find fixpoint CUDD.Ref(currentReachableFromInit, allReachableFromInit); CUDDNode allReachabeFromInitTemp = CUDD.Function.Or(currentReachableFromInit, allReachableFromInit); if (allReachabeFromInitTemp.Equals(allReachableFromInit)) { //reachable = false; CUDD.Deref(allReachabeFromInitTemp); break; } else { currentReachableFromInit = CUDD.Function.Different(currentReachableFromInit, allReachableFromInit); allReachableFromInit = allReachabeFromInitTemp; } } while (true); CUDD.Deref(allReachableFromInit, currentReachableFromInit, commonNode); // return(reachable); }
/// <summary> /// Return the intersection of model and negation of LTL /// Note that all of the state of model are the accepting state /// [ REFS: 'result', DEREFS:'automata1, automata2' ] /// </summary> /// <param name="system"></param> /// <param name="negationLTL"></param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Intersection(AutomataBDD system, AutomataBDD negationLTL, Model model) { //AddIdleTransAtDeadlockStates(system, model); AutomataBDD result = new AutomataBDD(); //Set var result.variableIndex.AddRange(system.variableIndex); result.variableIndex.AddRange(negationLTL.variableIndex); //Set Init result.initExpression = Expression.AND(system.initExpression, negationLTL.initExpression); //Set Acceptance State result.acceptanceExpression = negationLTL.acceptanceExpression; //Set Transition //transition must happen at both automata1 + negation LTL result.transitionBDD = CUDD.Function.And(system.transitionBDD, negationLTL.transitionBDD); // CUDD.Deref(system.channelInTransitionBDD, system.channelOutTransitionBDD, negationLTL.channelInTransitionBDD, negationLTL.channelOutTransitionBDD); return(result); }
/// <summary> /// [ REFS: traces, DEREFS: ] /// </summary> /// <param name="automataBDD"></param> /// <param name="model"></param> public void MCForTA(AutomataBDD automataBDD, Model model) { //Clear the old data this.traces.Clear(); List <CUDDNode> allTransitions = new List <CUDDNode>(automataBDD.transitionBDD); CUDDNode deadlockGoadDD = GetDeadlockDD(allTransitions, model); ExpressionBDDEncoding initEncoding = automataBDD.initExpression.TranslateBoolExpToBDD(model); if (initEncoding.GuardDDs.Count == 0) { this.VerificationOutput.VerificationResult = VerificationResultType.VALID; } else { CUDD.Ref(automataBDD.transitionBDD); List <CUDDNode> discreteTrans = CUDD.Function.And(automataBDD.transitionBDD, CUDD.Function.Not(AutomataBDD.GetTerminationTransEncoding(model))); discreteTrans = CUDD.Abstract.ThereExists(discreteTrans, model.GetAllEventVars()); CUDD.Ref(automataBDD.Ticks); List <CUDDNode> tickTrans = CUDD.Function.And(automataBDD.Ticks, CUDD.Function.Not(AutomataBDD.GetTerminationTransEncoding(model))); tickTrans = CUDD.Abstract.ThereExists(tickTrans, model.GetAllEventVars()); bool reachable = model.PathForTA(CUDD.Function.Or(initEncoding.GuardDDs), deadlockGoadDD, discreteTrans, tickTrans, automataBDD.SimulationRel, SelectedEngineName); CUDD.Deref(discreteTrans, tickTrans); this.VerificationOutput.VerificationResult = (reachable) ? VerificationResultType.INVALID : VerificationResultType.VALID; } }
/// <summary> /// return all states reachable to start /// P ◦ R+ /// [ REFS: 'result', DEREFS:start] /// </summary> /// <param name="start"></param> /// <param name="transitions">transitions[0]: normal transitions, transitions[1]: priority transition</param> /// <returns></returns> public CUDDNode PredecessorsPlus(CUDDNode start, List <List <CUDDNode> > transition) { CUDDNode allReachableStates = CUDD.Constant(0); CUDDNode currentStep = start; while (true) { currentStep = Predecessors(currentStep, transition); CUDD.Ref(allReachableStates, currentStep); CUDDNode allReachableTemp = CUDD.Function.Or(allReachableStates, currentStep); if (allReachableTemp.Equals(allReachableStates)) { CUDD.Deref(currentStep, allReachableTemp); return(allReachableStates); } else { CUDD.Deref(allReachableStates); allReachableStates = allReachableTemp; } } }
public override void Close() { CUDD.Deref(nondetMask); allNondetVars.Deref(); base.Close(); }
public static CUDDNode ProbBoundedUntil(CUDDNode trans, CUDDVars allRowVars, CUDDVars allColVars, CUDDNode yes, CUDDNode maybe, int bound) { DateTime startTime = DateTime.Now; CUDDNode a, sol, tmp; CUDD.Ref(trans, maybe); a = CUDD.Function.Times(trans, maybe); CUDD.Ref(yes); sol = yes; for (int i = 1; i <= bound; i++) { tmp = CUDD.Matrix.MatrixMultiplyVector(a, sol, allRowVars, allColVars); CUDD.Ref(yes); tmp = CUDD.Function.Maximum(tmp, yes); CUDD.Deref(sol); sol = tmp; } DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("ProbBoundedUntil: " + bound + " iterations in " + runningTime + " seconds"); // CUDD.Deref(a); return sol; }
public IModel Encode() { //get variable info from ModulesFile varList = new VariableList(modules); //Collect all sync label of all modules synchs = modules.GetAllSynchs().ToList(); AddVars(); //Create Expression Encoder, use the same copy of varList, variableEncoding expressionEncoder = new ExpressionToBDD(varList, variableEncoding); EncodeSystemDef(modules.systemDef); // get rid of any nondet dd variables not needed if (modules.modelType == ModelType.MDP) { CUDDNode tmp = CUDD.GetSupport(trans); tmp = CUDD.Abstract.ThereExists(tmp, allRowVars); tmp = CUDD.Abstract.ThereExists(tmp, allColVars); CUDDVars ddv = new CUDDVars(); while (!tmp.Equals(CUDD.ONE)) { ddv.AddVar(CUDD.Var(tmp.GetIndex())); tmp = tmp.GetThen(); } CUDD.Deref(tmp); allNondetVars.Deref(); allNondetVars = ddv; } init = GetInitState(); // CUDD.Deref(moduleRangeDDs, moduleIdentities, colVarRanges, syncVars, choiceVars); CUDD.Deref(moduleRowVars, moduleColVars, rowVars, colVars, new List <CUDDVars>() { globalRowVars, globalColVars, allSynchVars, allChoiceVars }); IModel result; if (modules.modelType == ModelType.DTMC) { // allNondetVars.Deref(); result = new ProbModel(trans, init, stateRewards, transRewards, allRowVars, allColVars, varList, allRowVarRanges, varIdentities, variableEncoding); } else { result = new NonDetModel(trans, init, stateRewards, transRewards, allRowVars, allColVars, allNondetVars, varList, allRowVarRanges, varIdentities, variableEncoding); } return(result); }
public CUDDNode GetKnowledgeBase() { List <CUDDNode> literalNodes = new List <CUDDNode>(); foreach (var gndPred in _predBooleanMap) { string name = gndPred.Key; int index = _problem.GroundPredicateDict[name].CuddIndex; CUDDNode node; if (gndPred.Value) { node = CUDD.Var(index); } else { node = CUDD.Function.Not(CUDD.Var(index)); } literalNodes.Add(node); } CUDDNode result = literalNodes[0]; for (int i = 1; i < literalNodes.Count; i++) { CUDDNode literalNode = literalNodes[i]; CUDDNode andNode = CUDD.Function.And(result, literalNode); CUDD.Ref(andNode); CUDD.Deref(result); CUDD.Deref(literalNode); result = andNode; } return(result); }
/// <summary> /// return all states reachable from start and Start /// P ◦ R* /// [ REFS: 'result', DEREFS:start] /// </summary> /// <param name="start"></param> /// <param name="transition"></param> /// <returns></returns> public CUDDNode PredecessorsStart(CUDDNode start, List <CUDDNode> transition) { CUDD.Ref(start); CUDDNode allReachableStates = start; CUDDNode currentStep = start; int numberOfLoop = 0; while (true) { numberOfLoop++; Debug.Write(numberOfLoop + " "); currentStep = Predecessors(currentStep, transition); CUDD.Ref(allReachableStates, currentStep); CUDDNode allReachableTemp = CUDD.Function.Or(allReachableStates, currentStep); if (allReachableTemp.Equals(allReachableStates)) { CUDD.Deref(currentStep, allReachableTemp); Debug.WriteLine("\nPredecessor* : " + numberOfLoop + " loops."); return(allReachableStates); } else { currentStep = CUDD.Function.Different(currentStep, allReachableStates); allReachableStates = allReachableTemp; } } }
public void Update(Observation observation) { CUDD.Ref(observation.Precondition); Knowledge = CUDD.Function.And(Knowledge, observation.Precondition); CUDD.Ref(observation.Precondition); CUDD.Ref(Belief); CUDDNode negPrecondition = CUDD.Function.Not(observation.Precondition); CUDDNode impliesNode = CUDD.Function.Implies(Belief, negPrecondition); if (!impliesNode.Equals(CUDD.ONE)) { CUDD.Ref(observation.Precondition); Belief = CUDD.Function.And(Belief, observation.Precondition); } else { CUDD.Deref(Belief); Belief = Knowledge; CUDD.Ref(Belief); } CUDD.Deref(impliesNode); Update(observation.EventModel); }
/// <summary> /// Return only guards for complete boolean expression, no expression /// Use this when we want to encode a single assignment or the assignment does not depend other assignments. /// </summary> public override ExpressionBDDEncoding TranslateBoolExpToBDD(Model model) { ExpressionBDDEncoding result = new ExpressionBDDEncoding(); ExpressionBDDEncoding variableBddEncoding = new VariablePrime(this.LeftHandSide).TranslateIntExpToBDD(model); ExpressionBDDEncoding valueBddEncoding = this.RightHandSide.TranslateIntExpToBDD(model); for (int i = 0; i < variableBddEncoding.Count(); i++) { for (int j = 0; j < valueBddEncoding.Count(); j++) { CUDD.Ref(variableBddEncoding.GuardDDs[i], valueBddEncoding.GuardDDs[j]); CUDDNode guardDD = CUDD.Function.And(variableBddEncoding.GuardDDs[i], valueBddEncoding.GuardDDs[j]); if (guardDD.Equals(CUDD.ZERO)) { CUDD.Deref(guardDD); continue; } CUDD.Ref(variableBddEncoding.ExpressionDDs[i], valueBddEncoding.ExpressionDDs[j]); CUDDNode assignmentDD = CUDD.Function.Equal(variableBddEncoding.ExpressionDDs[i], valueBddEncoding.ExpressionDDs[j]); guardDD = CUDD.Function.And(guardDD, assignmentDD); result.AddNodeToGuard(guardDD); } } //remove unused expression variableBddEncoding.DeRef(); valueBddEncoding.DeRef(); return(result); }
/// <summary> /// Pi.Trans/In/Out ∧ unchanged.i /// unchanged.i :(P.var \ Pi.var) = (P.var \Pi.var) ' /// Still keep the channlInTransitionBDD & channelOutTransitionBDD. when calculate sync channel and add to transition /// [ REFS: '', DEREFS: ''] /// </summary> private static void InterleaveCopyTransition(List <AutomataBDD> processes, Model model, AutomataBDD result) { CUDDNode notTerminateTrans = CUDD.Function.Not(GetTerminationTransEncoding(model)); foreach (var process in processes) { List <int> unchangedVariableIndex = new List <int>(result.variableIndex); foreach (int index in process.variableIndex) { unchangedVariableIndex.Remove(index); } //terminate event is synchornized in interleaving CUDD.Ref(notTerminateTrans); CUDD.Ref(process.transitionBDD); result.transitionBDD.AddRange(model.AddVarUnchangedConstraint(CUDD.Function.And(process.transitionBDD, notTerminateTrans), unchangedVariableIndex)); CUDD.Ref(notTerminateTrans); CUDD.Ref(process.priorityTransitionsBDD); result.priorityTransitionsBDD.AddRange(model.AddVarUnchangedConstraint(CUDD.Function.And(process.priorityTransitionsBDD, notTerminateTrans), unchangedVariableIndex)); } CUDD.Deref(notTerminateTrans); }
/// <summary> /// [ REFS: 'result', DEREFS: '' ] /// </summary> /// <param name="b"></param> /// <param name="min"></param> /// <returns></returns> public CUDDNode ComputeNextProb(CUDDNode b, bool min) { //Reference to b in the calling place and create a new copy CUDD.Ref(b, reach); b = CUDD.Function.And(b, reach); CUDDNode probs = CUDD.Matrix.MatrixMultiplyVector(trans, b, allRowVars, allColVars); if (min) { //at a state, suppose we have 2 choices, but actually in total we need 2 bit for 3 choices. //therefore the other choice is with prob 0 //we will promote it to 1 via nondetMask then MinAbstract will work CUDD.Ref(nondetMask); probs = CUDD.Function.Maximum(probs, nondetMask); probs = CUDD.Abstract.MinAbstract(probs, allNondetVars); } else { probs = CUDD.Abstract.MaxAbstract(probs, allNondetVars); } CUDD.Deref(b); // CUDD.Ref(start); return(CUDD.Function.Times(probs, start)); }
public static CUDDNode ProbReachReward(CUDDNode trans, CUDDNode stateReward, CUDDNode transReward, CUDDNode reach, CUDDVars allRowVars, CUDDVars allColVars, CUDDNode maybe, CUDDNode inf) { CUDD.Ref(trans, maybe); CUDDNode a = CUDD.Function.Times(trans, maybe); CUDD.Ref(stateReward, maybe); CUDDNode newStateReward = CUDD.Function.Times(stateReward, maybe); CUDD.Ref(transReward, a); CUDDNode newTransRewards = CUDD.Function.Times(transReward, a); newTransRewards = CUDD.Abstract.SumAbstract(newTransRewards, allColVars); CUDDNode allReward = CUDD.Function.Plus(newStateReward, newTransRewards); // CUDDNode tmp = CUDD.Matrix.Identity(allRowVars, allColVars); CUDD.Ref(reach); tmp = CUDD.Function.And(tmp, reach); a = CUDD.Function.Minus(tmp, a); CUDDNode sol = Jacobi(a, allReward, allReward, reach, allRowVars, allColVars, 1); // set reward for infinity states to infinity CUDD.Ref(inf); sol = CUDD.Function.ITE(inf, CUDD.PlusInfinity(), sol); // CUDD.Deref(a, allReward); return sol; }
/// <summary> /// syncTransition = P1.transition ∧ P2.transition /// syncEvent: formula of synchronized events /// P.transition = syncTransition ∨ (Pi.transition ∧ !syncEvent ∧ unchanged.i) /// Applied this formula for each pair of process: P1 || P2 || P3 = (P1 || P2) || P3 /// [ REFS: '', DEREFS: 'processes[i].transitionBDD, alphabet'] /// </summary> /// <param name="processes"></param> /// <param name="alphabets">alphabet of each process if provided. Give True if not provided</param> /// <param name="model"></param> /// <param name="result"></param> private static void ParallelEncodeTransition(List <AutomataBDD> processes, List <CUDDNode> alphabets, Model model, AutomataBDD result) { List <CUDDNode> transition = processes[0].transitionBDD; CUDDNode lastAlphabet = alphabets[0]; //Do encoding at each step, 2 processes once for (int i = 1; i < processes.Count; i++) { //find sync transitions CUDD.Ref(transition); CUDD.Ref(processes[i].transitionBDD); List <CUDDNode> syncTransition = CUDD.Function.And(transition, processes[i].transitionBDD); //sync alphabet = (P0.alphabet and P1.alphabet) or termination event //We rename the event with assignment whose name may be also in the alphabet //After the rename, they do not belong to the alphabet CUDD.Ref(lastAlphabet, alphabets[i]); CUDDNode syncEvent = CUDD.Function.Or(CUDD.Function.And(lastAlphabet, alphabets[i]), GetTerminationTransEncoding(model)); //sync transition must have no program block which mean no global variable updated foreach (var globalVarIndex in model.GlobalVarIndex) { CUDD.Ref(model.varIdentities[globalVarIndex]); syncEvent = CUDD.Function.And(syncEvent, model.varIdentities[globalVarIndex]); } CUDD.Ref(syncEvent); syncTransition = CUDD.Function.And(syncTransition, syncEvent); //update current alphabet lastAlphabet = CUDD.Function.Or(lastAlphabet, alphabets[i]); CUDD.Ref(syncTransition); List <CUDDNode> tempTransition = new List <CUDDNode>(syncTransition); //find not sync event, we need to add global variable unchanged to syncEvent because for example process a -> a {x = 1} -> P; //a may be in the alphabet, and the first a can be synced, but the secondtion is not CUDDNode notSyncEvents = CUDD.Function.Not(syncEvent); CUDD.Ref(notSyncEvents); tempTransition.AddRange(CUDD.Function.And(transition, notSyncEvents)); tempTransition.AddRange(CUDD.Function.And(processes[i].transitionBDD, notSyncEvents)); transition = tempTransition; } // CUDD.Deref(lastAlphabet); transition = model.AddVarUnchangedConstraint(transition, result.variableIndex); // result.transitionBDD = transition; }
/// <summary> /// Return the path from source to destination. If reachable, return true and path contains the path from source to destination /// [ REFS: '', DEREFS:] /// </summary> /// <param name="source"></param> /// <param name="destination"></param> /// <param name="transitions">transitions[0]: normal transitions, transitions[1]: priority transition</param> /// <returns></returns> public bool PathBackWard(CUDDNode source, CUDDNode destination, List <List <CUDDNode> > transitions) { CUDD.Ref(source, destination); CUDDNode temp = CUDD.Function.And(source, destination); //In case source already satisfies destination if (!temp.Equals(CUDD.ZERO)) { CUDD.Deref(temp); return(true); } bool reachable = false; CUDDNode allReachabeToGoal, currentReachableToGoal; CUDD.Ref(destination, destination); allReachabeToGoal = currentReachableToGoal = destination; CUDDNode commonNode = CUDD.Constant(0); do { //backward currentReachableToGoal = this.Predecessors(currentReachableToGoal, transitions); //Check 2 directions have intersection CUDD.Ref(currentReachableToGoal, source); CUDD.Deref(commonNode); commonNode = CUDD.Function.And(currentReachableToGoal, source); if (!commonNode.Equals(CUDD.ZERO)) { reachable = true; break; } //find fixpoint CUDD.Ref(currentReachableToGoal, allReachabeToGoal); CUDDNode allReachabeToGoalTemp = CUDD.Function.Or(allReachabeToGoal, currentReachableToGoal); if (allReachabeToGoalTemp.Equals(allReachabeToGoal)) { reachable = false; CUDD.Deref(allReachabeToGoalTemp); break; } else { currentReachableToGoal = CUDD.Function.Different(currentReachableToGoal, allReachabeToGoal); allReachabeToGoal = allReachabeToGoalTemp; } } while (true); CUDD.Deref(allReachabeToGoal, currentReachableToGoal, commonNode); // return(reachable); }
private CUDDNode GetCuddNode(PlanningParser.GdContext context) { CUDDNode result = null; if (context.atomicFormulaTerm() != null) { result = GetCuddNode(context.atomicFormulaTerm()); } else if (context.literalTerm() != null) { result = GetCuddNode(context.literalTerm()); } else if (context.AND() != null) { result = GetCuddNode(context.gd()[0]); for (int i = 1; i < context.gd().Count; i++) { CUDDNode gdNode = GetCuddNode(context.gd()[i]); CUDDNode andNode = CUDD.Function.And(result, gdNode); CUDD.Ref(andNode); CUDD.Deref(result); CUDD.Deref(gdNode); result = andNode; } } else if (context.OR() != null) { result = GetCuddNode(context.gd()[0]); for (int i = 1; i < context.gd().Count; i++) { CUDDNode gdNode = GetCuddNode(context.gd()[i]); CUDDNode orNode = CUDD.Function.Or(result, gdNode); CUDD.Ref(orNode); CUDD.Deref(result); CUDD.Deref(gdNode); result = orNode; } } else if (context.NOT() != null) { CUDDNode gdNode = GetCuddNode(context.gd()[0]); result = CUDD.Function.Not(gdNode); CUDD.Ref(result); CUDD.Deref(gdNode); } else if (context.IMPLY() != null) { CUDDNode gdNode0 = GetCuddNode(context.gd()[0]); CUDDNode gdNode1 = GetCuddNode(context.gd()[1]); result = CUDD.Function.Implies(gdNode0, gdNode1); CUDD.Ref(result); CUDD.Deref(gdNode0); CUDD.Deref(gdNode1); } return(result); }
public virtual void Close() { allRowVars.Deref(); allColVars.Deref(); CUDD.Deref(allRowVarRanges, trans, start, trans01, reach); CUDD.Deref(varIdentities, varEncodings, stateRewards, transRewards); CUDD.CloseDownCUDD(); }
/// <summary> /// Forward search, check destination is reachable from source /// (S x (Tick + Trans)*) /// [ REFS: '', DEREFS:] /// </summary> /// <param name="source"></param> /// <param name="destination"></param> /// <param name="transitions"></param> /// <returns></returns> public bool PathForward3(CUDDNode source, CUDDNode destination, List <CUDDNode> transitions) { // bool reachable = false; CUDDNode allReachableFromInit, currentReachableFromInit; CUDD.Ref(source, source); allReachableFromInit = currentReachableFromInit = source; CUDDNode commonNode = CUDD.Constant(0); int numberOfLoop = 0; do { numberOfLoop++; Debug.Write(numberOfLoop + " "); currentReachableFromInit = Successors(currentReachableFromInit, transitions); //Check 2 directions have intersection CUDD.Ref(destination, currentReachableFromInit); CUDD.Deref(commonNode); commonNode = CUDD.Function.And(destination, currentReachableFromInit); if (!commonNode.Equals(CUDD.ZERO)) { reachable = true; break; } //find fixpoint CUDD.Ref(currentReachableFromInit, allReachableFromInit); CUDDNode allReachabeFromInitTemp = CUDD.Function.Or(currentReachableFromInit, allReachableFromInit); if (allReachabeFromInitTemp.Equals(allReachableFromInit)) { //reachable = false; CUDD.Deref(allReachabeFromInitTemp); break; } else { currentReachableFromInit = CUDD.Function.Different(currentReachableFromInit, allReachableFromInit); allReachableFromInit = allReachabeFromInitTemp; } } while (true); Debug.WriteLine("\nTA Path Forward 3: " + numberOfLoop + " loops."); CUDD.Deref(allReachableFromInit, currentReachableFromInit, commonNode); // return(reachable); }
public static CUDDNode NondetUntil(CUDDNode trans, CUDDNode nondetMask, CUDDVars allRowVars, CUDDVars allColVars, CUDDVars nondetVars, CUDDNode yes, CUDDNode maybe, bool min) { DateTime startTime = DateTime.Now; int numberOfIterations = 0; CUDDNode a, sol, tmp; CUDD.Ref(trans, maybe); a = CUDD.Function.Times(trans, maybe); CUDD.Ref(yes); sol = yes; while (true) { numberOfIterations++; tmp = CUDD.Matrix.MatrixMultiplyVector(a, sol, allRowVars, allColVars); if (min) { CUDD.Ref(nondetMask); tmp = CUDD.Function.Maximum(tmp, nondetMask); tmp = CUDD.Abstract.MinAbstract(tmp, nondetVars); } else { tmp = CUDD.Abstract.MaxAbstract(tmp, nondetVars); } CUDD.Ref(yes); tmp = CUDD.Function.Maximum(tmp, yes); //check convergence if (CUDD.IsEqual(tmp, sol)) { CUDD.Deref(tmp); break; } CUDD.Deref(sol); sol = tmp; } DateTime endTime = DateTime.Now; double runningTime = (endTime - startTime).TotalSeconds; Debug.WriteLine("NondetUntil: " + numberOfIterations + " iterations in " + runningTime + " seconds"); // CUDD.Deref(a); return(sol); }
public CUDDNode ComputeReachReward(CUDDNode b, int rewardStructIndex) { //Reference to b in the calling place and create a new copy CUDD.Ref(b, reach); b = CUDD.Function.And(b, reach); // CUDDNode inf, maybe, reward; if (b.Equals(CUDD.ZERO)) { CUDD.Ref(reach); inf = reach; maybe = CUDD.Constant(0); } else if (b.Equals(reach)) { inf = CUDD.Constant(0); maybe = CUDD.Constant(0); } else { CUDDNode no = ProbAlgo.Prob0(trans01, reach, allRowVars, allColVars, reach, b); CUDDNode prob1 = ProbAlgo.Prob1(trans01, reach, allRowVars, allColVars, reach, b, no); CUDD.Deref(no); CUDD.Ref(reach); inf = CUDD.Function.And(reach, CUDD.Function.Not(prob1)); CUDD.Ref(reach, inf, b); maybe = CUDD.Function.And(reach, CUDD.Function.Not(CUDD.Function.Or(inf, b))); } // print out yes/no/maybe Debug.WriteLine("goal = " + CUDD.GetNumMinterms(b, allRowVars.GetNumVars())); Debug.WriteLine("inf = " + CUDD.GetNumMinterms(inf, allRowVars.GetNumVars())); Debug.WriteLine("maybe = " + CUDD.GetNumMinterms(maybe, allRowVars.GetNumVars())); if (maybe.Equals(CUDD.ZERO)) { CUDD.Ref(inf); reward = CUDD.Function.ITE(inf, CUDD.PlusInfinity(), CUDD.Constant(0)); } else { reward = ProbAlgo.ProbReachReward(trans, stateRewards[rewardStructIndex], transRewards[rewardStructIndex], reach, allRowVars, allColVars, maybe, inf); } CUDD.Deref(inf, maybe, b); CUDD.Ref(start); return(CUDD.Function.Times(reward, start)); }
/// <summary> /// Close the model, dereference variables /// </summary> public void Close() { this.AllRowVarsExceptSingleCopy.Deref(); this.AllColVars.Deref(); CUDD.Deref(this.varIdentities); CUDD.Deref(this.variableEncoding); CUDD.Deref(this.variableRanges); CUDD.CloseDownCUDD(); }
/// <summary> /// [ REFS: 'none', DEREFS: 'dd if failed to add' ] /// </summary> public void AddNodeToGuard(CUDDNode dd) { if (!dd.Equals(CUDD.ZERO)) { this.GuardDDs.Add(dd); } else { CUDD.Deref(dd); } }