-
Notifications
You must be signed in to change notification settings - Fork 115
Guide
Developer documentation is in progress.
Rules are typically defined with defrule, which has this structure:
A simple rule looks like this:
(defrule free-lunch-with-gizmo
"Anyone who purchases a gizmo gets a free lunch."
[Purchase (= item :gizmo)]
=>
(insert! (->Promotion :free-lunch-with-gizmo :lunch)))
Where Purchase is a Clojure Record or Java JavaBean containing an item field. If there exists a purchase that matches the :gizmo keyword, a new promotion is inserted into working memory, by simply creating a new Promotion record.
The left-hand side of the rule -- everything prior to the "=>" in the above -- uses a constraint expression described in the Constraint Expressions section below.
The right-hand side of the rule -- everything past the "=>" in the above example -- is simply a Clojure S-expression and can invoke arbitrary code, or use insert! to insert new information into the working memory.
Queries are typically defined with defquery, which has the following structure:
A sample query looks like this:
(defquery get-promotions
"Query to find promotions for the purchase."
[]
[?promotion <- Promotion])
The first argument is a vector of keywords to indicate parameters to a query. For instance, if we wanted to run a query that retrieves only a certain type of promotions, we might write this:
(defquery get-promotions
"Query to find promotions for the purchase."
[:?type]
[?promotion <- Promotion (== ?type type)]) ; Bind the ?type query to the promotion type.
A caller may then execute that query with arguments. So if we only wanted to find lunch promotions, we might perform the query like this:
(query session get-promotions :?type :lunch)
The conditions used by a query are the same structure as the left-hand side of a rule. See the Condition Expressions section below for usage.
Condition Expressions are the contents of the left-hand side of rules, or the constraints used in queries.
This part of rules and queries contains a series of expressions, each of which is one of the following:
- A fact expression, which selects a fact based on some given criteria.
- A boolean expression, which is simply a hierarchical and/or/not structure of other expressions.
- An accumulator, which is mechanism to reason about collections of facts
- A test, which is an arbitrary Clojure S-expression that can run predicate-style tests on variables bound earlier in the rule or query.
Details on each of these are below.
A key part of any rule engine is the ability to bind values to variables and unify variables to ensure all items described in a rule are constant.
In Clara, variable bindings can be performed within fact expressions and accumulators described below. They typically take the form of a bind operation ==, or as an assignment-style operator (<-) to bind an entire fact. See the Fact expressions section below for details.
Bound variables can be referenced in tests and the right-hand side of rules.
Fact expressions are the simplest and most common form of Clara conditions. They start with an optional binding for the fact, in the form of [?variableName <- MyFactType]. The fact type is then followed by zero or more S-expressions which can either be predicates run against a fact, or bindings (via the == macro), as described above.
A simple fact expression may look like this:
[?person <- Person (= first-name "Alice") (== ?last-name last-name)]
This example does the following:
- Matches all facts of type Person
- Eliminates any Person facts that don't have a first-name attribute that is equal to "Alice"
- Creates a new binding ?last-name, which contains the value of the last-name field in matched Person facts.
- Creates a new binding ?person, which contains the value of the matched Person object.
TODO: add details.
TODO: add details
TODO: add details
- Introduction to Clara
- Architecture overview
- clara examples
- Full railroad diagram of Clara syntax
- Clojure API Documentation
- Java API Documentation
Railroad diagrams generated with http://railroad.my28msec.com/rr/ui