Пример #1
0
        /// <summary>
        /// A helper method for easily creating an array of Individual predicates.
        /// </summary>
        /// <param name="predicates">The array of predicate values.</param>
        /// <returns>The array of Individual built on the predicate values.</returns>
        public static Individual[] NewArray(params object[] predicates)
        {
            Individual[] individuals = new Individual[predicates.Length];

            for (int i=0; i<predicates.Length; i++)
                individuals[i] = new Individual(predicates[i]);

            return individuals;
        }
Пример #2
0
        /// <summary>
        /// Creates a new Fact.
        /// </summary>
        /// <remarks>
        /// This method is an helper of the regular Fact instantiation.
        /// </remarks>
        /// <param name="type">The Type of the new Fact to assert.</param>
        /// <param name="individuals">The Individual predicatesthat the Fact will contain.</param>
        /// <returns>A new Fact of desired Type and individuals.</returns>
        public Fact NewFact(string type, params object[] individuals)
        {
            Fact newFact;

            if (individuals.Length == 0) {
                newFact = new Fact(type);
            }
            else if (individuals.Length == 1) {
                newFact = new Fact(type, new Individual(individuals[0]));
            }
            else {
                Individual[] members = new Individual[individuals.Length];
                for (int i=0; i<individuals.Length; i++) members[i] = new Individual(individuals[i]);
                newFact = new Fact(type, members);
            }

            return newFact;
        }
Пример #3
0
        protected override IPredicate BuildPredicate(XPathNavigator predicateElement, bool inHead, bool resolveImmediatly)
        {
            IPredicate predicate;
            string predicateName = predicateElement.Name;
            string predicateValue = predicateElement.Value;

            switch(predicateName) {
                // --------- IND predicates --------
                case "ind":
                    if (predicateValue.ToLower().StartsWith("expr:")) {
                        if (inHead) {
                            if (resolveImmediatly) predicate = new Individual(Compilation.Evaluate(predicateValue));
                            else predicate = new Formula(Formula.FormulaResolutionType.NxBRE,
                                                         Binder,
                                                         predicateValue);
                        }
                        else {
                            predicate = new Function(Function.FunctionResolutionType.Binder,
                                                     predicateValue,
                                                     new ExpressionEvaluator(predicateValue),
                                                   	 String.Empty,
                                                  	 String.Empty);
                        }
                    }
                    else if (predicateValue.ToLower().StartsWith("nxbre:")) {
                        // NxBRE functions must follow this pattern: NxBRE:Function(uniqueargument)
                        ObjectPair operatorCall = Parameter.ParseOperatorCall(predicateValue);
                        predicate = new Function(Function.FunctionResolutionType.NxBRE,
                                                 predicateValue,
                                                 null,
                                                                         (string)operatorCall.First,
                                                                         (string)operatorCall.Second);
                    }
                    else if (Binder == null) {
                        predicate = new Individual(predicateValue);
                    }
                    else if ((inHead) && (predicateValue.ToLower().StartsWith("binder:"))) {
                        predicate = new Formula(Formula.FormulaResolutionType.Binder,
                                                Binder,
                                                predicateValue);
                    }
                    else if ((inHead) && (predicateValue.EndsWith("()"))) {
                        predicate = new Formula(Formula.FormulaResolutionType.Binder,
                                                Binder,
                                                predicateValue);
                    }
                    else {
                        predicate = Binder.AnalyzeIndividualPredicate(new Individual(predicateValue));
                    }

                break;

            // --------- VAR predicates --------
            case "var":
                predicate = new Variable(predicateValue);
                break;

            // --------- UNKNOWN predicates --------
            default:
                throw new BREException("Unsupported predicate type: " + predicateName);
            }

            return predicate;
        }
        protected override IPredicate BuildPredicate(XPathNavigator predicateElement, bool inHead, bool resolveImmediatly)
        {
            IPredicate predicate;
            string predicateName = predicateElement.Name;
            string predicateValue = predicateElement.Value;

            switch(predicateName) {
                // --------- IND predicates --------
                case "Ind":
                    string predicateURI = predicateElement.GetAttribute("uri", String.Empty).ToLower();

                    switch(predicateURI) {
                        case "nxbre://expression":
                            if (inHead) {
                                if (resolveImmediatly) predicate = new Individual(Compilation.Evaluate(predicateValue));
                                else predicate = new Formula(Formula.FormulaResolutionType.NxBRE,
                                                             Binder,
                                                             predicateValue);
                            }
                            else {
                                predicate = new Function(Function.FunctionResolutionType.Binder,
                                                         predicateValue,
                                                         new ExpressionEvaluator(predicateValue),
                                                       	 String.Empty,
                                                      	 String.Empty);
                            }
                            break;

                        case "nxbre://operator":
                            // NxBRE operators must follow this pattern: operator(uniqueargument)
                            ObjectPair operatorCall = Parameter.ParseOperatorCall(predicateValue);
                            predicate = new Function(Function.FunctionResolutionType.NxBRE,
                                                     predicateValue,
                                                     null,
                                                     (string)operatorCall.First,
                                                                             (string)operatorCall.Second);
                            break;

                        case "nxbre://binder":
                            if (Binder == null) throw new BREException("No binder available for Individual: " + predicateValue);

                            if (inHead) predicate = new Formula(Formula.FormulaResolutionType.Binder,
                                                                            Binder,
                                                   							predicateValue);
                            else predicate = Binder.AnalyzeIndividualPredicate(new Individual(predicateValue));

                            break;

                        case "":
                            predicate = new Individual(predicateValue);
                            break;

                        default:
                            // there is a predicateURI but it is not recognized by the engine so we assimilate it as
                            // a web reference
                            predicate = new Individual(new HyperLink(predicateValue, predicateURI));
                            break;
                    }
                    break;

            // --------- VAR predicates --------
            case "Var":
                predicate = new Variable(predicateValue);
                break;

            // --------- DATA predicates --------
            case "Data":
                string schemaType = predicateElement.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance");
                if (schemaType != String.Empty) {
                    // remove any preceding namespace, like in "xs:string"
                    if (schemaType.IndexOf(':')>=0) schemaType = schemaType.Split(':')[1];

                    // this is a strongly typed individual
                    predicate = new Individual(Xml.ToClr(predicateValue, schemaType), schemaType);
                }
                else {
                    // this is just a string based predicate, using Data was not so wise...
                    predicate = new Individual(predicateValue);
                }

                break;

            // --------- SLOT predicates --------
            case "slot":
                // the first child must be an Ind, we do not support other slot name holders
                if (predicateElement.MoveToFirstChild()) {
                    if (predicateElement.Name != "Ind") throw new BREException("Only Ind is accepted as a slot name holder");
                    string slotName = predicateElement.Value;
                    if (!predicateElement.MoveToNext()) throw new BREException("A slot should contain two children");
                    predicate = new Slot(slotName, BuildPredicate(predicateElement, inHead, resolveImmediatly));
                }
                else {
                    throw new BREException("A slot can not be empty");
                }

                break;

            // --------- UNKNOWN predicates --------
            default:
                throw new BREException("Unsupported predicate type: " + predicateName);
            }

            return predicate;
        }
Пример #5
0
        private int RunImplication(Implication implication)
        {
            int implicationResultsCount = 0;

            IList<IList<FactBase.PositiveMatchResult>> processResults = WM.FB.ProcessAtomGroup(implication.AtomGroup);

            if (implication.Action == ImplicationAction.Count)
            {
                if (Logger.IsInferenceEngineVerbose) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Counting Implication '" + implication.Label + "' counted: " + processResults.Count);

                bool variableFound = false;
                IPredicate[] members = (IPredicate[])implication.Deduction.Members.Clone();
                for(int i=0; !variableFound && i<members.Length; i++) {
                    if (members[i] is Variable) {
                        members[i] = new Individual(processResults.Count);
                        variableFound = true;
                        break;
                    }
                }

                if ((strictImplication) && (!variableFound))
                    throw new BREException("Strict counting implication rejected the assertion due to lack of variable predicate: " + implication.Deduction);

                Fact deductedFact = new Fact(implication.Deduction.Type, members);
                implicationResultsCount++;

                // counting implication factbase action
                bool result = WM.FB.Assert(deductedFact);

                if ((result) && (NewFactHandler != null)) {
                    if (exposeEventContext) {
                        NewFactHandler(new NewFactEventArgs(deductedFact,
                                                            EventContextFactory.NewEventContext(processResults, implication)));
                    } else {
                        NewFactHandler(new NewFactEventArgs(deductedFact));
                    }
                }

                if (Logger.IsInferenceEngineVerbose) {
                    Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, (result?"Asserted":"Ignored Assertion of ") + " Fact: " + deductedFact.ToString());
                }
            }
            else if ((implication.Action == ImplicationAction.Assert)
              		|| (implication.Action == ImplicationAction.Retract))
            {
                // loop on each result and try to build a new fact out of the predicates coming for each result
                foreach(IList<FactBase.PositiveMatchResult> processResult in processResults) {
                    Fact deductedFact = BuildFact(implication.Deduction, processResult);

                    if (deductedFact != null) {
                        implicationResultsCount++;

                        if (implication.Action == ImplicationAction.Retract) {
                            // retracting implication factbase action
                            bool result = WM.FB.Retract(deductedFact);

                            if ((result) && (DeleteFactHandler != null)) {
                                if (exposeEventContext) {
                                    DeleteFactHandler(new NewFactEventArgs(deductedFact,
                                                                           EventContextFactory.NewEventContext(processResult, implication)));
                                } else {
                                    DeleteFactHandler(new NewFactEventArgs(deductedFact));
                                }
                            }

                            if (Logger.IsInferenceEngineVerbose) {
                                Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, (result?"Retracted":"Ignored Retraction of ") + " Fact: " + deductedFact.ToString());
                            }
                        }
                        else {
                            // asserting implication factbase action
                            bool result = WM.FB.Assert(deductedFact);

                            if ((result) && (NewFactHandler != null)) {
                                if (exposeEventContext) {
                                    NewFactHandler(new NewFactEventArgs(deductedFact,
                                                                        EventContextFactory.NewEventContext(processResult, implication)));
                                } else {
                                    NewFactHandler(new NewFactEventArgs(deductedFact));
                                }
                            }

                            if (Logger.IsInferenceEngineVerbose) {
                                Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, (result?"Asserted":"Ignored Assertion of ") + " Fact: " + deductedFact.ToString());
                            }
                        }
                    }
                }
            }
            else if (implication.Action == ImplicationAction.Modify)
            {
              foreach(IList<FactBase.PositiveMatchResult> processResult in processResults) {
                  // look for facts to modify by:
                  //  - resolving variable predicates of the deduction
                  //  - replacing formulas with variables
                  // and performing a search in the fact base
                  Atom modificationTargetLookup = FactBase.BuildQueryFromDeduction(implication.Deduction, processResult);

                  if (Logger.IsInferenceEngineVerbose) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Modifying Implication '" + implication.Label + "' will target matches of: " + modificationTargetLookup);

                 	foreach(Fact factToModify in FactBase.ExtractAllFacts(WM.FB.ProcessAtomGroup(new AtomGroup(AtomGroup.LogicalOperator.And, modificationTargetLookup)))) {
                      if (Logger.IsInferenceEngineVerbose) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "-> found target: " + factToModify);

                      // for each fact, perform the modification
                  	Fact deductedFact = BuildFact(implication.Deduction,
                  	                              FactBase.EnrichResults(processResult, modificationTargetLookup, factToModify));

                      if (Logger.IsInferenceEngineVerbose) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "-> modified target: " + deductedFact);

                      if ((deductedFact != null) && (!factToModify.Equals(deductedFact))) {
                            implicationResultsCount++;
                            bool result = WM.FB.Modify(factToModify, deductedFact);

                            if ((result) && (ModifyFactHandler != null)) {
                                if (exposeEventContext) {
                                    ModifyFactHandler(new NewFactEventArgs(factToModify,
                                                                           deductedFact,
                                                                           EventContextFactory.NewEventContext(processResult, implication)));
                                } else {
                                    ModifyFactHandler(new NewFactEventArgs(factToModify, deductedFact));
                                }
                            }

                            if (Logger.IsInferenceEngineVerbose) {
                                Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, (result?"Modified":"Ignored Modification of ") + " Fact: " + factToModify.ToString());
                            }
                        }
                  }
                }
            }
            else {
                throw new BREException("Implication action not supported: " + implication.Action);
            }

            return implicationResultsCount;
        }
        public void Gedcom()
        {
            deductionsToCheck = new string[]{
                "sibling{Girl,Boy}", "sibling{Boy,Girl}", "parent{Girl,Daddy}",
                "parent{Girl,Mummy}", "parent{Boy,Daddy}", "parent{Boy,Mummy}", "ancestor{Girl,Daddy}",
                "ancestor{Girl,Mummy}", "ancestor{Boy,Daddy}", "ancestor{Boy,Mummy}", "descendent{Daddy,Girl}",
                "descendent{Mummy,Girl}", "descendent{Daddy,Boy}", "descendent{Mummy,Boy}", "child{Daddy,Girl}",
                "child{Mummy,Girl}", "child{Daddy,Boy}", "child{Mummy,Boy}", "spouse{Daddy,Mummy}", "spouse{Mummy,Daddy}",
                "wife{Daddy,Mummy}", "daughter{Daddy,Girl}", "daughter{Mummy,Girl}", "mother{Girl,Mummy}",
                "mother{Boy,Mummy}", "sister{Boy,Girl}", "son{Daddy,Boy}", "son{Mummy,Boy}", "father{Girl,Daddy}",
                "father{Boy,Daddy}", "brother{Girl,Boy}", "husband{Mummy,Daddy}", "ancestor{Daddy,Old'Pa}",
                "descendent{Old'Pa,Daddy}", "ancestor{Girl,Old'Pa}", "ancestor{Boy,Old'Pa}", "descendent{Old'Pa,Girl}",
                "descendent{Old'Pa,Boy}", "grandparent{Girl,Old'Pa}", "grandparent{Boy,Old'Pa}", "granddaughter{Girl,Old'Pa}",
                "grandchild{Old'Pa,Girl}", "grandchild{Old'Pa,Boy}", "child{Old'Pa,Daddy}", "grandson{Old'Pa,Boy}",
                "son{Old'Pa,Daddy}", "grandfather{Girl,Old'Pa}", "grandfather{Boy,Old'Pa}", "father{Daddy,Old'Pa}",
                "ancestor{Uncle,Old'Pa}", "sibling{Daddy,Uncle}", "father{Uncle,Old'Pa}", "child{Old'Pa,Uncle}",
                "brother{Uncle,Daddy}", "brother{Daddy,Uncle}", "descendent{Old'Pa,Uncle}", "niece{Uncle,Girl}",
                "nephew{Uncle,Boy}", "son{Old'Pa,Uncle}", "uncle{Girl,Uncle}", "uncle{Boy,Uncle}",
                "firstCousin{Girl,Cousin}", "firstCousin{Boy,Cousin}", "firstCousin{Cousin,Girl}", "firstCousin{Cousin,Boy}",
                "ancestor{Cousin,Uncle}", "ancestor{Cousin,Old'Pa}", "father{Cousin,Uncle}", "child{Uncle,Cousin}",
                "grandparent{Cousin,Old'Pa}", "uncle{Cousin,Daddy}", "descendent{Uncle,Cousin}", "descendent{Old'Pa,Cousin}",
                "aunt{Cousin,Mummy}", "grandchild{Old'Pa,Cousin}", "cousin{Cousin,Girl}", "cousin{Cousin,Boy}",
                "cousin{Girl,Cousin}", "cousin{Boy,Cousin}", "grandfather{Cousin,Old'Pa}", "daughter{Uncle,Cousin}",
                "granddaughter{Cousin,Old'Pa}", "niece{Daddy,Cousin}"
            };

              	NewFactEvent henf = new NewFactEvent(HandleExpectedNewFact);
              	ie.NewFactHandler += henf;

              	ie.LoadRuleBase(NewGedcomAdapter());
            Individual male = new Individual("M");
            Individual female = new Individual("F");
            Individual happyFamily = new Individual("Happy");
            Individual daddy = new Individual("Daddy");
            Individual mummy = new Individual("Mummy");
            Individual girl = new Individual("Girl");
            Individual boy = new Individual("Boy");

            ie.Assert(new Fact("sex", daddy, male));
            ie.Assert(new Fact("sex", mummy, female));
            ie.Assert(new Fact("sex", girl, female));
            ie.Assert(new Fact("sex", boy, male));

            ie.Assert(new Fact("spouseIn", daddy, happyFamily));
            ie.Assert(new Fact("spouseIn", mummy, happyFamily));
            ie.Assert(new Fact("childIn", girl, happyFamily));
            ie.Assert(new Fact("childIn", boy, happyFamily));
            Process();

            Assert.AreEqual(32, deducted, "(1) Deducted");
            Assert.IsFalse(wrongDeduction, "(1) Deductions OK");

            Individual oldpa = new Individual("Old'Pa");
            ie.Assert(new Fact("sex", oldpa, male));
            ie.Assert(new Fact("parent", daddy, oldpa));
            Process();

            Assert.AreEqual(17, deducted, "(2) Deducted");
            Assert.IsFalse(wrongDeduction, "(2) Deductions OK");

            Individual uncle = new Individual("Uncle");
            ie.Assert(new Fact("sex", uncle, male));
            ie.Assert(new Fact("parent", uncle, oldpa));
            ie.Assert(new Fact("sibling", uncle, daddy));
            Process();

            Assert.AreEqual(12, deducted, "(3) Deducted");
            Assert.IsFalse(wrongDeduction, "(3) Deductions OK");

            Individual cousin = new Individual("Cousin");
            ie.Assert(new Fact("sex", cousin, female));
            ie.Assert(new Fact("parent", cousin, uncle));
            Process();

            Assert.AreEqual(22, deducted, "(4) Deducted");
            Assert.IsFalse(wrongDeduction, "(4) Deductions OK");

            ie.NewFactHandler -= henf;
              	deductionsToCheck = null;
        }
Пример #7
0
        /// <summary>
        /// Prepare the atom to be pattern matched by replacing in a fact:
        /// -  all the predicates that match function predicates in the passed atom with 
        ///   the string representation of these function predicates,
        /// -  in fully mode, all the predicates that match individual predicates in the passed atom with 
        ///   the string representation of these individual predicates.
        /// </summary>
        /// <remarks>
        /// This operation must be done *if and only if* the fact matches the atom.
        /// </remarks>
        /// <param name="fully">Forces resolution of non-string individual to String.</param>
        /// <param name="factToResolve">The fact that must be resolved.</param>
        /// <param name="atom">The atom with which the current fact matches.</param>
        /// <returns>A new fact with only String individuals.</returns>
        internal static Fact Resolve(bool fully, Fact factToResolve, Atom atom)
        {
            IPredicate[] predicates = new IPredicate[factToResolve.Members.Length];

            for(int i=0; i<factToResolve.Members.Length; i++) {
                if ((atom.Members[i] is Function)
                        || ((fully) && (atom.Members[i] is Individual) && (!(factToResolve.Members[i].Value is System.String)))) {
                    predicates[i] = new Individual(atom.Members[i].ToString());
                }
                else {
                    predicates[i] = factToResolve.Members[i];
                }
            }

            return (Fact)factToResolve.CloneWithNewMembers(predicates);
        }
Пример #8
0
        /* Atom Utils */
        /// <summary>
        /// Resolves all Function predicates by replacing them by their String representations.
        /// </summary>
        /// <param name="atom">The Atom to resolve.</param>
        /// <returns>A new Atom where all Function predicates have been resolved. If no
        /// Function predicate exists, it returns a clone of the current Atom.</returns>
        internal static Atom ResolveFunctions(Atom atom)
        {
            if (atom.HasFunction) {
                IPredicate[] predicates = new IPredicate[atom.Members.Length];

                for(int i=0; i<atom.Members.Length; i++)
                    if (atom.Members[i] is Function) predicates[i] = new Individual(atom.Members[i].ToString());
                    else predicates[i] = atom.Members[i];
                return new Atom(atom.Negative, atom.Type, predicates);
            }
            else
                return (Atom)atom.Clone();
        }
Пример #9
0
        /// <summary>
        /// Checks if an Individual matches the current Function by either calling a NxBRE helper method
        /// or using a binder.
        /// </summary>
        /// <param name="individual">The Individual to check.</param>
        /// <returns>True if the Individual matches the Function.</returns>
        public bool Evaluate(Individual individual)
        {
            try {
                if (resolutionType == FunctionResolutionType.NxBRE)
                    return EvaluateNxBREOperator(individual.Value, name, arguments);
                else if (resolutionType == FunctionResolutionType.Binder)
                    return bob.Evaluate(individual.Value, functionSignature, arguments);
                else
                    throw new BREException("Function evaluation mode not supported: " + resolutionType);
            }
            catch (Exception ex) {
                // Chuck Cross added try/catch block with addtional info in new thrown exception
                StringBuilder sb = new StringBuilder("Error evaluating formula ")
                                                                            .Append(this)
                                                                            .Append(".\r\n  Arguments:");

                foreach(string argument in arguments)
                    sb.Append("   ").Append(argument==null?"Null":argument).Append("\r\n");

                throw new BREException(sb.ToString(), ex);
            }
        }
Пример #10
0
        /// <summary>
        /// Called by the Inference Engine whenever an Individual predicate is found in the
        /// rule base and must be evaluated to determine if it is a function.
        /// </summary>
        /// <param name="individual">The Individual found in the rule base.</param>
        /// <returns>The unchanged Individual if it is not a function, else a Function predicate.</returns>
        public IPredicate AnalyzeIndividualPredicate(Individual individual)
        {
            if (individual.Value is string) {
                // Match the regular expression pattern against a text string.
                Match m = RegexFunction.Match((string)individual.Value);
                if (m.Success) {
                    // Create a function predicate with
                    ArrayList arguments = new ArrayList();
                    foreach (Capture c2 in m.Groups[2].Captures)
                        arguments.Add(c2.ToString().Trim());

                    return new Function(Function.FunctionResolutionType.Binder,
                                        (string)individual.Value,
                                        this,
                                        m.Groups[1].Captures[0].ToString(),
                                        (string[])arguments.ToArray(typeof(string)));
                }
            }

            return individual;
        }
Пример #11
0
        public void Predicates()
        {
            IPredicate v1 = new Variable("one");
            IPredicate v2 = new Variable("two");
            IPredicate i1 = new Individual("one");
            IPredicate i2 = new Individual("two");

            Assert.AreEqual(v1, new Variable("one"), "Similar Variables");
            Assert.IsFalse(v1.Equals(v2), "Different Variables");
            Assert.IsFalse(v1.Equals(i2), "Variable differs from Individual");

            Assert.AreEqual(i1, new Individual("one"), "Similar Individuals");
            Assert.IsFalse(i1.Equals(i2), "Different Variables");
            Assert.IsFalse(i2.Equals(v1), "Individual differs from Variable");
        }