/// <summary> /// Evaluates the expression. /// </summary> /// <param name="expression">Expression.</param> /// <returns>True if the expression is logically true, false otherwise.</returns> public virtual bool Visit(PredicateLiteralCNF expression) { IAtom groundedPredicateAtom = GroundingManager.GroundAtomDeep(expression.PredicateAtom, Substitution, ReferenceState); bool evaluationResult = (RigidRelations.Contains(groundedPredicateAtom) || ReferenceState.HasPredicate(groundedPredicateAtom)); return(!expression.IsNegated == evaluationResult); }
/// <summary> /// Evaluates the expression. /// </summary> /// <param name="expression">Expression.</param> /// <returns>True if the expression is logically true, false otherwise.</returns> public bool Visit(EqualsLiteralCNF expression) { bool evaluationResult = GroundingManager.GroundTermDeep(expression.LeftArgument, Substitution, ReferenceState).Equals( GroundingManager.GroundTermDeep(expression.RightArgument, Substitution, ReferenceState)); return(!expression.IsNegated == evaluationResult); }
/// <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> /// 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> /// Constructs the numeric assignment backwards replacer. /// </summary> /// <param name="numericFunctionAssignments">Numeric function assignments.</param> /// <param name="groundingManager">Grounding manager.</param> /// <param name="operatorSubstitution">Operator substitution.</param> /// <param name="expressionSubstitution">Expression substitution.</param> public NumericAssignmentsBackwardsReplacer(Dictionary <IAtom, INumericExpression> numericFunctionAssignments, GroundingManager groundingManager, ISubstitution operatorSubstitution, ISubstitution expressionSubstitution) { NumericFunctionAssignments = numericFunctionAssignments; GroundingManager = groundingManager; OperatorSubstitution = operatorSubstitution; ExpressionSubstitution = expressionSubstitution; }
/// <summary> /// Visits and performs a property count on forall expression. /// </summary> /// <param name="expression">Forall expression.</param> /// <returns>Tuple (property satisfied count, property not satisfied count).</returns> public Tuple <double, double> Visit(ForallExpression expression) { double positiveValue = 0; double negativeValue = 0; IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(expression.Parameters); foreach (var localSubstitution in localSubstitutions) { Substitution.AddLocalSubstitution(localSubstitution); var childPropertyCounts = expression.Child.Accept(this); Substitution.RemoveLocalSubstitution(localSubstitution); if (EvaluationStrategy == ForwardCostEvaluationStrategy.ADDITIVE_VALUE) { positiveValue += childPropertyCounts.Item1; negativeValue += childPropertyCounts.Item2; } else { positiveValue = Math.Max(positiveValue, childPropertyCounts.Item1); negativeValue = Math.Max(negativeValue, childPropertyCounts.Item2); } } return(Tuple.Create(positiveValue, negativeValue)); }
/// <summary> /// Processes forall effects. /// </summary> /// <param name="expression">Conditions expression in CNF.</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> private Tuple <bool, bool> ProcessForallEffects(ConditionsCNF expression) { bool positiveCondition = false; bool negativeCondition = true; foreach (var forallEffect in Effects.ForallEffects) { EffectsRelevanceConditionsEvaluator evaluator = new EffectsRelevanceConditionsEvaluator(forallEffect.Effects, GroundingManager); IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(forallEffect.Parameters); foreach (var localSubstitution in localSubstitutions) { OperatorSubstitution.AddLocalSubstitution(localSubstitution); var result = evaluator.EvaluateWithExtendedResult(expression, OperatorSubstitution, null); positiveCondition |= result.Item1; negativeCondition &= result.Item2; OperatorSubstitution.RemoveLocalSubstitution(localSubstitution); if (!negativeCondition) { return(result); } } } return(Tuple.Create(positiveCondition, true)); }
/// <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> /// Visits and handles the effect. /// </summary> /// <param name="effect">Effect.</param> public void Visit(NumericAssignEffect effect) { IAtom groundedFunctionAtom = GroundingManager.GroundAtomDeep(effect.FunctionAtom, Substitution, State); double value = NumericEvaluator.Value.Evaluate(effect.Value, Substitution, State); effect.ApplyAssignOperation(State, groundedFunctionAtom, value); }
/// <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> /// 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> /// 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> /// 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> /// 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> /// 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> /// Gets a collection of all possible successors (forward transitions) from the specified state. Lazy generated via yield return. /// </summary> /// <param name="state">Original state.</param> /// <returns>Lazy generated collection of successors.</returns> public IEnumerable <ISuccessor> GetSuccessors(IState state) { foreach (var liftedOperator in LiftedOperators) { IEnumerable <ISubstitution> operatorSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(liftedOperator.Parameters); foreach (var operatorSubstitution in operatorSubstitutions) { if (liftedOperator.IsApplicable(state, operatorSubstitution)) { yield return(new Successor(state, new Operator(liftedOperator, operatorSubstitution))); } } } }
/// <summary> /// Auxiliary function for transforming the argument sub-expression of a quantified expression. The expression is grounded /// by all possible substitutions and each of the resulting expression is recursively transformed. /// </summary> /// <param name="parameters">Quantified expression parameters.</param> /// <param name="expression">Argument sub-expression of the quantified expression.</param> /// <returns>List of all possible grounded and transformed sub-expressions.</returns> private List <IExpression> TransformQuantifiedSubExpression(Parameters parameters, IExpression expression) { List <IExpression> arguments = new List <IExpression>(); IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(parameters); foreach (var localSubstitution in localSubstitutions) { var groundedSubExpression = GroundingManager.GroundExpression(expression, localSubstitution); arguments.Add(groundedSubExpression.Accept(this)); } return(arguments); }
/// <summary> /// Visits and handles the effect. /// </summary> /// <param name="effect">Effect.</param> public void Visit(ForallEffect effect) { IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(effect.Parameters); foreach (var localSubstitution in localSubstitutions) { Substitution.AddLocalSubstitution(localSubstitution); foreach (var localEffect in effect.Effects) { localEffect.Accept(this); } Substitution.RemoveLocalSubstitution(localSubstitution); } }
/// <summary> /// Visits and handles the effect. /// </summary> /// <param name="effect">Effect.</param> public void Visit(NotEffect effect) { if (EffectsApplierMode == EffectsApplierMode.DELETE_RELAXATION) { return; } PredicateEffect argumentEffect = effect.Argument as PredicateEffect; if (argumentEffect != null) { IAtom groundedPredicateAtom = GroundingManager.GroundAtomDeep(argumentEffect.PredicateAtom, Substitution, State); State.RemovePredicate(groundedPredicateAtom); } }
/// <summary> /// Constructs the evaluation manager. /// </summary> /// <param name="groundingManager">Grounding manager.</param> /// <param name="rigidRelations">Rigid relations.</param> public EvaluationManager(GroundingManager groundingManager, RigidRelations rigidRelations = null) { ExpressionEvaluator = new Lazy <ExpressionEvaluator>(() => new ExpressionEvaluator(groundingManager, rigidRelations)); ConditionsCNFEvaluator = new Lazy <ConditionsCNFEvaluator>(() => new ConditionsCNFEvaluator(groundingManager, rigidRelations)); RigidRelationsComplianceEvaluator = new Lazy <RigidRelationsComplianceEvaluator>(() => new RigidRelationsComplianceEvaluator(groundingManager, rigidRelations)); NotAccomplishedConstraintsCounter = new Lazy <NotAccomplishedConstraintsCounter>(() => new NotAccomplishedConstraintsCounter(groundingManager, ExpressionEvaluator)); NotAccomplishedConstraintsCounterCNF = new Lazy <NotAccomplishedConstraintsCounterCNF>(() => new NotAccomplishedConstraintsCounterCNF(ConditionsCNFEvaluator)); PlanningGraphOperatorLabelEvaluator = new Lazy <PlanningGraphOperatorLabelEvaluator>(() => new PlanningGraphOperatorLabelEvaluator(groundingManager)); PlanningGraphOperatorLabelEvaluatorCNF = new Lazy <PlanningGraphOperatorLabelEvaluatorCNF>(() => new PlanningGraphOperatorLabelEvaluatorCNF(groundingManager)); SatisfyingAtomsEvaluator = new Lazy <SatisfyingAtomsEvaluator>(() => new SatisfyingAtomsEvaluator(groundingManager, rigidRelations)); ConditionsParametersRenamer = new Lazy <ConditionsParametersRenamer>(() => new ConditionsParametersRenamer()); ConditionsUsedPredicatesCollector = new Lazy <ConditionsUsedPredicatesCollector>(() => new ConditionsUsedPredicatesCollector()); RigidRelations = rigidRelations; GroundingManager = groundingManager; }
/// <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> /// Visits and evaluates forall expression. /// </summary> /// <param name="expression">Forall expression.</param> /// <returns>True if the specified expression evaluates as true, false otherwise.</returns> public bool Visit(ForallExpression expression) { IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(expression.Parameters); foreach (var localSubstitution in localSubstitutions) { Substitution.AddLocalSubstitution(localSubstitution); bool subExpressionResult = expression.Child.Accept(this); Substitution.RemoveLocalSubstitution(localSubstitution); if (!subExpressionResult) { return(false); } } return(true); }
/// <summary> /// Visits and performs a property count on exists expression. /// </summary> /// <param name="expression">Exists expression.</param> /// <returns>Tuple (property satisfied count, property not satisfied count).</returns> public Tuple <int, int> Visit(ExistsExpression expression) { int minFulfilled = int.MaxValue; int minNotFulfilled = int.MaxValue; IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(expression.Parameters); foreach (var localSubstitution in localSubstitutions) { Substitution.AddLocalSubstitution(localSubstitution); var childPropertyCounts = expression.Child.Accept(this); Substitution.RemoveLocalSubstitution(localSubstitution); minFulfilled = Math.Min(minFulfilled, childPropertyCounts.Item1); minNotFulfilled = Math.Min(minNotFulfilled, childPropertyCounts.Item2); } return(Tuple.Create(minFulfilled, minNotFulfilled)); }
/// <summary> /// Visits and performs a property count on forall expression. /// </summary> /// <param name="expression">Forall expression.</param> /// <returns>Tuple (property satisfied count, property not satisfied count).</returns> public Tuple <int, int> Visit(ForallExpression expression) { int fulfilled = 0; int notFulfilled = 0; IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(expression.Parameters); foreach (var localSubstitution in localSubstitutions) { Substitution.AddLocalSubstitution(localSubstitution); var childPropertyCounts = expression.Child.Accept(this); Substitution.RemoveLocalSubstitution(localSubstitution); fulfilled += childPropertyCounts.Item1; notFulfilled += childPropertyCounts.Item2; } return(Tuple.Create(fulfilled, notFulfilled)); }
/// <summary> /// Visits and performs a property count on exists expression. /// </summary> /// <param name="expression">Exists expression.</param> /// <returns>Tuple (property satisfied count, property not satisfied count).</returns> public Tuple <double, double> Visit(ExistsExpression expression) { double positiveValue = 0.0; double negativeValue = 0.0; IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(expression.Parameters); foreach (var localSubstitution in localSubstitutions) { Substitution.AddLocalSubstitution(localSubstitution); var childPropertyCounts = expression.Child.Accept(this); Substitution.RemoveLocalSubstitution(localSubstitution); positiveValue = Math.Max(positiveValue, childPropertyCounts.Item1); negativeValue = Math.Max(negativeValue, childPropertyCounts.Item2); } return(Tuple.Create(positiveValue, negativeValue)); }
/// <summary> /// Processes forall effects. /// </summary> /// <param name="expression">Conditions expression in CNF.</param> private ConditionsCNF ProcessForallEffects(ConditionsCNF expression) { if (Effects.ForallEffects.Count == 0) { return(expression); } foreach (var forallEffect in Effects.ForallEffects) { EffectsBackwardsConditionsApplier innerApplier = new EffectsBackwardsConditionsApplier(null, forallEffect.Effects, EvaluationManager); IEnumerable <ISubstitution> localSubstitutions = GroundingManager.GenerateAllLocalSubstitutions(forallEffect.Parameters); foreach (var localSubstitution in localSubstitutions) { OperatorSubstitution.AddLocalSubstitution(localSubstitution); expression = (ConditionsCNF)innerApplier.ApplyBackwards(expression, OperatorSubstitution); OperatorSubstitution.RemoveLocalSubstitution(localSubstitution); } } return(expression); }
/// <summary> /// Evaluates the expression. /// </summary> /// <param name="expression">Expression.</param> /// <returns>True if the expression is logically true, false otherwise.</returns> public override bool Visit(PredicateLiteralCNF expression) { IAtom groundedPredicateAtom = GroundingManager.GroundAtomDeep(expression.PredicateAtom, Substitution, ReferenceState); if (RigidRelations.Contains(groundedPredicateAtom)) { // satisfied or failed by rigid relation return(!expression.IsNegated); } bool hasPredicate = ReferenceState.HasPredicate(groundedPredicateAtom); if (hasPredicate == expression.IsNegated) { // failed by state predicate return(false); } // satisfied by state predicate -> store this atom Atoms.Add(groundedPredicateAtom); return(true); }
/// <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); }