/// <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> /// Generates all possible PDDL states meeting conditions specified by the relative state. Lazy generated via yield return. /// </summary> /// <param name="relativeState">Reference relative state.</param> /// <param name="problem">Planning problem.</param> /// <returns>All possible PDDL states meeting the conditions.</returns> public static IEnumerable <IState> EnumerateStates(IRelativeState relativeState, Problem problem) { // note: numeric function assignments are not enumerated (as it is generally infinite), but only fixed by the values of the source state Func <IAtom, bool?> predicateChecker = (predicate) => { if (relativeState.HasPredicate(predicate)) { return(true); } else if (relativeState.HasNegatedPredicate(predicate)) { return(false); } return(null); }; Func <IAtom, int> objectFunctionChecker = relativeState.GetObjectFunctionValue; IState initState = new State(problem.IdManager); foreach (var numericFunction in relativeState.GetNumericFunctions()) { initState.AssignNumericFunction(numericFunction.Key, numericFunction.Value); } var predicates = problem.EvaluationManager.GroundingManager.GetAllGroundedPredicates(); var objectFunctions = problem.EvaluationManager.GroundingManager.GetAllGroundedObjectFunctions(); foreach (var state in EnumerateStatesByPredicates(0, predicates, initState, predicateChecker)) { foreach (var resultState in EnumerateStatesByObjectFunctions(0, objectFunctions, state, objectFunctionChecker)) { yield return(resultState); } } }