private int RunImplication(Implication implication) { int implicationResultsCount = 0; FactBase.ProcessResultSet processResults = WM.FB.ProcessAtomGroup(implication.AtomGroup); if (implication.Action == ImplicationAction.Count) { if (HasLogListener) ForceDispatchLog("Counting Implication '" + implication.Label + "' counted: " + processResults.Count, LogEventImpl.DEBUG); 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 ((IEImpl.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)) NewFactHandler(new NewFactEventArgs(deductedFact)); if (HasLogListener) ForceDispatchLog((result?"Asserted":"Ignored Assertion of ") + " Fact: " + deductedFact.ToString(), LogEventImpl.DEBUG); } 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(ArrayList 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)) DeleteFactHandler(new NewFactEventArgs(deductedFact)); if (HasLogListener) ForceDispatchLog((result?"Retracted":"Ignored Retraction of ") + " Fact: " + deductedFact.ToString(), LogEventImpl.DEBUG); } else { // asserting implication factbase action bool result = WM.FB.Assert(deductedFact); if ((result) && (NewFactHandler != null)) NewFactHandler(new NewFactEventArgs(deductedFact)); if (HasLogListener) ForceDispatchLog((result?"Asserted":"Ignored Assertion of ") + " Fact: " + deductedFact.ToString(), LogEventImpl.DEBUG); } } } } else if (implication.Action == ImplicationAction.Modify) { foreach(ArrayList 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 (HasLogListener) ForceDispatchLog("Modifying Implication '" + implication.Label + "' will target matches of: " + modificationTargetLookup, LogEventImpl.DEBUG); foreach(Fact factToModify in FactBase.ExtractFacts(WM.FB.ProcessAtomGroup(new AtomGroup(AtomGroup.LogicalOperator.And, modificationTargetLookup)))) { if (HasLogListener) ForceDispatchLog("-> found target: " + factToModify, LogEventImpl.DEBUG); // for each fact, perform the modification Fact deductedFact = BuildFact(implication.Deduction, FactBase.EnrichResults(processResult, modificationTargetLookup, factToModify)); if (HasLogListener) ForceDispatchLog("-> modified target: " + deductedFact, LogEventImpl.DEBUG); if ((deductedFact != null) && (!factToModify.Equals(deductedFact))) { implicationResultsCount++; bool result = WM.FB.Modify(factToModify, deductedFact); if ((result) && (ModifyFactHandler != null))ModifyFactHandler(new NewFactEventArgs(factToModify, deductedFact)); if (HasLogListener) ForceDispatchLog((result?"Modified":"Ignored Modification of ") + " Fact: " + factToModify.ToString(), LogEventImpl.DEBUG); } } } } else throw new BREException("Implication action not supported: " + implication.Action); return implicationResultsCount; }
///<remarks>As Facts labels are basically ignored (no retrieval nor any operation based /// on it, the FactBase does not bother check if we have different facts with same labels.</remarks> public bool Assert(Fact fact) { if (!fact.IsFact) throw new BREException("Can not add non-facts to the fact base: "+fact.ToString()); if (!Exists(fact)) { factList.Add(fact.GetLongHashCode(), fact); // check if the new fact matches any of the registered atoms // and if yes, then reference this fact in the list of matching ones foreach(Atom atom in atomList.Values) if (atom.Matches(fact)) GetMatchingFactStorageTable(atom).Add(fact, atom); // the fact was new and added to the factbase, return true if (!ModifiedFlag) ModifiedFlag = true; return true; } else // else return false return false; }