/// <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); }
/// <summary> /// Visits the expression. /// </summary> /// <param name="expression">Expression.</param> public IElementCNF Visit(EqualsLiteralCNF expression) { var objectAssignEffects = Effects.GroundedObjectFunctionAssignmentEffects; if (objectAssignEffects.Count == 0) { return(expression.Clone()); } Func <ITerm, ITerm> transformArgument = null; transformArgument = (term) => { ObjectFunctionTerm objectFunction = term as ObjectFunctionTerm; if (objectFunction != null) { ITerm assignmentValue; if (objectAssignEffects.TryGetValue(GroundAtom(objectFunction.FunctionAtom), out assignmentValue)) { UsedGroundedFunctions.Add(objectFunction.FunctionAtom); return(transformArgument(assignmentValue)); } } return(term.Clone()); }; ITerm transformedLeftTerm = transformArgument(expression.LeftArgument); ITerm transformedRightTerm = transformArgument(expression.RightArgument); bool termsEqual = transformedLeftTerm.Equals(transformedRightTerm); if ((termsEqual && !expression.IsNegated) || (!termsEqual && expression.IsNegated)) { // exact constant assignment (or unassignment with negated equals) -> positively contributing, i.e. remove return(null); } return(new EqualsLiteralCNF(transformedLeftTerm, transformedRightTerm, expression.IsNegated)); }
/// <summary> /// Visits the expression. /// </summary> /// <param name="expression">Expression.</param> public IElementCNF Visit(NumericCompareLiteralCNF expression) { // 1.) Evaluates both of the arguments by NumericAssignmentsBackwardsReplacer - every numeric function instance is replaced by // the available numeric assignments from effects and the whole numeric expression is reduced (partially or fully evaluated). // 2.) In case of the full reduction of both arguments, the numeric comparison is evaluated - if successfully, the whole condition // is satisfied and we can remove it (i.e. return null). // 3.) Otherwise, the modified numeric compare expression is returned, replacing the original condition. var numericAssignEffects = Effects.GroundedNumericFunctionAssignmentEffects; if (numericAssignEffects.Count == 0) { // no assignment effects available, just return a copy of the original expression return(expression.Clone()); } NumericAssignmentsBackwardsReplacer replacer = new NumericAssignmentsBackwardsReplacer(numericAssignEffects, GroundingManager, OperatorSubstitution, ExpressionSubstitution); INumericExpression newLeftNumericExpression = replacer.Replace(expression.LeftArgument); INumericExpression newRightNumericExpression = replacer.Replace(expression.RightArgument); UsedGroundedFunctions.UnionWith(replacer.ReplacedFunctionAtomsInSubExpression); Number leftNumber = newLeftNumericExpression as Number; Number rightNumber = newRightNumericExpression as Number; if (leftNumber != null && rightNumber != null) { bool relationHolds = NumericCompareExpression.ApplyCompare(expression.Operator, leftNumber.Value, rightNumber.Value); if ((relationHolds && !expression.IsNegated) || (!relationHolds && expression.IsNegated)) { // the numeric comparison was successful -> condition is satisfied, i.e. remove return(null); } } // modified numeric compare expression, replacing the original one return(new NumericCompareLiteralCNF(expression.Operator, newLeftNumericExpression, newRightNumericExpression, expression.IsNegated)); }