/// <summary>
        /// Processes forall effects.
        /// </summary>
        /// <param name="relativeState">Relative state.</param>
        /// <returns>Effect relevance (relevant, irrelevant, or anti-relevant).</returns>
        private EffectRelevance ProcessForallEffects(IRelativeState relativeState)
        {
            bool anyRelevant = false;

            foreach (var forallEffect in Effects.ForallEffects)
            {
                EffectsRelevanceRelativeStateEvaluator evaluator = new EffectsRelevanceRelativeStateEvaluator(forallEffect.Effects, GroundingManager);

                IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(forallEffect.Parameters);
                foreach (var localSubstitution in localSubstitutions)
                {
                    OperatorSubstitution.AddLocalSubstitution(localSubstitution);

                    var result = evaluator.EvaluateInternal(relativeState, OperatorSubstitution);
                    anyRelevant |= (result == EffectRelevance.RELEVANT);

                    OperatorSubstitution.RemoveLocalSubstitution(localSubstitution);

                    if (result == EffectRelevance.ANTI_RELEVANT)
                    {
                        return(EffectRelevance.ANTI_RELEVANT);
                    }
                }
            }

            return((anyRelevant) ? EffectRelevance.RELEVANT : EffectRelevance.IRRELEVANT);
        }
        /// <summary>
        /// Processes conditional (when) effects.
        /// </summary>
        /// <param name="relativeState">Relative state.</param>
        /// <param name="relevantConditionalEffects">Output indices of relevant conditional effects (can be null).</param>
        /// <returns>Effect relevance (relevant, irrelevant, or anti-relevant).</returns>
        private EffectRelevance ProcessWhenEffects(IRelativeState relativeState, IList <int> relevantConditionalEffects = null)
        {
            bool anyRelevant     = false;
            int  whenEffectIndex = -1;

            foreach (var whenEffect in Effects.WhenEffects)
            {
                ++whenEffectIndex;

                List <IEffect> subEffects = new List <IEffect>();
                whenEffect.Effects.ForEach(subEffect => subEffects.Add(subEffect));
                EffectsRelevanceRelativeStateEvaluator evaluator = new EffectsRelevanceRelativeStateEvaluator(subEffects, GroundingManager);

                var result = evaluator.EvaluateInternal(relativeState, OperatorSubstitution, relevantConditionalEffects);
                if (result == EffectRelevance.ANTI_RELEVANT)
                {
                    // anti-relevant conditional effect -> can't be used (but it doesn't have to be, we just ignore it)
                    continue;
                }

                if (result == EffectRelevance.RELEVANT)
                {
                    relevantConditionalEffects?.Add(whenEffectIndex);
                    anyRelevant = true;
                }
            }

            return((anyRelevant) ? EffectRelevance.RELEVANT : EffectRelevance.IRRELEVANT);
        }
        /// <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);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Checks whether the operator effect is relevant to the given target relative state.
        /// </summary>
        /// <param name="relativeState">Relative state.</param>
        /// <returns>Effect relevance result.</returns>
        public override EffectRelevance IsRelevant(IRelativeState relativeState)
        {
            var assignmentRelevance = base.IsRelevant(relativeState);

            if (assignmentRelevance == EffectRelevance.RELEVANT)
            {
                foreach (var constraint in Conditions)
                {
                    if (constraint.GetVariable() == Assignment.GetVariable())
                    {
                        continue;
                    }

                    int value = relativeState.GetValue(constraint.GetVariable());
                    if (value == RelativeState.WildCardValue)
                    {
                        continue;
                    }

                    if (constraint.GetValue() != value)
                    {
                        return(EffectRelevance.IRRELEVANT);
                    }
                }
                return(EffectRelevance.RELEVANT);
            }

            // conditional effect does not have to be used, so it should never be explicitly anti-relevant
            return(EffectRelevance.IRRELEVANT);
        }
Example #5
0
        /// <summary>
        /// Checks whether the operator effects are relevant to the given target relative state.
        /// </summary>
        /// <param name="relativeState">Relative state for the application.</param>
        /// <param name="operatorPreconditions">Operator preconditions.</param>
        /// <returns>True if the operator effects are relevant to the given relative state, false otherwise.</returns>
        public bool IsRelevant(IRelativeState relativeState, ISimpleConditions operatorPreconditions)
        {
            CashedVariablesCollector.Clear();

            bool anyRelevant = false;

            foreach (var effect in this)
            {
                var relevance = effect.IsRelevant(relativeState);
                switch (relevance)
                {
                case EffectRelevance.ANTI_RELEVANT:
                {
                    return(false);
                }

                case EffectRelevance.RELEVANT:
                {
                    anyRelevant = true;
                    CashedVariablesCollector.Add(effect.GetAssignment().GetVariable());
                    break;
                }

                case EffectRelevance.IRRELEVANT:
                {
                    if (effect.GetConditions() != null)
                    {
                        CashedVariablesCollector.Add(effect.GetAssignment().GetVariable());
                    }
                    break;
                }
                }
            }

            if (!anyRelevant)
            {
                return(false);
            }

            // additionally, the relative state has to be checked against operator preconditions ("hidden effects")
            foreach (var constraint in operatorPreconditions)
            {
                int variable = constraint.GetVariable();
                if (!CashedVariablesCollector.Contains(variable))
                {
                    int value = relativeState.GetValue(variable);
                    if (value == RelativeState.WildCardValue)
                    {
                        continue;
                    }

                    if (value != constraint.GetValue())
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        /// <summary>
        /// Evaluates whether the operator effects are relevant for the specified relative state.
        /// </summary>
        /// <param name="relativeState">Relative state.</param>
        /// <param name="operatorSubstitution">Variables substitution of the operator.</param>
        /// <param name="relevantConditionalEffects">Output indices of relevant conditional effects (can be null).</param>
        /// <returns>Effect relevance (relevant, irrelevant, or anti-relevant).</returns>
        private EffectRelevance EvaluateInternal(IRelativeState relativeState, ISubstitution operatorSubstitution, IList <int> relevantConditionalEffects = null)
        {
            Effects.GroundEffectsByCurrentOperatorSubstitution(GroundingManager, operatorSubstitution);

            OperatorSubstitution = operatorSubstitution;

            var primitivesResult = ProcessPrimitiveEffects(relativeState);

            if (primitivesResult == EffectRelevance.ANTI_RELEVANT)
            {
                return(EffectRelevance.ANTI_RELEVANT);
            }

            var forallResult = ProcessForallEffects(relativeState);

            if (forallResult == EffectRelevance.ANTI_RELEVANT)
            {
                return(EffectRelevance.ANTI_RELEVANT);
            }

            var whenResult = ProcessWhenEffects(relativeState, relevantConditionalEffects);

            if (whenResult == EffectRelevance.ANTI_RELEVANT)
            {
                return(EffectRelevance.ANTI_RELEVANT);
            }

            if (primitivesResult == EffectRelevance.RELEVANT || forallResult == EffectRelevance.RELEVANT || whenResult == EffectRelevance.RELEVANT)
            {
                return(EffectRelevance.RELEVANT);
            }

            return(EffectRelevance.IRRELEVANT);
        }
 /// <summary>
 /// Gets the heuristic value for the given relative state (in the context of backward search).
 /// </summary>
 /// <param name="relativeState">Relative state to be evaluated.</param>
 /// <returns>Heuristic value for the specified relative state.</returns>
 protected override double GetValueImpl(IRelativeState relativeState)
 {
     if (Random.NextDouble() < Heuristics.First().Item2)
     {
         return(Heuristics.First().Item1.GetValue(relativeState));
     }
     return(Heuristics.Sum(heuristic => heuristic.Item2 * heuristic.Item1.GetValue(relativeState)));
 }
Example #8
0
 /// <summary>
 /// Checks whether the operator is relevant to the given target relative state.
 /// </summary>
 /// <param name="relativeState">Target relative state.</param>
 /// <param name="substitution">Variables substitution.</param>
 /// <param name="relevantConditionalEffects">Output indices of relevant conditional effects (can be null).</param>
 /// <returns>True if the operator is relevant to the given relative state, false otherwise.</returns>
 public bool IsRelevant(IRelativeState relativeState, ISubstitution substitution, IList <int> relevantConditionalEffects = null)
 {
     if (!Preconditions.EvaluateRigidRelationsCompliance(substitution))
     {
         return(false);
     }
     return(Effects.IsRelevant(relativeState, substitution, relevantConditionalEffects));
 }
Example #9
0
 /// <summary>
 /// Gets the heuristic value for the given relative state (in the context of backward search).
 /// </summary>
 /// <param name="relativeState">Relative state to be evaluated.</param>
 /// <returns>Heuristic value for the specified relative state.</returns>
 public double GetValue(IRelativeState relativeState)
 {
     if (Statistics.DoMeasure)
     {
         double value = GetValueImpl(relativeState);
         Statistics.UpdateStatistics(value);
         return(value);
     }
     return(GetValueImpl(relativeState));
 }
Example #10
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);
                }
            }
        }
        /// <summary>
        /// Processes primitive effects.
        /// </summary>
        /// <param name="relativeState">Relative state.</param>
        /// <returns>Effect relevance (relevant, irrelevant, or anti-relevant).</returns>
        private EffectRelevance ProcessPrimitiveEffects(IRelativeState relativeState)
        {
            bool anyRelevant = false;

            foreach (var predicateAtom in relativeState.GetPredicates())
            {
                anyRelevant |= Effects.GroundedPositivePredicateEffects.Contains(predicateAtom);
                if (Effects.GroundedNegativePredicateEffects.Contains(predicateAtom))
                {
                    return(EffectRelevance.ANTI_RELEVANT);
                }
            }

            foreach (var predicateAtom in relativeState.GetNegatedPredicates())
            {
                anyRelevant |= Effects.GroundedNegativePredicateEffects.Contains(predicateAtom);
                if (Effects.GroundedPositivePredicateEffects.Contains(predicateAtom))
                {
                    return(EffectRelevance.ANTI_RELEVANT);
                }
            }

            foreach (var function in relativeState.GetObjectFunctions())
            {
                ITerm assignValue;
                if (Effects.GroundedObjectFunctionAssignmentEffects.TryGetValue(function.Key, out assignValue))
                {
                    ConstantTerm constantValue = assignValue as ConstantTerm;
                    if (constantValue == null || constantValue.NameId != function.Value)
                    {
                        // surely assigning different value -> anti-relevant
                        return(EffectRelevance.ANTI_RELEVANT);
                    }
                    anyRelevant = true;
                }
            }

            foreach (var function in relativeState.GetNumericFunctions())
            {
                INumericExpression assignExpression;
                if (Effects.GroundedNumericFunctionAssignmentEffects.TryGetValue(function.Key, out assignExpression))
                {
                    Number numberValue = assignExpression as Number;
                    if (numberValue == null || !numberValue.Value.Equals(function.Value))
                    {
                        // surely assigning different value -> anti-relevant
                        return(EffectRelevance.ANTI_RELEVANT);
                    }
                    anyRelevant = true;
                }
            }

            return((anyRelevant) ? EffectRelevance.RELEVANT : EffectRelevance.IRRELEVANT);
        }
        /// <summary>
        /// Collects relevant when effects for the specified relative state.
        /// </summary>
        /// <param name="relativeState">Relative state.</param>
        /// <returns>List of relevant when effects.</returns>
        private List <WhenEffect> GetRelevantWhenEffectsForConditions(IRelativeState relativeState)
        {
            List <int> relevantWhenEffectsIndices = new List <int>();
            EffectsRelevanceRelativeStateEvaluator relevanceEvaluator = new EffectsRelevanceRelativeStateEvaluator(Effects, GroundingManager);

            relevanceEvaluator.Evaluate(relativeState, new Substitution(), relevantWhenEffectsIndices); // empty substitution here because effects already grounded

            List <WhenEffect> relevantWhenEffects = new List <WhenEffect>();

            relevantWhenEffectsIndices.ForEach(index => relevantWhenEffects.Add(Effects.WhenEffects[index]));
            return(relevantWhenEffects);
        }
        /// <summary>
        /// Gets a collection of all relevant predecessors (backwards transitions) from the specified relative state. Lazy generated via yield return.
        /// </summary>
        /// <param name="relativeState">Original relative state.</param>
        /// <returns>Lazy generated collection of relevant predecessors.</returns>
        public IEnumerable <IPredecessor> GetPredecessors(IRelativeState relativeState)
        {
            // This part may be later optimized to use operator decision tree, just like IConditions

            foreach (var op in Problem.Operators)
            {
                if (op.IsRelevant(relativeState))
                {
                    yield return(new Predecessor(relativeState, op));
                }
            }
        }
Example #14
0
        /// <summary>
        /// Checks whether the operator effect is relevant to the given target relative state.
        /// </summary>
        /// <param name="relativeState">Relative state.</param>
        /// <returns>Effect relevance result.</returns>
        public virtual EffectRelevance IsRelevant(IRelativeState relativeState)
        {
            int value = relativeState.GetValue(Assignment.GetVariable());

            if (value == RelativeState.WildCardValue)
            {
                // not a conflict, but not positively contributing either
                return(EffectRelevance.IRRELEVANT);
            }

            return((Assignment.GetValue() == value) ? EffectRelevance.RELEVANT : EffectRelevance.ANTI_RELEVANT);
        }
Example #15
0
 /// <summary>
 /// Gets a collection of all relevant predecessors (backwards transitions) from the specified relative state. Lazy generated via yield return.
 /// </summary>
 /// <param name="relativeState">Original state.</param>
 /// <returns>Lazy generated collection of relevant predecessors.</returns>
 public IEnumerable <IPredecessor> GetPredecessors(IRelativeState relativeState)
 {
     foreach (var liftedOperator in LiftedOperators)
     {
         IEnumerable <ISubstitution> operatorSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(liftedOperator.Parameters);
         foreach (var operatorSubstitution in operatorSubstitutions)
         {
             if (liftedOperator.IsRelevant(relativeState, operatorSubstitution))
             {
                 yield return(new Predecessor(relativeState, new Operator(liftedOperator, operatorSubstitution)));
             }
         }
     }
 }
        /// <summary>
        /// Processes primitive effects.
        /// </summary>
        /// <param name="relativeState">Relative state to be modified.</param>
        private void ProcessPrimitiveEffects(IRelativeState relativeState)
        {
            foreach (var positivePredicate in Effects.GroundedPositivePredicateEffects)
            {
                if (relativeState.HasPredicate(positivePredicate))
                {
                    relativeState.RemovePredicate(positivePredicate);
                }
            }

            foreach (var negatedPredicate in Effects.GroundedNegativePredicateEffects)
            {
                if (relativeState.HasNegatedPredicate(negatedPredicate))
                {
                    relativeState.RemoveNegatedPredicate(negatedPredicate);
                }
            }

            foreach (var objectFunction in Effects.GroundedObjectFunctionAssignmentEffects)
            {
                var groundedValue = GroundingManager.GroundTermDeep(objectFunction.Value, OperatorSubstitution, relativeState);

                ConstantTerm constantValue = groundedValue as ConstantTerm;
                if (constantValue != null)
                {
                    if (relativeState.GetObjectFunctionValue(objectFunction.Key) == constantValue.NameId)
                    {
                        relativeState.AssignObjectFunction(objectFunction.Key, ObjectFunctionTerm.UndefinedValue);
                    }
                }
            }

            foreach (var numericFunction in Effects.GroundedNumericFunctionAssignmentEffects)
            {
                NumericAssignmentsBackwardsReplacer replacer = new NumericAssignmentsBackwardsReplacer(Effects.GroundedNumericFunctionAssignmentEffects, GroundingManager, OperatorSubstitution, new Substitution());
                INumericExpression reducedAssignExpression   = replacer.Replace(numericFunction.Value);

                Number assignNumber = reducedAssignExpression as Number;
                if (assignNumber != null)
                {
                    if (relativeState.GetNumericFunctionValue(numericFunction.Key).Equals(assignNumber.Value))
                    {
                        relativeState.AssignNumericFunction(numericFunction.Key, NumericFunction.UndefinedValue);
                    }
                }
            }
        }
Example #17
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);
        }
        /// <summary>
        /// Applies the operator preconditions to the given relative state.
        /// </summary>
        /// <param name="operatorPreconditions">Grounded operator preconditions.</param>
        /// <param name="relativeState">Relative state.</param>
        /// <returns>Modified relative states.</returns>
        private static IEnumerable <IRelativeState> ProcessOperatorPreconditions(Conditions operatorPreconditions, IRelativeState relativeState)
        {
            var conditionsCNF = (ConditionsCNF)operatorPreconditions.GetCNF();

            HashSet <IRelativeState> states = new HashSet <IRelativeState> {
                relativeState
            };

            foreach (var conjunct in conditionsCNF)
            {
                // this block processes all possible combinations of applications in a single clause (even though it is a primitive clause of one literal)

                HashSet <IRelativeState> newStatesForConjunct = new HashSet <IRelativeState>();

                foreach (var literal in conjunct.GetLiterals())
                {
                    HashSet <IRelativeState> newStatesForLiteral = new HashSet <IRelativeState>();

                    foreach (var state in states)
                    {
                        IRelativeState newState = (IRelativeState)state.Clone();
                        ProcessPreconditionLiteral(literal, newState);
                        newStatesForLiteral.Add(newState);
                    }

                    foreach (var state in newStatesForConjunct)
                    {
                        IRelativeState newState = (IRelativeState)state.Clone();
                        ProcessPreconditionLiteral(literal, newState);
                        newStatesForLiteral.Add(newState);
                    }

                    newStatesForConjunct.UnionWith(newStatesForLiteral);
                }

                states = newStatesForConjunct;
            }

            foreach (var resultState in states)
            {
                yield return(resultState);
            }
        }
        /// <summary>
        /// Processes forall effects.
        /// </summary>
        /// <param name="relativeState">Relative state to be modified.</param>
        /// <returns>Possibly modified relative state.</returns>
        private IRelativeState ProcessForallEffects(IRelativeState relativeState)
        {
            if (Effects.ForallEffects.Count == 0)
            {
                return(relativeState);
            }

            foreach (var forallEffect in Effects.ForallEffects)
            {
                EffectsBackwardsRelativeStateApplier innerApplier = new EffectsBackwardsRelativeStateApplier(null, forallEffect.Effects, EvaluationManager);

                IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(forallEffect.Parameters);
                foreach (var localSubstitution in localSubstitutions)
                {
                    OperatorSubstitution.AddLocalSubstitution(localSubstitution);
                    relativeState = (IRelativeState)innerApplier.ApplyBackwards(relativeState, OperatorSubstitution).First();
                    OperatorSubstitution.RemoveLocalSubstitution(localSubstitution);
                }
            }

            return(relativeState);
        }
        /// <summary>
        /// Processes conditional (when) effects.
        /// </summary>
        /// <param name="relativeState">>Relative state to be processed.</param>
        /// <returns>Modified relative states.</returns>
        private IEnumerable <IRelativeState> ProcessWhenEffects(IRelativeState relativeState)
        {
            if (Effects.WhenEffects.Count == 0)
            {
                yield return(relativeState);

                yield break;
            }

            // Collect the relevant when effects, first
            List <WhenEffect> relevantWhenEffects = GetRelevantWhenEffectsForConditions(relativeState);

            // Each of the relevant when effect is either used or not (dynamic programming approach to get all combinations of when effects usage)
            List <IRelativeState> applicationResults = new List <IRelativeState> {
                relativeState
            };

            foreach (var whenEffect in relevantWhenEffects)
            {
                Conditions whenCondition = new Conditions(whenEffect.Expression, EvaluationManager);
                EffectsBackwardsRelativeStateApplier innerApplier = new EffectsBackwardsRelativeStateApplier(whenCondition, new List <IEffect>(whenEffect.Effects), EvaluationManager);

                List <IRelativeState> currentEffectApplications = new List <IRelativeState>();
                foreach (var currentRelativeState in applicationResults)
                {
                    foreach (var resultRelativeState in innerApplier.ApplyBackwards(currentRelativeState, new Substitution()))
                    {
                        currentEffectApplications.Add((IRelativeState)resultRelativeState);
                    }
                }

                applicationResults.AddRange(currentEffectApplications);
            }

            foreach (var resultRelativeState in applicationResults)
            {
                yield return(resultRelativeState);
            }
        }
Example #21
0
        /// <summary>
        /// Generates all possible PDDL states meeting conditions specified by the relative state. Lazy generated via yield return.
        /// </summary>
        /// <param name="relativeState">Reference relative state.</param>
        /// <param name="problem">Planning problem.</param>
        /// <returns>All possible PDDL states meeting the conditions.</returns>
        public static IEnumerable <IState> EnumerateStates(IRelativeState relativeState, Problem problem)
        {
            // note: numeric function assignments are not enumerated (as it is generally infinite), but only fixed by the values of the source state

            Func <IAtom, bool?> predicateChecker = (predicate) =>
            {
                if (relativeState.HasPredicate(predicate))
                {
                    return(true);
                }
                else if (relativeState.HasNegatedPredicate(predicate))
                {
                    return(false);
                }
                return(null);
            };

            Func <IAtom, int> objectFunctionChecker = relativeState.GetObjectFunctionValue;

            IState initState = new State(problem.IdManager);

            foreach (var numericFunction in relativeState.GetNumericFunctions())
            {
                initState.AssignNumericFunction(numericFunction.Key, numericFunction.Value);
            }

            var predicates      = problem.EvaluationManager.GroundingManager.GetAllGroundedPredicates();
            var objectFunctions = problem.EvaluationManager.GroundingManager.GetAllGroundedObjectFunctions();

            foreach (var state in EnumerateStatesByPredicates(0, predicates, initState, predicateChecker))
            {
                foreach (var resultState in EnumerateStatesByObjectFunctions(0, objectFunctions, state, objectFunctionChecker))
                {
                    yield return(resultState);
                }
            }
        }
Example #22
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);
                }
            }
        }
Example #23
0
 /// <summary>
 /// Constructs the predecessor entity from relative state.
 /// </summary>
 /// <param name="referenceRelativeState">Reference to the original relative state.</param>
 /// <param name="appliedOperator">Grounded applied operator.</param>
 public Predecessor(IRelativeState referenceRelativeState, IOperator appliedOperator)
 {
     ReferenceRelativeState = referenceRelativeState;
     AppliedOperator        = appliedOperator;
 }
Example #24
0
 /// <summary>
 /// Gets the heuristic value for the given relative state (in the context of backward search).
 /// </summary>
 /// <param name="relativeState">Relative state to be evaluated.</param>
 /// <returns>Heuristic value for the specified relative state.</returns>
 protected override double GetValueImpl(IRelativeState relativeState)
 {
     return(Heuristics.Sum(heuristic => heuristic.GetValue(relativeState)));
 }
Example #25
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">Target relative state.</param>
 /// <param name="substitution">Variables substitution.</param>
 /// <returns>Preceding relative states.</returns>
 public IEnumerable <Planner.IRelativeState> ApplyBackwards(IRelativeState relativeState, ISubstitution substitution)
 {
     return(EffectsBackwardsRelativeStateApplier.Value.ApplyBackwards(relativeState, substitution));
 }
Example #26
0
 /// <summary>
 /// Checks whether the operator is relevant to the given target relative state.
 /// </summary>
 /// <param name="relativeState">Target relative state.</param>
 /// <param name="substitution">Variables substitution.</param>
 /// <param name="relevantConditionalEffects">Output indices of relevant conditional effects (can be null).</param>
 /// <returns>True if the operator is relevant to the given relative state, false otherwise.</returns>
 public bool IsRelevant(IRelativeState relativeState, ISubstitution substitution, IList <int> relevantConditionalEffects = null)
 {
     return(EffectsRelevanceRelativeStateEvaluator.Value.Evaluate(relativeState, substitution, relevantConditionalEffects));
 }
Example #27
0
        /// <summary>
        /// Generates all possible SAS+ states meeting conditions specified by the relative state. Lazy generated via yield return.
        /// </summary>
        /// <param name="relativeState">Reference relative state.</param>
        /// <param name="variables">Variables of the planning problem.</param>
        /// <returns>All possible SAS+ states meeting the conditions.</returns>
        public static IEnumerable <IState> EnumerateStates(IRelativeState relativeState, Variables variables)
        {
            Func <int, int> checker = relativeState.GetValue;

            return(EnumerateStates(0, new State(new int[variables.Count]), checker, variables));
        }
Example #28
0
 /// <summary>
 /// Gets the heuristic value for the given relative state (in the context of backward search).
 /// </summary>
 /// <param name="relativeState">Relative state to be evaluated.</param>
 /// <returns>Heuristic value for the specified relative state.</returns>
 protected virtual double GetValueImpl(IRelativeState relativeState)
 {
     return(GetValueImpl(relativeState.GetDescribingConditions(Problem)));
 }
 /// <summary>
 /// Gets the heuristic value for the given relative state (in the context of backward search).
 /// </summary>
 /// <param name="relativeState">Relative state to be evaluated.</param>
 /// <returns>Heuristic value for the specified relative state.</returns>
 protected override double GetValueImpl(IRelativeState relativeState)
 {
     return(Weight * Heuristic.GetValue(relativeState));
 }
Example #30
0
 /// <summary>
 /// Gets the heuristic value for the given relative state (in the context of backward search).
 /// </summary>
 /// <param name="relativeState">Relative state to be evaluated.</param>
 /// <returns>Heuristic value for the specified relative state.</returns>
 protected override double GetValueImpl(IRelativeState relativeState)
 {
     return(0.0);
 }