/// <summary>
        /// Applies backwards the relevant operator effects and operator preconditions to the given target relative state.
        /// </summary>
        /// <param name="relativeState">Target relative state to be modified.</param>
        /// <param name="operatorSubstitution">Variables substitution.</param>
        /// <returns>Preceding relative states.</returns>
        public IEnumerable <Planner.IRelativeState> ApplyBackwards(IRelativeState relativeState, ISubstitution operatorSubstitution)
        {
            OperatorSubstitution = operatorSubstitution;
            Effects.GroundEffectsByCurrentOperatorSubstitution(GroundingManager, operatorSubstitution);

            relativeState = (IRelativeState)relativeState.Clone();

            // prepare operator preconditions
            var operatorPreconditions = (OperatorPreconditions != null) ? GroundingManager.GroundConditions(ClearRigidRelations(OperatorPreconditions), OperatorSubstitution) : null;

            // remove positively contributing effects from the relative state and insert the operator preconditions
            ProcessPrimitiveEffects(relativeState);
            relativeState = ProcessForallEffects(relativeState);
            foreach (var resultState in ProcessWhenEffects(relativeState))
            {
                if (operatorPreconditions != null)
                {
                    foreach (var modifiedResultState in ProcessOperatorPreconditions(operatorPreconditions, resultState))
                    {
                        yield return(modifiedResultState);
                    }
                }
                else
                {
                    yield return(resultState);
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Applies the operator backwards to the given target relative state. The result is a new relative state (or more relative states, if conditional effects are present).
        /// </summary>
        /// <param name="relativeState">Relative state for the application.</param>
        /// <param name="operatorPreconditions">Operator preconditions.</param>
        /// <returns>Preceding relative states.</returns>
        public IEnumerable <IRelativeState> ApplyBackwards(IRelativeState relativeState, ISimpleConditions operatorPreconditions)
        {
            IRelativeState result = (IRelativeState)relativeState.Clone();

            bool anyConditionalEffect = false;

            foreach (var effect in this)
            {
                if (effect.GetConditions() == null)
                {
                    result = effect.ApplyBackwards(result);
                }
                else
                {
                    anyConditionalEffect = true;
                }
            }

            foreach (var constraint in operatorPreconditions)
            {
                result.SetValue(constraint.GetVariable(), constraint.GetValue());
            }

            if (!anyConditionalEffect)
            {
                yield return(result);
            }
            else
            {
                List <IRelativeState> states = new List <IRelativeState> {
                    result
                };

                foreach (var effect in this)
                {
                    if (effect.GetConditions() != null)
                    {
                        int statesCount = states.Count;
                        for (int i = 0; i < statesCount; ++i)
                        {
                            var newEffect = effect.ApplyBackwards(states[i]);
                            if (newEffect != null)
                            {
                                states.Add(newEffect);
                            }
                        }
                    }
                }

                foreach (var state in states)
                {
                    yield return(state);
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Applies the effect backwards to the given relative state.
        /// </summary>
        /// <param name="relativeState">Relative state.</param>
        public override IRelativeState ApplyBackwards(IRelativeState relativeState)
        {
            // we explicitly apply the effect for the relative state, if it's relevant
            if (IsRelevant(relativeState) == EffectRelevance.RELEVANT)
            {
                var newState = (IRelativeState)relativeState.Clone();

                newState.SetValue(Assignment.GetVariable(), RelativeState.WildCardValue);
                foreach (var constraint in Conditions)
                {
                    newState.SetValue(constraint.GetVariable(), constraint.GetValue());
                }

                return(newState);
            }

            // the conditional effect was not applied, because it was not relevant
            return(null);
        }
Exemple #4
0
        /// <summary>
        /// Generates all possible PDDL relative states meeting given CNF conditions (in the form of a list of conjuncts). Lazy generated recursively via yield return.
        /// </summary>
        /// <param name="index">Current index in the conjuncts list.</param>
        /// <param name="conjuncts">List of conjuncts of the CNF conditions.</param>
        /// <param name="result">Current relative state being built.</param>
        /// <returns>All possible PDDL relative states meeting the CNF conditions.</returns>
        private static IEnumerable <IRelativeState> EnumerateRelativeStatesByCNF(int index, List <IConjunctCNF> conjuncts, IRelativeState result)
        {
            if (index == 0)
            {
                // the constructed state can have trailing values from the previous unfinished enumeration!
                result.ClearContent();
            }

            Action <IRelativeState, LiteralCNF> addLiteral = (state, literal) =>
            {
                // Note: At the moment, there is limited support for object and numeric function assignments.
                // For example, numeric comparison literals like (< (numFunc) 5) will be omitted in the resulting relative state.

                PredicateLiteralCNF predicateLiteral = literal as PredicateLiteralCNF;
                if (predicateLiteral != null)
                {
                    if (literal.IsNegated)
                    {
                        state.AddNegatedPredicate(predicateLiteral.PredicateAtom.Clone());
                    }
                    else
                    {
                        state.AddPredicate(predicateLiteral.PredicateAtom.Clone());
                    }
                    return;
                }

                EqualsLiteralCNF equalsLiteral = literal as EqualsLiteralCNF;
                if (equalsLiteral != null)
                {
                    var assignment = equalsLiteral.TryGetObjectFunctionAssignment();
                    if (assignment != null)
                    {
                        if (!literal.IsNegated)
                        {
                            state.AssignObjectFunction(assignment.Item1.FunctionAtom.Clone(), assignment.Item2.NameId);
                        }
                    }
                    return;
                }

                NumericCompareLiteralCNF compareLiteral = literal as NumericCompareLiteralCNF;
                if (compareLiteral != null)
                {
                    var assignment = compareLiteral.TryGetNumericFunctionAssignment();
                    if (assignment != null)
                    {
                        if (!compareLiteral.IsNegated)
                        {
                            state.AssignNumericFunction(assignment.Item1.FunctionAtom.Clone(), assignment.Item2.Value);
                        }
                    }
                }
            };

            Action <IRelativeState, LiteralCNF> removeLiteral = (state, literal) =>
            {
                PredicateLiteralCNF predicateLiteral = literal as PredicateLiteralCNF;
                if (predicateLiteral != null)
                {
                    if (literal.IsNegated)
                    {
                        state.RemoveNegatedPredicate(predicateLiteral.PredicateAtom.Clone());
                    }
                    else
                    {
                        state.RemovePredicate(predicateLiteral.PredicateAtom.Clone());
                    }
                    return;
                }

                EqualsLiteralCNF equalsLiteral = literal as EqualsLiteralCNF;
                if (equalsLiteral != null)
                {
                    var assignment = equalsLiteral.TryGetObjectFunctionAssignment();
                    if (assignment != null)
                    {
                        if (!literal.IsNegated)
                        {
                            state.AssignObjectFunction(assignment.Item1.FunctionAtom.Clone(), ObjectFunctionTerm.UndefinedValue);
                        }
                    }
                    return;
                }

                NumericCompareLiteralCNF compareLiteral = literal as NumericCompareLiteralCNF;
                if (compareLiteral != null)
                {
                    var assignment = compareLiteral.TryGetNumericFunctionAssignment();
                    if (assignment != null)
                    {
                        if (!compareLiteral.IsNegated)
                        {
                            state.AssignNumericFunction(assignment.Item1.FunctionAtom.Clone(), NumericFunction.UndefinedValue);
                        }
                    }
                }
            };

            if (index >= conjuncts.Count)
            {
                yield return((IRelativeState)result.Clone());
            }
            else
            {
                var conjunct = conjuncts[index];

                ClauseCNF clause = conjunct as ClauseCNF;
                if (clause != null)
                {
                    foreach (var literal in clause)
                    {
                        addLiteral(result, literal);

                        foreach (var item in EnumerateRelativeStatesByCNF(index + 1, conjuncts, result))
                        {
                            yield return(item);
                        }

                        removeLiteral(result, literal);
                    }
                }
                else
                {
                    LiteralCNF literal = conjunct as LiteralCNF;
                    Debug.Assert(literal != null);

                    addLiteral(result, literal);

                    foreach (var item in EnumerateRelativeStatesByCNF(index + 1, conjuncts, result))
                    {
                        yield return(item);
                    }

                    removeLiteral(result, literal);
                }
            }
        }