0

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

enter code here

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 enter image description here

Can anyone please tell me how to achieve this?

merkle
  • 1,585
  • 4
  • 18
  • 33

0 Answers0