/// <summary> /// Forward search, check destination is reachable from source /// NOT store all reachable states, use some special condition to terminate /// At step t, find all reachable states after t time units /// Fix point when rechable(t1 + a, t1 + a) is a subset of rechable(t1, t1) /// Rabbit algorithm (S x Tick x Trans*)* /// [ REFS: '', DEREFS:] /// </summary> /// <param name="source"></param> /// <param name="destination"></param> /// <param name="discreteTransitions"></param> /// <returns></returns> public bool PathForward2(CUDDNode source, CUDDNode destination, List <CUDDNode> discreteTransitions, List <CUDDNode> tickTransitions) { // bool reachable = false; CUDD.Ref(source); CUDDNode currentReachableFromInit = SuccessorsStart(source, discreteTransitions); CUDDNode previousReachableFromInit = CUDD.Constant(0); int s, p; s = p = 0; CUDDNode commonNode = CUDD.Constant(0); int numberOfLoop = 0; while (!CUDD.IsSubSet(previousReachableFromInit, currentReachableFromInit)) { numberOfLoop++; Debug.Write(numberOfLoop + " "); if (p <= s / 2) { p = s; CUDD.Deref(previousReachableFromInit); CUDD.Ref(currentReachableFromInit); previousReachableFromInit = currentReachableFromInit; } currentReachableFromInit = Successors(currentReachableFromInit, tickTransitions); currentReachableFromInit = SuccessorsStart(currentReachableFromInit, discreteTransitions); s++; //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; } } Debug.WriteLine("\nTA Path Forward 2: " + numberOfLoop + " loops."); CUDD.Deref(currentReachableFromInit, previousReachableFromInit, commonNode); // return(reachable); }