internal bool AddPathEdge(PathEdgesPartition NewPathEdge, BddManager Manager) { Bdd allPaths = GetJointPaths(Manager); Bdd tempBdd = Manager.LogicalOr(allPaths, NewPathEdge.PathEdges); if (tempBdd == allPaths) { allPaths.FreeBdd(); return(false); } allPaths.FreeBdd(); m_PathEdgesByLength.Sort(); int position = m_PathEdgesByLength.BinarySearch(NewPathEdge); bool updated = false; if (position >= 0) { if (m_PathEdgesByLength[position].AddPaths(NewPathEdge.PathEdges, Manager)) { updated = true; } } else { m_PathEdgesByLength.Add(NewPathEdge); updated = true; m_PathEdgesByLength.Sort(); } return(updated); }
internal Bdd GetJointPaths(BddManager Manager) { Bdd JointPaths = Manager.CreateBddZero(); foreach (PathEdgesPartition part in m_PathEdgesByLength) { Bdd tempBdd = JointPaths; JointPaths = Manager.LogicalOr(JointPaths, part.PathEdges); tempBdd.FreeBdd(); } return(JointPaths); }
internal bool AddPaths(Bdd newPaths, BddManager Manager) { Bdd tempBdd = m_PathEdges; m_PathEdges = Manager.LogicalOr(m_PathEdges, newPaths); bool changed = true; if (tempBdd == m_PathEdges) { changed = false; } tempBdd.FreeBdd(); return(changed); }
public static Bdd ExprToBdd(CommonAST Expr, BddManager Manager, Dictionary <string, int> LocalVarNameToId, Dictionary <string, int> GlobalVarNameToId) { Debug.Assert(Expr.Type == BoolParserTokenTypes.EXPR); Bdd ExprBdd = null; CommonAST walker = (CommonAST)Expr.getFirstChild(); switch (walker.Type) { case BoolParserTokenTypes.EXPR: ExprBdd = ExprToBdd(walker, Manager, LocalVarNameToId, GlobalVarNameToId); break; case BoolParserTokenTypes.EMARK: walker = (CommonAST)walker.getNextSibling(); Bdd tempBdd = ExprToBdd(walker, Manager, LocalVarNameToId, GlobalVarNameToId); ExprBdd = Manager.LogicalNot(tempBdd); tempBdd.FreeBdd(); break; case BoolParserTokenTypes.ID: int VariableID; if (!LocalVarNameToId.TryGetValue(walker.getText(), out VariableID)) { if (!GlobalVarNameToId.TryGetValue(walker.getText(), out VariableID)) { Debug.Assert(false); //Varijabla mora biti ili medju lokalnim ili medju globalnim } } ExprBdd = Manager.GetBddVariableWithID(VariableID); break; case BoolParserTokenTypes.CONST: if (walker.getText() == "1") { ExprBdd = Manager.CreateBddOne(); } else { ExprBdd = Manager.CreateBddZero(); } break; default: Debug.Assert(false); break; } if ((walker.getNextSibling() != null) && ((walker = (CommonAST)walker.getNextSibling()).Type == BoolParserTokenTypes.BINOP)) { Bdd firstOperand = ExprBdd; string Operation = walker.getText(); walker = (CommonAST)walker.getNextSibling(); Bdd secondOperand = ExprToBdd(walker, Manager, LocalVarNameToId, GlobalVarNameToId); switch (Operation) { case ("|"): ExprBdd = Manager.LogicalOr(firstOperand, secondOperand); break; case ("&"): ExprBdd = Manager.LogicalAnd(firstOperand, secondOperand); break; case ("^"): ExprBdd = Manager.LogicalXor(firstOperand, secondOperand); break; case ("="): ExprBdd = Manager.LogicalXnor(firstOperand, secondOperand); break; case ("!="): ExprBdd = Manager.LogicalXor(firstOperand, secondOperand); break; case ("=>"): ExprBdd = Manager.LogicalImplies(firstOperand, secondOperand); break; default: Debug.Assert(false); break; } firstOperand.FreeBdd(); secondOperand.FreeBdd(); } return(ExprBdd); }
public void Reachable(debugPrintDelegate debugPrint) { if (ProgramCFG.CfgNodes.Count <= 1) { debugPrint("Invalid Program, unable to proceed!\n"); return; } m_PathEdges.Clear(); m_SummaryEdges.Clear(); BuildTransferFunctions(); LinkedList <CFGNode> workList = new LinkedList <CFGNode>(); CFGNodeProcedure tempNodeProc; CFGNode tempNode; Bdd bddLift, bddSummaryEdges, bddNew; PathEdges bddSelfLoop, bddJoin, bddPathEdges; Bdd [] array = new Bdd[3]; foreach (CFGNode node in ProgramCFG.CfgNodes) { m_PathEdges.Add(node, new PathEdges()); m_SummaryEdges.Add(node, m_BddManager.CreateBddZero()); } ProgramCFG.ProcedureNameToNode().TryGetValue("main", out tempNodeProc); workList.AddFirst(tempNodeProc.FirstStmtOf); m_PathEdges.Remove(tempNodeProc.FirstStmtOf); PathEdges firstMain = new PathEdges(); firstMain.AddPathEdge(new PathEdgesPartition(0, HelperFunctions.BuildIdentityTransfer (m_BddManager, tempNodeProc.LocalVariables.VariablesToId, ProgramCFG.GlobalVariables.VariablesToId)), m_BddManager); m_PathEdges.Add(tempNodeProc.FirstStmtOf, firstMain); #region Debug part of the reachability algorithm /* * ///////Debug //////////// * Dictionary<string, int>.ValueCollection valCollection = tempNodeProc.LocalVariables.VariablesToId.Values; * foreach (int id in valCollection) * { * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalOr(tempBdd, m_BddManager.GetBddVariableWithID(id)); * tempBdd1.FreeBdd(); * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalXnor(tempBdd, m_BddManager.GetBddVariableWithID(id + 2)); * tempBdd1.FreeBdd(); * } * * foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values) * { * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalImplies(tempBdd, m_BddManager.GetBddVariableWithID(id)); * tempBdd1.FreeBdd(); * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalOr(tempBdd, m_BddManager.GetBddVariableWithID(id + 2)); * tempBdd1.FreeBdd(); * } * array[0] = tempBdd; * tempBdd = m_BddManager.CreateBddOne(); * * foreach (int id in valCollection) * { * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalAnd(tempBdd, m_BddManager.GetBddVariableWithID(id)); * tempBdd1.FreeBdd(); * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalNor(tempBdd, m_BddManager.GetBddVariableWithID(id + 2)); * tempBdd1.FreeBdd(); * } * * foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values) * { * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalImplies(tempBdd, m_BddManager.GetBddVariableWithID(id)); * tempBdd1.FreeBdd(); * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalXor(tempBdd, m_BddManager.GetBddVariableWithID(id + 2)); * tempBdd1.FreeBdd(); * } * array[1] = tempBdd; * * //array[2] = Join(array[0], array[1], tempNodeProc.LocalVariables); * array[2] = SelfLoop(array[1], tempNodeProc.LocalVariables, tempNodeProc.LocalVariables); * m_BddManager.ForceGarbageCollection(); * return array; * //////////////////////// */ #endregion while (workList.Count != 0) { tempNode = workList.First.Value; debugPrint("Processing Node: " + tempNode.ToString() + ".\n"); workList.RemoveFirst(); if (tempNode is CFGNodeStmtProcCall) { CFGNodeStmtProcCall procCall = tempNode as CFGNodeStmtProcCall; m_PathEdges.TryGetValue(tempNode, out bddPathEdges); bddJoin = Join(bddPathEdges, procCall.Transfer, procCall.ProcOf.LocalVariables); bddSelfLoop = SelfLoop(bddJoin, procCall.ProcOf.LocalVariables, (procCall.Succesor as CFGNodeStatement).ProcOf.LocalVariables); Propagate(procCall.Succesor, bddSelfLoop, workList); bddJoin.FreeAllBdd(); bddSelfLoop.FreeAllBdd(); m_PathEdges.TryGetValue(tempNode, out bddPathEdges); m_SummaryEdges.TryGetValue(tempNode, out bddSummaryEdges); if (bddSummaryEdges != null) { bddJoin = Join(bddPathEdges, bddSummaryEdges, procCall.ProcOf.LocalVariables); Propagate(procCall.ReturnPoint, bddJoin, workList); bddJoin.FreeAllBdd(); } } else if (tempNode is CFGNodeProcedure) { foreach (CFGNodeStmtSkip node in (tempNode as CFGNodeProcedure).Succesor) { bddLift = Lift(node.previousProcCall, tempNode as CFGNodeProcedure); m_SummaryEdges.TryGetValue(node.previousProcCall, out bddSummaryEdges); m_PathEdges.TryGetValue(node.previousProcCall, out bddPathEdges); if (bddSummaryEdges != null) { bddNew = m_BddManager.LogicalOr(bddLift, bddSummaryEdges); bddLift.FreeBdd(); } else { bddNew = bddLift; } if (bddSummaryEdges != bddNew) { m_SummaryEdges.Remove(node.previousProcCall); m_SummaryEdges.Add(node.previousProcCall, bddNew); bddSummaryEdges.FreeBdd(); bddJoin = Join(bddPathEdges, bddNew, (node as CFGNodeStmtSkip).previousProcCall.ProcOf.LocalVariables); Propagate(node, bddJoin, workList); bddJoin.FreeAllBdd(); } } } else if (tempNode is CFGNodeStmtConditional) { CFGNodeStmtConditional tempNode1 = tempNode as CFGNodeStmtConditional; m_PathEdges.TryGetValue(tempNode, out bddPathEdges); bddJoin = Join(bddPathEdges, tempNode1.TransferTrue, tempNode1.ProcOf.LocalVariables); Propagate(tempNode1.TrueSuccesor, bddJoin, workList); bddJoin.FreeAllBdd(); m_PathEdges.TryGetValue(tempNode, out bddPathEdges); bddJoin = Join(bddPathEdges, tempNode1.TransferFalse, tempNode1.ProcOf.LocalVariables); Propagate(tempNode1.FalseSuccesor, bddJoin, workList); bddJoin.FreeAllBdd(); } else { if (!(tempNode is CFGNodeError)) { m_PathEdges.TryGetValue(tempNode, out bddPathEdges); bddJoin = Join(bddPathEdges, (tempNode as CFGNodeStatement).Transfer, (tempNode as CFGNodeStatement).ProcOf.LocalVariables); Propagate(tempNode.Succesor, bddJoin, workList); bddJoin.FreeAllBdd(); } } } m_BddManager.ForceGarbageCollection(); }