예제 #1
0
        /// <summary>
        /// Build an atom for querying facts on the basis of an implication deduction, whose individual
        /// predicates will be replaced by variables and whose variables will be resolved from values
        /// coming from an implication result stack.
        /// </summary>
        /// <param name="targetAtom">The implication deduction atom.</param>
        /// <param name="resultStack">The implication result stack.</param>
        /// <returns>The atom ready for querying facts.</returns>
        public static Atom BuildQueryFromDeduction(Atom targetAtom, IList <PositiveMatchResult> resultStack)
        {
            IPredicate[] members = (IPredicate[])targetAtom.Members.Clone();

            // populate the variable elements with predicate values coming
            // from the query part of the implication
            foreach (PositiveMatchResult pmr in resultStack)
            {
                RulesUtil.Populate(pmr.Fact, pmr.Source, members);
            }

            if ((targetAtom.HasFormula) || (targetAtom.HasIndividual))
            {
                // formulas and individuals must be replaced by variables
                // named after the position of the predicate
                for (int i = 0; i < members.Length; i++)
                {
                    if (members[i] is Formula)
                    {
                        members[i] = new Variable(i);
                    }
                    // Individuals present in the deduction are static values (compared to values coming from
                    // variables) and must be transformed into variables in order to perform a selection of
                    // potentially matching facts.
                    // To the contrary, Variables, resolved with values coming from the body part of the implication
                    // must be used to search matching facts.
                    else if (targetAtom.Members[i] is Individual)
                    {
                        members[i] = new Variable(i.ToString());
                    }
                }
            }

            // clone the target with new members, because atom is immutable
            return(targetAtom.CloneWithNewMembers(members));
        }
예제 #2
0
        /// <summary>
        /// Replaces non-fixed elements of an atom (variables, formulas...) with fixed values (individuals) when possible
        /// </summary>
        /// <param name="targetAtom"></param>
        /// <param name="resultStack"></param>
        /// <param name="evaluateFormulas"></param>
        /// <returns></returns>
        public static Atom Populate(Atom targetAtom, IList <PositiveMatchResult> resultStack, bool evaluateFormulas)
        {
            IPredicate[] members = (IPredicate[])targetAtom.Members.Clone();

            // populate the variable elements with predicate values coming
            // from the query part of the implication
            foreach (PositiveMatchResult pmr in resultStack)
            {
                if (!(pmr.Fact is FactBase.NegativeFact))
                {
                    RulesUtil.Populate(pmr.Fact, pmr.Source, members);
                }
            }

            // if there are formulas in the atom, resolve these expressions, passing
            // the variable values as arguments
            if ((evaluateFormulas) && (targetAtom.HasFormula))
            {
                // formulas must be evaluated and the results placed in individual predicates
                IDictionary arguments = new Hashtable();

                foreach (PositiveMatchResult pmr in resultStack)
                {
                    if (!(pmr.Fact is FactBase.NegativeFact))
                    {
                        for (int i = 0; i < pmr.Source.Members.Length; i++)
                        {
                            object sourcePredicateKey = null;

                            if (pmr.Source.Members[i] is Variable)
                            {
                                sourcePredicateKey = pmr.Source.Members[i].Value;
                            }
                            else if (pmr.Source.SlotNames[i] != String.Empty)
                            {
                                sourcePredicateKey = pmr.Source.SlotNames[i];
                            }

                            if ((sourcePredicateKey != null) && (!arguments.Contains(sourcePredicateKey)))
                            {
                                arguments.Add(sourcePredicateKey, pmr.Fact.Members[i].Value);
                            }
                        }
                    }
                }

                for (int i = 0; i < members.Length; i++)
                {
                    if (members[i] is Formula)
                    {
                        try {
                            members[i] = new Individual(((Formula)members[i]).Evaluate(arguments));
                        }
                        catch (Exception ex) {
                            // Chuck Cross added try/catch block with addtional info in new thrown exception
                            StringBuilder sb = new StringBuilder("Error evaluating formula ")
                                               .Append(members[i])
                                               .Append(" in atom: ")
                                               .Append(targetAtom.Type)
                                               .Append(".\r\n  Arguments:");

                            foreach (DictionaryEntry entry in arguments)
                            {
                                sb.Append("   ")
                                .Append(entry.Key.ToString());

                                if (entry.Value != null)
                                {
                                    sb.Append("[")
                                    .Append(entry.Value.GetType().ToString())
                                    .Append("] = ")
                                    .Append(entry.Value.ToString());
                                }
                                else
                                {
                                    sb.Append("[Null]");
                                }

                                sb.Append("\r\n");
                            }

                            throw new BREException(sb.ToString(), ex);
                        }
                    }
                }
            }

            // clone the target with new members, because atom is immutable
            return(targetAtom.CloneWithNewMembers(members));
        }