private void PerformNafSupport(IRuleBaseAdapter irba) { ie.LoadRuleBase(irba); deductionsToCheck = new string[] { "Detector In Room{A102}", "Detector In Room{A100}", "Firemen In Room{A102}" }; qrs = ie.RunQuery("Safe Room List"); Assert.AreEqual(3, qrs.Count, "(1) Safe Room List: Count"); ParseResult(); Assert.IsFalse(wrongDeduction, "(1) Safe Room List Deductions OK"); deductionsToCheck = new string[] { "Alarm Fault In Room{Smoke Detected,A100}", "Safe Room{A102}" }; NewFactEvent henf = new NewFactEvent(HandleExpectedNewFact); ie.NewFactHandler += henf; Process(); Assert.AreEqual(2, deducted, "Deducted"); Assert.IsFalse(wrongDeduction, "Deductions OK"); ie.NewFactHandler -= henf; deductionsToCheck = new string[] { "Detector In Room{A102}", "Firemen In Room{A102}" }; qrs = ie.RunQuery("Safe Room List"); Assert.AreEqual(2, qrs.Count, "(2) Safe Room List: Count"); ParseResult(); Assert.IsFalse(wrongDeduction, "(2) Safe Room List Deductions OK"); deductionsToCheck = null; }
public DslAdapter(string dslFile, string definitionFile, GrammarLanguages grammarLanguage) { RuleBaseBuilder rbb = new RuleBaseBuilder(new Definitions(definitionFile)); string ruleml = null; if (grammarLanguage == GrammarLanguages.EN) { InferenceRules_ENParser ipr = new InferenceRules_ENParser( new CommonTokenStream( new InferenceRules_ENLexer( new ANTLRFileStream(dslFile)))); ipr.rbb = rbb; ipr.rulebase(); ruleml = ipr.rbb.RuleML; } else if (grammarLanguage == GrammarLanguages.FR) { InferenceRules_FRParser ipr = new InferenceRules_FRParser( new CommonTokenStream( new InferenceRules_FRLexer( new ANTLRFileStream(dslFile)))); ipr.rbb = rbb; ipr.rulebase(); ruleml = ipr.rbb.RuleML; } adapter = new RuleML09NafDatalogAdapter(new MemoryStream(new UTF8Encoding().GetBytes(ruleml)), FileAccess.Read); }
private void PerformCountingImpFunctionRelSupport(IRuleBaseAdapter irba, bool withBinder) { ie.LoadRuleBase(irba); ie.NewWorkingMemory(WorkingMemoryTypes.Isolated); deductionsToCheck = new string[] { "Result{Physics,Passed}", "Result{Poetry,Passed}", "Result Count{2,Passed}" }; NewFactEvent henf = new NewFactEvent(HandleExpectedNewFact); ie.NewFactHandler += henf; Process(withBinder?new Hashtable():null); Assert.AreEqual(3, deducted, "(1) Deducted"); Assert.IsFalse(wrongDeduction, "(1) Deductions OK"); ie.NewFactHandler -= henf; ie.NewWorkingMemory(WorkingMemoryTypes.Isolated); // let's turn maths failure into success ie.Retract("Maths Score"); ie.Assert(new Fact("Score", new Individual("Maths"), new Individual(88))); deductionsToCheck = new string[] { "Result{Physics,Passed}", "Result{Poetry,Passed}", "Result{Maths,Passed}", "Result Count{3,Passed}", "Graduation Success{}" }; henf = new NewFactEvent(HandleExpectedNewFact); ie.NewFactHandler += henf; Process(withBinder?new Hashtable():null); Assert.AreEqual(5, deducted, "(2) Deducted"); Assert.IsFalse(wrongDeduction, "(2) Deductions OK"); ie.NewFactHandler -= henf; deductionsToCheck = null; }
private void EnsureFactCorrectlyTyped(IRuleBaseAdapter adapter, int expectedFactCount) { ie.LoadRuleBase(adapter); Assert.AreEqual(expectedFactCount, ie.FactsCount, "Number of facts"); for(IEnumerator e = ie.Facts ; e.MoveNext(); ) { Fact fact = (Fact) e.Current; Assert.AreEqual(fact.Type.Substring(1 + fact.Type.LastIndexOf(' ')), fact.GetPredicateValue(0).GetType().FullName, "Ensure type support"); } }
private void PerformChocolateBoxTwiddling(IRuleBaseAdapter irba, bool withBinder) { ie.LoadRuleBase(irba); Process(withBinder?new Hashtable():null); Assert.AreEqual(0, deducted, "Deducted"); Assert.AreEqual(0, deleted, "Deleted"); Assert.AreEqual(2, modified, "Modified"); Assert.AreEqual("Chocolate_Box_Weight{MyBox,2.5}", ie.GetFact("Total Weight").ToString(), "Total Weight OK"); }
public void DoPersistenceOfNonConvertibleTypedFacts(IRuleBaseAdapter adapter) { string outFile = Parameter.GetString("unittest.outputfolder") + "/outfacts.ruleml"; ie.LoadRuleBase(adapter); TestBinder.Character theDuke = new TestBinder.Character("The Duke", "hello world"); Assert.IsTrue(ie.Assert(new Fact("Character Name", new Individual(theDuke), new Individual(theDuke.Name))), "Asserted Typed Fact"); ie.SaveFacts(new RuleML086NafDatalogAdapter(outFile, FileAccess.Write, true)); Assert.Fail("Should never reach me!"); }
/// <summary> /// Saves the WorkingMemory in a rule base. /// </summary> /// <param name="adapter">The Adapter used to save the rule base.</param> /// <remarks> /// The adapter will be disposed at the end of the method's execution. /// </remarks> /// <see cref="org.nxbre.ie.adapters.IRuleBaseAdapter"/> public void SaveRuleBase(IRuleBaseAdapter adapter) { CheckInitialized(); if (HasLogListener) { ForceDispatchLog("NxBRE Inference Engine Rule Base Saving Started, using adapter " + adapter.GetType().FullName, LogEventImpl.INFO); } using (adapter) { // header adapter.Direction = Direction; adapter.Label = Label; //queries ArrayList queries = new ArrayList(); foreach (Query query in QB) { queries.Add(query); } adapter.Queries = queries; // implications ArrayList implications = new ArrayList(); foreach (Implication implication in IB) { implications.Add(implication); } adapter.Implications = implications; // equivalents & integrity queries if supported if (adapter is IExtendedRuleBaseAdapter) { ((IExtendedRuleBaseAdapter)adapter).Equivalents = equivalents; ((IExtendedRuleBaseAdapter)adapter).IntegrityQueries = integrityQueries; } // facts ArrayList facts = new ArrayList(); foreach (Fact fact in WM.FB) { facts.Add(fact); } adapter.Facts = facts; } if (HasLogListener) { ForceDispatchLog("NxBRE Inference Engine Rule Base Saving Finished", LogEventImpl.INFO); } }
private void RunTestBoundFormulas(IBinder binder, IRuleBaseAdapter rba) { // regression test for RFE 1504353 IInferenceEngine ie = new IEImpl(binder); ie.LoadRuleBase(rba); Assert.IsTrue(ie.Assert(new Fact("operandA", new Individual(23)))); Assert.IsTrue(ie.Assert(new Fact("operandB", new Individual(7)))); ie.Process(); Assert.AreEqual(4, ie.FactsCount); Assert.IsTrue(ie.FactExists(new Fact("resultA-B", new Individual(16))), "resultA-B is wrong"); Assert.IsTrue(ie.FactExists(new Fact("resultB-A", new Individual(-16))), "resultB-A is wrong"); }
/// <summary> /// Get a specific list type from an adapter. /// </summary> /// <typeparam name="T">Type of the list to return</typeparam> /// <param name="adapter">adapter to return the list from</param> /// <param name="listType"></param> /// <returns></returns> private IList <T> GetAdaptersList <T>(IRuleBaseAdapter adapter, AdapterListType listType) { switch (listType) { case AdapterListType.Fact: return((IList <T>)adapter.Facts); case AdapterListType.Implication: return((IList <T>)adapter.Implications); case AdapterListType.Query: return((IList <T>)adapter.Queries); } IExtendedRuleBaseAdapter extendedAdapter = adapter as IExtendedRuleBaseAdapter; if (adapter != null) { switch (listType) { case AdapterListType.Retraction: return((IList <T>)extendedAdapter.Retractions); case AdapterListType.IntegrityQuery: return((IList <T>)extendedAdapter.IntegrityQueries); case AdapterListType.Equivalent: return((IList <T>)extendedAdapter.Equivalents); case AdapterListType.Assertion: return((IList <T>)extendedAdapter.Assertions); } } return(new List <T>(0)); }
private void CommonDiscountVisio2003(IRuleBaseAdapter rba) { ie.LoadRuleBase(rba); Process(); Assert.AreEqual(3, deducted, "(1) Deducted"); Assert.AreEqual(6, ie.FactsCount, "(2) Total Facts Count"); deductionsToCheck = new string[] { "Discount{Peter Miller,Honda,5.0}", "Discount{Peter Miller,Porsche,7.5}" }; qrs = ie.RunQuery(new Query(new AtomGroup(AtomGroup.LogicalOperator.And, new Atom("Discount", new Variable("customer"), new Variable("product"), new Variable("amount"))))); Assert.AreEqual(2, qrs.Count, "(1) Query Result Size"); ParseResult(); Assert.IsFalse(wrongDeduction, "(1) Query Results"); // Spending JQDoe Assert.IsTrue(ie.Assert(new Fact("Spending", new Individual("John Q. Doe"), new Individual(2004), new Individual(123.45f))), "jqdoeSpending asserted"); Fact jqdoePremiumRating = new Fact("Customer Rating", new Individual("John Q. Doe"), new Individual("Premium")); Assert.IsTrue(ie.Assert(jqdoePremiumRating), "jqdoePremiumRating asserted"); // SpendingJDupont Assert.IsTrue(ie.Assert(new Fact("Spending", new Individual("Jean Dupont"), new Individual(2004), new Individual(3245.25f))), "jdupontSpending asserted"); Process(); Assert.IsFalse(ie.FactExists(jqdoePremiumRating), "jqdoePremiumRating was retracted"); Assert.AreEqual(4, deducted, "(2) Deducted"); Assert.AreEqual(12, ie.FactsCount, "(2) Total Facts Count"); // Run named queries deductionsToCheck = new string[] { "Discount{Peter Miller,Honda,5.0}", "Discount{Peter Miller,Porsche,7.5}", "Discount{Jean Dupont,Honda,5.0}", "Discount{Jean Dupont,Porsche,7.5}" }; qrs = ie.RunQuery("Calculated Discounts"); Assert.AreEqual(4, qrs.Count, "(2) Query Result Size"); ParseResult(); Assert.IsFalse(wrongDeduction, "(2) Query Results"); deductionsToCheck = new string[] { "Customer Rating{Peter Miller,Premium}", "Customer Rating{John Q. Doe,Regular}", "Customer Rating{Jean Dupont,Premium}" }; qrs = ie.RunQuery("Customer Ratings"); Assert.AreEqual(3, qrs.Count, "(3) Query Result Size"); ParseResult(); Assert.IsFalse(wrongDeduction, "(3) Query Results"); }
/// <summary> /// Saves the WorkingMemory in a rule base. /// </summary> /// <param name="adapter">The Adapter used to save the rule base.</param> /// <remarks> /// The adapter will be disposed at the end of the method's execution. /// </remarks> /// <see cref="NxBRE.InferenceEngine.IO.IRuleBaseAdapter"/> public void SaveRuleBase(IRuleBaseAdapter adapter) { CheckInitialized(); if (Logger.IsInferenceEngineInformation) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Information, 0, "NxBRE Inference Engine Rule Base Saving Started, using adapter " + adapter.GetType().FullName); using(adapter) { // header adapter.Direction = Direction; adapter.Label = Label; //queries IList<Query> queries = new List<Query>(); foreach(Query query in QB) queries.Add(query); adapter.Queries = queries; // implications IList<Implication> implications = new List<Implication>(); foreach(Implication implication in IB) implications.Add(implication); adapter.Implications = implications; // build a collection of in-memory facts IList<Fact> factsInWorkingMemory = new List<Fact>(); foreach(Fact fact in WM.FB) factsInWorkingMemory.Add(fact); if (adapter is IExtendedRuleBaseAdapter) { // equivalents & integrity queries, assertions and retractions, if supported IExtendedRuleBaseAdapter extendedAdapter = (IExtendedRuleBaseAdapter)adapter; extendedAdapter.Equivalents = equivalents; extendedAdapter.IntegrityQueries = integrityQueries; extendedAdapter.Assertions = factsInWorkingMemory; //TODO FR-1546485: write facts retractions } else { // basic adapter facts output adapter.Facts = factsInWorkingMemory; } } if (Logger.IsInferenceEngineInformation) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Information, 0, "NxBRE Inference Engine Rule Base Saving Finished"); }
/// <summary> /// Loads a rule base. The working memory is reset (all facts are lost). /// </summary> /// <param name="adapter">The Adapter used to read the rule base.</param> /// <param name="processPerformatives">Immediatly process the performative actions (assert, retract) found in the rule base.</param> /// <remarks> /// The adapter will be disposed at the end of the method's execution. /// </remarks> /// <see cref="NxBRE.InferenceEngine.IO.IRuleBaseAdapter"/> public void LoadRuleBase(IRuleBaseAdapter adapter, bool processPerformatives) { LoadRuleBase(adapter, Binder, processPerformatives); }
/// <summary> /// Loads a rule base. The working memory is reset (all facts are lost). /// </summary> /// <param name="adapter">The Adapter used to read the rule base.</param> /// <param name="businessObjectsBinder">The business object binder that the engine must use.</param> /// <param name="processPerformatives">Immediatly process the performative actions (assert, retract) found in the rule base.</param> /// <remarks> /// The adapter will be disposed at the end of the method's execution. /// </remarks> /// <see cref="NxBRE.InferenceEngine.IO.IRuleBaseAdapter"/> public void LoadRuleBase(IRuleBaseAdapter adapter, IBinder businessObjectsBinder, bool processPerformatives) { if (Logger.IsInferenceEngineInformation) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Information, 0, "NxBRE Inference Engine Rule Base Loading Started, using adapter " + adapter.GetType().FullName); using(adapter) { // reset the WM WM.PrepareInitialization(); // sets the Binder Binder = businessObjectsBinder; // and pass it to the adapter if needed if (Binder != null) adapter.Binder = Binder; // currently only forward chaining is supported direction = adapter.Direction; if (direction == "backward") { throw new BREException("NxBRE does not support backward chaining"); } else if (direction == String.Empty) { if (Logger.IsInferenceEngineWarning) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Warning, 0, "NxBRE interprets no-direction directive as forward chaining."); } else if (direction == "bidirectional") { if (Logger.IsInferenceEngineWarning) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Warning, 0, "NxBRE interprets bidirectional as forward chaining."); } else if (direction != "forward") { throw new BREException("NxBRE does not support direction: " + direction); } // sets the label label = adapter.Label; // load the Equivalents and IntegrityQueries if the adapter supports it IExtendedRuleBaseAdapter extendedAdapter = null; if (adapter is IExtendedRuleBaseAdapter) { extendedAdapter = (IExtendedRuleBaseAdapter)adapter; equivalents = extendedAdapter.Equivalents; if (Logger.IsInferenceEngineVerbose) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Loaded " + equivalents.Count + " Equivalents"); integrityQueries = extendedAdapter.IntegrityQueries; if (Logger.IsInferenceEngineVerbose) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Loaded " + integrityQueries.Count + " IntegrityQueries"); } else { equivalents = new List<Equivalent>(0); integrityQueries = new List<Query>(0); } // instantiate the different storage ib = new ImplicationBase(); qb = new QueryBase(); // instantiate the related managers mm = new MutexManager(IB); pm = new PreconditionManager(IB); // load queries foreach(Query query in adapter.Queries) QB.Add(query); if (Logger.IsInferenceEngineVerbose) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Loaded " + QB.Count + " Queries"); // load implications foreach(Implication implication in adapter.Implications) IB.Add(implication); if (Logger.IsInferenceEngineVerbose) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Loaded " + IB.Count + " Implications\n"); // load mutexes mm.AnalyzeImplications(); if (Logger.IsInferenceEngineVerbose) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Loaded Mutexes\n" + mm.ToString()); // load preconditions pm.AnalyzeImplications(); if (Logger.IsInferenceEngineVerbose) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Loaded Preconditions\n" + pm.ToString()); initialized = true; // load facts assertions performativeAssertions = new List<Fact>((extendedAdapter!=null)?extendedAdapter.Assertions:adapter.Facts); //TODO FR-1546485: load facts retractions if (processPerformatives) ProcessPerfomatives(); if (Logger.IsInferenceEngineVerbose) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Loaded " + WM.FB.Count + " Facts"); // finish the WM init WM.FinishInitialization(); } //end: using adapter if (Logger.IsInferenceEngineInformation) Logger.InferenceEngineSource.TraceEvent(TraceEventType.Information, 0, "NxBRE Inference Engine Rule Base Loading Finished"); }
public void LoadRules() { // prepare the rule base adapter for reading the rule file var ruleFileFullPath = configurationFolder + Path.DirectorySeparatorChar + RuleFile; if (Logger.IsInferenceEngineVerbose) { Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Loading rule file: " + ruleFileFullPath + " of format: " + engineConfiguration.Rules.Format); } IRuleBaseAdapter ruleBaseAdapter = null; switch (engineConfiguration.Rules.Format) { case RulesFormat.HRF086: ruleBaseAdapter = new HRF086Adapter(ruleFileFullPath, FileAccess.Read); break; case RulesFormat.RuleML08Datalog: ruleBaseAdapter = new RuleML08DatalogAdapter(ruleFileFullPath, FileAccess.Read); break; case RulesFormat.RuleML086Datalog: ruleBaseAdapter = new RuleML086DatalogAdapter(ruleFileFullPath, FileAccess.Read); break; case RulesFormat.RuleML086NafDatalog: ruleBaseAdapter = new RuleML086NafDatalogAdapter(ruleFileFullPath, FileAccess.Read); break; case RulesFormat.RuleML09NafDatalog: ruleBaseAdapter = new RuleML09NafDatalogAdapter(ruleFileFullPath, FileAccess.Read); break; case RulesFormat.Visio2003: ruleBaseAdapter = new Visio2003Adapter(ruleFileFullPath, FileAccess.Read); break; default: throw new ArgumentOutOfRangeException(); } // estimate if a binder is present if (engineConfiguration.Binder != null) { var binder = engineConfiguration.Binder as CSharpBinderConfiguration; if (binder != null) { var cSharpBinderConfiguration = binder; binderFile = cSharpBinderConfiguration.File; if (Logger.IsInferenceEngineVerbose) { Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Using CSharp binder file: " + binderFile); } // we load the binder code in a string and then compile it: this method is more reliable than // providing a file path directly using (var sr = File.OpenText(configurationFolder + Path.DirectorySeparatorChar + binderFile)) { engine.LoadRuleBase(ruleBaseAdapter, CSharpBinderFactory.LoadFromString(cSharpBinderConfiguration.Class, sr.ReadToEnd())); } } else if (engineConfiguration.Binder is VisualBasicBinderConfiguration) { var visualBasicBinderConfiguration = (VisualBasicBinderConfiguration)engineConfiguration.Binder; binderFile = visualBasicBinderConfiguration.File; if (Logger.IsInferenceEngineVerbose) { Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Using Visual Basic binder file: " + binderFile); } // we load the binder code in a string and then compile it: this method is more reliable than // providing a file path directly using (StreamReader sr = File.OpenText(configurationFolder + Path.DirectorySeparatorChar + binderFile)) { engine.LoadRuleBase(ruleBaseAdapter, VisualBasicBinderFactory.LoadFromString(visualBasicBinderConfiguration.Class, sr.ReadToEnd())); } } else if (engineConfiguration.Binder is FlowEngineBinderConfiguration) { FlowEngineBinderConfiguration flowEngineBinderConfiguration = (FlowEngineBinderConfiguration)engineConfiguration.Binder; binderFile = flowEngineBinderConfiguration.File; if (Logger.IsInferenceEngineVerbose) { Logger.InferenceEngineSource.TraceEvent(TraceEventType.Verbose, 0, "Using FlowEngine binder file: " + binderFile); } engine.LoadRuleBase(ruleBaseAdapter, new NxBRE.InferenceEngine.IO.FlowEngineBinder(configurationFolder + Path.DirectorySeparatorChar + binderFile, flowEngineBinderConfiguration.Type)); } else { throw new BREException("Unexpected type of binder object in registry configuration: " + engineConfiguration.Binder.GetType().FullName); } } else { // no binder specified binderFile = null; engine.LoadRuleBase(ruleBaseAdapter); } }
/// <summary> /// Loads a rule base. The working memory is reset (all facts are lost). /// </summary> /// <param name="adapter">The Adapter used to read the rule base.</param> /// <param name="businessObjectsBinder">The business object binder that the engine must use.</param> /// <remarks> /// The adapter will be disposed at the end of the method's execution. /// </remarks> /// <see cref="org.nxbre.ie.adapters.IRuleBaseAdapter"/> public void LoadRuleBase(IRuleBaseAdapter adapter, IBinder businessObjectsBinder) { if (HasLogListener) ForceDispatchLog("NxBRE Inference Engine Rule Base Loading Started, using adapter " + adapter.GetType().FullName, LogEventImpl.INFO); using(adapter) { // reset the WM WM.PrepareInitialization(); // sets the Binder Binder = businessObjectsBinder; // and pass it to the adapter if needed if (Binder != null) adapter.Binder = Binder; // currently only forward chaining is supported direction = adapter.Direction; if (direction == "backward") throw new BREException("NxBRE does not support backward chaining"); else if (direction == String.Empty) if (HasLogListener) ForceDispatchLog("NxBRE interprets no-direction directive as forward chaining.", LogEventImpl.WARN); else if (direction == "bidirectional") if (HasLogListener) ForceDispatchLog("NxBRE interprets bidirectional as forward chaining.", LogEventImpl.WARN); else if (direction != "forward") throw new BREException("NxBRE does not support direction: "+direction); // sets the label label = adapter.Label; // load the Equivalents and IntegrityQueries if the adapter supports it if (adapter is IExtendedRuleBaseAdapter) { equivalents = ((IExtendedRuleBaseAdapter)adapter).Equivalents; if (HasLogListener) ForceDispatchLog("Loaded " + equivalents.Count + " Equivalents", LogEventImpl.DEBUG); integrityQueries = ((IExtendedRuleBaseAdapter)adapter).IntegrityQueries; foreach(Query integrityQuery in integrityQueries) WM.FB.RegisterAtoms(integrityQuery.AtomGroup.AllAtoms); if (HasLogListener) ForceDispatchLog("Loaded " + integrityQueries.Count + " IntegrityQueries", LogEventImpl.DEBUG); } else { equivalents = new ArrayList(); integrityQueries = equivalents; } // instantiate the implication base and the query base ib = new ImplicationBase(); qb = new QueryBase(); // instantiate the related managers mm = new MutexManager(IB); pm = new PreconditionManager(IB); initialized = true; // load queries foreach(Query query in adapter.Queries) { QB.Add(query); WM.FB.RegisterAtoms(query.AtomGroup.AllAtoms); } if (HasLogListener) ForceDispatchLog("Loaded " + QB.Count + " Queries", LogEventImpl.DEBUG); // load implications foreach(Implication implication in adapter.Implications) { IB.Add(implication); int nbRA = WM.FB.RegisterAtoms(implication.AtomGroup.AllAtoms); if (HasLogListener) ForceDispatchLog("Registered: " + nbRA + " body atoms", LogEventImpl.DEBUG); // modifying implication must run searches based on their deduction, so must register the atom if (implication.Action == ImplicationAction.Modify) { nbRA = WM.FB.RegisterAtoms(implication.Deduction); if (HasLogListener) ForceDispatchLog("Registered: " + nbRA + " head atoms", LogEventImpl.DEBUG); } } if (HasLogListener) ForceDispatchLog("Loaded " + IB.Count + " Implications\n", LogEventImpl.DEBUG); // load mutexes mm.AnalyzeImplications(); if (HasLogListener) ForceDispatchLog("Loaded Mutexes\n" + mm.ToString(), LogEventImpl.DEBUG); // load preconditions pm.AnalyzeImplications(); if (HasLogListener) ForceDispatchLog("Loaded Preconditions\n" + pm.ToString(), LogEventImpl.DEBUG); // load facts foreach(Fact fact in adapter.Facts) Assert(fact); if (HasLogListener) ForceDispatchLog("Loaded " + WM.FB.Count + " Facts", LogEventImpl.DEBUG); // finish the WM init WM.FinishInitialization(); } //end: using adapter if (HasLogListener) ForceDispatchLog("NxBRE Inference Engine Rule Base Loading Finished", LogEventImpl.INFO); }
/// <summary> /// Loads a rule base. The working memory is reset (all facts are lost). /// </summary> /// <param name="adapter">The Adapter used to read the rule base.</param> /// <remarks> /// The adapter will be disposed at the end of the method's execution. /// </remarks> /// <see cref="org.nxbre.ie.adapters.IRuleBaseAdapter"/> public void LoadRuleBase(IRuleBaseAdapter adapter) { LoadRuleBase(adapter, Binder); }
/// <summary> /// Save facts of the current working memory. Current implications, facts and queries /// remain unchanged. /// </summary> /// <remarks> /// The adapter will be disposed at the end of the method's execution. /// </remarks> /// <param name="adapter">The Adapter used to save the fact base.</param> public void SaveFacts(IRuleBaseAdapter adapter) { CheckInitialized(); if (HasLogListener) ForceDispatchLog("NxBRE Inference Engine Facts Saving Started, using adapter " + adapter.GetType().FullName, LogEventImpl.INFO); using(adapter) { // header adapter.Direction = Direction; adapter.Label = Label; // facts ArrayList facts = new ArrayList(); foreach(Fact fact in WM.FB) facts.Add(fact); adapter.Facts = facts; } //end: using adapter if (HasLogListener) ForceDispatchLog("NxBRE Inference Engine Facts Saving Finished", LogEventImpl.INFO); }
private void PerformCountingImpFunctionRelSupport(IRuleBaseAdapter irba, bool withBinder) { ie.LoadRuleBase(irba); ie.NewWorkingMemory(WorkingMemoryTypes.Isolated); deductionsToCheck = new string[] {"Result{Physics,Passed}", "Result{Poetry,Passed}", "Result Count{2,Passed}"}; NewFactEvent henf = new NewFactEvent(HandleExpectedNewFact); ie.NewFactHandler += henf; Process(withBinder?new Hashtable():null); Assert.AreEqual(3, deducted, "(1) Deducted"); Assert.IsFalse(wrongDeduction, "(1) Deductions OK"); ie.NewFactHandler -= henf; ie.NewWorkingMemory(WorkingMemoryTypes.Isolated); // let's turn maths failure into success ie.Retract("Maths Score"); ie.Assert(new Fact("Score", new Individual("Maths"), new Individual(88))); deductionsToCheck = new string[] {"Result{Physics,Passed}", "Result{Poetry,Passed}", "Result{Maths,Passed}", "Result Count{3,Passed}", "Graduation Success{}"}; henf = new NewFactEvent(HandleExpectedNewFact); ie.NewFactHandler += henf; Process(withBinder?new Hashtable():null); Assert.AreEqual(5, deducted, "(2) Deducted"); Assert.IsFalse(wrongDeduction, "(2) Deductions OK"); ie.NewFactHandler -= henf; deductionsToCheck = null; }
private void PerformNafSupport(IRuleBaseAdapter irba) { ie.LoadRuleBase(irba); deductionsToCheck = new string[] {"Detector In Room{A102}", "Detector In Room{A100}", "Firemen In Room{A102}"}; qrs = ie.RunQuery("Safe Room List"); Assert.AreEqual(3, qrs.Count, "(1) Safe Room List: Count"); ParseResult(); Assert.IsFalse(wrongDeduction, "(1) Safe Room List Deductions OK"); deductionsToCheck = new string[] {"Alarm Fault In Room{Smoke Detected,A100}", "Safe Room{A102}"}; NewFactEvent henf = new NewFactEvent(HandleExpectedNewFact); ie.NewFactHandler += henf; Process(); Assert.AreEqual(2, deducted, "Deducted"); Assert.IsFalse(wrongDeduction, "Deductions OK"); ie.NewFactHandler -= henf; deductionsToCheck = new string[] {"Detector In Room{A102}", "Firemen In Room{A102}"}; qrs = ie.RunQuery("Safe Room List"); Assert.AreEqual(2, qrs.Count, "(2) Safe Room List: Count"); ParseResult(); Assert.IsFalse(wrongDeduction, "(2) Safe Room List Deductions OK"); deductionsToCheck = null; }
/// <summary> /// Loads a rule base. The working memory is reset (all facts are lost). /// </summary> /// <param name="adapter">The Adapter used to read the rule base.</param> /// <param name="businessObjectsBinder">The business object binder that the engine must use.</param> /// <remarks> /// The adapter will be disposed at the end of the method's execution. /// </remarks> /// <see cref="org.nxbre.ie.adapters.IRuleBaseAdapter"/> public void LoadRuleBase(IRuleBaseAdapter adapter, IBinder businessObjectsBinder) { if (HasLogListener) { ForceDispatchLog("NxBRE Inference Engine Rule Base Loading Started, using adapter " + adapter.GetType().FullName, LogEventImpl.INFO); } using (adapter) { // reset the WM WM.PrepareInitialization(); // sets the Binder Binder = businessObjectsBinder; // and pass it to the adapter if needed if (Binder != null) { adapter.Binder = Binder; } // currently only forward chaining is supported direction = adapter.Direction; if (direction == "backward") { throw new BREException("NxBRE does not support backward chaining"); } else if (direction == String.Empty) { if (HasLogListener) { ForceDispatchLog("NxBRE interprets no-direction directive as forward chaining.", LogEventImpl.WARN); } else if (direction == "bidirectional") { if (HasLogListener) { ForceDispatchLog("NxBRE interprets bidirectional as forward chaining.", LogEventImpl.WARN); } else if (direction != "forward") { throw new BREException("NxBRE does not support direction: " + direction); } } } // sets the label label = adapter.Label; // load the Equivalents and IntegrityQueries if the adapter supports it if (adapter is IExtendedRuleBaseAdapter) { equivalents = ((IExtendedRuleBaseAdapter)adapter).Equivalents; if (HasLogListener) { ForceDispatchLog("Loaded " + equivalents.Count + " Equivalents", LogEventImpl.DEBUG); } integrityQueries = ((IExtendedRuleBaseAdapter)adapter).IntegrityQueries; foreach (Query integrityQuery in integrityQueries) { WM.FB.RegisterAtoms(integrityQuery.AtomGroup.AllAtoms); } if (HasLogListener) { ForceDispatchLog("Loaded " + integrityQueries.Count + " IntegrityQueries", LogEventImpl.DEBUG); } } else { equivalents = new ArrayList(); integrityQueries = equivalents; } // instantiate the implication base and the query base ib = new ImplicationBase(); qb = new QueryBase(); // instantiate the related managers mm = new MutexManager(IB); pm = new PreconditionManager(IB); initialized = true; // load queries foreach (Query query in adapter.Queries) { QB.Add(query); WM.FB.RegisterAtoms(query.AtomGroup.AllAtoms); } if (HasLogListener) { ForceDispatchLog("Loaded " + QB.Count + " Queries", LogEventImpl.DEBUG); } // load implications foreach (Implication implication in adapter.Implications) { IB.Add(implication); int nbRA = WM.FB.RegisterAtoms(implication.AtomGroup.AllAtoms); if (HasLogListener) { ForceDispatchLog("Registered: " + nbRA + " body atoms", LogEventImpl.DEBUG); } // modifying implication must run searches based on their deduction, so must register the atom if (implication.Action == ImplicationAction.Modify) { nbRA = WM.FB.RegisterAtoms(implication.Deduction); if (HasLogListener) { ForceDispatchLog("Registered: " + nbRA + " head atoms", LogEventImpl.DEBUG); } } } if (HasLogListener) { ForceDispatchLog("Loaded " + IB.Count + " Implications\n", LogEventImpl.DEBUG); } // load mutexes mm.AnalyzeImplications(); if (HasLogListener) { ForceDispatchLog("Loaded Mutexes\n" + mm.ToString(), LogEventImpl.DEBUG); } // load preconditions pm.AnalyzeImplications(); if (HasLogListener) { ForceDispatchLog("Loaded Preconditions\n" + pm.ToString(), LogEventImpl.DEBUG); } // load facts foreach (Fact fact in adapter.Facts) { Assert(fact); } if (HasLogListener) { ForceDispatchLog("Loaded " + WM.FB.Count + " Facts", LogEventImpl.DEBUG); } // finish the WM init WM.FinishInitialization(); } //end: using adapter if (HasLogListener) { ForceDispatchLog("NxBRE Inference Engine Rule Base Loading Finished", LogEventImpl.INFO); } }
private void CommonDiscountVisio2003(IRuleBaseAdapter rba) { ie.LoadRuleBase(rba); Process(); Assert.AreEqual(3, deducted, "(1) Deducted"); Assert.AreEqual(6, ie.FactsCount, "(2) Total Facts Count"); deductionsToCheck = new string[] {"Discount{Peter Miller,Honda,5.0}", "Discount{Peter Miller,Porsche,7.5}"}; qrs = ie.RunQuery(new Query(new AtomGroup(AtomGroup.LogicalOperator.And, new Atom("Discount", new Variable("customer"), new Variable("product"), new Variable("amount"))))); Assert.AreEqual(2, qrs.Count, "(1) Query Result Size"); ParseResult(); Assert.IsFalse(wrongDeduction, "(1) Query Results"); // Spending JQDoe Assert.IsTrue(ie.Assert(new Fact("Spending", new Individual("John Q. Doe"), new Individual(2004), new Individual(123.45f))), "jqdoeSpending asserted"); Fact jqdoePremiumRating = new Fact("Customer Rating", new Individual("John Q. Doe"), new Individual("Premium")); Assert.IsTrue(ie.Assert(jqdoePremiumRating), "jqdoePremiumRating asserted"); // SpendingJDupont Assert.IsTrue(ie.Assert(new Fact("Spending", new Individual("Jean Dupont"), new Individual(2004), new Individual(3245.25f))), "jdupontSpending asserted"); Process(); Assert.IsFalse(ie.FactExists(jqdoePremiumRating), "jqdoePremiumRating was retracted"); Assert.AreEqual(4, deducted, "(2) Deducted"); Assert.AreEqual(12, ie.FactsCount, "(2) Total Facts Count"); // Run named queries deductionsToCheck = new string[] {"Discount{Peter Miller,Honda,5.0}", "Discount{Peter Miller,Porsche,7.5}", "Discount{Jean Dupont,Honda,5.0}", "Discount{Jean Dupont,Porsche,7.5}"}; qrs = ie.RunQuery("Calculated Discounts"); Assert.AreEqual(4, qrs.Count, "(2) Query Result Size"); ParseResult(); Assert.IsFalse(wrongDeduction, "(2) Query Results"); deductionsToCheck = new string[] {"Customer Rating{Peter Miller,Premium}", "Customer Rating{John Q. Doe,Regular}", "Customer Rating{Jean Dupont,Premium}"}; qrs = ie.RunQuery("Customer Ratings"); Assert.AreEqual(3, qrs.Count, "(3) Query Result Size"); ParseResult(); Assert.IsFalse(wrongDeduction, "(3) Query Results"); }
/// <summary> /// Saves the WorkingMemory in a rule base. /// </summary> /// <param name="adapter">The Adapter used to save the rule base.</param> /// <remarks> /// The adapter will be disposed at the end of the method's execution. /// </remarks> /// <see cref="org.nxbre.ie.adapters.IRuleBaseAdapter"/> public void SaveRuleBase(IRuleBaseAdapter adapter) { CheckInitialized(); if (HasLogListener) ForceDispatchLog("NxBRE Inference Engine Rule Base Saving Started, using adapter " + adapter.GetType().FullName, LogEventImpl.INFO); using(adapter) { // header adapter.Direction = Direction; adapter.Label = Label; //queries ArrayList queries = new ArrayList(); foreach(Query query in QB) queries.Add(query); adapter.Queries = queries; // implications ArrayList implications = new ArrayList(); foreach(Implication implication in IB) implications.Add(implication); adapter.Implications = implications; // equivalents & integrity queries if supported if (adapter is IExtendedRuleBaseAdapter) { ((IExtendedRuleBaseAdapter)adapter).Equivalents = equivalents; ((IExtendedRuleBaseAdapter)adapter).IntegrityQueries = integrityQueries; } // facts ArrayList facts = new ArrayList(); foreach(Fact fact in WM.FB) facts.Add(fact); adapter.Facts = facts; } if (HasLogListener) ForceDispatchLog("NxBRE Inference Engine Rule Base Saving Finished", LogEventImpl.INFO); }
/// <summary> /// Load facts in the current working memory. Current implications, facts and queries /// remain unchanged. /// </summary> /// <remarks> /// The adapter will be disposed at the end of the method's execution. /// </remarks> /// <param name="adapter">The Adapter used to read the fact base.</param> public void LoadFacts(IRuleBaseAdapter adapter) { CheckInitialized(); if (HasLogListener) ForceDispatchLog("NxBRE Inference Engine Facts Loading Started, using adapter " + adapter.GetType().FullName, LogEventImpl.INFO); using(adapter) { // sets the eventual Binder if (Binder != null) adapter.Binder = Binder; // load facts int initialFactsCount = WM.FB.Count; foreach(Fact fact in adapter.Facts) Assert(fact); if (HasLogListener) ForceDispatchLog("Added " + (WM.FB.Count - initialFactsCount) + " new Facts", LogEventImpl.DEBUG); } //end: using adapter if (HasLogListener) ForceDispatchLog("NxBRE Inference Engine Facts Loading Finished", LogEventImpl.INFO); }
/// <summary> /// Loads a rule base and process the performatives. The working memory is reset (all facts are lost). /// </summary> /// <param name="adapter">The Adapter used to read the rule base.</param> /// <remarks> /// The adapter will be disposed at the end of the method's execution. /// This is equivalent to calling: <code>LoadRuleBase(adapter, true)</code> /// </remarks> /// <see cref="NxBRE.InferenceEngine.IO.IRuleBaseAdapter"/> public void LoadRuleBase(IRuleBaseAdapter adapter) { LoadRuleBase(adapter, true); }
/// <summary> /// Get a specific list type from an adapter. /// </summary> /// <typeparam name="T">Type of the list to return</typeparam> /// <param name="adapter">adapter to return the list from</param> /// <param name="listType"></param> /// <returns></returns> private IList <T> GetAdaptersList <T>(IRuleBaseAdapter adapter, AdapterListType listType) { switch (listType) { case AdapterListType.Fact: return((IList <T>)adapter.Facts); case AdapterListType.Implication: return((IList <T>)adapter.Implications); case AdapterListType.Query: return((IList <T>)adapter.Queries); case AdapterListType.Assertion: break; case AdapterListType.Retraction: break; case AdapterListType.Equivalent: break; case AdapterListType.IntegrityQuery: break; default: throw new ArgumentOutOfRangeException(nameof(listType), listType, null); } var extendedAdapter = adapter as IExtendedRuleBaseAdapter; if (adapter == null) { return(new List <T>(0)); } switch (listType) { case AdapterListType.Retraction: return((IList <T>)extendedAdapter.Retractions); case AdapterListType.IntegrityQuery: return((IList <T>)extendedAdapter.IntegrityQueries); case AdapterListType.Equivalent: return((IList <T>)extendedAdapter.Equivalents); case AdapterListType.Assertion: return((IList <T>)extendedAdapter.Assertions); case AdapterListType.Fact: break; case AdapterListType.Query: break; case AdapterListType.Implication: break; default: throw new ArgumentOutOfRangeException(nameof(listType), listType, null); } return(new List <T>(0)); }
/// <summary> /// Loads a rule base and process the performatives. The working memory is reset (all facts are lost). /// </summary> /// <param name="adapter">The Adapter used to read the rule base.</param> /// <param name="businessObjectsBinder">The business object binder that the engine must use.</param> /// <remarks> /// The adapter will be disposed at the end of the method's execution. /// This is equivalent to calling: <code>LoadRuleBase(adapter, businessObjectsBinder, true)</code> /// </remarks> /// <see cref="NxBRE.InferenceEngine.IO.IRuleBaseAdapter"/> public void LoadRuleBase(IRuleBaseAdapter adapter, IBinder businessObjectsBinder) { LoadRuleBase(adapter, businessObjectsBinder, true); }