private void GoalPathNodesI(ArrayList goalpath, DBNode node, Stack path) { if (node == null) { return; } if (module.IsGoal(node.State) && goalpath.Contains(node) == false) { /* * Console.WriteLine ("goals:"); * foreach (IDBSpaceState state in goals) * Console.WriteLine (" {0}", state); * * Console.WriteLine (" add: {0}", node.State); */ goalpath.Add(node); foreach (DBNode pNode in path) { if (goalpath.Contains(pNode) == false) { goalpath.Add(pNode); } } } foreach (DBNode child in node.Children) { path.Push(node); GoalPathNodesI(goalpath, child, path); path.Pop(); } }
// TODO private void AddCombinationStage(DBNode node, Stack path) { //Console.WriteLine ("AddCombinationStage"); if (node == null || node.Level > level) { return; } if (node.Type == DBNode.NodeType.Dependency && node.Level == level && node.IsGoal == false) { /*for (int l = 0 ; l < node.Level ; ++l) * Console.Write (" "); * Console.WriteLine ("({0}) down", node.DebugNN);*/ module.DoExpirationCheck(); FindAllCombinationNodes(node, path, root, new Stack()); } path.Push(node); foreach (DBNode child in node.Children) { AddCombinationStage(child, path); } path.Pop(); }
private void DumpTree(DBNode node) { if (node == null) { return; } if (node.dumped) { return; } node.dumped = true; for (int n = 0; n < node.Level; ++n) { Console.Write(" "); } Console.WriteLine(node); foreach (DBNode child in node.Children) { DumpTree(child); } }
// TODO: // if tracing back this nodes anypath to the root node, will we cross // 'node' ? public bool BacktraceLeadsOverNode(DBNode node) { // TODO: this is inefficient, as we check almost the whole graph // By reversing it (and storing backpointers in each node, we // could make this faster). if (this == node) { return(true); } if (node.Level >= Level) { return(false); } foreach (DBNode child in node.Children) { if (BacktraceLeadsOverNode(child)) { return(true); } } return(false); }
public void AddCombinationNode(DBNode node, DBNode newNode) { TreeSizeIncreased = true; nodeCount += 1; // Graph bookkeeping node.Children.Add(newNode); }
private int DEBUGParentNN(DBNode node, DBNode search) { if (node.Children.IndexOf(search) >= 0) { return(node.DebugNN); } foreach (DBNode child in node.Children) { int cnn = DEBUGParentNN(child, search); if (cnn != -1) { return(cnn); } } return(-1); }
private bool HaveCommonCombinedChild(DBNode node1, DBNode node2) { foreach (DBNode child1 in node1.Children) { if (node2.CombinedChildren.IndexOf(child1) >= 0) { return(true); } } foreach (DBNode child2 in node2.Children) { if (node1.CombinedChildren.IndexOf(child2) >= 0) { return(true); } } return(false); }
private void AddDependentChildren(DBNode node, int subLevel) { // Console.WriteLine (" AddDependentChildren"); // TODO IDBOperator[] opers = module.LegalOperators(node); if (opers == null) { return; } //Console.WriteLine (" opers.Count = {0}", opers.Length); foreach (IDBOperator op in opers) { if (module.Applicable(op, node)) { DBNode newChild = LinkNewChildToGraph(node, op); newChild.subLevel = subLevel; if (newChild.IsGoal == false) { if (breadthFirst) { dependencyNodeQueue.Enqueue (new DepQElem(newChild, subLevel + 1)); } else { AddDependentChildren(newChild, subLevel + 1); } } else if (module.OneGoalStopsSearch || (module.GoalCountThresh != 0 && goalCount >= module.GoalCountThresh)) { throw (new GoalCountExceededException()); } } } }
private void AddDependencyStage(DBNode node) { //Console.WriteLine ("AddDependencyStage"); if (node == null) { return; } if (level == (node.Level + 1) && (node.Type == DBNode.NodeType.Root || node.Type == DBNode.NodeType.Combination)) { // Do not expand goal nodes any further or nodes that have // already been expanded. if (node.IsGoal == false && node.DependencyExpanded == false) { if (breadthFirst) { dependencyNodeQueue.Enqueue(new DepQElem(node, 0)); node.DependencyExpanded = true; } else { AddDependentChildren(node, 0); } } // FIXME: check if this is ok, seems to be and makes sense return; } foreach (DBNode child in node.Children) { AddDependencyStage(child); } }
// Returns new child private DBNode LinkNewChildToGraph(DBNode node, IDBOperator op) { IDBSpaceState newState = op.Apply(module, node.State); newState.UpdateIsGoal(module); DBNode newNode = new DBNode(DBNode.NodeType.Dependency, newState, level); if (newNode.IsGoal) { goalCount += 1; } TreeSizeIncreased = true; nodeCount += 1; // Graph bookkeeping node.Children.Add(newNode); module.RegisterNewNode(newNode, root); return(newNode); }
private void GoalStatesI(ArrayList goals, DBNode node) { if (node == null) { return; } if (module.IsGoal(node.State) && goals.Contains(node.State) == false) { /* * Console.WriteLine ("goals:"); * foreach (IDBSpaceState state in goals) * Console.WriteLine (" {0}", state); * * Console.WriteLine (" add: {0}", node.State); */ goals.Add(node.State); } foreach (DBNode child in node.Children) { GoalStatesI(goals, child); } }
// partnerPath: path up to and excluding partner // nodePath: path up to and excluding node private void FindAllCombinationNodes(DBNode partner, Stack partnerPath, DBNode node, Stack nodePath) { //Console.WriteLine ("FindAllCombinationNodes"); if (node == null || node == partner) { return; } if (node.IsGoal) { return; } if (node.Type == DBNode.NodeType.Root || module.NotInConflict(partner, node)) { // HaveCommonChild checks if we already combined in the // reverse direction, but we also need to check whether their // path's are independant. That is, whether tracing node's // path back to root we will cross over partner. Also whether // tracing partner's path back will lead us over node. if (node.Type == DBNode.NodeType.Dependency && HaveCommonCombinedChild(partner, node) == false) { IDBSpaceState combination = module.CombineIfResultIsNewOperators(partner, partnerPath, node, nodePath); if (combination != null) { DBNode combNode = new DBNode(DBNode.NodeType.Combination, combination, level); combNode.IsGoal = module.IsGoal(combination); if (combNode.IsGoal) { goalCount += 1; } AddCombinationNode(partner, combNode); // Also make the new node a child ("combined child") of // node. We do not add it it to the Children array // for two reasons: // 1. We want a strict tree structure in memory, no // DAG // 2. The only point where this DAG-like // relationship is used is in this method, when // its checked we did not already combine them. node.CombinedChildren.Add(combNode); // Notify the implementation of a new node. module.RegisterNewNode(combNode, root); if (combNode.IsGoal) { if (module.OneGoalStopsSearch || (module.GoalCountThresh != 0 && goalCount >= module.GoalCountThresh)) { throw (new GoalCountExceededException()); } } } } nodePath.Push(node); foreach (DBNode child in node.Children) { FindAllCombinationNodes(partner, partnerPath, child, nodePath); } nodePath.Pop(); } }
internal DepQElem(DBNode node, int subLevel) { this.node = node; this.subLevel = subLevel; }
public void Search(IDBSpaceState rootState) { rootState.UpdateIsGoal(module); root = new DBNode(DBNode.NodeType.Root, rootState, 0); if (root.IsGoal) { goalCount += 1; } module.RegisterNewNode(root, root); level = 1; TreeSizeIncreased = true; try { while (TreeSizeIncreased) { //Console.WriteLine ("level {0}", level); TreeSizeIncreased = false; if (breadthFirst) { dependencyNodeQueue.Clear(); } AddDependencyStage(root); if (breadthFirst) { SolveDependencyStage(); } //DumpTree (root); /*Console.WriteLine ("level {0} dependency finished: {1} nodes, {2} goals", * level, nodeCount, goalCount);*/ if (TreeSizeIncreased == false) { break; } if (module.GoalCountThresh != 0 && goalCount >= module.GoalCountThresh) { break; } /* * Console.WriteLine ("COMB TEST"); * module.CombinationStage (level, root, this); * * if (module.GoalCountThresh != 0 && goalCount >= module.GoalCountThresh) * break; */ AddCombinationStage(root, new Stack()); /*Console.WriteLine ("level {0} combination finished: {1} nodes, {2} goals", * level, nodeCount, goalCount);*/ if (TreeSizeIncreased == false) { break; } if (module.GoalCountThresh != 0 && goalCount >= module.GoalCountThresh) { break; } //DumpTree (root); level += 1; } } catch (GoalCountExceededException) { /* * Console.WriteLine ("GOAL count limit of {0} exceeded.", * module.GoalCountThresh);*/ } }
private void DumpDOT(TextWriter dotFile, DBNode node, ArrayList nodesFilter) { if (node == null) { return; } if (nodesFilter != null && nodesFilter.Contains(node) == false) { return; } if (node.dumped) { return; } node.dumped = true; for (int n = 0; n < node.Level; ++n) { dotFile.Write(" "); } // Order nodes on level string rankLevel; if (node.Level == 0) { rankLevel = "root"; } else if (node.Type == DBNode.NodeType.Dependency) { rankLevel = String.Format("dep{0}", node.Level); } else if (node.Type == DBNode.NodeType.Combination) { rankLevel = String.Format("comb{0}", node.Level); } else { rankLevel = "invalid"; } if (node.subLevel == 0) { dotFile.WriteLine("{{ rank=same; {0};", rankLevel); } dotFile.WriteLine("{0} [shape=box label = <{1}>];", node.DebugNN, node.State.DescShort); if (node.subLevel == 0) { dotFile.WriteLine("}"); } foreach (DBNode child in node.Children) { if (nodesFilter != null && nodesFilter.Contains(child) == false) { continue; } for (int n = 0; n < node.Level; ++n) { dotFile.Write(" "); } dotFile.WriteLine("{0} -> {1};", node.DebugNN, child.DebugNN); } // Also combined children if (node.CombinedChildren != null) { foreach (DBNode child in node.CombinedChildren) { if (nodesFilter != null && nodesFilter.Contains(child) == false) { continue; } for (int n = 0; n < node.Level; ++n) { dotFile.Write(" "); } dotFile.WriteLine("{0} -> {1} [color=\"#b0b0b0\"] ;", node.DebugNN, child.DebugNN); } } foreach (DBNode child in node.Children) { DumpDOT(dotFile, child, nodesFilter); } }