/// <summary> /// Evaluates the expression. /// </summary> /// <param name="expression">Expression.</param> /// <returns>True if the expression is logically true, false otherwise.</returns> public bool Visit(NumericCompareLiteralCNF expression) { double leftValue = NumericEvaluator.Value.Evaluate(expression.LeftArgument, Substitution, ReferenceState); double rightValue = NumericEvaluator.Value.Evaluate(expression.RightArgument, Substitution, ReferenceState); bool evaluationResult = NumericCompareExpression.ApplyCompare(expression.Operator, leftValue, rightValue); return(!expression.IsNegated == evaluationResult); }
/// <summary> /// Visits the expression. /// </summary> /// <param name="expression">Expression.</param> public Tuple <bool, bool> Visit(NumericCompareLiteralCNF expression) { HashSet <NumericFunction> numericFunctions = new HashSet <NumericFunction>(); NumericFunctionsCollector collector = new NumericFunctionsCollector(); numericFunctions.UnionWith(collector.Collect(expression.LeftArgument)); numericFunctions.UnionWith(collector.Collect(expression.RightArgument)); bool positiveCondition = false; foreach (var numericFunction in numericFunctions) { positiveCondition |= Effects.GroundedNumericFunctionAssignmentEffects.ContainsKey(GroundingManager.GroundAtom(numericFunction.FunctionAtom, ExpressionSubstitution)); } return(Tuple.Create(positiveCondition, true)); }
/// <summary> /// Checks the equality of objects. /// </summary> /// <param name="obj">Object to be checked.</param> /// <returns>True if the objects are equal, false otherwise.</returns> public override bool Equals(object obj) { if (obj == this) { return(true); } NumericCompareLiteralCNF other = obj as NumericCompareLiteralCNF; if (other == null) { return(false); } return(Operator.Equals(other.Operator) && LeftArgument.Equals(other.LeftArgument) && RightArgument.Equals(other.RightArgument) && IsNegated == other.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)); }
/// <summary> /// Generates all possible PDDL relative states meeting given CNF conditions (in the form of a list of conjuncts). Lazy generated recursively via yield return. /// </summary> /// <param name="index">Current index in the conjuncts list.</param> /// <param name="conjuncts">List of conjuncts of the CNF conditions.</param> /// <param name="result">Current relative state being built.</param> /// <returns>All possible PDDL relative states meeting the CNF conditions.</returns> private static IEnumerable <IRelativeState> EnumerateRelativeStatesByCNF(int index, List <IConjunctCNF> conjuncts, IRelativeState result) { if (index == 0) { // the constructed state can have trailing values from the previous unfinished enumeration! result.ClearContent(); } Action <IRelativeState, LiteralCNF> addLiteral = (state, literal) => { // Note: At the moment, there is limited support for object and numeric function assignments. // For example, numeric comparison literals like (< (numFunc) 5) will be omitted in the resulting relative state. PredicateLiteralCNF predicateLiteral = literal as PredicateLiteralCNF; if (predicateLiteral != null) { if (literal.IsNegated) { state.AddNegatedPredicate(predicateLiteral.PredicateAtom.Clone()); } else { state.AddPredicate(predicateLiteral.PredicateAtom.Clone()); } return; } EqualsLiteralCNF equalsLiteral = literal as EqualsLiteralCNF; if (equalsLiteral != null) { var assignment = equalsLiteral.TryGetObjectFunctionAssignment(); if (assignment != null) { if (!literal.IsNegated) { state.AssignObjectFunction(assignment.Item1.FunctionAtom.Clone(), assignment.Item2.NameId); } } return; } NumericCompareLiteralCNF compareLiteral = literal as NumericCompareLiteralCNF; if (compareLiteral != null) { var assignment = compareLiteral.TryGetNumericFunctionAssignment(); if (assignment != null) { if (!compareLiteral.IsNegated) { state.AssignNumericFunction(assignment.Item1.FunctionAtom.Clone(), assignment.Item2.Value); } } } }; Action <IRelativeState, LiteralCNF> removeLiteral = (state, literal) => { PredicateLiteralCNF predicateLiteral = literal as PredicateLiteralCNF; if (predicateLiteral != null) { if (literal.IsNegated) { state.RemoveNegatedPredicate(predicateLiteral.PredicateAtom.Clone()); } else { state.RemovePredicate(predicateLiteral.PredicateAtom.Clone()); } return; } EqualsLiteralCNF equalsLiteral = literal as EqualsLiteralCNF; if (equalsLiteral != null) { var assignment = equalsLiteral.TryGetObjectFunctionAssignment(); if (assignment != null) { if (!literal.IsNegated) { state.AssignObjectFunction(assignment.Item1.FunctionAtom.Clone(), ObjectFunctionTerm.UndefinedValue); } } return; } NumericCompareLiteralCNF compareLiteral = literal as NumericCompareLiteralCNF; if (compareLiteral != null) { var assignment = compareLiteral.TryGetNumericFunctionAssignment(); if (assignment != null) { if (!compareLiteral.IsNegated) { state.AssignNumericFunction(assignment.Item1.FunctionAtom.Clone(), NumericFunction.UndefinedValue); } } } }; if (index >= conjuncts.Count) { yield return((IRelativeState)result.Clone()); } else { var conjunct = conjuncts[index]; ClauseCNF clause = conjunct as ClauseCNF; if (clause != null) { foreach (var literal in clause) { addLiteral(result, literal); foreach (var item in EnumerateRelativeStatesByCNF(index + 1, conjuncts, result)) { yield return(item); } removeLiteral(result, literal); } } else { LiteralCNF literal = conjunct as LiteralCNF; Debug.Assert(literal != null); addLiteral(result, literal); foreach (var item in EnumerateRelativeStatesByCNF(index + 1, conjuncts, result)) { yield return(item); } removeLiteral(result, literal); } } }
/// <summary> /// Visits and performs a property count on relational operator expression. /// </summary> /// <param name="expression">Relational operator expression.</param> /// <returns>Tuple (property satisfied count, property not satisfied count).</returns> public Tuple <int, int> Visit(NumericCompareLiteralCNF expression) { return(ProcessPrimitiveExpression(expression)); }
/// <summary> /// Visits and performs a property count on relational operator expression. /// </summary> /// <param name="expression">Relational operator expression.</param> /// <returns>Tuple (property satisfied count, property not satisfied count).</returns> public Tuple <double, double> Visit(NumericCompareLiteralCNF expression) { // this property is not taken into account return(Tuple.Create(0.0, 0.0)); }
/// <summary> /// Evaluates the expression. /// </summary> /// <param name="expression">Expression.</param> public void Visit(NumericCompareLiteralCNF expression) { }
/// <summary> /// Evaluates the expression. /// </summary> /// <param name="expression">Expression.</param> public void Visit(NumericCompareLiteralCNF expression) { expression.LeftArgument.Accept(this); expression.RightArgument.Accept(this); }
/// <summary> /// Processes a single CNF literal of operator preconditions. /// </summary> /// <param name="literal">CNF literal.</param> /// <param name="state">Relative state to be applied to.</param> private static void ProcessPreconditionLiteral(LiteralCNF literal, IRelativeState state) { PredicateLiteralCNF predicateLiteral = literal as PredicateLiteralCNF; if (predicateLiteral != null) { if (predicateLiteral.IsNegated) { state.AddNegatedPredicate(predicateLiteral.PredicateAtom); } else { state.AddPredicate(predicateLiteral.PredicateAtom); } return; } EqualsLiteralCNF equalsLiteral = literal as EqualsLiteralCNF; if (equalsLiteral != null) { ObjectFunctionTerm objFunc = equalsLiteral.LeftArgument as ObjectFunctionTerm; ConstantTerm constTerm = equalsLiteral.RightArgument as ConstantTerm; if (objFunc == null || constTerm == null) { objFunc = equalsLiteral.RightArgument as ObjectFunctionTerm; constTerm = equalsLiteral.LeftArgument as ConstantTerm; } if (objFunc != null && constTerm != null) { if (equalsLiteral.IsNegated) { if (state.GetObjectFunctionValue(objFunc.FunctionAtom) == constTerm.NameId) { state.AssignObjectFunction(objFunc.FunctionAtom, IdManager.InvalidId); } } else { state.AssignObjectFunction(objFunc.FunctionAtom, constTerm.NameId); } } return; } NumericCompareLiteralCNF compareLiteral = literal as NumericCompareLiteralCNF; if (compareLiteral != null) { if (compareLiteral.Operator != NumericCompareExpression.RelationalOperator.EQ) { return; } NumericFunction numFunc = compareLiteral.LeftArgument as NumericFunction; Number number = compareLiteral.RightArgument as Number; if (numFunc == null || number == null) { numFunc = compareLiteral.RightArgument as NumericFunction; number = compareLiteral.LeftArgument as Number; } if (numFunc != null && number != null) { if (compareLiteral.IsNegated) { if (state.GetNumericFunctionValue(numFunc.FunctionAtom).Equals(number.Value)) { state.AssignNumericFunction(numFunc.FunctionAtom, NumericFunction.DefaultValue); } } else { state.AssignNumericFunction(numFunc.FunctionAtom, number.Value); } } } }