// 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);
        }
Example #2
0
        // 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);
        }