예제 #1
0
        // Get the set of exceptional and constituent edges.
        public static List <StateSpaceEdge> GetPossibleActions(Domain domain, Problem problem, Plan plan, State state)
        {
            // Make the set of outgoing edges.
            List <StateSpaceEdge> actions = new List <StateSpaceEdge>();

            // Find the current constituent action.
            StateSpaceEdge constituent = GetConstituentAction(domain, problem, plan, state);

            // Add the constituent action to the possible actions.
            actions.Add(constituent);

            // Find and add the current exceptional actions.
            List <StateSpaceEdge> exceptionals = GetExceptionalActions(domain, problem, plan, state);

            // Remove any exceptional actions that correspond to the constituent step.
            foreach (StateSpaceEdge exception in exceptionals)
            {
                if (!exception.Action.Equals(constituent.Action))
                {
                    actions.Add(exception);
                }
            }

            // Return the outgoing edges.
            return(actions);
        }
예제 #2
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;
 }
예제 #3
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;
 }
예제 #4
0
        // Creates a list of all possible things the player can do.
        public static List <StateSpaceEdge> GetAllPossibleActions(Domain domain, Problem problem, Plan plan, State state)
        {
            // Create a list of possible player actions in the current state.
            List <Operator> possibleActions = GetPlayerActions(domain, problem, state);

            // Create a list of the causal links that span the state.
            List <CausalLink> spanningLinks = (List <CausalLink>)GetSpanningLinks(plan);

            // Create an empty list of exceptional actions.
            List <StateSpaceEdge> exceptionalActions = new List <StateSpaceEdge>();

            // Store the exceptional actions to be removed later.
            List <Operator> exceptions = new List <Operator>();

            // Store exceptional effects.
            Hashtable exceptionalEffects = new Hashtable();

            // Loop through every possible action.
            foreach (Operator action in possibleActions)
            {
                // Loop through every action's effects.
                foreach (Predicate effect in action.Effects)
                {
                    // Loop through every spanning link.
                    foreach (CausalLink link in spanningLinks)
                    {
                        // If the effect is the inverse of the protected predicate...
                        if (effect.IsInverse(link.Predicate))
                        {
                            // Identify the exceptional effect.
                            if (exceptionalEffects.ContainsKey(action.Predicate.ToString()))
                            {
                                List <IPredicate> list = exceptionalEffects[action.Predicate.ToString()] as List <IPredicate>;
                                list.Add(effect.Clone() as Predicate);
                                exceptionalEffects[action.Predicate.ToString()] = list;
                            }
                            else
                            {
                                exceptionalEffects[action.Predicate.ToString()] = new List <IPredicate> {
                                    effect.Clone() as Predicate
                                }
                            };

                            // Add the current action to the list of exceptional actions.
                            exceptionalActions.Add(new StateSpaceEdge(action.Clone() as Operator, ActionType.Exceptional));

                            // Add the actual action to the exception list.
                            exceptions.Add(action);
                        }
                    }
                }


                //Loop through the action's axioms
                foreach (IAxiom conditional in state.ApplicableConditionals(action, problem.Objects))
                {
                    // Loop through every conditional's effects.
                    foreach (IPredicate effect in conditional.Effects)
                    {
                        // Loop through every spanning link.
                        foreach (IDependency link in spanningLinks)
                        {
                            // If the effect is the inverse of the protected predicate...
                            if (effect.IsInverse(link.Predicate))
                            {
                                // Identify the exceptional effect.
                                if (exceptionalEffects.ContainsKey(action.Predicate.ToString()))
                                {
                                    List <IPredicate> list = exceptionalEffects[action.Predicate.ToString()] as List <IPredicate>;
                                    list.Add(effect.Clone() as Predicate);
                                    exceptionalEffects[action.Predicate.ToString()] = list;
                                }
                                else
                                {
                                    exceptionalEffects[action.Predicate.ToString()] = new List <IPredicate> {
                                        effect.Clone() as Predicate
                                    }
                                };

                                // Add the current action to the list of exceptional actions.
                                exceptionalActions.Add(new StateSpaceEdge(action.Clone() as Operator, ActionType.Exceptional));

                                // Add the actual action to the exception list.
                                exceptions.Add(action);
                            }
                        }
                    }
                }
            }

            // Remove the exceptions from the possible actions.
            foreach (Operator exception in exceptions)
            {
                possibleActions.Remove(exception);
            }

            // This is a hack to remove duplicate exceptional actions with a Remove By Property method.
            List <int> remove = new List <int>();

            // Remove duplicate actions.
            for (int i = 0; i < exceptionalActions.Count - 1; i++)
            {
                for (int j = i + 1; j < exceptionalActions.Count; j++)
                {
                    if (exceptionalActions[i].Action.Equals(exceptionalActions[j].Action))
                    {
                        remove.Add(j);
                    }
                }
            }

            for (int i = exceptionalActions.Count - 1; i >= 0; i--)
            {
                if (remove.Contains(i))
                {
                    exceptionalActions.RemoveAt(i);
                }
                else
                {
                    exceptionalActions[i].Action.ExceptionalEffects = exceptionalEffects[exceptionalActions[i].Action.Predicate.ToString()] as List <IPredicate>;
                }
            }

            // Create an empty list of consistent actions.
            List <StateSpaceEdge> consistentActions = new List <StateSpaceEdge>();

            // Loop through the remaining actions.
            foreach (Operator action in possibleActions)
            {
                // Add the current action to the list of consistent actions.
                consistentActions.Add(new StateSpaceEdge(action.Clone() as Operator, ActionType.Consistent));
            }

            // Make the set of outgoing edges.
            List <StateSpaceEdge> actions = new List <StateSpaceEdge>();

            // Find the current constituent action.
            StateSpaceEdge constituent = GetConstituentAction(domain, problem, plan, state);

            // Add the constituent action to the possible actions.
            actions.Add(constituent);

            // Remove any exceptional actions that correspond to the constituent step.
            foreach (StateSpaceEdge exception in exceptionalActions)
            {
                if (!exception.Action.Equals(constituent.Action))
                {
                    actions.Add(exception);
                }
            }

            // Remove any exceptional actions that correspond to the constituent step.
            foreach (StateSpaceEdge consistent in consistentActions)
            {
                if (!consistent.Action.Equals(constituent.Action))
                {
                    actions.Add(consistent);
                }
            }

            // Return the outgoing edges.
            return(actions);
        }
예제 #5
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);
        }
예제 #6
0
        // Rewrites history to remove harmful conditional effects.
        public static StateSpaceNode RemoveConditionalEffects(Planner planner, Domain domain, Problem problem, Plan plan, State state, StateSpaceEdge edge, int depth)
        {
            // Store the incoming action.
            Operator incoming = edge.Action as Operator;

            // Create a new plan object.
            Plan newPlan = new Plan();

            // Examine each exceptional effect.
            foreach (Predicate effect in incoming.ExceptionalEffects)
            {
                // Create a new domain object.
                Domain newDomain = new Domain();

                // Save the domain's name.
                newDomain.Name        = domain.Name;
                newDomain.staticStart = domain.staticStart;

                // If the current effect is conditional...
                if (incoming.IsConditional(effect))
                {
                    // If the conditional effect has not been observed by the player.

                    // Remove the conditional effect from the domain.

                    // Copy the current operator templates into a list.
                    List <IOperator> templates = new List <IOperator>();
                    foreach (IOperator templ in domain.Operators)
                    {
                        templates.Add(templ.Clone() as IOperator);
                    }

                    // Create a clone of the incoming action's unbound operator template.
                    IOperator temp = incoming.Template() as Operator;

                    // Find the incoming action template in the domain list.
                    Operator template = templates.Find(t => t.Equals(temp)) as Operator;

                    // Remove the incoming action template from the domain list.
                    templates.Remove(template);

                    // Create a clone of the incoming action.
                    Operator clone = incoming.Clone() as Operator;

                    // Create a list of conditional effects to remove from the template.
                    List <IAxiom> remove = new List <IAxiom>();
                    foreach (IAxiom conditional in clone.Conditionals)
                    {
                        if (conditional.Effects.Contains(effect))
                        {
                            remove.Add(conditional);
                        }
                    }

                    // Remove each conditional effect from the template.
                    foreach (IAxiom rem in remove)
                    {
                        template.Conditionals.Remove(rem.Template() as IAxiom);
                    }

                    // Add the modified template to the domain list.
                    templates.Add(template);

                    // Push the modified list to the new domain object.
                    newDomain.Operators = templates;

                    // Write new problem and domain files.
                    Writer.ProblemToPDDL(Parser.GetTopDirectory() + @"Benchmarks/" + domain.Name.ToLower() + @"/probrob.pddl", newDomain, problem, state.Predicates);
                    Writer.DomainToPDDL(Parser.GetTopDirectory() + @"Benchmarks/" + domain.Name.ToLower() + @"/domrob.pddl", newDomain);

                    // Find a new plan.
                    if (planner.Equals(Planner.FastDownward))
                    {
                        newPlan = FastDownward.Plan(newDomain, problem);
                    }
                    else if (planner.Equals(Planner.Glaive))
                    {
                        newPlan = Glaive.Plan(newDomain, problem);
                    }

                    // If the modified domain can accommodate the player's action...
                    if (newPlan.Steps.Count > 0)
                    {
                        // Clone the modified incoming action template.
                        Operator newAction = template.Clone() as Operator;

                        // Bind the cloned action with the incoming action's bindings.
                        newAction.Bindings = incoming.Bindings;

                        // Push the modified action to the edge object.
                        edge.Action = newAction;

                        // Expand the tree using the new domain.
                        return(ExpandTree(planner, newDomain, problem, plan, state, edge, depth));
                    }
                }
            }

            return(null);
        }
예제 #7
0
 // Rewrites history using alibi generation.
 public static StateSpaceNode GenerateAlibi(Planner planner, Domain domain, Problem problem, Plan plan, State state, StateSpaceEdge edge, int depth)
 {
     return(RemoveConditionalEffects(planner, domain, problem, plan, state, edge, depth));
 }
예제 #8
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);
        }