/// <summary> /// Processes forall effects. /// </summary> /// <param name="relativeState">Relative state.</param> /// <returns>Effect relevance (relevant, irrelevant, or anti-relevant).</returns> private EffectRelevance ProcessForallEffects(IRelativeState relativeState) { bool anyRelevant = false; foreach (var forallEffect in Effects.ForallEffects) { EffectsRelevanceRelativeStateEvaluator evaluator = new EffectsRelevanceRelativeStateEvaluator(forallEffect.Effects, GroundingManager); IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(forallEffect.Parameters); foreach (var localSubstitution in localSubstitutions) { OperatorSubstitution.AddLocalSubstitution(localSubstitution); var result = evaluator.EvaluateInternal(relativeState, OperatorSubstitution); anyRelevant |= (result == EffectRelevance.RELEVANT); OperatorSubstitution.RemoveLocalSubstitution(localSubstitution); if (result == EffectRelevance.ANTI_RELEVANT) { return(EffectRelevance.ANTI_RELEVANT); } } } return((anyRelevant) ? EffectRelevance.RELEVANT : EffectRelevance.IRRELEVANT); }
/// <summary> /// Processes conditional (when) effects. /// </summary> /// <param name="relativeState">Relative state.</param> /// <param name="relevantConditionalEffects">Output indices of relevant conditional effects (can be null).</param> /// <returns>Effect relevance (relevant, irrelevant, or anti-relevant).</returns> private EffectRelevance ProcessWhenEffects(IRelativeState relativeState, IList <int> relevantConditionalEffects = null) { bool anyRelevant = false; int whenEffectIndex = -1; foreach (var whenEffect in Effects.WhenEffects) { ++whenEffectIndex; List <IEffect> subEffects = new List <IEffect>(); whenEffect.Effects.ForEach(subEffect => subEffects.Add(subEffect)); EffectsRelevanceRelativeStateEvaluator evaluator = new EffectsRelevanceRelativeStateEvaluator(subEffects, GroundingManager); var result = evaluator.EvaluateInternal(relativeState, OperatorSubstitution, relevantConditionalEffects); if (result == EffectRelevance.ANTI_RELEVANT) { // anti-relevant conditional effect -> can't be used (but it doesn't have to be, we just ignore it) continue; } if (result == EffectRelevance.RELEVANT) { relevantConditionalEffects?.Add(whenEffectIndex); anyRelevant = true; } } return((anyRelevant) ? EffectRelevance.RELEVANT : EffectRelevance.IRRELEVANT); }
/// <summary> /// Applies backwards the relevant operator effects and operator preconditions to the given target relative state. /// </summary> /// <param name="relativeState">Target relative state to be modified.</param> /// <param name="operatorSubstitution">Variables substitution.</param> /// <returns>Preceding relative states.</returns> public IEnumerable <Planner.IRelativeState> ApplyBackwards(IRelativeState relativeState, ISubstitution operatorSubstitution) { OperatorSubstitution = operatorSubstitution; Effects.GroundEffectsByCurrentOperatorSubstitution(GroundingManager, operatorSubstitution); relativeState = (IRelativeState)relativeState.Clone(); // prepare operator preconditions var operatorPreconditions = (OperatorPreconditions != null) ? GroundingManager.GroundConditions(ClearRigidRelations(OperatorPreconditions), OperatorSubstitution) : null; // remove positively contributing effects from the relative state and insert the operator preconditions ProcessPrimitiveEffects(relativeState); relativeState = ProcessForallEffects(relativeState); foreach (var resultState in ProcessWhenEffects(relativeState)) { if (operatorPreconditions != null) { foreach (var modifiedResultState in ProcessOperatorPreconditions(operatorPreconditions, resultState)) { yield return(modifiedResultState); } } else { yield return(resultState); } } }
/// <summary> /// Checks whether the operator effect is relevant to the given target relative state. /// </summary> /// <param name="relativeState">Relative state.</param> /// <returns>Effect relevance result.</returns> public override EffectRelevance IsRelevant(IRelativeState relativeState) { var assignmentRelevance = base.IsRelevant(relativeState); if (assignmentRelevance == EffectRelevance.RELEVANT) { foreach (var constraint in Conditions) { if (constraint.GetVariable() == Assignment.GetVariable()) { continue; } int value = relativeState.GetValue(constraint.GetVariable()); if (value == RelativeState.WildCardValue) { continue; } if (constraint.GetValue() != value) { return(EffectRelevance.IRRELEVANT); } } return(EffectRelevance.RELEVANT); } // conditional effect does not have to be used, so it should never be explicitly anti-relevant return(EffectRelevance.IRRELEVANT); }
/// <summary> /// Checks whether the operator effects are relevant to the given target relative state. /// </summary> /// <param name="relativeState">Relative state for the application.</param> /// <param name="operatorPreconditions">Operator preconditions.</param> /// <returns>True if the operator effects are relevant to the given relative state, false otherwise.</returns> public bool IsRelevant(IRelativeState relativeState, ISimpleConditions operatorPreconditions) { CashedVariablesCollector.Clear(); bool anyRelevant = false; foreach (var effect in this) { var relevance = effect.IsRelevant(relativeState); switch (relevance) { case EffectRelevance.ANTI_RELEVANT: { return(false); } case EffectRelevance.RELEVANT: { anyRelevant = true; CashedVariablesCollector.Add(effect.GetAssignment().GetVariable()); break; } case EffectRelevance.IRRELEVANT: { if (effect.GetConditions() != null) { CashedVariablesCollector.Add(effect.GetAssignment().GetVariable()); } break; } } } if (!anyRelevant) { return(false); } // additionally, the relative state has to be checked against operator preconditions ("hidden effects") foreach (var constraint in operatorPreconditions) { int variable = constraint.GetVariable(); if (!CashedVariablesCollector.Contains(variable)) { int value = relativeState.GetValue(variable); if (value == RelativeState.WildCardValue) { continue; } if (value != constraint.GetValue()) { return(false); } } } return(true); }
/// <summary> /// Evaluates whether the operator effects are relevant for the specified relative state. /// </summary> /// <param name="relativeState">Relative state.</param> /// <param name="operatorSubstitution">Variables substitution of the operator.</param> /// <param name="relevantConditionalEffects">Output indices of relevant conditional effects (can be null).</param> /// <returns>Effect relevance (relevant, irrelevant, or anti-relevant).</returns> private EffectRelevance EvaluateInternal(IRelativeState relativeState, ISubstitution operatorSubstitution, IList <int> relevantConditionalEffects = null) { Effects.GroundEffectsByCurrentOperatorSubstitution(GroundingManager, operatorSubstitution); OperatorSubstitution = operatorSubstitution; var primitivesResult = ProcessPrimitiveEffects(relativeState); if (primitivesResult == EffectRelevance.ANTI_RELEVANT) { return(EffectRelevance.ANTI_RELEVANT); } var forallResult = ProcessForallEffects(relativeState); if (forallResult == EffectRelevance.ANTI_RELEVANT) { return(EffectRelevance.ANTI_RELEVANT); } var whenResult = ProcessWhenEffects(relativeState, relevantConditionalEffects); if (whenResult == EffectRelevance.ANTI_RELEVANT) { return(EffectRelevance.ANTI_RELEVANT); } if (primitivesResult == EffectRelevance.RELEVANT || forallResult == EffectRelevance.RELEVANT || whenResult == EffectRelevance.RELEVANT) { return(EffectRelevance.RELEVANT); } return(EffectRelevance.IRRELEVANT); }
/// <summary> /// Gets the heuristic value for the given relative state (in the context of backward search). /// </summary> /// <param name="relativeState">Relative state to be evaluated.</param> /// <returns>Heuristic value for the specified relative state.</returns> protected override double GetValueImpl(IRelativeState relativeState) { if (Random.NextDouble() < Heuristics.First().Item2) { return(Heuristics.First().Item1.GetValue(relativeState)); } return(Heuristics.Sum(heuristic => heuristic.Item2 * heuristic.Item1.GetValue(relativeState))); }
/// <summary> /// Checks whether the operator is relevant to the given target relative state. /// </summary> /// <param name="relativeState">Target relative state.</param> /// <param name="substitution">Variables substitution.</param> /// <param name="relevantConditionalEffects">Output indices of relevant conditional effects (can be null).</param> /// <returns>True if the operator is relevant to the given relative state, false otherwise.</returns> public bool IsRelevant(IRelativeState relativeState, ISubstitution substitution, IList <int> relevantConditionalEffects = null) { if (!Preconditions.EvaluateRigidRelationsCompliance(substitution)) { return(false); } return(Effects.IsRelevant(relativeState, substitution, relevantConditionalEffects)); }
/// <summary> /// Gets the heuristic value for the given relative state (in the context of backward search). /// </summary> /// <param name="relativeState">Relative state to be evaluated.</param> /// <returns>Heuristic value for the specified relative state.</returns> public double GetValue(IRelativeState relativeState) { if (Statistics.DoMeasure) { double value = GetValueImpl(relativeState); Statistics.UpdateStatistics(value); return(value); } return(GetValueImpl(relativeState)); }
/// <summary> /// Applies the operator backwards to the given target relative state. The result is a new relative state (or more relative states, if conditional effects are present). /// </summary> /// <param name="relativeState">Relative state for the application.</param> /// <param name="operatorPreconditions">Operator preconditions.</param> /// <returns>Preceding relative states.</returns> public IEnumerable <IRelativeState> ApplyBackwards(IRelativeState relativeState, ISimpleConditions operatorPreconditions) { IRelativeState result = (IRelativeState)relativeState.Clone(); bool anyConditionalEffect = false; foreach (var effect in this) { if (effect.GetConditions() == null) { result = effect.ApplyBackwards(result); } else { anyConditionalEffect = true; } } foreach (var constraint in operatorPreconditions) { result.SetValue(constraint.GetVariable(), constraint.GetValue()); } if (!anyConditionalEffect) { yield return(result); } else { List <IRelativeState> states = new List <IRelativeState> { result }; foreach (var effect in this) { if (effect.GetConditions() != null) { int statesCount = states.Count; for (int i = 0; i < statesCount; ++i) { var newEffect = effect.ApplyBackwards(states[i]); if (newEffect != null) { states.Add(newEffect); } } } } foreach (var state in states) { yield return(state); } } }
/// <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> /// Collects relevant when effects for the specified relative state. /// </summary> /// <param name="relativeState">Relative state.</param> /// <returns>List of relevant when effects.</returns> private List <WhenEffect> GetRelevantWhenEffectsForConditions(IRelativeState relativeState) { List <int> relevantWhenEffectsIndices = new List <int>(); EffectsRelevanceRelativeStateEvaluator relevanceEvaluator = new EffectsRelevanceRelativeStateEvaluator(Effects, GroundingManager); relevanceEvaluator.Evaluate(relativeState, new Substitution(), relevantWhenEffectsIndices); // empty substitution here because effects already grounded List <WhenEffect> relevantWhenEffects = new List <WhenEffect>(); relevantWhenEffectsIndices.ForEach(index => relevantWhenEffects.Add(Effects.WhenEffects[index])); return(relevantWhenEffects); }
/// <summary> /// Gets a collection of all relevant predecessors (backwards transitions) from the specified relative state. Lazy generated via yield return. /// </summary> /// <param name="relativeState">Original relative state.</param> /// <returns>Lazy generated collection of relevant predecessors.</returns> public IEnumerable <IPredecessor> GetPredecessors(IRelativeState relativeState) { // This part may be later optimized to use operator decision tree, just like IConditions foreach (var op in Problem.Operators) { if (op.IsRelevant(relativeState)) { yield return(new Predecessor(relativeState, op)); } } }
/// <summary> /// Checks whether the operator effect is relevant to the given target relative state. /// </summary> /// <param name="relativeState">Relative state.</param> /// <returns>Effect relevance result.</returns> public virtual EffectRelevance IsRelevant(IRelativeState relativeState) { int value = relativeState.GetValue(Assignment.GetVariable()); if (value == RelativeState.WildCardValue) { // not a conflict, but not positively contributing either return(EffectRelevance.IRRELEVANT); } return((Assignment.GetValue() == value) ? EffectRelevance.RELEVANT : EffectRelevance.ANTI_RELEVANT); }
/// <summary> /// Gets a collection of all relevant predecessors (backwards transitions) from the specified relative state. Lazy generated via yield return. /// </summary> /// <param name="relativeState">Original state.</param> /// <returns>Lazy generated collection of relevant predecessors.</returns> public IEnumerable <IPredecessor> GetPredecessors(IRelativeState relativeState) { foreach (var liftedOperator in LiftedOperators) { IEnumerable <ISubstitution> operatorSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(liftedOperator.Parameters); foreach (var operatorSubstitution in operatorSubstitutions) { if (liftedOperator.IsRelevant(relativeState, operatorSubstitution)) { yield return(new Predecessor(relativeState, new Operator(liftedOperator, operatorSubstitution))); } } } }
/// <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> /// Applies the effect backwards to the given relative state. /// </summary> /// <param name="relativeState">Relative state.</param> public override IRelativeState ApplyBackwards(IRelativeState relativeState) { // we explicitly apply the effect for the relative state, if it's relevant if (IsRelevant(relativeState) == EffectRelevance.RELEVANT) { var newState = (IRelativeState)relativeState.Clone(); newState.SetValue(Assignment.GetVariable(), RelativeState.WildCardValue); foreach (var constraint in Conditions) { newState.SetValue(constraint.GetVariable(), constraint.GetValue()); } return(newState); } // the conditional effect was not applied, because it was not relevant return(null); }
/// <summary> /// Applies the operator preconditions to the given relative state. /// </summary> /// <param name="operatorPreconditions">Grounded operator preconditions.</param> /// <param name="relativeState">Relative state.</param> /// <returns>Modified relative states.</returns> private static IEnumerable <IRelativeState> ProcessOperatorPreconditions(Conditions operatorPreconditions, IRelativeState relativeState) { var conditionsCNF = (ConditionsCNF)operatorPreconditions.GetCNF(); HashSet <IRelativeState> states = new HashSet <IRelativeState> { relativeState }; foreach (var conjunct in conditionsCNF) { // this block processes all possible combinations of applications in a single clause (even though it is a primitive clause of one literal) HashSet <IRelativeState> newStatesForConjunct = new HashSet <IRelativeState>(); foreach (var literal in conjunct.GetLiterals()) { HashSet <IRelativeState> newStatesForLiteral = new HashSet <IRelativeState>(); foreach (var state in states) { IRelativeState newState = (IRelativeState)state.Clone(); ProcessPreconditionLiteral(literal, newState); newStatesForLiteral.Add(newState); } foreach (var state in newStatesForConjunct) { IRelativeState newState = (IRelativeState)state.Clone(); ProcessPreconditionLiteral(literal, newState); newStatesForLiteral.Add(newState); } newStatesForConjunct.UnionWith(newStatesForLiteral); } states = newStatesForConjunct; } foreach (var resultState in states) { yield return(resultState); } }
/// <summary> /// Processes forall effects. /// </summary> /// <param name="relativeState">Relative state to be modified.</param> /// <returns>Possibly modified relative state.</returns> private IRelativeState ProcessForallEffects(IRelativeState relativeState) { if (Effects.ForallEffects.Count == 0) { return(relativeState); } foreach (var forallEffect in Effects.ForallEffects) { EffectsBackwardsRelativeStateApplier innerApplier = new EffectsBackwardsRelativeStateApplier(null, forallEffect.Effects, EvaluationManager); IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(forallEffect.Parameters); foreach (var localSubstitution in localSubstitutions) { OperatorSubstitution.AddLocalSubstitution(localSubstitution); relativeState = (IRelativeState)innerApplier.ApplyBackwards(relativeState, OperatorSubstitution).First(); OperatorSubstitution.RemoveLocalSubstitution(localSubstitution); } } return(relativeState); }
/// <summary> /// Processes conditional (when) effects. /// </summary> /// <param name="relativeState">>Relative state to be processed.</param> /// <returns>Modified relative states.</returns> private IEnumerable <IRelativeState> ProcessWhenEffects(IRelativeState relativeState) { if (Effects.WhenEffects.Count == 0) { yield return(relativeState); yield break; } // Collect the relevant when effects, first List <WhenEffect> relevantWhenEffects = GetRelevantWhenEffectsForConditions(relativeState); // Each of the relevant when effect is either used or not (dynamic programming approach to get all combinations of when effects usage) List <IRelativeState> applicationResults = new List <IRelativeState> { relativeState }; foreach (var whenEffect in relevantWhenEffects) { Conditions whenCondition = new Conditions(whenEffect.Expression, EvaluationManager); EffectsBackwardsRelativeStateApplier innerApplier = new EffectsBackwardsRelativeStateApplier(whenCondition, new List <IEffect>(whenEffect.Effects), EvaluationManager); List <IRelativeState> currentEffectApplications = new List <IRelativeState>(); foreach (var currentRelativeState in applicationResults) { foreach (var resultRelativeState in innerApplier.ApplyBackwards(currentRelativeState, new Substitution())) { currentEffectApplications.Add((IRelativeState)resultRelativeState); } } applicationResults.AddRange(currentEffectApplications); } foreach (var resultRelativeState in applicationResults) { yield return(resultRelativeState); } }
/// <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); } } }
/// <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> /// Constructs the predecessor entity from relative state. /// </summary> /// <param name="referenceRelativeState">Reference to the original relative state.</param> /// <param name="appliedOperator">Grounded applied operator.</param> public Predecessor(IRelativeState referenceRelativeState, IOperator appliedOperator) { ReferenceRelativeState = referenceRelativeState; AppliedOperator = appliedOperator; }
/// <summary> /// Gets the heuristic value for the given relative state (in the context of backward search). /// </summary> /// <param name="relativeState">Relative state to be evaluated.</param> /// <returns>Heuristic value for the specified relative state.</returns> protected override double GetValueImpl(IRelativeState relativeState) { return(Heuristics.Sum(heuristic => heuristic.GetValue(relativeState))); }
/// <summary> /// Applies the operator backwards to the given target relative state. The result is a new relative state (or more relative states, if conditional effects are present). /// </summary> /// <param name="relativeState">Target relative state.</param> /// <param name="substitution">Variables substitution.</param> /// <returns>Preceding relative states.</returns> public IEnumerable <Planner.IRelativeState> ApplyBackwards(IRelativeState relativeState, ISubstitution substitution) { return(EffectsBackwardsRelativeStateApplier.Value.ApplyBackwards(relativeState, substitution)); }
/// <summary> /// Checks whether the operator is relevant to the given target relative state. /// </summary> /// <param name="relativeState">Target relative state.</param> /// <param name="substitution">Variables substitution.</param> /// <param name="relevantConditionalEffects">Output indices of relevant conditional effects (can be null).</param> /// <returns>True if the operator is relevant to the given relative state, false otherwise.</returns> public bool IsRelevant(IRelativeState relativeState, ISubstitution substitution, IList <int> relevantConditionalEffects = null) { return(EffectsRelevanceRelativeStateEvaluator.Value.Evaluate(relativeState, substitution, relevantConditionalEffects)); }
/// <summary> /// Generates all possible SAS+ states meeting conditions specified by the relative state. Lazy generated via yield return. /// </summary> /// <param name="relativeState">Reference relative state.</param> /// <param name="variables">Variables of the planning problem.</param> /// <returns>All possible SAS+ states meeting the conditions.</returns> public static IEnumerable <IState> EnumerateStates(IRelativeState relativeState, Variables variables) { Func <int, int> checker = relativeState.GetValue; return(EnumerateStates(0, new State(new int[variables.Count]), checker, variables)); }
/// <summary> /// Gets the heuristic value for the given relative state (in the context of backward search). /// </summary> /// <param name="relativeState">Relative state to be evaluated.</param> /// <returns>Heuristic value for the specified relative state.</returns> protected virtual double GetValueImpl(IRelativeState relativeState) { return(GetValueImpl(relativeState.GetDescribingConditions(Problem))); }
/// <summary> /// Gets the heuristic value for the given relative state (in the context of backward search). /// </summary> /// <param name="relativeState">Relative state to be evaluated.</param> /// <returns>Heuristic value for the specified relative state.</returns> protected override double GetValueImpl(IRelativeState relativeState) { return(Weight * Heuristic.GetValue(relativeState)); }
/// <summary> /// Gets the heuristic value for the given relative state (in the context of backward search). /// </summary> /// <param name="relativeState">Relative state to be evaluated.</param> /// <returns>Heuristic value for the specified relative state.</returns> protected override double GetValueImpl(IRelativeState relativeState) { return(0.0); }