cloj-rules-engine is a very simple rules engine written in Clojure and designed to work with Java.
Table of Contents
cloj-rules-engine is a rules engine written in Clojure.
Features:
Each rule has a condition (composed of conditional expressions -written in Clojure- that refer to facts), and a set of actions that are activated if the condition is satisfied. Facts are the data upon which rules operate. The fired actions are a represented as a set of identifiers (strings).
Rules are expressed in a simple and easy to read Clojure format (clojure maps)
{
:RULE_1 {:cond "(and (< #A 10) (> #B 50))"
:actions ["action-1"]}
...
}
:RULE_2 {:cond "(> #A 10)"
:actions [{"action-B" 0.5} {"action-C" 0.5}]
(update-map-facts {"#A" "14"})
PersistentArrayMap facts_map = new PersistentArrayMap(new Object[] {
"#A", "14"
});
clrules.updateMapFacts(facts_map);
This library can be used from Java or Clojure code
Third party libraries used in this project:
Libs | Version | License |
---|---|---|
clojure | 1.8.0 | |
tools.logging | 0.3.1 | |
log4j | 1.2.17 | |
data.json | 0.2.6 | |
proto-repl | 0.3.1 | |
math.numeric-tower | 0.0.4 |
Main methods:
(initialize "rules.clj")
clrules.initialize("rules.clj");
(update-map-facts {"#A" "14"})
clrules.updateMapFacts(facts_map);
(get-rules-actions)
clrules.getRulesActions();
get-fired-rules
initialize-from-json
get-rules-actions-probs (ONLY Rules with 'probabilities') valuates rules based on current facts, and return a list (String) of 'fired' actions
(RULES DEFINITION) The set of rules are defined using Clojure syntax => Clojure maps. Parameters / facts have the following formatt: #FACTNAME
#"\#[A-Za-z][A-Za-z0-9]*"
(RULES EVALUATION) The rules and facts are evaluated following the steps of the next example:
In the example we have 2 facts or parameters: #A and #B
Rules conditions:
:RULE_1 {:cond "(and (< #A 10) (> #B 50))"
:actions ["action-1"]}
(update-map-facts {"#A" 33, "#B" 66}))
(when (and (< 33 10) (> 66 50)) :RULE_1)
(RULES DEFINITION) Conditions are clojure expressions surrounded by quotes.
(RULES DEFINITION) When creating the set of rules, use a hash for each of the parameters / facts (i.e. #A and #B):
:RULE_1 {:cond "(and (< #A 10) (> #B 50))"
:actions ["action-1"]}
str
function, single quotes or double quotes (and escape character) if you want to eval String variables.:RULE_5 {:cond "(= (str #D) (str 50))"
:actions ["action-E"]}
:RULE_6 {:cond "(= #D \"goldenaxe\")"
:actions ["action-F"]}
:RULE_7 {:cond "(= #D 'goldenaxe2')"
:actions ["action-G"]}
(update-map-facts {"#A" 15, "#D" "\"goldenaxe\""}))
Java version 8
Leiningen 2.0.0 or above installed.
First, define a set of rules ("rules.clj"):
{
:RULE_1 {:cond "(and (< #A 10) (> #B 50))"
:actions ["action-1"]
:desc "Rule description: 'launch' action-1 if 'a' is lower than 10 and if 'b' is greater than 50"}
:RULE_2 {:cond "(> #A 10)"
:actions ["action-2"]}
}
And then, ...
(initialize "rules.clj")
(update-map-facts {"#A" "14"})
(get-rules-actions)
(get-fired-rules)
Or...
(if (initialize "rules.clj")
(when (update-map-facts {"#A" "15", "#B" 13, "#D" "\"goldenaxe\""})
(get-rules-actions))
false)
Java code to use the library:
cloj_rules_engine.ClojRules clrules = new cloj_rules_engine.ClojRules();
...
clrules.initialize("rules.clj");
PersistentArrayMap facts_map = new PersistentArrayMap(new Object[] {
"#A", "5",
"#B", "51"
});
clrules.updateMapFacts(facts_map);
clrules.getRulesActions();
clrules.getFiredRules(); // get fired rules in json format
expt
, abs
, gcd
, lcm
, floor
...:RULE_8 {:cond "(> (sqrt #C) 10)"
:actions ["action-H-sqrt"]
:desc "Rule description: 'launch' action-H-sqrt if square root of #C is greater than 10."}
every?
, even?
, odd?
...:RULE_9 {:cond "(every? even? (list #A #B #C))"
:actions ["action-I-even?"]
:desc "Rule description: 'launch' action-I-even? if all elements from list are even."}
#(> % 10)
:RULE_10 {:cond "(every? #(> % 10) [#A #B #C])"
:actions ["action-J-func"]
:desc "Rule description: 'launch' action-J-func if all elements from list / vector are greater than 10"}
:RULE_11 {:cond "(every? #(> % 100) #LIST1)"
:actions ["action-K-func"]
:desc "Rule description: 'launch' action-K-func if all elements from list / vector '#LIST1' are greater than 10"}
(update-map-facts {"#A" "21", "#B" 43, "#C" 1000, "#LIST1" "[121 321 123 122 1233]"})
Copyright © 2017 Roi Sucasas Font
Distributed under the Eclipse Public License, the same as Clojure.
Can you improve this documentation? These fine people already did:
rsucasasf, Roi & roiEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close