示例#1
0
        /// <summary>
        /// Allows custom plans to be passed in.
        /// </summary>
        /// <param name="domain">The node's domain.</param>
        /// <param name="problem">The node's problem.</param>
        /// <param name="incoming">The node's incoming edge.</param>
        /// <returns>A new tree node.</returns>
        private MediationTreeNode CreateNode(Domain domain, Problem problem, MediationTreeEdge incoming, Plan plan)
        {
            // Create a placeholder for the new node object.
            MediationTreeNode node = null;

            // If the node is a root, initialize a root node.
            if (incoming == null)
            {
                if (!data.superpositionManipulation)
                {
                    node = new MediationTreeNode(domain, problem, 0);
                }
                else
                {
                    node = new VirtualMediationTreeNode(domain, problem, 0);
                }
            }
            // Otherwise, it is a child node...
            else
            {
                // Store the current node's ID in the incoming edge.
                incoming.Child = ++data.nodeCounter;

                if (!data.superpositionManipulation)
                {
                    node = new MediationTreeNode(domain, problem, incoming, GetSuccessorState(incoming), plan, incoming.Child, GetDepth(incoming.Parent) + 1);
                }
                else
                {
                    node = new VirtualMediationTreeNode(domain, problem, incoming, GetSuccessorSuperposition(incoming), plan, incoming.Child, GetDepth(incoming.Parent) + 1);
                }

                // Add the edge to the tree hashtable.
                data.tree[incoming.Child] = incoming.Parent;

                MediationTreeNode parent = GetNode(incoming.Parent);
                if (incoming.Action != null)
                {
                    parent.Outgoing.Find(x => x.Action.Equals(incoming.Action)).Child = node.ID;
                }
                else
                {
                    foreach (MediationTreeEdge edge in parent.Outgoing)
                    {
                        if (edge is VirtualMediationTreeEdge)
                        {
                            if ((edge as VirtualMediationTreeEdge).Equals(incoming as VirtualMediationTreeEdge))
                            {
                                edge.Child = node.ID;
                            }
                        }
                    }
                }

                SetNode(parent);

                if (data.superpositionManipulation)
                {
                    Superposition super = node.State as Superposition;
                    super.States = SuperpositionManipulator.Collapse(data.player, node as VirtualMediationTreeNode, SuperpositionChooser.ChooseUtility);
                    node.State   = super;
                }
            }

            // If the node is a goal state, iterate the goal state counter.
            if (node.IsGoal)
            {
                data.goalStateCount++;
            }

            // If the node is a dead end, iterate the dead end counter.
            if (node.DeadEnd)
            {
                if (data.eventRevision)
                {
                    EventRevisor.EventRevision(Planner.FastDownward, node, this);
                }

                if (node.DeadEnd && data.domainRevision)
                {
                    DomainRevisor.DomainRevision(Planner.FastDownward, node, this);
                }

                if (node.DeadEnd)
                {
                    data.deadEndCount++;
                }
            }

            // If the node is at a lower depth than the previous record holder, update the depth counter.
            if (node.Depth > data.lowestDepth)
            {
                data.lowestDepth = node.Depth;
            }

            // If the node is not a dead end.
            if (!node.DeadEnd)
            {
                // Find and store the node's outgoing edges.
                node.Outgoing = GetOutgoingEdges(node, GetCurrentTurn(node));
            }

            // Save the current node to disk.
            SetNode(node);

            // Return the current node object.
            return(node);
        }
示例#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;
                        }
                    }
                }
            }
        }