Exemple #1
0
        // Creates and reads a plan into an object.
        public static Plan Plan(Planner planner, Domain domain, Problem problem)
        {
            if (planner.Equals(Planner.FastDownward))
            {
                return(FastDownward.Plan(domain, problem));
            }
            else if (planner.Equals(Planner.FDMulti))
            {
                return(FDMulti.Plan(domain, problem));
            }
            else if (planner.Equals(Planner.Glaive))
            {
                return(Glaive.Plan(domain, problem));
            }

            return(null);
        }
Exemple #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.
                if (planner.Equals(Planner.FastDownward))
                {
                    newPlan = FastDownward.Plan(newDomain, newProblem);
                }
                else if (planner.Equals(Planner.Glaive))
                {
                    newPlan = Glaive.Plan(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.
                        if (planner.Equals(Planner.FastDownward))
                        {
                            newPlan = FastDownward.Plan(newDomain, newProblem);
                        }
                        else if (planner.Equals(Planner.Glaive))
                        {
                            newPlan = Glaive.Plan(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);
        }
Exemple #3
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);
        }
Exemple #4
0
        /// <summary>
        /// An online text-based command line game that is a traversal of mediation space.
        /// </summary>
        /// <param name="domainName">The game domain.</param>
        /// <param name="debug">Whether or not debug mode is enabled.</param>
        public static void Play()
        {
            Console.Clear();
            string domainName = "";

            // Make sure the file exists.
            while
            (!File.Exists(Parser.GetTopDirectory() + @"Benchmarks\" + domainName + @"\domain.pddl") ||
             !File.Exists(Parser.GetTopDirectory() + @"Benchmarks\" + domainName + @"\prob01.pddl"))
            {
                // Prompt the user for game name.
                Console.WriteLine("What would you like to play?");
                Console.WriteLine("     Type 'exit' to end program.");
                Console.WriteLine("     Type 'path' to modify the directory.");
                Console.WriteLine("     Type 'planner' to choose the planner.");
                Console.WriteLine("     Type 'help' to print game titles.");
                Console.Write("     Type 'debug' to turn debug mode ");
                if (debug)
                {
                    Console.WriteLine("off.");
                }
                else
                {
                    Console.WriteLine("on.");
                }
                Console.WriteLine();
                Console.Write(">");

                // Read in the game to load.
                domainName = Console.ReadLine().ToLower();

                // Print domains if prompted.
                if (domainName.Equals("help"))
                {
                    Console.WriteLine();
                    if (System.IO.Directory.Exists(Parser.GetTopDirectory() + @"Benchmarks\"))
                    {
                        foreach (string file in Directory.GetFileSystemEntries(Parser.GetTopDirectory() + @"Benchmarks\"))
                        {
                            Console.WriteLine(Path.GetFileName(file));
                        }

                        Console.WriteLine();
                        Console.Write(">");

                        // Read in the game to load.
                        domainName = Console.ReadLine().ToLower();
                    }
                    else
                    {
                        Console.WriteLine(Parser.GetTopDirectory() + @"Benchmarks\ does not exist!");
                        Console.ReadKey();
                        domainName = "482990adkdlllifkdlkfjlaoow";
                    }
                }

                // Rewrite directory if prompted.
                if (domainName.Equals("path"))
                {
                    Console.WriteLine();
                    Console.WriteLine("Your current game directory is: " + Parser.GetTopDirectory());
                    Console.WriteLine("Enter new path.");
                    Console.WriteLine();
                    Console.Write(">");
                    string newPath = Console.ReadLine();
                    Console.WriteLine();

                    if (Directory.Exists(newPath + @"Benchmarks\"))
                    {
                        Parser.path = newPath;
                    }
                    else
                    {
                        Console.WriteLine("Sorry, " + newPath + @"Benchmarks\" + " does not exist.");
                        Console.ReadKey();
                    }
                }

                // Change the planner if prompted.
                if (domainName.Equals("planner"))
                {
                    Console.WriteLine();
                    Console.WriteLine("Your current planner is: " + planner);
                    Console.WriteLine("Enter new planner.");
                    Console.WriteLine();
                    Console.Write(">");
                    string newPlanner = Console.ReadLine();
                    Console.WriteLine();

                    if (Enum.IsDefined(typeof(Planner), newPlanner))
                    {
                        planner = (Planner)Enum.Parse(typeof(Planner), newPlanner, true);
                        Console.WriteLine("Your planner is now " + planner);
                        Console.ReadKey();
                    }
                    else
                    {
                        Console.WriteLine("Sorry, " + newPlanner + " does not exist.");
                        Console.ReadKey();
                    }
                }

                // Exit if prompted.
                if (domainName.Equals("exit"))
                {
                    Environment.Exit(0);
                }

                // Toggle debug if prompted
                if (domainName.Equals("debug"))
                {
                    debug = !debug;
                }

                if
                ((!File.Exists(Parser.GetTopDirectory() + @"Benchmarks\" + domainName + @"\domain.pddl") ||
                  !File.Exists(Parser.GetTopDirectory() + @"Benchmarks\" + domainName + @"\prob01.pddl")) &&
                 !domainName.Equals("debug") && !domainName.Equals("path") && !domainName.Equals("planner") && !domainName.Equals("482990adkdlllifkdlkfjlaoow"))
                {
                    // Prompt that the game doesn't exist.
                    Console.WriteLine();
                    Console.WriteLine("I'm sorry, but I can't find " + domainName.ToUpper());
                    Console.WriteLine();
                    Console.ReadKey();
                }

                // Clear the console screen.
                Console.Clear();
            }

            // Parse the domain file.
            domain = Parser.GetDomain(Parser.GetTopDirectory() + @"Benchmarks\" + domainName + @"\domain.pddl", PlanType.StateSpace);

            // Parse the problem file.
            problem = Parser.GetProblemWithTypes(Parser.GetTopDirectory() + @"Benchmarks\" + domainName + @"\prob01.pddl", domain);

            // Find the initial plan.
            if (planner.Equals(Planner.FastDownward))
            {
                plan = FastDownward.Plan(domain, problem);
            }
            else if (planner.Equals(Planner.Glaive))
            {
                plan = Glaive.Plan(domain, problem);
            }

            // Welcome the player to the game.
            Console.WriteLine("Welcome to " + domain.Name);

            // Find the first state.
            state = plan.GetFirstState();

            // Create the initial node of mediation space.
            root = StateSpaceMediator.BuildTree(planner, domain, problem, plan, state, 0);

            // Initialize a stopwatch for debugging.
            Stopwatch watch = new Stopwatch();

            // Present information about the player.
            command   = "look";
            arguments = new List <string> {
                "me"
            };
            Look();
            Console.WriteLine();

            // Present the initial state.
            command = "";
            Look();

            // Loop while this is false.
            bool exit = false;

            while (!exit)
            {
                // Initialize the frontier.
                frontier = new Hashtable();

                // Expand the frontier in a new thread.
                frontierThread = new Thread(ExpandFrontier);

                // Start the thread.
                frontierThread.Start();

                // Ask for input.
                Console.WriteLine();
                Console.Write(">");
                input = Console.ReadLine();

                // If in debug mode, start the stop watch.
                if (debug)
                {
                    watch.Reset();
                    watch.Start();
                }

                // Parse the command and its arguments.
                command   = ParseCommand(input).ToLower();
                arguments = ParseArguments(input);

                // Interpret the command.
                switch (command)
                {
                case "exit":
                    exit = true;
                    break;

                case "clear":
                    Console.Clear();
                    break;

                case "cls":
                    Console.Clear();
                    break;

                case "look":
                    Look();
                    break;

                case "help":
                    Help();
                    break;

                case "wait":
                    Console.Clear();
                    Wait();
                    break;

                default:
                    OneArg();
                    break;
                }

                // If debugging, write the current plan and the elapsed time.
                if (debug && plan.Steps.Count > 0 && !command.Equals("clear") && !command.Equals("cls"))
                {
                    Console.Out.WriteLine();
                    Console.WriteLine("Narrative Trajectory:");
                    int longestName = 0;
                    foreach (Operator step in plan.Steps)
                    {
                        if (step.TermAt(0).Length > longestName)
                        {
                            longestName = step.TermAt(0).Length;
                        }
                    }
                    string lastName = "";
                    foreach (Operator step in plan.Steps)
                    {
                        if (!step.TermAt(0).Equals(lastName))
                        {
                            lastName = step.TermAt(0);
                            Console.Out.Write("".PadLeft(5) + UppercaseFirst(step.TermAt(0)) + "".PadLeft(longestName - step.TermAt(0).Length + 1));
                        }
                        else
                        {
                            Console.Out.Write("".PadLeft(5) + "".PadLeft(longestName + 1));
                        }

                        string[] splitName = step.Name.Split('-');
                        Console.Out.Write(splitName[0] + "s ");
                        for (int i = 1; i < step.Name.Count(x => x == '-') + 1; i++)
                        {
                            Console.Out.Write(UppercaseFirst(step.TermAt(i)) + " ");
                        }
                        Console.Out.WriteLine();
                    }
                    Console.Out.WriteLine();
                    Console.Write("Elapsed time: ");
                    Console.Out.Write(watch.ElapsedMilliseconds);
                    Console.WriteLine("ms");
                }

                // Check for goal state.
                if (root.Goal)
                {
                    Console.WriteLine("GOAL STATE");
                    Console.ReadKey();
                    exit = true;
                }
                // Check for incompatible state.
                else if (root.Incompatible)
                {
                    Console.WriteLine("UNWINNABLE STATE");
                    Console.ReadKey();
                    exit = true;
                }

                if (exit)
                {
                    Console.Clear();
                }

                // Kill the frontier thread (this should be okay).
                frontierThread.Abort();
            }

            Game.Play();
        }