kpanic / retex

A boilerplate/proof-of-concept for a Rete Algorithm implementation in Elixir

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Retex

Elixir CI

The Rete Algorithm

"The Rete Match Algorithm is an efficient method for comparing a large collection of patterns to a large collection of objects. It finds all the objects that match each pattern. The algorithm was developed for use in production system interpreters, and it has been used for systems containing from a few hundred to more than a thousand patterns and objects" - C. Forgy

Boilerplate/PoC of a version of the Rete Algorithm implementated in Elixir

Rete is a complex stateful algorithm, this is an attempt of reproducing it with some slight modifications, using a functional immutable language such as Elixir/Erlang. Read more about Rete

Requirements

  • Erlang/OTP 22
  • Elixir 1.12.1 (compiled with Erlang/OTP 22)

Concepts

  • Retex compiles the rules using a directed acyclic graph data structure
  • The activation of nodes is done using a State Monad and Forward Chaining.
  • A list of bindings is stored at each active node in order to generate complete matches from partial ones

When compiled, the network will look something like the following:

pic2

Installation

def deps do
  [
    {:retex, git: "https://github.com/lorenzosinisi/retex"}
  ]
end

Installation using the wrapper NeuralBridge

If you want you can have a predefined generic DSL and the wrapper NeuralBridge so that you don't have to build the rest of the Expert System from zero

def deps do
  [
    {:neural_bridge, git: "https://github.com/lorenzosinisi/neural_bridge"}
  ]
end

Examples and usage with NeuralBridge (a wrapper around Retex)

Generic inferred knowledge

    alias NeuralBridge.{Engine, Rule}
    engine = Engine.new("test")

    rules = [
      Rule.new(
        id: 1,
        given: """
        Person's name is equal "bob"
        """,
        then: """
        Person's age is 23
        """
      ),
      Rule.new(
        id: 2,
        given: """
        Person's name is equal $name
        Person's age is equal 23
        """,
        then: fn production ->
          require Logger
          bindings = Map.get(production, :bindings)
          Logger.info(inspect(bindings))
        end
      )
    ]

    engine = Engine.add_rules(engine, rules)
    engine = Engine.add_facts(engine, "Person's name is \"bob\"")
    rule = List.first(engine.rule_engine.agenda)
    engine = Engine.apply_rule(engine, rule)

    Enum.each(engine.rule_engine.agenda, fn pnode ->
        Engine.apply_rule(engine, pnode)
        end)
    end # will log %{"$name" => "bob"}

Medical diagnosis

    alias NeuralBridge.{Engine, Rule}
    engine = Engine.new("doctor_AI")

    engine =
      Engine.add_rules(engine, [
        Rule.new(
          id: 1,
          given: """
          Patient's fever is greater 38.5
          Patient's name is equal $name
          Patient's generic_weakness is equal "Yes"
          """,
          then: """
          Patient's diagnosis is "flu"
          """
        ),
        Rule.new(
          id: 2,
          given: """
          Patient's fever is lesser 38.5
          Patient's name is equal $name
          Patient's generic_weakness is equal "No"
          """,
          then: """
          Patient's diagnosis is "all good"
          """
        )
      ])

    engine =
      Engine.add_facts(engine, """
      Patient's fever is 39
      Patient's name is "Aylon"
      Patient's generic_weakness is "Yes"
      """)

    ## contains Patient's diagnnosis
    [
      %_{
        action: [
          %Retex.Wme{
            identifier: "Patient",
            attribute: "diagnosis",
            value: "flu"
          }
        ],
        bindings: %{"$name" => "Aylon"}
      }
    ] = engine.rule_engine.agenda

Test

  • Run mix test

Benchmark adding 20k rules and triggering one

  • Run elixir benchmark/rule_chain.exs

Warnings

  • Use at your own risk
  • This is just a template for complexer implementations of the described algorithms

## For more on Rete algorithm

About

A boilerplate/proof-of-concept for a Rete Algorithm implementation in Elixir

License:Apache License 2.0


Languages

Language:Elixir 100.0%