Created
August 8, 2012 22:07
-
-
Save webpigeon/3299260 to your computer and use it in GitHub Desktop.
Foward Chaining expert system
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python2 | |
## | |
# Implementation of MyCIN-like expert system | |
# Copyright (c) 2012, Joseph Walton-Rivers <joseph@webpigeon.me.uk> | |
## | |
from collections import defaultdict | |
CV_TRUE = +1.0 | |
CV_UNKNOWN = 0 | |
CV_FALSE = -1.0 | |
class Solver(object): | |
def __init__(self): | |
self.facts = defaultdict(lambda: defaultdict(float)) | |
self.rules = set() | |
def run(self): | |
while self.rules: | |
currRule = None | |
# look at rules | |
for rule in self.rules: | |
if self.canFire(rule): | |
currRule = rule | |
break | |
# No rule can be executed | |
if not currRule: | |
break | |
# Update the fact for this rule | |
self.rules.remove(currRule) | |
self.addFact(currRule[1][0], currRule[1][1], currRule[1][2]) | |
def canFire(self, rule): | |
for (fact,value) in rule[0]: | |
if fact not in self.facts: | |
return False | |
if value not in self.facts[fact]: | |
return False | |
return True | |
def addFact(self, fact, value, cRule): | |
cCurr = self.facts[fact][value] | |
cNew = cCurr + cRule * (1 - cCurr) | |
self.facts[fact][value] = cNew | |
def prettyPrint(goal, facts): | |
items = facts[goal].items() | |
items = filter(lambda x: x[1] > 0.2, items) | |
items = sorted(items, key=lambda x: -x[1]) | |
if not items: | |
print("Sorry, I couldn't figure it out") | |
return | |
for (p, value) in items: | |
print value, p | |
def main(): | |
solver = Solver() | |
solver.addFact("ears", "pointy", 1) | |
solver.addFact("tail", "waggy", 1) | |
solver.addFact("noise", "meow", 1) | |
solver.addFact("size", "small", 1) | |
solver.rules.add( ((("ears", "pointy"),), ("animal", "cat", 0.7)) ) | |
solver.rules.add( ((("tail", "waggy"),), ("animal", "dog", 0.5)) ) | |
solver.rules.add( ((("noise", "meow"),), ("animal", "cat", 0.9)) ) | |
solver.rules.add( ((("noise", "woof"),), ("animal", "dog", 1)) ) | |
solver.rules.add( ((("size", "small"),), ("animal", "cat", 0.9)) ) | |
solver.rules.add( ((("size", "small"),), ("animal", "dog", 0.3)) ) | |
solver.run() | |
prettyPrint("animal", solver.facts) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment