Пример #1
0
        // 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);
        }
Пример #2
0
        // 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);
        }
Пример #3
0
 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;
 }
Пример #4
0
 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;
 }
Пример #5
0
        // 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);
        }
Пример #6
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);
        }
Пример #7
0
        // 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);
        }
Пример #8
0
        // 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);
        }