Showing posts with label Expert System Shell. Show all posts
Showing posts with label Expert System Shell. Show all posts

Thursday, May 25, 2017

Open Source: C# implementation of a simple expert system shell

cs-expert-system-shell

C# implementation of an expert system shell, targeting .Net Core 1.1
Build Status

Install

Run the following command to install:
Install-Package cs-expert-system-shell

Usage

The sample code below shows how to create a rule engine and initialize it with a set of rules:
using chen0040.ExpertSystem;
public RuleInferenceEngine getInferenceEngine()
{
 RuleInferenceEngine rie = new RuleInferenceEngine();

 Rule rule = new Rule("Bicycle");
 rule.AddAntecedent(new IsClause("vehicleType", "cycle"));
 rule.AddAntecedent(new IsClause("num_wheels", "2"));
 rule.AddAntecedent(new IsClause("motor", "no"));
 rule.setConsequent(new IsClause("vehicle", "Bicycle"));
 rie.AddRule(rule);

 rule = new Rule("Tricycle");
 rule.AddAntecedent(new IsClause("vehicleType", "cycle"));
 rule.AddAntecedent(new IsClause("num_wheels", "3"));
 rule.AddAntecedent(new IsClause("motor", "no"));
 rule.setConsequent(new IsClause("vehicle", "Tricycle"));
 rie.AddRule(rule);

 rule = new Rule("Motorcycle");
 rule.AddAntecedent(new IsClause("vehicleType", "cycle"));
 rule.AddAntecedent(new IsClause("num_wheels", "2"));
 rule.AddAntecedent(new IsClause("motor", "yes"));
 rule.setConsequent(new IsClause("vehicle", "Motorcycle"));
 rie.AddRule(rule);

 rule = new Rule("SportsCar");
 rule.AddAntecedent(new IsClause("vehicleType", "automobile"));
 rule.AddAntecedent(new IsClause("size", "medium"));
 rule.AddAntecedent(new IsClause("num_doors", "2"));
 rule.setConsequent(new IsClause("vehicle", "Sports_Car"));
 rie.AddRule(rule);

 rule = new Rule("Sedan");
 rule.AddAntecedent(new IsClause("vehicleType", "automobile"));
 rule.AddAntecedent(new IsClause("size", "medium"));
 rule.AddAntecedent(new IsClause("num_doors", "4"));
 rule.setConsequent(new IsClause("vehicle", "Sedan"));
 rie.AddRule(rule);

 rule = new Rule("MiniVan");
 rule.AddAntecedent(new IsClause("vehicleType", "automobile"));
 rule.AddAntecedent(new IsClause("size", "medium"));
 rule.AddAntecedent(new IsClause("num_doors", "3"));
 rule.setConsequent(new IsClause("vehicle", "MiniVan"));
 rie.AddRule(rule);

 rule = new Rule("SUV");
 rule.AddAntecedent(new IsClause("vehicleType", "automobile"));
 rule.AddAntecedent(new IsClause("size", "large"));
 rule.AddAntecedent(new IsClause("num_doors", "4"));
 rule.setConsequent(new IsClause("vehicle", "SUV"));
 rie.AddRule(rule);

 rule = new Rule("Cycle");
 rule.AddAntecedent(new LessClause("num_wheels", "4"));
 rule.setConsequent(new IsClause("vehicleType", "cycle"));
 rie.AddRule(rule);

 rule = new Rule("Automobile");
 rule.AddAntecedent(new IsClause("num_wheels", "4"));
 rule.AddAntecedent(new IsClause("motor", "yes"));
 rule.setConsequent(new IsClause("vehicleType", "automobile"));
 rie.AddRule(rule);

 return rie;
}
The sample code below shows how to use forward chaining in the rule engine to derive more facts from the known facts using rules:
RuleInferenceEngine rie = getInferenceEngine();
rie.AddFact(new IsClause("num_wheels", "4"));
rie.AddFact(new IsClause("motor", "yes"));
rie.AddFact(new IsClause("num_doors", "3"));
rie.AddFact(new IsClause("size", "medium"));

console.WriteLine("before inference");
console.WriteLine("{0}", rie.Facts);
console.WriteLine("");

rie.Infer(); //forward chain

console.WriteLine("after inference");
console.WriteLine("{0}", rie.Facts);
console.WriteLine("");
The sample code below shows how to use the backward chaining to reach conclusion for a target variable given a set of known facts:
RuleInferenceEngine rie = getInferenceEngine();
rie.AddFact(new IsClause("num_wheels", "4"));
rie.AddFact(new IsClause("motor", "yes"));
rie.AddFact(new IsClause("num_doors", "3"));
rie.AddFact(new IsClause("size", "medium"));

console.WriteLine("Infer: vehicle");

List<Clause> unproved_conditions = new List<Clause>();

Clause conclusion = rie.Infer("vehicle", unproved_conditions);

console.WriteLine("Conclusion: " + conclusion);

Assert.Equal(conclusion.Value, "MiniVan");
The sample code below shows how to use the rule engine to ask more questions when it fails to reach conclusion for the target variable given a limited set of known facts:
RuleInferenceEngine rie = getInferenceEngine();

console.WriteLine("Infer with All Facts Cleared:");
rie.ClearFacts();

List<Clause> unproved_conditions = new List<Clause>();

Clause conclusion = null;
while (conclusion == null)
{
 conclusion = rie.Infer("vehicle", unproved_conditions);
 if (conclusion == null)
 {
  if (unproved_conditions.Count == 0)
  {
   break;
  }
  Clause c = unproved_conditions[0];
  console.WriteLine("ask: " + c + "?");
  unproved_conditions.Clear();
  console.WriteLine("What is " + c.Variable + "?");
  String value = Console.ReadLine();
  rie.AddFact(new IsClause(c.Variable, value));
 }
}

console.WriteLine("Conclusion: " + conclusion);
console.WriteLine("Memory: ");
console.WriteLine("{0}", rie.Facts);

Thursday, July 25, 2013

Expert System Shell in Agent-Based Modeling: Demo using Zombie Sim game

Have completed my expert system shell in Java and C#, so rewrote this simple Zombie Sim game (which is originally by http://wr3cktangle.wordpress.com/2008/05/29/zombie-sim-open-source/)  using agent-based modeling, in which instead of hand-coded C# rules, expert system is used for the agent (both human and zombie) decision making.


The demo video can be found at:
http://youtu.be/PWcW6ZuLLJE

The expert system shell support major features such as forward, backward chaining, etc. Below is the code snippet for the human agent expert shell code:

RuleInferenceEngine rie = new RuleInferenceEngine();

Rule rule = new Rule("Rule 1");
rule.AddAntecedent(new IsClause("IsTargetVisible", "yes"));
rule.AddAntecedent(new IsClause("IsTargetAvailable", "yes"));
rule.AddAntecedent(new IsClause("IsCourageous", "yes"));
rule.AddAntecedent(new IsClause("IsUnderAttack", "no"));
rule.setConsequent(new IsClause("Action", "PursuitTarget"));
rie.AddRule(rule);

rule = new Rule("Rule 2");
rule.AddAntecedent(new IsClause("IsUnderAttack", "yes"));
rule.AddAntecedent(new IsClause("IsTargetAvailable", "yes"));
rule.setConsequent(new IsClause("Action", "Attack"));
rie.AddRule(rule);

rule = new Rule("Rule 3");
rule.AddAntecedent(new IsClause("IsTargetAvailable", "yes"));
rule.AddAntecedent(new IsClause("IsCourageous", "no"));
rule.AddAntecedent(new IsClause("IsUnderAttack", "no"));
rule.setConsequent(new IsClause("Action", "RunawayFromTarget"));
rie.AddRule(rule);

rule = new Rule("Rule 4");
rule.AddAntecedent(new IsClause("IsTargetAvailable", "no"));
rule.AddAntecedent(new IsClause("IsFighting", "yes"));
rule.setConsequent(new IsClause("IsFighting", "no"));
rie.AddRule(rule);
Below is the partial code the invoke the expert system for decision making in the human agent
mExpertSystem.ClearFacts();

mExpertSystem.AddFact(new IsClause("IsUnderAttack", is_under_attack ? "yes" : "no"));
mExpertSystem.AddFact(new IsClause("IsTargetVisible", mTarget != null && closest < SpotDistance ? "yes" : "no"));
mExpertSystem.AddFact(new IsClause("IsTargetAvailable", mTarget != null ? "yes" : "no"));
mExpertSystem.AddFact(new IsClause("IsCourageous", mWorld.Random.Next(9) + 1 > mCourage ? "yes" : "no"));

List<clause> unproved_conditions = new List<clause>();

Clause conclusion = mExpertSystem.Infer("Action", unproved_conditions);

if (conclusion == null)
{
 System.Console.WriteLine(mExpertSystem.Facts.ToString());
 Console.WriteLine("/////////////////////////////////////");
 return;
}

if (conclusion.getValue() == "Attack")
{
 mFighting = true;
 mMode = MentalState.Aggressive;
 mTarget.IsAttacked((int)Math.Floor(mWorld.Random.NextDouble() * mStrength));
}
Below are some images showing the ZombieSim Game rewritten using Expert System Shell and Agent-Based Modeling: