I built a rules engine for iris flowers using and, or conditions and I would like to generate the flowchart using those rules. I could able to generate the flowchart for all the rules mentioned in the rules engine but I want to hightlight the path of the flowchart based on the input provided.
Below is the code:
from experta import *
import pydot
class Iris(Fact):
"""IRIS"""
sepal_length = Field(float)
sepal_width = Field(float)
petal_length = Field(float)
petal_width = Field(float)
class Species(Fact):
"""Species characteristics"""
pass
class IrisExpert(KnowledgeEngine):
def __init__(self):
super().__init__()
self.status = None
@Rule(Iris(sepal_length=P(lambda x: x > 5), sepal_width=P(lambda x: x < 3)))
def rule1(self):
self.status = 'Iris Setosa'
return self.declare(Species(flower='Iris Setosa'))
@Rule(AND(
Iris(sepal_length=P(lambda x: x > 5.5)),
Iris(sepal_width=P(lambda x: x > 2.5))
))
def rule2(self):
self.status = 'Iris Versicolor'
return self.declare(Species(flower='Iris Versicolor'))
@Rule(AND(
Iris(petal_length=P(lambda x: x > 4.8)),
Iris(petal_width=P(lambda x: x > 1.8))
))
def rule3(self):
self.status = 'Iris Virginica'
return self.declare(Species(flower='Iris Virginica'))
@Rule(OR(
Iris(petal_length=P(lambda x: x > 8)),
Iris(petal_width=P(lambda x: x < 1))
))
def rule4(self):
self.status = 'Iris or condition'
return self.declare(Species(flower='Iris or condition'))
rule_conditions_and = ['sepal_length > 5.5','sepal_width > 2.5', 'petal_length > 4.8', 'petal_width > 1.8']
rule_conditions_or = ['petal_length > 8', 'petal_width < 1']
rule_static = ['sepal_length > 5, sepal_width < 3']
# Create a new knowledge engine instance
engine = IrisExpert()
engine.reset()
# Create a Pydot graph
graph = pydot.Dot(graph_type='digraph', comment='IRIS Expert Rules')
and_counter = 0
or_counter = 10
rule_and_counter = 0
rule_or_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(rule_conditions_and[rule_and_counter])
graph.add_node(cond_node)
edge = pydot.Edge(cond_node, and_node)
graph.add_edge(edge)
rule_and_counter += 1
edge = pydot.Edge(and_node, qual_node)
graph.add_edge(edge)
elif isinstance(rule, OR):
or_node = pydot.Node(name=or_counter, label='OR')
graph.add_node(or_node)
or_counter += 1
for condition in rule:
cond_node_or = pydot.Node(rule_conditions_or[rule_or_counter])
graph.add_node(cond_node_or)
edge_or = pydot.Edge(cond_node_or, or_node)
graph.add_edge(edge_or)
rule_or_counter += 1
edge_or = pydot.Edge(or_node, qual_node)
graph.add_edge(edge_or)
else:
cond_node = pydot.Node(rule_static[0])
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('iris_fix_test.png')
iris = Iris(
sepal_length=0.0,
sepal_width=0.0,
petal_length=9.0,
petal_width=0.8
)
engine.declare(iris)
engine.run()
print('facts: ',engine.facts)
print('status: ', engine.status)
Below the generated graph for the above code
But in the input, I provided the below values which leads to the OR condition
sepal_length=0.0,
sepal_width=0.0,
petal_length=9.0,
petal_width=0.8
While generating the flowchart, I want to highlight the path in the flowchart.
For example, please check the below graph where I had highlighted manually for reference
Can anyone please tell me how to achieve this?