I would like to generate a flow using the rules that I defined in the rules engine. Below is the code
from pyknow import *
import pydot
class Wine(Fact):
"""Wine characteristics"""
pass
class Quality(Fact):
"""Wine quality"""
pass
class WineExpert(KnowledgeEngine):
@Rule(Wine(color='red'))
def rule1(self):
self.declare(Quality(color='red', quality='rich'))
@Rule(Wine(color='white'))
def rule2(self):
self.declare(Quality(color='white', quality='crisp'))
@Rule(AND(
Wine(color='red'),
Wine(body='light'),
Wine(tannin='low')
))
def rule3(self):
self.declare(Quality(color='red', quality='smooth'))
@Rule(AND(
Wine(color='red'),
Wine(body='full'),
Wine(tannin='high')
))
def rule4(self):
self.declare(Quality(color='red', quality='bold'))
# Create a new knowledge engine instance
engine = WineExpert()
# Create a Pydot graph
graph = pydot.Dot(graph_type='digraph', comment='Wine Expert Rules')
# Add nodes for each rule
for rule in engine.get_rules():
node = pydot.Node(rule.__name__)
graph.add_node(node)
# Check for AND conditions
if isinstance(rule.new_conditions, AND):
for condition in rule.new_conditions.args:
label = str(condition).replace("<", "\\<").replace(">", "\\>")
edge = pydot.Edge(label, rule.__name__)
graph.add_edge(edge)
else:
label = str(rule.new_conditions).replace("<", "\\<").replace(">", "\\>")
edge = pydot.Edge(label, rule.__name__)
graph.add_edge(edge)
# Save the graph to a file
graph.write_png('wine_expert_rules.png')
I am getting a graph which I can't interpret it. Can anyone tell me how to get a good flowchart out of it?
There seems to be a some confusion with decorators and classes. Also you never execute the rule. Do you expect quality to appear on your flow chart? If so, you should run the rules in your loop.
Note: I'm also returning Quality to avoid accessing the engine's agenda and drawing AND
nodes (also using experta which is a fork and available at pypi):
from experta import *
import pydot
class Wine(Fact):
"""Wine characteristics"""
pass
class Quality(Fact):
"""Wine quality"""
pass
class WineExpert(KnowledgeEngine):
@Rule(Wine(color='red'))
def rule1(self):
return self.declare(Quality(color='red', quality='rich'))
@Rule(Wine(color='white'))
def rule2(self):
return self.declare(Quality(color='white', quality='crisp'))
@Rule(AND(
Wine(color='red'),
Wine(body='light'),
Wine(tannin='low')
))
def rule3(self):
return self.declare(Quality(color='red', quality='smooth'))
@Rule(AND(
Wine(color='red'),
Wine(body='full'),
Wine(tannin='high')
))
def rule4(self):
return self.declare(Quality(color='red', quality='bold'))
# Create a new knowledge engine instance
engine = WineExpert()
engine.reset()
# Create a Pydot graph
graph = pydot.Dot(graph_type='digraph', comment='Wine Expert Rules')
and_counter = 0
# Add nodes for each rule
for rule_instance in engine.get_rules():
quality = rule_instance()
qual_node = pydot.Node(repr(quality))
graph.add_node(qual_node)
for rule in rule_instance:
# Check for AND conditions
if isinstance(rule, AND):
and_node = pydot.Node(name=and_counter, label='AND')
graph.add_node(and_node)
and_counter += 1
for condition in rule:
cond_node = pydot.Node(repr(condition))
graph.add_node(cond_node)
edge = pydot.Edge(cond_node, and_node)
graph.add_edge(edge)
edge = pydot.Edge(and_node, qual_node)
graph.add_edge(edge)
else:
cond_node = pydot.Node(repr(rule))
graph.add_node(cond_node)
edge = pydot.Edge(cond_node, qual_node)
graph.add_edge(edge)
# Save the graph to a file
graph.write_png('wine_expert_rules.png')
Output: