/// <summary>
        /// Processes forall effects.
        /// </summary>
        /// <param name="expression">Conditions expression in CNF.</param>
        /// <returns>Tuple of two values, where the first is true when the positive relevance condition (inclusion) is satisfied, while the second is
        /// true when the negative condition (exclusion) is not violated. False otherwise.</returns>
        private Tuple <bool, bool> ProcessForallEffects(ConditionsCNF expression)
        {
            bool positiveCondition = false;
            bool negativeCondition = true;

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

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

                    var result = evaluator.EvaluateWithExtendedResult(expression, OperatorSubstitution, null);
                    positiveCondition |= result.Item1;
                    negativeCondition &= result.Item2;

                    OperatorSubstitution.RemoveLocalSubstitution(localSubstitution);

                    if (!negativeCondition)
                    {
                        return(result);
                    }
                }
            }
            return(Tuple.Create(positiveCondition, true));
        }
Пример #2
0
        /// <summary>
        /// Applies backwards the relevant operator effects and operator preconditions to the given target conditions.
        /// </summary>
        /// <param name="conditions">Target conditions to be modified.</param>
        /// <param name="operatorSubstitution">Variables substitution.</param>
        /// <returns>Preceding conditions.</returns>
        public IConditions ApplyBackwards(IConditions conditions, ISubstitution operatorSubstitution)
        {
            ConditionsCNF expression = (ConditionsCNF)conditions?.GetCNF();

            if (expression == null)
            {
                return(null);
            }

            OperatorSubstitution = operatorSubstitution;
            Effects.GroundEffectsByCurrentOperatorSubstitution(GroundingManager, operatorSubstitution);

            if (expression.Parameters != null)
            {
                EffectsRelevanceConditionsEvaluator evaluator = new EffectsRelevanceConditionsEvaluator(Effects, GroundingManager);

                List <ConditionsCNF>        subResults = new List <ConditionsCNF>();
                IEnumerable <ISubstitution> expressionSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(expression.Parameters);
                expression.Parameters = null;

                foreach (var expressionSubstitution in expressionSubstitutions)
                {
                    // do backward apply only when the effects are relevant to the current grounding of the expression
                    if (evaluator.Evaluate(expression, operatorSubstitution, expressionSubstitution))
                    {
                        subResults.Add(ApplyBackwardsImpl(expression, expressionSubstitution));
                    }
                }

                return(ConstructCNFFromDisjunction(subResults));
            }

            return(ApplyBackwardsImpl(expression, new Substitution()));
        }
        /// <summary>
        /// Processes conditional (when) effects.
        /// </summary>
        /// <param name="expression">Conditions expression in CNF.</param>
        /// <param name="relevantConditionalEffects">Output indices of relevant conditional effects (can be null).</param>
        /// <returns>Tuple of two values, where the first is true when the positive relevance condition (inclusion) is satisfied, while the second is
        /// true when the negative condition (exclusion) is not violated. False otherwise.</returns>
        private Tuple <bool, bool> ProcessWhenEffects(ConditionsCNF expression, IList <int> relevantConditionalEffects)
        {
            bool positiveCondition = false;
            int  whenEffectIndex   = -1;

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

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

                var result = evaluator.EvaluateWithExtendedResult(expression, OperatorSubstitution, ExpressionSubstitution, relevantConditionalEffects);
                if (!result.Item2)
                {
                    continue;
                }

                if (result.Item1 && result.Item2)
                {
                    relevantConditionalEffects?.Add(whenEffectIndex);
                }
                positiveCondition |= result.Item1;
            }
            return(Tuple.Create(positiveCondition, true));
        }
Пример #4
0
        /// <summary>
        /// Processes conditional (when) effects.
        /// </summary>
        /// <param name="expression">Conditions expression in CNF.</param>
        private ConditionsCNF ProcessWhenEffects(ConditionsCNF expression)
        {
            if (Effects.WhenEffects.Count == 0)
            {
                return(expression);
            }

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

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

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

                List <ConditionsCNF> currentEffectApplications = new List <ConditionsCNF>();
                foreach (var currentCondition in applicationResults)
                {
                    ConditionsCNF modifiedCondition = (ConditionsCNF)innerApplier.ApplyBackwards(currentCondition, new Substitution());
                    currentEffectApplications.Add(modifiedCondition);
                }

                applicationResults.AddRange(currentEffectApplications);
            }

            // Now, all the possible results need to be merged into a single condition via OR and converted into a valid CNF
            return(ConstructCNFFromDisjunction(applicationResults));
        }
Пример #5
0
        /// <summary>
        /// Merges the specified CNF conditions into the current CNF conditions. The other CNF shouldn't be used anymore (its items are reused in the current CNF).
        /// </summary>
        /// <param name="other">Other CNF conditions.</param>
        public void Merge(ConditionsCNF other)
        {
            if (Parameters == null)
            {
                Parameters = new Parameters();
            }

            if (Parameters.AreConflictedWith(other.Parameters))
            {
                EvaluationManager.RenameConditionParameters(other, Parameters.GetMaxUsedParameterId() + 1);
            }

            if (other.Parameters != null)
            {
                Parameters.AddRange(other.Parameters);
            }

            if (Parameters.Count == 0)
            {
                Parameters = null;
            }

            foreach (var items in other)
            {
                Add(items);
            }
        }
        /// <summary>
        /// Evaluates the label of the operator with the specified preconditions and substitution.
        /// </summary>
        /// <param name="conditions">Operator conditions.</param>
        /// <param name="substitution">Variable substitution.</param>
        /// <param name="stateLabels">Atom labels in the predecessor layer.</param>
        /// <param name="evaluationStrategy">Evaluation strategy.</param>
        /// <returns>Operator label value in the relaxed planning graph.</returns>
        public double Evaluate(ConditionsCNF conditions, ISubstitution substitution, StateLabels stateLabels, ForwardCostEvaluationStrategy evaluationStrategy)
        {
            Substitution       = substitution;
            StateLabels        = stateLabels;
            EvaluationStrategy = evaluationStrategy;

            return(conditions.Accept(this).Item1);
        }
        /// <summary>
        /// Gets a list of atoms used in the specified conditions.
        /// </summary>
        /// <param name="conditions">Conditions to be evaluated.</param>
        /// <returns>Collection of used atoms.</returns>
        public HashSet <IAtom> Collect(IConditions conditions)
        {
            ConditionsCNF conditionsCNF = (ConditionsCNF)conditions.GetCNF();

            Atoms = new HashSet <IAtom>();

            conditionsCNF.Accept(this);

            return(Atoms);
        }
        /// <summary>
        /// Gets a list of atoms from the specified state that are necessary to make these conditions true.
        /// </summary>
        /// <param name="conditions">Conditions to evaluate.</param>
        /// <param name="substitution">Variable substitution.</param>
        /// <param name="predecessorState">Preceding state.</param>
        /// <returns>List of satisfying atoms.</returns>
        public List <IAtom> Evaluate(IConditions conditions, ISubstitution substitution, IState predecessorState)
        {
            ConditionsCNF conditionsCNF = (ConditionsCNF)conditions.GetCNF();

            Atoms          = new List <IAtom>();
            Substitution   = substitution;
            ReferenceState = predecessorState;

            conditionsCNF.Accept(this);

            return(Atoms);
        }
Пример #9
0
        /// <summary>
        /// Collects relevant when effects for the specified conditions.
        /// </summary>
        /// <param name="expression">Conditions in CNF.</param>
        /// <returns>List of relevant when effects.</returns>
        private List <WhenEffect> GetRelevantWhenEffectsForConditions(ConditionsCNF expression)
        {
            List <int> relevantWhenEffectsIndices = new List <int>();
            EffectsRelevanceConditionsEvaluator relevanceEvaluator = new EffectsRelevanceConditionsEvaluator(Effects, GroundingManager);

            relevanceEvaluator.Evaluate(expression, new Substitution(), ExpressionSubstitution, 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>
        /// Visits and performs a property count on CNF conjunction.
        /// </summary>
        /// <param name="expression">CNF conjunction.</param>
        /// <returns>Tuple (property satisfied count, property not satisfied count).</returns>
        public Tuple <int, int> Visit(ConditionsCNF expression)
        {
            int fulfilled    = 0;
            int notFulfilled = 0;

            foreach (var conjunct in expression)
            {
                var childPropertyCounts = conjunct.Accept(this);
                fulfilled    += childPropertyCounts.Item1;
                notFulfilled += childPropertyCounts.Item2;
            }

            return(Tuple.Create(fulfilled, notFulfilled));
        }
Пример #11
0
        /// <summary>
        /// Accepts a conjunctive-normal-form expression backwards applier visitor.
        /// </summary>
        /// <param name="visitor">CNF expression visitor.</param>
        public IElementCNF Accept(IElementCNFBackwardsApplierVisitor visitor)
        {
            ConditionsCNF newExpression = CloneEmpty();

            foreach (var conjunct in this)
            {
                var resultExpression = conjunct.Accept(visitor);
                if (resultExpression != null)
                {
                    newExpression.Add((IConjunctCNF)resultExpression);
                }
            }
            return(newExpression);
        }
Пример #12
0
        /// <summary>
        /// Checks the equality of objects.
        /// </summary>
        /// <param name="obj">Object to be checked.</param>
        /// <returns>True if the objects are equal, false otherwise.</returns>
        public override bool Equals(object obj)
        {
            if (obj == this)
            {
                return(true);
            }

            ConditionsCNF other = obj as ConditionsCNF;

            if (other == null)
            {
                return(false);
            }

            return(CollectionsEquality.Equals(this, other));
        }
        /// <summary>
        /// Renames the parameters (and the corresponding occurences in the conditions), starting from the given free parameter ID.
        /// </summary>
        /// <param name="conditions">Conditions to be edited.</param>
        /// <param name="firstFreeParameterId">First free parameter ID.</param>
        public void Rename(ConditionsCNF conditions, int firstFreeParameterId)
        {
            // firstly, build a renaming map and rename the parameters

            ParametersRemapping.Clear();

            int currentParameterId = firstFreeParameterId;

            foreach (var parameter in conditions.Parameters)
            {
                ParametersRemapping.Add(parameter.ParameterNameId, currentParameterId);
                parameter.ParameterNameId = currentParameterId;
                ++currentParameterId;
            }

            // rename the conditions

            conditions.Accept(this);
        }
Пример #14
0
 /// <summary>
 /// Evaluates the conditions with the given reference state and variable substitution.
 /// </summary>
 /// <param name="conditions">Conditions to be evaluated.</param>
 /// <param name="substitution">Used variables substitution.</param>
 /// <param name="referenceState">Reference state.</param>
 /// <returns>True if all conditions are met in the given state, false otherwise.</returns>
 public bool Evaluate(ConditionsCNF conditions, ISubstitution substitution, IState referenceState = null)
 {
     // the conditions is lifted, but no direct variable substitution provided -> try whether there is a valid grounding to satisfy the conditions
     if (conditions.Parameters != null && substitution == null)
     {
         IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(conditions.Parameters);
         foreach (var localSubstitution in localSubstitutions)
         {
             if (ConditionsCNFEvaluator.Value.Evaluate(conditions, localSubstitution, referenceState))
             {
                 return(true);
             }
         }
         return(false);
     }
     else
     {
         return(ConditionsCNFEvaluator.Value.Evaluate(conditions, substitution, referenceState));
     }
 }
Пример #15
0
        /// <summary>
        /// Applies backwards the relevant operator effects and operator preconditions to the given target conditions.
        /// </summary>
        /// <param name="expression">Target conditions in CNF.</param>
        /// <param name="expressionSubstitution">Variables substitution of the expression.</param>
        /// <returns>Preceding conditions.</returns>
        private ConditionsCNF ApplyBackwardsImpl(ConditionsCNF expression, ISubstitution expressionSubstitution)
        {
            UsedGroundedPredicates.Clear();
            UsedGroundedFunctions.Clear();
            ExpressionSubstitution = expressionSubstitution;

            // remove positively contributing effects from the target conditions
            ConditionsCNF resultExpression = ProcessPrimitiveEffects(expression);

            resultExpression = ProcessForallEffects(resultExpression);
            resultExpression = ProcessWhenEffects(resultExpression);

            // unite processed conditions with partially grounded preconditions of the operator
            if (OperatorPreconditions != null)
            {
                var preconditions = ClearRigidRelations(OperatorPreconditions);
                resultExpression.Merge((ConditionsCNF)GroundConditions(preconditions).GetCNF());
            }

            return(resultExpression);
        }
Пример #16
0
        /// <summary>
        /// Processes forall effects.
        /// </summary>
        /// <param name="expression">Conditions expression in CNF.</param>
        private ConditionsCNF ProcessForallEffects(ConditionsCNF expression)
        {
            if (Effects.ForallEffects.Count == 0)
            {
                return(expression);
            }

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

                IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(forallEffect.Parameters);
                foreach (var localSubstitution in localSubstitutions)
                {
                    OperatorSubstitution.AddLocalSubstitution(localSubstitution);
                    expression = (ConditionsCNF)innerApplier.ApplyBackwards(expression, OperatorSubstitution);
                    OperatorSubstitution.RemoveLocalSubstitution(localSubstitution);
                }
            }
            return(expression);
        }
        /// <summary>
        /// Visits and performs a property count on CNF conjunction.
        /// </summary>
        /// <param name="expression">CNF conjunction.</param>
        /// <returns>Tuple (property satisfied count, property not satisfied count).</returns>
        public Tuple <double, double> Visit(ConditionsCNF expression)
        {
            double positiveValue = 0;
            double negativeValue = 0;

            foreach (var child in expression)
            {
                var childPropertyCounts = child.Accept(this);

                if (EvaluationStrategy == ForwardCostEvaluationStrategy.ADDITIVE_VALUE)
                {
                    positiveValue += childPropertyCounts.Item1;
                    negativeValue += childPropertyCounts.Item2;
                }
                else
                {
                    positiveValue = Math.Max(positiveValue, childPropertyCounts.Item1);
                    negativeValue = Math.Max(negativeValue, childPropertyCounts.Item2);
                }
            }

            return(Tuple.Create(positiveValue, negativeValue));
        }
        /// <summary>
        /// Evaluates whether the operator effects are relevant for the specified conditions.
        /// </summary>
        /// <param name="conditions">Conditions expression.</param>
        /// <param name="operatorSubstitution">Variables substitution of the operator.</param>
        /// <param name="expressionSubstitution">Variables substitution of the expression.</param>
        /// <param name="relevantConditionalEffects">Output indices of relevant conditional effects (can be null).</param>
        /// <returns>Tuple of two values, where the first is true when the positive relevance condition (inclusion) is satisfied, while the second is
        /// true when the negative condition (exclusion) is not violated. False otherwise.</returns>
        public Tuple <bool, bool> EvaluateWithExtendedResult(IConditions conditions, ISubstitution operatorSubstitution, ISubstitution expressionSubstitution, IList <int> relevantConditionalEffects = null)
        {
            ConditionsCNF expression = (ConditionsCNF)conditions?.GetCNF();

            if (expression == null)
            {
                return(Tuple.Create(false, false));
            }

            Effects.GroundEffectsByCurrentOperatorSubstitution(GroundingManager, operatorSubstitution);

            OperatorSubstitution   = operatorSubstitution;
            ExpressionSubstitution = expressionSubstitution;

            var primitivesResult = ProcessPrimitiveEffects(expression);

            if (!primitivesResult.Item2)
            {
                return(primitivesResult);
            }

            var forallResult = ProcessForallEffects(expression);

            if (!forallResult.Item2)
            {
                return(forallResult);
            }

            var whenResult = ProcessWhenEffects(expression, relevantConditionalEffects);

            if (!whenResult.Item2)
            {
                return(whenResult);
            }

            return(Tuple.Create((primitivesResult.Item1 || forallResult.Item1 || whenResult.Item1), true));
        }
Пример #19
0
        /// <summary>
        /// Builds CNF conditions form from the given conditions.
        /// </summary>
        /// <param name="conditions">Source conditions.</param>
        /// <returns>Expression in CNF.</returns>
        public ConditionsCNF Build(Conditions conditions)
        {
            IExpression expression = conditions.GetWrappedConditions();

            if (expression == null)
            {
                return(null);
            }

            IExpression transformedExpression = ExpressionToCNFTransformer.Transform(expression);

            Debug.Assert(Stack.Count == 0);
            Stack.Clear();

            transformedExpression.Accept(this);

            ConditionsCNF conditionsCNF = new ConditionsCNF(EvaluationManager, conditions.Parameters);

            while (Stack.Count != 0)
            {
                conditionsCNF.Add(Stack.Pop());
            }
            return(conditionsCNF);
        }
 /// <summary>
 /// Gets the number of not accomplished condition constraints for the specified state.
 /// </summary>
 /// <param name="conditions">Conditions to be evaluated.</param>
 /// <param name="referenceState">Reference state.</param>
 /// <returns>Number of not accomplished condition constraints.</returns>
 public int Evaluate(ConditionsCNF conditions, IState referenceState)
 {
     ReferenceState = referenceState;
     return(conditions.Accept(this).Item2);
 }
Пример #21
0
 /// <summary>
 /// Gets the number of not accomplished condition constraints for the specified state.
 /// </summary>
 /// <param name="conditions">Conditions.</param>
 /// <param name="state">State to be evaluated.</param>
 /// <returns>Number of not accomplished condition constraints.</returns>
 public int GetNotAccomplishedConstraintsCount(ConditionsCNF conditions, IState state)
 {
     return(NotAccomplishedConstraintsCounterCNF.Value.Evaluate(conditions, state));
 }
Пример #22
0
 /// <summary>
 /// Computes the operator label in the relaxed planning graph.
 /// </summary>
 /// <param name="conditions">Operator preconditions.</param>
 /// <param name="substitution">Variable substitution.</param>
 /// <param name="stateLabels">Atom labels from the predecessor layer in the graph.</param>
 /// <param name="evaluationStrategy">Evaluation strategy of the planning graph.</param>
 /// <returns>Computed operator label in the relaxed planning graph.</returns>
 public double EvaluateOperatorPlanningGraphLabel(ConditionsCNF conditions, ISubstitution substitution, StateLabels stateLabels, ForwardCostEvaluationStrategy evaluationStrategy)
 {
     return(PlanningGraphOperatorLabelEvaluatorCNF.Value.Evaluate(conditions, substitution, stateLabels, evaluationStrategy));
 }
Пример #23
0
 /// <summary>
 /// Renames the parameters (and the corresponding occurences in the conditions), starting from the given free parameter ID.
 /// </summary>
 /// <param name="conditions">Conditions to be edited.</param>
 /// <param name="firstFreeParameterId">First free parameter ID.</param>
 public void RenameConditionParameters(ConditionsCNF conditions, int firstFreeParameterId)
 {
     ConditionsParametersRenamer.Value.Rename(conditions, firstFreeParameterId);
 }
 /// <summary>
 /// Processes primitive effects.
 /// </summary>
 /// <param name="expression">Conditions expression in CNF.</param>
 /// <returns>Tuple of two values, where the first is true when the positive relevance condition (inclusion) is satisfied, while the second is
 /// true when the negative condition (exclusion) is not violated. False otherwise.</returns>
 private Tuple <bool, bool> ProcessPrimitiveEffects(ConditionsCNF expression)
 {
     return(expression.Accept(this));
 }
Пример #25
0
 /// <summary>
 /// Processes primitive effects.
 /// </summary>
 /// <param name="expression">Conditions expression in CNF.</param>
 private ConditionsCNF ProcessPrimitiveEffects(ConditionsCNF expression)
 {
     // standard processing of simple effects via visitor pattern
     return((ConditionsCNF)expression.Accept(this));
 }