/// <summary> /// Grounds all the cached effects with the currently use operator substitution. /// </summary> /// <param name="groundingManager">Grounding manager.</param> /// <param name="operatorSubstitution">Variables substitution.</param> public void GroundEffectsByCurrentOperatorSubstitution(GroundingManager groundingManager, ISubstitution operatorSubstitution) { OriginalLiftedPredicates.Clear(); OriginalLiftedFunctions.Clear(); GroundedPositivePredicateEffects.Clear(); foreach (var predicate in PositivePredicateEffects) { var groundedPredicate = operatorSubstitution.IsEmpty() ? predicate : groundingManager.GroundAtom(predicate, operatorSubstitution); GroundedPositivePredicateEffects.Add(groundedPredicate); if (!OriginalLiftedPredicates.ContainsKey(groundedPredicate)) { OriginalLiftedPredicates.Add(groundedPredicate, predicate); } } GroundedNegativePredicateEffects.Clear(); foreach (var predicate in NegativePredicateEffects) { var groundedPredicate = operatorSubstitution.IsEmpty() ? predicate : groundingManager.GroundAtom(predicate, operatorSubstitution); GroundedNegativePredicateEffects.Add(groundedPredicate); if (!OriginalLiftedPredicates.ContainsKey(groundedPredicate)) { OriginalLiftedPredicates.Add(groundedPredicate, predicate); } } GroundedNumericFunctionAssignmentEffects.Clear(); foreach (var numericFunc in NumericFunctionAssignmentEffects) { var groundedFunction = operatorSubstitution.IsEmpty() ? numericFunc.FunctionAtom : groundingManager.GroundAtom(numericFunc.FunctionAtom, operatorSubstitution); var groundedAssignment = operatorSubstitution.IsEmpty() ? numericFunc.GetBackwardsSubstitutedValue() : groundingManager.GroundNumericExpression(numericFunc.GetBackwardsSubstitutedValue(), operatorSubstitution); GroundedNumericFunctionAssignmentEffects.Add(groundedFunction, groundedAssignment); if (!OriginalLiftedFunctions.ContainsKey(groundedFunction)) { OriginalLiftedFunctions.Add(groundedFunction, numericFunc.FunctionAtom); } } GroundedObjectFunctionAssignmentEffects.Clear(); foreach (var objectFunc in ObjectFunctionAssignmentEffects) { var groundedFunction = operatorSubstitution.IsEmpty() ? objectFunc.FunctionAtom : groundingManager.GroundAtom(objectFunc.FunctionAtom, operatorSubstitution); var groundedAssignment = operatorSubstitution.IsEmpty() ? objectFunc.Value : groundingManager.GroundTerm(objectFunc.Value, operatorSubstitution); GroundedObjectFunctionAssignmentEffects.Add(groundedFunction, groundedAssignment); if (!OriginalLiftedFunctions.ContainsKey(groundedFunction)) { OriginalLiftedFunctions.Add(groundedFunction, objectFunc.FunctionAtom); } } }
/// <summary> /// Visits the expression. /// </summary> /// <param name="expression">Expression.</param> public Tuple <bool, bool> Visit(EqualsLiteralCNF expression) { bool positiveCondition = false; bool negativeCondition = true; Action <ITerm, ITerm> checkObjectFunctionArgument = (argument, secondaryArgument) => { ObjectFunctionTerm objectFunction = argument as ObjectFunctionTerm; if (objectFunction != null) { ITerm assignValue; if (Effects.GroundedObjectFunctionAssignmentEffects.TryGetValue(GroundingManager.GroundAtom(objectFunction.FunctionAtom, ExpressionSubstitution), out assignValue)) { positiveCondition = true; if (!(secondaryArgument is ObjectFunctionTerm) && !(assignValue is ObjectFunctionTerm)) { bool valueDiffersValueAssign = !GroundingManager.GroundTerm(secondaryArgument, ExpressionSubstitution).Equals(GroundingManager.GroundTerm(assignValue, OperatorSubstitution)); if (valueDiffersValueAssign && !expression.IsNegated || !valueDiffersValueAssign && expression.IsNegated) { // surely assigning different value (or assigning exact value with negated equals) -> not relevant negativeCondition = false; } } } } }; checkObjectFunctionArgument(expression.LeftArgument, expression.RightArgument); checkObjectFunctionArgument(expression.RightArgument, expression.LeftArgument); return(Tuple.Create(positiveCondition, negativeCondition)); }
/// <summary> /// Visits and handles the effect. /// </summary> /// <param name="effect">Effect.</param> public void Visit(PredicateEffect effect) { if (!IsNegated) { ResultAtoms.Add(GroundingManager.GroundAtom(effect.PredicateAtom, Substitution)); } }
/// <summary> /// Visits the expression. /// </summary> /// <param name="expression">Expression.</param> public Tuple <bool, bool> Visit(PredicateLiteralCNF expression) { bool hasPositive = Effects.GroundedPositivePredicateEffects.Contains(GroundingManager.GroundAtom(expression.PredicateAtom, ExpressionSubstitution)); bool hasNegative = Effects.GroundedNegativePredicateEffects.Contains(GroundingManager.GroundAtom(expression.PredicateAtom, ExpressionSubstitution)); bool positiveCondition = (expression.IsNegated) ? hasNegative : hasPositive; bool negativeCondition = !((expression.IsNegated) ? hasPositive : hasNegative); return(Tuple.Create(positiveCondition, negativeCondition)); }
/// <summary> /// Visits and evaluates predicate expression. /// </summary> /// <param name="expression">Predicate expression.</param> /// <returns>True if the specified expression evaluates as true, false otherwise.</returns> public bool Visit(PredicateExpression expression) { // if the predicate is a rigid relation, then check whether it has the correct value if (RigidRelations.IsPredicateRigidRelation(expression.PredicateAtom)) { IAtom predicateAtom = GroundingManager.GroundAtom(expression.PredicateAtom, Substitution); return(RigidRelations.Contains(predicateAtom)); } return(true); }
/// <summary> /// Visits and performs a property count on predicate expression. /// </summary> /// <param name="expression">Predicate expression.</param> /// <returns>Tuple (property satisfied count, property not satisfied count).</returns> public Tuple <double, double> Visit(PredicateLiteralCNF expression) { var groundedAtom = GroundingManager.GroundAtom(expression.PredicateAtom, Substitution); double value; if (StateLabels.TryGetValue(groundedAtom, out value)) { return((expression.IsNegated) ? Tuple.Create(0.0, value) : Tuple.Create(value, 0.0)); } return(Tuple.Create(0.0, 0.0)); }
/// <summary> /// Transforms the numeric expression. /// </summary> /// <param name="expression">Numeric expression.</param> /// <returns>Transformed numeric expression.</returns> public INumericExpression Visit(NumericFunction expression) { IAtom functionAtom = GroundingManager.GroundAtom(expression.FunctionAtom, ExpressionSubstitution); if (!ReplacedFunctionAtomsInSubExpression.Contains(functionAtom)) { INumericExpression substitutedValue; if (NumericFunctionAssignments.TryGetValue(functionAtom, out substitutedValue)) { ReplacedFunctionAtomsInSubExpression.Add(functionAtom); ExpressionSubstitution.AddLocalSubstitution(OperatorSubstitution); INumericExpression transformedValue = substitutedValue.Accept(this); ExpressionSubstitution.RemoveLocalSubstitution(OperatorSubstitution); ReplacedFunctionAtomsInSubExpression.Remove(functionAtom); return(transformedValue); } } return(expression.Clone()); }
/// <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> /// Grounds the specified atom. /// </summary> /// <param name="atom">Atom.</param> /// <returns>Grounded atom.</returns> private IAtom GroundAtom(IAtom atom) { return(GroundingManager.GroundAtom(atom, ExpressionSubstitution)); }