// Given a tree layer, creates the next layer of child nodes and returns them. public static List <StateSpaceNode> BuildLayer(Planner planner, List <StateSpaceNode> currentLayer) { // Create a new list for the child nodes. List <StateSpaceNode> childLayer = new List <StateSpaceNode>(); // Loop through the nodes in the current layer. foreach (StateSpaceNode node in currentLayer) { // Loop through all outgoing edges of the current node. foreach (StateSpaceEdge edge in node.outgoing) { // Generate the child node. StateSpaceNode child = CreateChild(planner, node.domain, node.problem, node.plan, node.state, edge); // Set the child's parent to this node. child.parent = node; // Add the child to the parent's collection of children, by way of the current action. node.children[edge] = child; // Add the node to the child layer childLayer.Add(child); } } // Return the child layer. return(childLayer); }
// Checks whether a node is a leaf or a branch. public static Boolean CheckLeaf(Plan plan, State state, StateSpaceNode node) { // Return any empty plans. if (plan.Steps.Count == 0) { // If the goal is satisfied... if (state.Satisfies(plan.GoalStep.Preconditions)) { // Differentiate a satisfied goal. node.satisfiesGoal = true; // Record that a goal state was reached. StateSpaceMediator.GoalStateCount++; } else { // Record that a dead end state was reached. StateSpaceMediator.DeadEndCount++; } // Return that the node is a leaf. return(true); } // Return that the node is a branch. return(false); }
public StateSpaceNode(StateSpaceNode parent, StateSpaceEdge incoming, State state) { this.parent = parent; this.incoming = incoming; systemActions = new List <IOperator>(); this.state = state; outgoing = new List <StateSpaceEdge>(); children = new Hashtable(); plan = new Plan(); problem = new Problem(); domain = new Domain(); id = System.Threading.Interlocked.Increment(ref Counter); satisfiesGoal = false; }
public StateSpaceNode() { parent = null; incoming = null; systemActions = new List <IOperator>(); state = new State(); outgoing = new List <StateSpaceEdge>(); children = new Hashtable(); plan = new Plan(); problem = new Problem(); domain = new Domain(); id = System.Threading.Interlocked.Increment(ref Counter); satisfiesGoal = false; }
// Creates and returns a new node. public static StateSpaceNode CreateNode(Planner planner, Domain domain, Problem problem, Plan plan, State state) { // Create a node for the current state. StateSpaceNode root = new StateSpaceNode(); // Record that a node was created. StateSpaceMediator.NodeCount++; // Check if the node is a leaf. if (StateSpaceSearchTools.CheckLeaf(plan, state, root)) { return(root); } // Set the node's domain. root.domain = domain; // Set the node's problem. root.problem = problem; // Set the node's plan. root.plan = plan; // Set the node's state. root.state = state; // Find out what the player knows. root.problem.Initial = RobertsonMicrotheory.Annotate(problem.Initial, problem.Player); // Find all outgoing user actions from this state. root.outgoing = StateSpaceTools.GetAllPossibleActions(domain, problem, plan, state); // Record the number of outgoing edges. StateSpaceMediator.OutgoingEdgesCount = StateSpaceMediator.OutgoingEdgesCount + root.outgoing.Count; // Return the current node. return(root); }
// Creates a child node. private static StateSpaceNode CreateChild(Planner planner, Domain domain, Problem problem, Plan plan, State state, StateSpaceEdge edge) { // Create a new problem object. Problem newProblem = new Problem(); // Create a new domain object. Domain newDomain = domain; // Create a new plan object. Plan newPlan = new Plan(); // Store actions the system takes. List <IOperator> systemActions = new List <IOperator>(); // If the outgoing action is an exceptional step... if (edge.ActionType == ActionType.Exceptional) { // Count the exceptional edge. Exceptional++; // Create a new problem object. newProblem = NewProblem(newDomain, problem, state, edge.Action); // Find a new plan. newPlan = PlannerInterface.Plan(planner, newDomain, newProblem); // If the action was accommodated and the first step of the new plan isn't taken by the player... if (newPlan.Steps.Count > 0) { // Add the action to the system action list. systemActions = GetSystemActions(newPlan, new List <string> { problem.Player }, new List <IOperator>()); // Update the problem object with the system's next move. newProblem = NewProblem(newDomain, newProblem, new State(newProblem.Initial, newPlan.InitialStep, (Operator)newPlan.Steps.First()), systemActions); // Update the plan with the system's next move. newPlan = newPlan.GetPlanUpdate(newProblem, systemActions); } else if (CEDeletion) { // Try to find a domain revision alibi. Tuple <Domain, Operator> alibi = ReviseDomain(planner, newDomain, problem, state, edge.Action as Operator); // If domain revision worked. if (alibi != null) { // Remember the new domain. newDomain = alibi.First; // Push the modified action to the edge object. edge.Action = alibi.Second; // Create a new problem object. newProblem = NewProblem(newDomain, problem, state, edge.Action); // Find a new plan. newPlan = PlannerInterface.Plan(planner, newDomain, newProblem); // Add the action to the system action list. systemActions = GetSystemActions(newPlan, new List <string> { problem.Player }, new List <IOperator>()); // Update the problem object with the system's next move. newProblem = NewProblem(newDomain, newProblem, new State(newProblem.Initial, newPlan.InitialStep, (Operator)newPlan.Steps.First()), systemActions); // Update the plan with the system's next move. newPlan = newPlan.GetPlanUpdate(newProblem, systemActions); } } } // Otherwise, if the action is a consistent step... else if (edge.ActionType == ActionType.Consistent) { // Count the consistent edge. Consistent++; // Create a new problem object. newProblem = NewProblem(newDomain, problem, state, edge.Action); // Add the action to the system action list. systemActions = GetSystemActions(plan, new List <string> { problem.Player }, new List <IOperator>()); // Create a new state. State newState = new State(newProblem.Initial, state.nextStep, (Operator)plan.Steps.First()); // Create a new problem object. newProblem = NewProblem(newDomain, newProblem, newState, systemActions); // Create a new plan. newPlan = plan.GetPlanUpdate(newProblem, systemActions); } // Otherwise, the action is a constituent step... else { // Count the constituent edge. Constituent++; // If there are effects of the constituent action... if (edge.Action.Effects.Count > 0) { // Create a new problem object. newProblem = NewProblem(newDomain, problem, state, edge.Action); // Create a new plan. newPlan = plan.GetPlanUpdate(newProblem, edge.Action as Operator); } // Otherwise, initialize to the old problem and plan... else { newProblem = problem; newPlan = plan.Clone() as Plan; } // If there are still plan actions... if (newPlan.Steps.Count > 0) { // Add the action to the system action list. systemActions = GetSystemActions(newPlan, new List <string> { problem.Player }, new List <IOperator>()); // Update the problem object with the system's next move. newProblem = NewProblem(newDomain, newProblem, new State(newProblem.Initial, newPlan.InitialStep, (Operator)newPlan.Steps.First()), systemActions); // Update the plan with the system's next move. newPlan = newPlan.GetPlanUpdate(newProblem, systemActions); } } // Add the system actions to the current edge. edge.SystemActions = systemActions; // Create an empty child node. StateSpaceNode child = null; // If there are remaining plan steps... if (newPlan.Steps.Count > 0) { // Build a new tree using the first step of the plan as the next step. child = StateSpaceSearchTools.CreateNode(planner, newDomain, newProblem, newPlan, new State(newProblem.Initial, newPlan.InitialStep, (Operator)newPlan.Steps.First())); } else { // Terminate the tree by adding a goal node. child = StateSpaceSearchTools.CreateNode(planner, newDomain, newProblem, newPlan, new State(newProblem.Initial, newPlan.InitialStep, newPlan.GoalStep)); } // Store the system actions. child.systemActions = systemActions; // Record the action that triggered the node's generation. child.incoming = edge; return(child); }
// Expand an edge. public static StateSpaceNode ExpandTree(Planner planner, Domain domain, Problem problem, Plan plan, State state, StateSpaceEdge edge, int depth) { // Create a new problem object. Problem newProblem = new Problem(); // Create a new plan object. Plan newPlan = new Plan(); // Store actions the system takes. List <IOperator> systemActions = new List <IOperator>(); // If the action is an exceptional step... if (edge.ActionType == ActionType.Exceptional) { // Count the exceptional edge. Exceptional++; // Create a new problem object. newProblem = NewProblem(domain, problem, state, edge.Action); // Find a new plan. newPlan = PlannerInterface.Plan(planner, domain, newProblem); // If the action was accommodated and the first step of the new plan isn't taken by the player... if (newPlan.Steps.Count > 0) { // Add the action to the system action list. systemActions = GetSystemActions(newPlan, new List <string> { problem.Player }, new List <IOperator>()); // Update the problem object with the system's next move. newProblem = NewProblem(domain, newProblem, new State(newProblem.Initial, newPlan.InitialStep, (Operator)newPlan.Steps.First()), systemActions); // Update the plan with the system's next move. newPlan = newPlan.GetPlanUpdate(newProblem, systemActions); } else if (CEDeletion) { StateSpaceNode alibi = GenerateAlibi(planner, domain, problem, plan, state, edge, depth); if (alibi != null) { return(alibi); } } } // Otherwise, if the action is a consistent step... else if (edge.ActionType == ActionType.Consistent) { // Count the consistent edge. Consistent++; // Create a new problem object. newProblem = NewProblem(domain, problem, state, edge.Action); // Add the action to the system action list. systemActions = GetSystemActions(plan, new List <string> { problem.Player }, new List <IOperator>()); // Create a new state. State newState = new State(newProblem.Initial, state.nextStep, (Operator)plan.Steps.First()); // Create a new problem object. newProblem = NewProblem(domain, newProblem, newState, systemActions); // Create a new plan. newPlan = plan.GetPlanUpdate(newProblem, systemActions); } // Otherwise, the action is a constituent step... else { // Count the constituent edge. Constituent++; // If there are effects of the constituent action... if (edge.Action.Effects.Count > 0) { // Create a new problem object. newProblem = NewProblem(domain, problem, state, edge.Action); // Create a new plan. newPlan = plan.GetPlanUpdate(newProblem, edge.Action as Operator); } // Otherwise, initialize to the old problem and plan... else { newProblem = problem; newPlan = plan.Clone() as Plan; } // If there are still plan actions... if (newPlan.Steps.Count > 0) { // Add the action to the system action list. systemActions = GetSystemActions(newPlan, new List <string> { problem.Player }, new List <IOperator>()); // Update the problem object with the system's next move. newProblem = NewProblem(domain, newProblem, new State(newProblem.Initial, newPlan.InitialStep, (Operator)newPlan.Steps.First()), systemActions); // Update the plan with the system's next move. newPlan = newPlan.GetPlanUpdate(newProblem, systemActions); } } // Add the system actions to the current edge. edge.SystemActions = systemActions; // Create an empty child node. StateSpaceNode child = null; // If there are remaining plan steps... if (newPlan.Steps.Count > 0) { // Build a new tree using the first step of the plan as the next step. child = BuildTree(planner, domain, newProblem, newPlan, new State(newProblem.Initial, newPlan.InitialStep, (Operator)newPlan.Steps.First()), depth - 1); } else { // Terminate the tree by adding a goal node. child = BuildTree(planner, domain, newProblem, newPlan, new State(newProblem.Initial, newPlan.InitialStep, newPlan.GoalStep), depth - 1); } // Store the system actions. child.systemActions = systemActions; // Record the action that triggered the node's generation. child.incoming = edge; return(child); }
// Build the mediation tree using a depth-first strategy. public static StateSpaceNode BuildTree(Planner planner, Domain domain, Problem problem, Plan plan, State state, int depth) { // Create a node for the current state. StateSpaceNode root = new StateSpaceNode(); // Record that a node was created. NodeCount++; // Return any empty plans. if (plan.Steps.Count == 0) { // If the goal is satisfied... if (state.Satisfies(plan.GoalStep.Preconditions)) { // Differentiate a satisfied goal. root.satisfiesGoal = true; // Record that a goal state was reached. GoalStateCount++; } else { // Record that a dead end state was reached. DeadEndCount++; } // Return the leaf node. return(root); } // Set the node's domain. root.domain = domain; // Set the node's problem. root.problem = problem; // Set the node's plan. root.plan = plan; // Set the node's state. root.state = state; // Find out what the player knows. root.problem.Initial = RobertsonMicrotheory.Annotate(problem.Initial, problem.Player); // Find all outgoing user actions from this state. root.outgoing = StateSpaceTools.GetAllPossibleActions(domain, problem, plan, state); // Return the node if the depth limit has been reached. if (depth <= 0) { return(root); } // Loop through the possible actions. foreach (StateSpaceEdge edge in root.outgoing) { StateSpaceNode child = ExpandTree(planner, domain, problem, plan.Clone() as Plan, state.Clone() as State, edge, depth); // Set the child's parent to this node. child.parent = root; // Add the child to the parent's collection of children, by way of the current action. root.children[edge] = child; } // Return the current node. return(root); }