/// <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)); }
/// <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)); }
/// <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); }