/// <summary> /// Checks whether the operator effects are relevant to the given target conditions. /// </summary> /// <param name="conditions">Conditions for the application.</param> /// <param name="operatorPreconditions">Operator preconditions.</param> /// <returns>True if the operator effects are relevant to the given conditions, false otherwise.</returns> public bool IsRelevant(IConditions conditions, ISimpleConditions operatorPreconditions) { // Besides the effects relevance, we need to check whether the operator preconditions are not in conflict with the resulting // conditions (after backward-apply). This can be done via affected variables: if some effect is relevant, then it modifies a // variable, and a constraint corresponding to this variable can be removed from the preconditions. At the end, we check the // modified precondition constraints with the target conditions and if there are conflicts, we consider the operator not // relevant. This approach works even for conditional-effects, because we take the worst case scenario. IConditions nonAffectedPreconditions = (IConditions)operatorPreconditions.Clone(); bool anyRelevant = false; foreach (var effect in this) { var relevance = effect.IsRelevant(conditions); if (relevance == EffectRelevance.ANTI_RELEVANT) { return(false); } else if (relevance == EffectRelevance.RELEVANT) { anyRelevant = true; nonAffectedPreconditions.RemoveConstraint(effect.GetAssignment()); } } return(anyRelevant && !nonAffectedPreconditions.IsConflictedWith(conditions)); }
/// <summary> /// Applies the effect backwards to the given conditions. /// </summary> /// <param name="conditions">Conditions.</param> public virtual IConditions ApplyBackwards(IConditions conditions) { if (!conditions.IsConflictedWith(Assignment)) { conditions.RemoveConstraint(Assignment); return(conditions); } return(new ConditionsContradiction()); }
/// <summary> /// Applies the effect backwards to the given conditions. /// </summary> /// <param name="conditions">Conditions.</param> public override IConditions ApplyBackwards(IConditions conditions) { if (IsRelevant(conditions) == EffectRelevance.RELEVANT) { IConditions newConditions = (IConditions)conditions.Clone(); newConditions.RemoveConstraint(Assignment); newConditions = newConditions.ConjunctionWith(Conditions); return(conditions.DisjunctionWith(newConditions)); } return(conditions); }
/// <summary> /// Checks whether the operator effect is relevant to the given target conditions. /// </summary> /// <param name="conditions">Conditions.</param> /// <returns>Effect relevance result.</returns> public override EffectRelevance IsRelevant(IConditions conditions) { var assignmentRelevance = base.IsRelevant(conditions); if (assignmentRelevance == EffectRelevance.RELEVANT) { IConditions nonAffectedConditions = (IConditions)Conditions.Clone(); nonAffectedConditions.RemoveConstraint(Assignment); if (!nonAffectedConditions.IsConflictedWith(conditions)) { return(EffectRelevance.RELEVANT); } } // conditional effect does not have to be used, so it should never be explicitly anti-relevant return(EffectRelevance.IRRELEVANT); }