public void Agenda() { Agenda a = new Agenda(); Implication impLow = new Implication("impLow", ImplicationPriority.Minimum, String.Empty, String.Empty, imp2, new AtomGroup(AtomGroup.LogicalOperator.And, atom2_2, atom3)); Implication impLowMed = new Implication("impLowMed", 25, String.Empty, String.Empty, imp2, new AtomGroup(AtomGroup.LogicalOperator.And, atom2_2, atom3)); Implication impMed = new Implication("impMed", ImplicationPriority.Medium, String.Empty, String.Empty, imp2, new AtomGroup(AtomGroup.LogicalOperator.And, atom2_2, atom3)); Implication impMedSaLo = new Implication("impMedSaLo", ImplicationPriority.Medium, String.Empty, String.Empty, imp2, new AtomGroup(AtomGroup.LogicalOperator.And, atom2_2, atom3)); impMedSaLo.Salience = 1; Assert.AreEqual(5101, impMedSaLo.Weight, "Weight impMedSaLo"); Implication impMedSaHi = new Implication("impMedSaHi", ImplicationPriority.Medium, String.Empty, String.Empty, imp2, new AtomGroup(AtomGroup.LogicalOperator.And, atom2_2, atom3)); impMedSaHi.Salience = 99; Assert.AreEqual(5199, impMedSaHi.Weight, "Weight impMedSaLo"); Implication impMedHi = new Implication("impMedHi", 75, String.Empty, String.Empty, imp2, new AtomGroup(AtomGroup.LogicalOperator.And, atom2_2, atom3)); Implication impHi = new Implication("impHi", ImplicationPriority.Maximum, String.Empty, String.Empty, imp2, new AtomGroup(AtomGroup.LogicalOperator.And, atom2_2, atom3)); // schedule in any order a.Schedule(impMedSaHi); a.Schedule(impLow); a.Schedule(impMed); a.Schedule(impMedHi); a.Schedule(impMedSaLo); a.Schedule(impLowMed); a.Schedule(impHi); // prepare for execution, which should sort this mess out a.PrepareExecution(); Implication[] expected = new Implication[] {impHi, impMedHi, impMedSaHi, impMedSaLo, impMed, impLowMed, impLow}; int i = 0; Implication implicationParser; while (a.HasMoreToExecute) { implicationParser = a.NextToExecute; Assert.IsTrue(implicationParser.Equals(expected[i]), "Agenda not ordered: " + implicationParser.Label + "::" + implicationParser.Weight + " != " + expected[i].Label + "::" + expected[i].Weight); i++; } }
private void InferUntilNoNewFact(ArrayList positiveImplications) { long iniTime; if (HasLogListener) ForceDispatchLog("(Starting) " + ((WM.Type == WorkingMemoryTypes.Global)?"Global":"Isolated") + "Working Memory contains: " + WM.FB.Count + " facts, " + IB.Count + " implications, " + QB.Count + " queries.", LogEventImpl.DEBUG); iniTime = DateTime.Now.Ticks; ArrayList iterationPositiveImplications = null; bool iterate = true; Agenda agenda = new Agenda(); // Loop as long as there are new deduction made while(iterate) { if (iteration >= IterationLimit) throw new BREException("Maximum limit of iterations reached: " + IterationLimit); iterate = false; iteration++; // Schedule all implications matching the existing facts agenda.Schedule(iterationPositiveImplications, IB); agenda.PrepareExecution(); if (HasLogListener) ForceDispatchLog("Iteration #" + iteration + ": " + agenda.Count + " implications in agenda, with " + positiveImplications.Count + " positive.", LogEventImpl.DEBUG); iterationPositiveImplications = new ArrayList(); while (agenda.HasMoreToExecute) { Implication firedImplication = agenda.NextToExecute; // check if this implication is worth processing: // first: see if it is not mutexed by a previously positive implication if ((firedImplication.MutexChain != null) && (!positiveImplications.Contains(firedImplication)) && (Misc.AreIntersecting(firedImplication.MutexChain, positiveImplications))) { if (HasLogListener) ForceDispatchLog("Mutexed: "+firedImplication.Label, LogEventImpl.DEBUG); firedImplication = null; } // second: see if it is not pre-condition disabled by a previously negative implication if ((firedImplication != null) && (firedImplication.PreconditionImplication != null) && (!positiveImplications.Contains(firedImplication.PreconditionImplication))) { if (HasLogListener) ForceDispatchLog("Negative Precondition: "+firedImplication.Label, LogEventImpl.DEBUG); firedImplication = null; } if (firedImplication != null) { WM.FB.ModifiedFlag = false; int resultsCount = RunImplication(firedImplication); if (HasLogListener) ForceDispatchLog("Fired Implication: " + firedImplication.ToString() + " returned: " + resultsCount, LogEventImpl.DEBUG); // if processor has been positive, i.e an implication deducted at least one fact if (resultsCount > 0) positiveImplications.Add(firedImplication); // if the fact base has been anyhow modified if (WM.FB.ModifiedFlag) iterationPositiveImplications.Add(firedImplication); } } // while agenda has more // if at least one is accepted ask for another processing iteration iterate = (iterationPositiveImplications.Count > 0); } // while iterate // perform integrity checks foreach(Query integrityQuery in IntegrityQueries) { QueryResultSet qrs = RunQuery(integrityQuery); if (qrs.Count == 0) throw new IntegrityException("Rulebase integrity violated: " + integrityQuery.Label); } if (HasLogListener) ForceDispatchLog("NxBRE Inference Engine Execution Time: " + (long)(DateTime.Now.Ticks - iniTime)/10000 + " milliseconds", LogEventImpl.INFO); if (HasLogListener) ForceDispatchLog("(Finishing) " + ((WM.Type == WorkingMemoryTypes.Global)?"Global":"Isolated") + "Working Memory contains: " + WM.FB.Count + " facts, " + IB.Count + " implications, " + QB.Count + " queries.", LogEventImpl.DEBUG); }