/// <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> /// Applies the effect backwards to the given relative state. /// </summary> /// <param name="relativeState">Relative state.</param> public virtual IRelativeState ApplyBackwards(IRelativeState relativeState) { // we are fine here with the direct modification relativeState.SetValue(Assignment.GetVariable(), RelativeState.WildCardValue); return(relativeState); }