/// <summary> /// Visits and handles the effect. /// </summary> /// <param name="effect">Effect.</param> public void Visit(ObjectAssignEffect effect) { IAtom groundedFunctionAtom = GroundingManager.GroundAtomDeep(effect.FunctionAtom, Substitution, State); ITerm value = GroundingManager.GroundTermDeep(effect.Value, Substitution, State); ConstantTerm constantTermValue = (ConstantTerm)value; State.AssignObjectFunction(groundedFunctionAtom, constantTermValue.NameId); }
/// <summary> /// Processes primitive effects. /// </summary> /// <param name="relativeState">Relative state.</param> /// <returns>Effect relevance (relevant, irrelevant, or anti-relevant).</returns> private EffectRelevance ProcessPrimitiveEffects(IRelativeState relativeState) { bool anyRelevant = false; foreach (var predicateAtom in relativeState.GetPredicates()) { anyRelevant |= Effects.GroundedPositivePredicateEffects.Contains(predicateAtom); if (Effects.GroundedNegativePredicateEffects.Contains(predicateAtom)) { return(EffectRelevance.ANTI_RELEVANT); } } foreach (var predicateAtom in relativeState.GetNegatedPredicates()) { anyRelevant |= Effects.GroundedNegativePredicateEffects.Contains(predicateAtom); if (Effects.GroundedPositivePredicateEffects.Contains(predicateAtom)) { return(EffectRelevance.ANTI_RELEVANT); } } foreach (var function in relativeState.GetObjectFunctions()) { ITerm assignValue; if (Effects.GroundedObjectFunctionAssignmentEffects.TryGetValue(function.Key, out assignValue)) { ConstantTerm constantValue = assignValue as ConstantTerm; if (constantValue == null || constantValue.NameId != function.Value) { // surely assigning different value -> anti-relevant return(EffectRelevance.ANTI_RELEVANT); } anyRelevant = true; } } foreach (var function in relativeState.GetNumericFunctions()) { INumericExpression assignExpression; if (Effects.GroundedNumericFunctionAssignmentEffects.TryGetValue(function.Key, out assignExpression)) { Number numberValue = assignExpression as Number; if (numberValue == null || !numberValue.Value.Equals(function.Value)) { // surely assigning different value -> anti-relevant return(EffectRelevance.ANTI_RELEVANT); } anyRelevant = true; } } return((anyRelevant) ? EffectRelevance.RELEVANT : EffectRelevance.IRRELEVANT); }
/// <summary> /// Checks whether the literal is in the form of a simple object function assignment, e.g. (= (objFunc) constA), /// and in such case returns the pair of object function and its assigned value. Otherwise returns null. /// </summary> /// <returns>Object function assignment with its value, if the literal is in such form. Null otherwise.</returns> public Tuple <ObjectFunctionTerm, ConstantTerm> TryGetObjectFunctionAssignment() { ObjectFunctionTerm objFunc = LeftArgument as ObjectFunctionTerm; ConstantTerm constTerm = RightArgument as ConstantTerm; if (objFunc == null || constTerm == null) { objFunc = RightArgument as ObjectFunctionTerm; constTerm = LeftArgument as ConstantTerm; } return((objFunc == null || constTerm == null) ? null : Tuple.Create(objFunc, constTerm)); }
/// <summary> /// Processes primitive effects. /// </summary> /// <param name="relativeState">Relative state to be modified.</param> private void ProcessPrimitiveEffects(IRelativeState relativeState) { foreach (var positivePredicate in Effects.GroundedPositivePredicateEffects) { if (relativeState.HasPredicate(positivePredicate)) { relativeState.RemovePredicate(positivePredicate); } } foreach (var negatedPredicate in Effects.GroundedNegativePredicateEffects) { if (relativeState.HasNegatedPredicate(negatedPredicate)) { relativeState.RemoveNegatedPredicate(negatedPredicate); } } foreach (var objectFunction in Effects.GroundedObjectFunctionAssignmentEffects) { var groundedValue = GroundingManager.GroundTermDeep(objectFunction.Value, OperatorSubstitution, relativeState); ConstantTerm constantValue = groundedValue as ConstantTerm; if (constantValue != null) { if (relativeState.GetObjectFunctionValue(objectFunction.Key) == constantValue.NameId) { relativeState.AssignObjectFunction(objectFunction.Key, ObjectFunctionTerm.UndefinedValue); } } } foreach (var numericFunction in Effects.GroundedNumericFunctionAssignmentEffects) { NumericAssignmentsBackwardsReplacer replacer = new NumericAssignmentsBackwardsReplacer(Effects.GroundedNumericFunctionAssignmentEffects, GroundingManager, OperatorSubstitution, new Substitution()); INumericExpression reducedAssignExpression = replacer.Replace(numericFunction.Value); Number assignNumber = reducedAssignExpression as Number; if (assignNumber != null) { if (relativeState.GetNumericFunctionValue(numericFunction.Key).Equals(assignNumber.Value)) { relativeState.AssignNumericFunction(numericFunction.Key, NumericFunction.UndefinedValue); } } } }
/// <summary> /// Gets the unification with the specified atom, i.e. calculates the variable substitution required to ground variable terms of the /// current atom with the grounded terms (i.e. constants) of the other atom. /// </summary> /// <param name="referenceAtom">Reference atom.</param> /// <returns>Unification in the form of variable substitution.</returns> public ISubstitution GetUnificationWith(IAtom referenceAtom) { Debug.Assert(GetNameId() == referenceAtom.GetNameId() && GetTerms().Count == referenceAtom.GetTerms().Count, "Unification of incompatible atoms!"); ISubstitution unification = new Substitution(); int termIndex = 0; foreach (var term in GetTerms()) { VariableTerm variableTerm = term as VariableTerm; if (variableTerm != null) { ConstantTerm valueTerm = referenceAtom.GetTerms()[termIndex] as ConstantTerm; if (valueTerm != null) { unification.Add(variableTerm.NameId, valueTerm.NameId); } } ++termIndex; } return(unification); }
/// <summary> /// Visits expression term. /// </summary> /// <param name="term">Expression term.</param> public void Visit(ConstantTerm term) { TermStack.Push(term.NameID); }
/// <summary> /// Gets the grounded term of the atom (i.e. constant/object ID), if grounded. /// </summary> /// <param name="index">Term index.</param> /// <returns>Grounded term (i.e. constant/object ID), or -1 if not grounded.</returns> public int GetGroundedTerm(int index) { ConstantTerm constantTerm = Terms[index] as ConstantTerm; return(constantTerm?.NameId ?? NotGroundedTerm); }
/// <summary> /// Transforms the term. /// </summary> /// <param name="term">Term.</param> /// <returns>Transformed term.</returns> public ITerm Visit(ConstantTerm term) { return(term.Clone()); }
/// <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); } } } }