Exemplo n.º 1
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);
                }
            }
        }