//Editor Stuff #if UNITY_EDITOR public override bool Draw() { GUILayout.BeginHorizontal(); GUILayout.Label(name); switch (type) { case Type.Boolean: bValue = EditorGUILayout.Toggle(bValue); break; case Type.Float: fCondition = (FConditions)EditorGUILayout.EnumPopup(fCondition); fValue = EditorGUILayout.FloatField(fValue); break; case Type.Int: iCondition = (IConditions)EditorGUILayout.EnumPopup(iCondition); iValue = EditorGUILayout.IntField(iValue); break; } if (GUILayout.Button("Delete")) { return(false); } GUILayout.EndHorizontal(); return(true); }
/// <summary> /// Generates all possible SAS+ relative states meeting conditions specified by the given conditions. Lazy generated via yield return. /// </summary> /// <param name="conditions">Reference conditions.</param> /// <param name="variables">Variables of the planning problem.</param> /// <returns>All possible SAS+ relative states meeting the conditions.</returns> public static IEnumerable <IRelativeState> EnumerateRelativeStates(IConditions conditions, Variables variables) { foreach (var simpleCondition in conditions.GetSimpleConditions()) { yield return(GetCorrespondingRelativeState(simpleCondition, variables)); } }
/// <summary> /// Checks whether the operator effects are relevant to the given target conditions. /// </summary> /// <param name="conditions">Conditions for the application.</param> /// <param name="operatorPreconditions">Operator preconditions.</param> /// <returns>True if the operator effects are relevant to the given conditions, false otherwise.</returns> public bool IsRelevant(IConditions conditions, ISimpleConditions operatorPreconditions) { // Besides the effects relevance, we need to check whether the operator preconditions are not in conflict with the resulting // conditions (after backward-apply). This can be done via affected variables: if some effect is relevant, then it modifies a // variable, and a constraint corresponding to this variable can be removed from the preconditions. At the end, we check the // modified precondition constraints with the target conditions and if there are conflicts, we consider the operator not // relevant. This approach works even for conditional-effects, because we take the worst case scenario. IConditions nonAffectedPreconditions = (IConditions)operatorPreconditions.Clone(); bool anyRelevant = false; foreach (var effect in this) { var relevance = effect.IsRelevant(conditions); if (relevance == EffectRelevance.ANTI_RELEVANT) { return(false); } else if (relevance == EffectRelevance.RELEVANT) { anyRelevant = true; nonAffectedPreconditions.RemoveConstraint(effect.GetAssignment()); } } return(anyRelevant && !nonAffectedPreconditions.IsConflictedWith(conditions)); }
/// <summary> /// Creates a disjunction of the current conditions and the specified other conditions. /// </summary> /// <param name="other">Other conditions.</param> /// <returns>Disjunction of the current conditions and the given other conditions.</returns> public IConditions DisjunctionWith(IConditions other) { if (other is ConditionsContradiction) { return((IConditions)Clone()); } ConditionsClause newClause = (ConditionsClause)Clone(); ConditionsClause otherClause = other as ConditionsClause; if (otherClause != null) { foreach (var conditions in otherClause) { newClause.Add((Conditions)conditions.Clone()); } } else { Debug.Assert(other is Conditions); newClause.Add((Conditions)other.Clone()); } return(newClause); }
/// <summary> /// Computes the forward cost heuristics for the given state in the relaxed planning graph. /// </summary> /// <param name="state">Starting state.</param> /// <param name="goalConditions">Goal conditions.</param> /// <param name="evaluationStrategy">Evaluation strategy.</param> /// <returns>Forward cost heuristic value from the specified state.</returns> private double ComputeForwardCost(IState state, IConditions goalConditions, ForwardCostEvaluationStrategy evaluationStrategy) { IStateLayer previousStateLayer = null; IStateLayer stateLayer = CreateLabeledStateLayer(state.GetRelaxedState()); ActionLayer actionLayer = new ActionLayer(); while (!stateLayer.Equals(previousStateLayer)) { // check goal conditions if (goalConditions.Evaluate(stateLayer.GetState())) { return(goalConditions.EvaluateOperatorPlanningGraphLabel(stateLayer.GetStateLabels(), evaluationStrategy)); } // build new action layer actionLayer.Clear(); foreach (var successor in RelaxedProblem.GetSuccessors(stateLayer.GetState())) { IOperator appliedOperator = successor.GetAppliedOperator(); double label = appliedOperator.ComputePlanningGraphLabel(stateLayer.GetStateLabels(), evaluationStrategy); actionLayer.Add(new ActionNode(appliedOperator, label + appliedOperator.GetCost())); } // build new state layer previousStateLayer = stateLayer; stateLayer = CreateLabeledStateLayer(stateLayer, actionLayer); } // failure, solution cannot be found from the specified state return(int.MaxValue); }
/// <summary> /// Applies backwards the relevant operator effects and operator preconditions to the given target conditions. /// </summary> /// <param name="conditions">Target conditions to be modified.</param> /// <param name="operatorSubstitution">Variables substitution.</param> /// <returns>Preceding conditions.</returns> public IConditions ApplyBackwards(IConditions conditions, ISubstitution operatorSubstitution) { ConditionsCNF expression = (ConditionsCNF)conditions?.GetCNF(); if (expression == null) { return(null); } OperatorSubstitution = operatorSubstitution; Effects.GroundEffectsByCurrentOperatorSubstitution(GroundingManager, operatorSubstitution); if (expression.Parameters != null) { EffectsRelevanceConditionsEvaluator evaluator = new EffectsRelevanceConditionsEvaluator(Effects, GroundingManager); List <ConditionsCNF> subResults = new List <ConditionsCNF>(); IEnumerable <ISubstitution> expressionSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(expression.Parameters); expression.Parameters = null; foreach (var expressionSubstitution in expressionSubstitutions) { // do backward apply only when the effects are relevant to the current grounding of the expression if (evaluator.Evaluate(expression, operatorSubstitution, expressionSubstitution)) { subResults.Add(ApplyBackwardsImpl(expression, expressionSubstitution)); } } return(ConstructCNFFromDisjunction(subResults)); } return(ApplyBackwardsImpl(expression, new Substitution())); }
/// <summary> /// Checks whether the operator is relevant to the given target conditions. /// </summary> /// <param name="conditions">Target conditions.</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 conditions, false otherwise.</returns> public bool IsRelevant(IConditions conditions, ISubstitution substitution, IList <int> relevantConditionalEffects = null) { if (!Preconditions.EvaluateRigidRelationsCompliance(substitution)) { return(false); } return(Effects.IsRelevant(conditions, substitution, relevantConditionalEffects)); }
/// <summary> /// Gets the heuristic value for the given conditions (in the context of backward search). /// </summary> /// <param name="conditions">Conditions to be evaluated.</param> /// <returns>Heuristic value for the specified conditions.</returns> protected override double GetValueImpl(IConditions conditions) { if (Random.NextDouble() < Heuristics.First().Item2) { return(Heuristics.First().Item1.GetValue(conditions)); } return(Heuristics.Sum(heuristic => heuristic.Item2 * heuristic.Item1.GetValue(conditions))); }
public TwoConditionEvent(IConditions condition1, IConditions condition2, IActions action1, IActions action2, IActions action3) { Condition1 = condition1; Condition2 = condition2; Action1 = action1; Action2 = action2; Action3 = action3; }
/// <summary> /// Applies the effect backwards to the given conditions. /// </summary> /// <param name="conditions">Conditions.</param> public virtual IConditions ApplyBackwards(IConditions conditions) { if (!conditions.IsConflictedWith(Assignment)) { conditions.RemoveConstraint(Assignment); return(conditions); } return(new ConditionsContradiction()); }
public Service(IConditions conditions = null) { if (conditions == null) { Conditions = new Conditions(); return; } Conditions = conditions; }
/// <summary> /// Gets a list of atoms used in the specified conditions. /// </summary> /// <param name="conditions">Conditions to be evaluated.</param> /// <returns>Collection of used atoms.</returns> public HashSet <IAtom> Collect(IConditions conditions) { ConditionsCNF conditionsCNF = (ConditionsCNF)conditions.GetCNF(); Atoms = new HashSet <IAtom>(); conditionsCNF.Accept(this); return(Atoms); }
/// <summary> /// Generates all possible PDDL states meeting conditions specified by the given conditions. Lazy generated via yield return. /// </summary> /// <param name="conditions">Reference conditions.</param> /// <param name="problem">Planning problem.</param> /// <returns>All possible PDDL states meeting the conditions.</returns> public static IEnumerable <IState> EnumerateStates(IConditions conditions, Problem problem) { foreach (var relativeState in EnumerateRelativeStates(conditions, problem)) { foreach (var state in EnumerateStates(relativeState, problem)) { yield return(state); } } }
/// <summary> /// Generates all possible SAS+ states meeting conditions specified by the given conditions. Lazy generated via yield return. /// </summary> /// <param name="conditions">Reference conditions.</param> /// <param name="variables">Variables of the planning problem.</param> /// <returns>All possible SAS+ states meeting the conditions.</returns> public static IEnumerable <IState> EnumerateStates(IConditions conditions, Variables variables) { foreach (var simpleCondition in conditions.GetSimpleConditions()) { foreach (var state in EnumerateStates(simpleCondition, variables)) { yield return(state); } } }
/// <summary> /// Gets the heuristic value for the given conditions (in the context of backward search). /// </summary> /// <param name="conditions">Conditions to be evaluated.</param> /// <returns>Heuristic value for the specified conditions.</returns> public double GetValue(IConditions conditions) { if (Statistics.DoMeasure) { double value = GetValueImpl(conditions); Statistics.UpdateStatistics(value); return(value); } return(GetValueImpl(conditions)); }
/// <summary> /// Checks whether the conditions are in conflict with the other conditions (i.e. different constraints on the same variables). /// </summary> /// <param name="other">Other conditions.</param> /// <returns>True if the conditions are conflicted with the other conditions, false otherwise.</returns> public bool IsConflictedWith(IConditions other) { foreach (var assignment in this) { if (other.IsConflictedWith(assignment)) { return(true); } } return(false); }
/// <summary> /// Checks whether the conditions are in conflict with the other conditions (i.e. different constraints on the same variables). /// </summary> /// <param name="other">Other conditions.</param> /// <returns>True if the conditions are conflicted with the other conditions, false otherwise.</returns> public bool IsConflictedWith(IConditions other) { // in the context of clause condition, at least one of the disjuncts needs to be non-conflicting foreach (var conditions in this) { if (!conditions.IsConflictedWith(other)) { return(false); } } return(true); }
/// <summary> /// Applies the operator backwards to the given target conditions. The result is a new set of conditions. /// </summary> /// <param name="conditions">Conditions for the application.</param> /// <param name="operatorPreconditions">Operator preconditions.</param> /// <returns>Preceding conditions.</returns> public IConditions ApplyBackwards(IConditions conditions, ISimpleConditions operatorPreconditions) { IConditions newConditions = (IConditions)conditions.Clone(); foreach (var effect in this) { newConditions = effect.ApplyBackwards(newConditions); } newConditions = newConditions.ConjunctionWith(operatorPreconditions); return(newConditions); }
/// <summary> /// Applies the effect backwards to the given conditions. /// </summary> /// <param name="conditions">Conditions.</param> public override IConditions ApplyBackwards(IConditions conditions) { if (IsRelevant(conditions) == EffectRelevance.RELEVANT) { IConditions newConditions = (IConditions)conditions.Clone(); newConditions.RemoveConstraint(Assignment); newConditions = newConditions.ConjunctionWith(Conditions); return(conditions.DisjunctionWith(newConditions)); } return(conditions); }
/// <summary> /// Gets a list of atoms from the specified state that are necessary to make these conditions true. /// </summary> /// <param name="conditions">Conditions to evaluate.</param> /// <param name="substitution">Variable substitution.</param> /// <param name="predecessorState">Preceding state.</param> /// <returns>List of satisfying atoms.</returns> public List <IAtom> Evaluate(IConditions conditions, ISubstitution substitution, IState predecessorState) { ConditionsCNF conditionsCNF = (ConditionsCNF)conditions.GetCNF(); Atoms = new List <IAtom>(); Substitution = substitution; ReferenceState = predecessorState; conditionsCNF.Accept(this); return(Atoms); }
/// <summary> /// Gets a collection of all relevant predecessors (backwards transitions) from the specified conditions. Lazy generated via yield return. /// </summary> /// <param name="conditions">Original conditions.</param> /// <returns>Lazy generated collection of relevant predecessors.</returns> public IEnumerable <IPredecessor> GetPredecessors(IConditions conditions) { foreach (var liftedOperator in LiftedOperators) { IEnumerable <ISubstitution> operatorSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(liftedOperator.Parameters); foreach (var operatorSubstitution in operatorSubstitutions) { if (liftedOperator.IsRelevant(conditions, operatorSubstitution)) { yield return(new Predecessor(conditions, new Operator(liftedOperator, operatorSubstitution))); } } } }
/// <summary> /// Creates a disjunction of the current conditions and the specified other conditions. /// </summary> /// <param name="other">Other conditions.</param> /// <returns>Disjunction of the current conditions and the given other conditions.</returns> public IConditions DisjunctionWith(IConditions other) { if (Count == 0) { // empty conditions always evaluate as true, so any disjunction with this conditions // would also be a tautology -> we don't create a clause in this case and just return return((IConditions)Clone()); } if (other is ConditionsClause || other is ConditionsContradiction) { return(other.DisjunctionWith(this)); } Debug.Assert(other is Conditions); return(new ConditionsClause((Conditions)Clone(), (Conditions)other.Clone())); }
/// <summary> /// Checks whether the operator effect is relevant to the given target conditions. /// </summary> /// <param name="conditions">Conditions.</param> /// <returns>Effect relevance result.</returns> public override EffectRelevance IsRelevant(IConditions conditions) { var assignmentRelevance = base.IsRelevant(conditions); if (assignmentRelevance == EffectRelevance.RELEVANT) { IConditions nonAffectedConditions = (IConditions)Conditions.Clone(); nonAffectedConditions.RemoveConstraint(Assignment); if (!nonAffectedConditions.IsConflictedWith(conditions)) { return(EffectRelevance.RELEVANT); } } // conditional effect does not have to be used, so it should never be explicitly anti-relevant return(EffectRelevance.IRRELEVANT); }
/// <summary> /// Computes the distances to the goals for the specified pattern. /// </summary> /// <param name="pattern">Pattern (i.e. variables of the pattern) to process.</param> private PatternValuesDistances ComputePatternDistances(int[] pattern) { IHeap <double, ISimpleConditions> fringe = new LeftistHeap <ISimpleConditions>(); InsertPatternConditions(fringe, (Conditions)Problem.GoalConditions, 0, pattern); PatternValuesDistances patternValuesDistances = new PatternValuesDistances(); while (fringe.GetSize() > 0) { double distance = fringe.GetMinKey(); ISimpleConditions conditions = fringe.RemoveMin(); int[] patternValues = conditions.GetAssignedValues(); Debug.Assert(pattern.Length == conditions.GetSize()); Debug.Assert(pattern.Length == patternValues.Length); if (patternValuesDistances.ContainsKey(patternValues)) { // already processed with a lower cost continue; } patternValuesDistances.Add(patternValues, distance); foreach (var predecessor in Problem.GetPredecessors(conditions)) { IConditions predecessorConditions = (IConditions)predecessor.GetPredecessorConditions(); IOperator predecessorOperator = (IOperator)predecessor.GetAppliedOperator(); foreach (var predecessorSimpleConditions in predecessorConditions.GetSimpleConditions()) { double cost = distance + predecessorOperator.GetCost(); InsertPatternConditions(fringe, predecessorSimpleConditions, cost, pattern); } } } return(patternValuesDistances); }
/// <summary> /// Creates a conjunction of the current conditions and the specified other conditions. /// </summary> /// <param name="other">Other conditions.</param> /// <returns>Conjunction of the current conditions and the given other conditions.</returns> public IConditions ConjunctionWith(IConditions other) { List <Conditions> newConditions = new List <Conditions>(); foreach (var conditions in this) { if (!conditions.IsConflictedWith(other)) { IConditions conjunction = conditions.ConjunctionWith(other); ConditionsClause clause = conjunction as ConditionsClause; if (clause != null) { foreach (var innerConditions in clause) { newConditions.Add(innerConditions); } } else { Conditions innerConditions = conjunction as Conditions; if (innerConditions != null) { newConditions.Add(innerConditions); } } } } switch (newConditions.Count) { case 0: return(new ConditionsContradiction()); case 1: return(newConditions[0]); default: return(new ConditionsClause(newConditions.ToArray())); } }
/// <summary> /// Creates a conjunction of the current conditions and the specified other conditions. /// </summary> /// <param name="other">Other conditions.</param> /// <returns>Conjunction of the current conditions and the given other conditions.</returns> public IConditions ConjunctionWith(IConditions other) { if (other is ConditionsClause || other is ConditionsContradiction) { return(other.ConjunctionWith(this)); } Conditions otherConditions = other as Conditions; Debug.Assert(otherConditions != null); if (IsConflictedWith(otherConditions)) { return(new ConditionsContradiction()); } Conditions conditions = (Conditions)Clone(); conditions.AddConditions(otherConditions); return(conditions); }
/// <summary> /// Evaluates whether the operator effects are relevant for the specified conditions. /// </summary> /// <param name="conditions">Conditions expression.</param> /// <param name="operatorSubstitution">Variables substitution of the operator.</param> /// <param name="expressionSubstitution">Variables substitution of the expression.</param> /// <param name="relevantConditionalEffects">Output indices of relevant conditional effects (can be null).</param> /// <returns>Tuple of two values, where the first is true when the positive relevance condition (inclusion) is satisfied, while the second is /// true when the negative condition (exclusion) is not violated. False otherwise.</returns> public Tuple <bool, bool> EvaluateWithExtendedResult(IConditions conditions, ISubstitution operatorSubstitution, ISubstitution expressionSubstitution, IList <int> relevantConditionalEffects = null) { ConditionsCNF expression = (ConditionsCNF)conditions?.GetCNF(); if (expression == null) { return(Tuple.Create(false, false)); } Effects.GroundEffectsByCurrentOperatorSubstitution(GroundingManager, operatorSubstitution); OperatorSubstitution = operatorSubstitution; ExpressionSubstitution = expressionSubstitution; var primitivesResult = ProcessPrimitiveEffects(expression); if (!primitivesResult.Item2) { return(primitivesResult); } var forallResult = ProcessForallEffects(expression); if (!forallResult.Item2) { return(forallResult); } var whenResult = ProcessWhenEffects(expression, relevantConditionalEffects); if (!whenResult.Item2) { return(whenResult); } return(Tuple.Create((primitivesResult.Item1 || forallResult.Item1 || whenResult.Item1), true)); }
/// <summary> /// Generates all possible PDDL relative states meeting conditions specified by the given conditions. Lazy generated via yield return. /// </summary> /// <param name="conditions">Reference conditions.</param> /// <param name="problem">Planning problem.</param> /// <returns>All possible PDDL relative states meeting the conditions.</returns> public static IEnumerable <IRelativeState> EnumerateRelativeStates(IConditions conditions, Problem problem) { return(EnumerateRelativeStatesByCNF(0, new List <IConjunctCNF>((ConditionsCNF)conditions.GetCNF()), new RelativeState(problem.IdManager))); }
/// <summary> /// Constructs the predecessor entity from conditions. /// </summary> /// <param name="referenceConditions">Reference to the original conditions.</param> /// <param name="appliedOperator">Grounded applied operator.</param> public Predecessor(IConditions referenceConditions, IOperator appliedOperator) { ReferenceConditions = referenceConditions; AppliedOperator = appliedOperator; }
/// <summary> /// Gets a collection of all relevant predecessors (backwards transitions) from the specified conditions. Lazy generated via yield return. /// </summary> /// <param name="conditions">Original conditions.</param> /// <returns>Lazy generated collection of relevant predecessors.</returns> public IEnumerable <IPredecessor> GetPredecessors(IConditions conditions) { return(PredecessorsCollector.GetPredecessors(TreeRoot, conditions)); }