/// <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));
        }
Ejemplo n.º 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 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));
        }
Ejemplo n.º 4
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);
        }