private static void IndividualFactTest() { DateTime end; DateTime start; TimeSpan diff; Xml x; int total; ROM rom = new ROM(); //set up out facts Fact F1 = new Fact("F1", 1, new Naked("1", typeof(double)), typeof(double)); Fact F2 = new Fact("F2", 1, new Naked("1", typeof(double)), typeof(double)); Fact F3 = new Fact("F3", 1, new Naked(null, typeof(double)), typeof(double)); rom.AddEvidence(F1); rom.AddEvidence(F2); rom.AddEvidence(F3); //set up our assignments ActionExpression A1 = new ActionExpression("1", "F1", "2", 2); ActionExpression A2 = new ActionExpression("2", "F2", "2", 2); rom.AddEvidence(A1); rom.AddEvidence(A2); List<EvidenceSpecifier> list = new List<EvidenceSpecifier>(); list.Add(new EvidenceSpecifier(true, "1")); list.Add(new EvidenceSpecifier(true, "2")); //create a rule Rule R1 = new Rule("R1", "1==1", list, 500, true); rom.AddEvidence(R1); rom.Evaluate(); Console.WriteLine("Starting Test:" + DateTime.Now); total = 1000; start = DateTime.Now; for (int counter = 0; counter < total; counter++) { //cause rules to evaluate rom.Evaluate(); } end = DateTime.Now; diff = end - start; Console.WriteLine("Total ms: " + diff.TotalMilliseconds); Console.WriteLine("milliseconds per rule: " + (diff.TotalMilliseconds / (total * 8d))); //eight rules per run }
public void TestEvaluateFunctionality() { RuleEngine.ROM rom = new RuleEngine.ROM(); //facts and rules available to these text cases RuleEngine.Evidence.Fact f1 = new RuleEngine.Evidence.Fact("f1", 1, 2d, typeof(double)); RuleEngine.Evidence.Fact f2 = new RuleEngine.Evidence.Fact("f2", 1, 4d, typeof(double)); RuleEngine.Evidence.Actions.ActionExpression a1 = new RuleEngine.Evidence.Actions.ActionExpression("a1", "f1", "3", 1); RuleEngine.Evidence.Actions.ActionExpression a2 = new RuleEngine.Evidence.Actions.ActionExpression("a2", "f2", "4", 1); RuleEngine.Evidence.Actions.ActionExecute a3 = new RuleEngine.Evidence.Actions.ActionExecute("a3", "R2", 1); System.Collections.Generic.List <RuleEngine.Evidence.EvidenceSpecifier> actionList = new System.Collections.Generic.List <RuleEngine.Evidence.EvidenceSpecifier>(); actionList.Add(new RuleEngine.Evidence.EvidenceSpecifier(true, "a1")); actionList.Add(new RuleEngine.Evidence.EvidenceSpecifier(true, "a2")); actionList.Add(new RuleEngine.Evidence.EvidenceSpecifier(true, "a3")); RuleEngine.Evidence.Rule r1 = new RuleEngine.Evidence.Rule("R1", "f1==f1", actionList, 1, true); RuleEngine.Evidence.Rule r2 = new RuleEngine.Evidence.Rule("R2", "f1==f2", actionList, 1, false); rom.AddEvidence(f1); rom.AddEvidence(f2); rom.AddEvidence(a1); rom.AddEvidence(a2); rom.AddEvidence(a3); rom.AddEvidence(r1); rom.AddEvidence(r2); f1.IsEvaluatable = true; f2.IsEvaluatable = true; a1.IsEvaluatable = true; a2.IsEvaluatable = true; a3.IsEvaluatable = true; r1.IsEvaluatable = true; r2.IsEvaluatable = true; rom.Evaluate(); Assert.AreEqual("3", f1.Value.ToString()); Assert.AreEqual("4", f2.Value.ToString()); }
private static void LoadFacts(ROM rom, XmlDocument document) { XmlNodeList facts = document.SelectNodes("RuleEngine/Facts//Fact"); foreach (XmlNode factNode in facts) { string id = factNode.Attributes["id"].Value; string type = factNode.Attributes["type"].Value; string desc = factNode.Attributes["desc"].Value; string modelId = factNode.Attributes["modelId"].Value; Type valueType = null; //ensure same rule wont be entered twice if (rom[id]!=null) throw new Exception("Fact has already been loaded: " + id); //determine priority int priority = 500; if (factNode.Attributes["priority"]!=null) priority = Int32.Parse(factNode.Attributes["priority"].Value); IFact fact = null; if (factNode["xpath"].InnerText != String.Empty) { //determine xpath string xpath = factNode["xpath"].InnerText; //determine value type switch (type) //deterrmine the type of value returned by xpath { case "double": valueType = typeof(double); break; case "boolean": valueType = typeof(bool); break; case "string": valueType = typeof(string); break; default: throw new Exception("Invalid type: " + id + " " + type); } //determine value Xml x = new Xml(xpath, valueType, modelId); //create fact and add it to the rom fact = new Fact(id, priority, xpath, valueType, modelId); } else { /* //determine value type switch (type) //deterrmine the type of value returned by xpath { case "double": valueType = typeof(double); break; case "boolean": valueType = typeof(bool); break; case "string": valueType = typeof(string); break; default: throw new Exception("Invalid type: " + id + " " + type); } //determine value Naked x = new Naked(value, valueType); //create fact and add it to the rom fact = new Fact(id, priority, valueType,); */ } rom.AddEvidence(fact); } }
private static void LoadRules(ROM rom, XmlDocument document) { XmlNodeList rules = document.SelectNodes("RuleEngine/Rules//Rule"); foreach (XmlNode ruleNode in rules) { string id = ruleNode.Attributes["id"].Value; bool inference = false; if (ruleNode.Attributes["chainable"] != null) inference = Boolean.Parse(ruleNode.Attributes["chainable"].Value); int priority = 500; if (ruleNode.Attributes["priority"] != null) priority = Int32.Parse(ruleNode.Attributes["priority"].Value); //ensure this has not already been entered if (rom[id] != null) throw new Exception("Rule Id's must be unique: " + id); //expression string condition = ruleNode["Condition"].InnerText; //actions int actionCounter = 0; List<EvidenceSpecifier> actions = new List<EvidenceSpecifier>(); XmlNodeList actionList; #region Evaluate actionList = ruleNode.SelectNodes("Actions//Evaluate"); foreach (XmlNode a in actionList) { try { string actionOperatingName = a.Attributes["factId"].Value; string aValue = a.InnerText; bool result = true; int actionPriority = 500; if (a.Attributes["priority"] != null) actionPriority = Int32.Parse(a.Attributes["priority"].Value); if (a.Attributes["result"] != null) result = Boolean.Parse(a.Attributes["result"].Value); string actionId = id + "-" + actionOperatingName + "-" + actionCounter++; rom.AddEvidence(new ActionExpression(actionId, actionOperatingName, aValue, actionPriority)); actions.Add(new EvidenceSpecifier(result, actionId)); } catch (Exception e) { throw new Exception("Invalid action: " + a.OuterXml, e); } } #endregion #region Execute actionList = ruleNode.SelectNodes("Actions//Execute"); foreach (XmlNode a in actionList) { try { string actionOperatingName = a.Attributes["factId"].Value; bool result = true; int actionPriority = 500; if (a.Attributes["priority"] != null) actionPriority = Int32.Parse(a.Attributes["priority"].Value); if (a.Attributes["result"] != null) result = Boolean.Parse(a.Attributes["result"].Value); string actionId = id + "-" + actionOperatingName + "-" + actionCounter++; rom.AddEvidence(new ActionExecute(actionId, actionOperatingName, actionPriority)); actions.Add(new EvidenceSpecifier(result, actionId)); } catch (Exception e) { throw new Exception("Invalid action: " + a.OuterXml, e); } } #endregion //now create the rule IRule r = new Rule(id, condition, actions, priority, inference); rom.AddEvidence(r); } }