Exemplo n.º 1
0
        /// <summary>
        /// Given a planner, a mediation tree node, and a mediation tree, return an event revision plan and state to set for the node.
        /// </summary>
        /// <param name="planner">The planner to use.</param>
        /// <param name="node">The current node in the mediation tree.</param>
        /// <param name="tree">The mediation tree.</param>
        /// <returns>A plan state pair for the current node.</returns>
        public static void EventRevision(Planner planner, MediationTreeNode node, MediationTree tree)
        {
            // Compute the event revision problem and domain for the current node.
            Tuple <Domain, Problem> pair = GetEventRevisionPair(node, tree);

            // Use the planner to find an event revision plan.
            Plan plan = PlannerInterface.Plan(planner, pair.First, pair.Second);

            if (plan.Steps.Count > 0)
            {
                Tuple <Plan, State> planState = GetPlanStatePair(plan, node, tree);
                node.Plan            = planState.First;
                node.State           = planState.Second;
                node.Problem.Initial = node.State.Predicates;
            }
        }
Exemplo n.º 2
0
        public static void DomainRevision(Planner planner, MediationTreeNode node, MediationTree tree)
        {
            // Store the incoming action.
            Operator incoming = node.Incoming.Action as Operator;

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

            List <Tuple <Operator, State> > knowledge = EventRevisor.GetWorldKnowledge(tree.Player, node, tree);

            knowledge.RemoveAt(knowledge.Count - 1);
            List <Operator> observedActions = new List <Operator>();

            foreach (Tuple <Operator, State> pair in knowledge)
            {
                if (pair.First != null)
                {
                    if (pair.First.Name.Equals(incoming.Name))
                    {
                        observedActions.Add(pair.First);
                    }
                }
            }

            // Examine each exceptional effect.
            foreach (Predicate effect in incoming.ExceptionalEffects)
            {
                // Create a new domain object.
                Domain newDomain = node.Domain.Clone() as Domain;
                newDomain.Operators = new List <IOperator>();

                // If the current effect is conditional...
                if (incoming.IsConditional(effect))
                {
                    bool observed = false;

                    // If the conditional effect has not been observed by the player.
                    foreach (Operator action in observedActions)
                    {
                        if (!observed)
                        {
                            foreach (IAxiom conditional in action.Conditionals)
                            {
                                if (conditional.Effects.Contains(effect) && !observed)
                                {
                                    observed = true;
                                }
                            }
                        }
                    }

                    // Remove the conditional effect from the domain.

                    if (!observed)
                    {
                        // Copy the current operator templates into a list.
                        List <IOperator> templates = new List <IOperator>();
                        foreach (IOperator templ in node.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;

                        // 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;

                        MediationTreeEdge newEdge = new MediationTreeEdge(newAction, ActionType.Exceptional, node.Incoming.Parent, node.ID);

                        Problem newProblem = node.Problem.Clone() as Problem;
                        newProblem.Initial = tree.GetSuccessorState(newEdge).Predicates;

                        // Find a new plan.
                        newPlan = PlannerInterface.Plan(planner, newDomain, newProblem);

                        // If the modified domain can accommodate the player's action...
                        if (newPlan.Steps.Count > 0)
                        {
                            node.Plan            = newPlan;
                            node.Incoming.Action = newAction;
                            node.State           = tree.GetSuccessorState(node.Incoming);
                            node.Domain          = newDomain;
                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Given an event revision plan, a mediation tree node, and a mediation tree, returns the plan and state to set in the node.
        /// </summary>
        /// <param name="plan">The full event revision plan from the original initial state.</param>
        /// <param name="node">The current node in the mediation tree.</param>
        /// <param name="tree">The mediation tree object.</param>
        /// <returns>The current state to set in the node after event revision and the plan from the state forward.</returns>
        public static Tuple <Plan, State> GetPlanStatePair(Plan plan, MediationTreeNode node, MediationTree tree)
        {
            // Reformat the event revision plan to get a regular plan.
            Plan formattedPlan = ReformatPlan(plan, tree.Root.Domain, tree.Root.Problem);

            // Create a list to hold event revision steps.
            List <IOperator> pastSteps = new List <IOperator>();

            // Create another list to hold future plan steps.
            List <IOperator> futureSteps = new List <IOperator>();

            // Loop through the steps in the formatted event revision plan...
            for (int i = 0; i < formattedPlan.Steps.Count; i++)
            {
                // If the step happened before the current state, it is an event revision step.
                if (i < node.Depth)
                {
                    pastSteps.Add(formattedPlan.Steps[i]);
                }
                // If the step happens at or after the current state, it is a future plan step.
                else
                {
                    futureSteps.Add(formattedPlan.Steps[i]);
                }
            }

            // Create a new state object by cloning the initial state of the original planning problem.
            State current = tree.Root.State.Clone() as State;

            // Loop through each of the event revision steps...
            foreach (IOperator step in pastSteps)
            {
                // And update the state object by applying the action.
                current = new State(current.ApplyAction(step as Operator, node.Problem.Objects));
            }

            // Return the future plan along with the computed state.
            return(new Tuple <Plan, State>(new Plan(node.Domain, node.Problem, futureSteps), current));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Given a character, node, and tree, returns the character's knowledge of the world history.
        /// </summary>
        /// <param name="character">The character.</param>
        /// <param name="node">The node that corresponds to the current state.</param>
        /// <param name="tree">The mediation tree.</param>
        /// <returns>A list of action-state pairs that represent what the character knows.</returns>
        public static List <Tuple <Operator, State> > GetWorldKnowledge(string character, MediationTreeNode node, MediationTree tree)
        {
            // An object to hold the character's knowledge of the world history.
            List <Tuple <Operator, State> > knowledge = new List <Tuple <Operator, State> >();

            // Get the objective world history.
            List <MediationTreeNode> history = GetWorldHistory(node, tree);

            // Loop through the nodes in the world history branch...
            foreach (MediationTreeNode current in history)
            {
                // Create a new action.
                Operator action = null;

                // Make sure the current node is not the root.
                if (current.Incoming != null)
                {
                    // Check if the character observes the incoming action.
                    if (KnowledgeAnnotator.Observes(character, current.Incoming.Action, current.State.Predicates))
                    {
                        // If so, remember that the character observed the action.
                        action = current.Incoming.Action.Clone() as Operator;
                    }
                }

                // Create a new state consisting only of terms the character observed.
                State state = new State(KnowledgeAnnotator.FullKnowledgeState(tree.Root.Domain.Predicates, tree.Root.Problem.ObjectsByType, current.State.Predicates, character));

                // Store the observed action-state pair as a tuple.
                knowledge.Add(new Tuple <Operator, State>(action, state));
            }

            // Return the sequence of observed action-state pairs.
            return(knowledge);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Given a mediation tree and a node in the tree, returns the node's world history.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="tree">The tree.</param>
        /// <returns>The path through the tree from the root to the node.</returns>
        public static List <MediationTreeNode> GetWorldHistory(MediationTreeNode node, MediationTree tree)
        {
            // Create an empty list object to hold the history.
            List <MediationTreeNode> history = new List <MediationTreeNode>();

            // Add the node to the world history.
            history.Add(node);

            // Remember the current node's ID.
            int current = node.ID;

            // While the current node's parent is not null...
            while (tree.GetParent(current) != -1)
            {
                // Store the current node's parent object.
                MediationTreeNode parent = tree.GetNode(tree.GetParent(current));

                // Remember the parent's ID.
                current = parent.ID;

                // Insert the parent node into the world history.
                history.Insert(0, parent);
            }

            // Return the world history.
            return(history);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Given a mediation tree and a node in the tree, returns a event revision domain and problem.
        /// </summary>
        /// <param name="node">The mediation tree node.</param>
        /// <param name="tree">The mediation tree.</param>
        /// <returns>The event revision problem and domain for the node.</returns>
        public static Tuple <Domain, Problem> GetEventRevisionPair(MediationTreeNode node, MediationTree tree)
        {
            // Create a clone of the node's original domain.
            Domain revisionDomain = node.Domain.Clone() as Domain;

            // Create a clone of the node's original problem.
            Problem revisionProblem = tree.Root.Problem.Clone() as Problem;

            // Get the series of actions and state literals the player has observed.
            List <Tuple <Operator, State> > playerKnowledge = GetWorldKnowledge(tree.Player, node, tree);

            // Rename the problem to the automated slot.
            revisionProblem.Name = "rob";

            // Add the initial state tracking literal to the problem's initial state.
            revisionProblem.Initial.Add(new Predicate("state-depth", new List <ITerm> {
                new Term("depth1", true)
            }, true));

            revisionDomain.AddTypePair("depth", "state");
            revisionDomain.Predicates.Add(new Predicate("state-depth", new List <ITerm> {
                new Term("?depth", "", "state")
            }, true));

            // For every operator in the cloned domain...
            foreach (Operator op in revisionDomain.Operators)
            {
                // Add a state tracking precondition that prevents it from being applied until after the event revision operations have been performed.
                op.Preconditions.Add(new Predicate("state-depth", new List <ITerm> {
                    new Term("depth" + playerKnowledge.Count.ToString(), true)
                }, true));
            }

            // Loop through the action-state pairs in the player knowledge.
            for (int i = 1; i < playerKnowledge.Count; i++)
            {
                // For each of these, add a new state tracker to the list of objects.
                revisionProblem.Objects.Add(new Obj("depth" + i.ToString(), "depth"));

                // If the player did not observed the current action, add a set of unobserved templates to the list of operators.
                if (playerKnowledge[i].First == null)
                {
                    revisionDomain.Operators.AddRange(GetUnobservedActionTemplates(i, tree.GetTurnAtIndex(i - 1), node.Domain, playerKnowledge[i - 1].Second));
                }
                // If the player did observe the current action, add the observed template to the list of operators.
                else
                {
                    revisionDomain.Operators.Add(GetObservedActionTemplate(i, playerKnowledge[i].First));
                }
            }

            // Add the final state tracking object to the problem.
            revisionProblem.Objects.Add(new Obj("depth" + playerKnowledge.Count.ToString(), "depth"));

            // Return the domain-problem pair.
            return(new Tuple <Domain, Problem> (revisionDomain, revisionProblem));
        }