/// <summary>
        /// Visits and performs a property count on CNF clause.
        /// </summary>
        /// <param name="expression">CNF clause.</param>
        /// <returns>Tuple (property satisfied count, property not satisfied count).</returns>
        public Tuple <int, int> Visit(ClauseCNF expression)
        {
            int minFulfilled    = int.MaxValue;
            int minNotFulfilled = int.MaxValue;

            foreach (var literal in expression)
            {
                var childPropertyCounts = literal.Accept(this);
                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 CNF clause.
        /// </summary>
        /// <param name="expression">CNF clause.</param>
        /// <returns>Tuple (property satisfied count, property not satisfied count).</returns>
        public Tuple <double, double> Visit(ClauseCNF expression)
        {
            double positiveValue = 0;
            double negativeValue = 0;

            foreach (var child in expression)
            {
                var childPropertyCounts = child.Accept(this);
                positiveValue = Math.Max(positiveValue, childPropertyCounts.Item1);
                negativeValue = Math.Max(negativeValue, childPropertyCounts.Item2);
            }

            return(Tuple.Create(positiveValue, negativeValue));
        }
Пример #3
0
        /// <summary>
        /// Checks the equality of objects.
        /// </summary>
        /// <param name="obj">Object to be checked.</param>
        /// <returns>True if the objects are equal, false otherwise.</returns>
        public override bool Equals(object obj)
        {
            if (obj == this)
            {
                return(true);
            }

            ClauseCNF other = obj as ClauseCNF;

            if (other == null)
            {
                return(false);
            }

            return(CollectionsEquality.Equals(this, other));
        }
Пример #4
0
        /// <summary>
        /// Accepts a conjunctive-normal-form expression backwards applier visitor.
        /// </summary>
        /// <param name="visitor">CNF expression visitor.</param>
        public IElementCNF Accept(IElementCNFBackwardsApplierVisitor visitor)
        {
            ClauseCNF newExpression = new ClauseCNF();

            foreach (var literal in this)
            {
                var resultExpression = literal.Accept(visitor);
                if (resultExpression == null)
                {
                    // any of element from the clause holds -> the whole clause holds
                    return(null);
                }
                else
                {
                    newExpression.Add((LiteralCNF)resultExpression);
                }
            }
            return(newExpression);
        }
Пример #5
0
        /// <summary>
        /// Visits the expression.
        /// </summary>
        /// <param name="expression">Expression.</param>
        public override void Visit(OrExpression expression)
        {
            expression.Children.ForEach(child => child.Accept(this));

            ClauseCNF clause = new ClauseCNF();

            for (int i = 0; i < expression.Children.Count; ++i)
            {
                LiteralCNF literal = Stack.Pop() as LiteralCNF;
                if (literal != null)
                {
                    clause.Add(literal);
                }
                else
                {
                    Debug.Assert(false, "Source expression not in CNF!");
                }
            }
            Stack.Push(clause);
        }
Пример #6
0
        /// <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);
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Constructs a new CNF from the given disjunction of CNFs.
        /// </summary>
        /// <param name="cnfList">List of possible CNF expressions.</param>
        /// <returns>CNF expression of the CNFs disjunction.</returns>
        private ConditionsCNF ConstructCNFFromDisjunction(List <ConditionsCNF> cnfList)
        {
            if (cnfList.Count == 1)
            {
                return(cnfList[0]);
            }

            // adjust the CNF list, so their parameters don't collide before they will be merged
            Parameters mergedParameters;

            MakeUniqueParametersForCNFList(cnfList, out mergedParameters);

            HashSet <IConjunctCNF> conjuncts = new HashSet <IConjunctCNF>();

            foreach (var andExpr in cnfList)
            {
                HashSet <IConjunctCNF> newConjuncts = new HashSet <IConjunctCNF>();
                foreach (var andElem in andExpr)
                {
                    HashSet <LiteralCNF> andElemItems = new HashSet <LiteralCNF>();

                    ClauseCNF orExpr = andElem as ClauseCNF;
                    if (orExpr != null)
                    {
                        foreach (var child in orExpr)
                        {
                            andElemItems.Add(child);
                        }
                    }
                    else
                    {
                        andElemItems.Add((LiteralCNF)andElem);
                    }

                    if (conjuncts.Count == 0)
                    {
                        newConjuncts.Add(new ClauseCNF(andElemItems));
                    }
                    else
                    {
                        foreach (var conjunct in conjuncts)
                        {
                            ClauseCNF clause = conjunct as ClauseCNF;
                            if (clause != null)
                            {
                                HashSet <LiteralCNF> newOrChildren = new HashSet <LiteralCNF>();
                                foreach (var child in clause)
                                {
                                    newOrChildren.Add(child);
                                }
                                newOrChildren.UnionWith(andElemItems);
                                newConjuncts.Add(new ClauseCNF(newOrChildren));
                            }
                            else
                            {
                                andElemItems.Add((LiteralCNF)conjunct);
                                newConjuncts.Add(andElemItems.Count > 1 ? new ClauseCNF(andElemItems) : conjunct);
                            }
                        }
                    }
                }
                conjuncts = newConjuncts;
            }

            return(new ConditionsCNF(conjuncts, EvaluationManager, mergedParameters));
        }