Skip to content
Switch branches/tags
Go to file
Cannot retrieve contributors at this time

This is a history of changes to clara-rules.


  • Add support to specify query binding arguments as symbols instead of only keywords so that defquery syntax looks closer to function definition syntax.


  • Add names to anonymous functions generated by rule compilation; these names will be in the class names of the generated objects. Issue 261 and issue 291
  • Add types information to alpha nodes. Issue 237
  • Fix a bug related to Java object facts with IndexedPropertyDescriptor fields. Issue 446
  • Validate that parameters provided to queries exist on the query at compilation and throw an exception if queries on a session don't specify the required parameters. Issue 454
  • Add an optional listener that reports suspected infinite loops of rules. Issue 275


  • Add a flag to omit compilation context (used by the durability layer) after Session compilation to save space when not needed. Defaults to true. issue 422
  • Correct duplicate bindings within the same condition. See issue 417
  • Correct sharing of nodes with different parents. See issue 433


  • Added a new field to the clara.rules.engine/Accumulator record. This could be a breaking change for any user durability implementations with low-level performance optimizations. See PR 410 for details.
  • Performance improvements for :exists conditions. See issue 298.
  • Decrease memory usage post deserialization (Durability). See Issue 419
  • Added a new function that returns the number of times a rule was interacted with as a proxy for rules that may be the cause of performance problems. This function requires information from the tracing listener to work. See issue 344 for details.


  • Remove a warning about qualified-keyword? being replaced when using Clojure 1.9.
  • Batch evaluation of node expressions for better compilation performance. See issue 381.
  • Remove unneeded use of get-in to improve performance. See issue 402.
  • Fix issue in test conditions where there is a previous binding. See issue 357.
  • Fix incorrect unification logic caused by differing equality semantics between Java and Clojure. See issue 393.


  • Remove unnecessary memory operations from ProductionNode to optimize performance. Remove :rule-matches in session inspection that did not cause logical insertions and add a new optional feature to return all rule matches, regardless of what their RHS did or whether they were retracted. Add a new listener and tracing method fire-activation!. These changes are moderately non-passive with respect to listening, tracing, and session inspection but are otherwise passive. See issue 386 for details.
  • Support keyword names for use in custom DSLs. See issue 371 for details.
  • Remove unused let-bindings from generated RHS functions. See issue 383 .
  • Improve performance of building rule sessions where conditions have many descendants. See issue 377.
  • Refactoring to better support custom user-designed DSLs in ClojureScript. See issue 362.
  • Fix a ClassCastException in error handling code for shared LHS conditions. See issue 379.


  • Breaking change affecting clara.rules.listener and namespaces. insert-facts! and retract-facts! listener methods are now called with node and token arguments. See PR 366.
  • Fix issue with incorrect namespace qualification of rule and query code in ClojureScript. See issue 359.
  • Add clear-ns-productions! functionality to support clean reloading of rule and query definitions. See issue 316 for details.
  • Support session inspection and fact-graph in ClojureScript. See issue 307 for details.
  • Refactor defrule and defquery to better support customization. See issue 362 for details.


  • Fix deserialization failure when the rulebase contains a clojure.lang.PersistentList$EmptyList. See issue 352 for details.
  • Fix bug in which bindings from previous conditions could be ignored in negations of compound boolean expressions. See issue 304 for details.
  • Fail at compile time when :test conditions are empty. See PR 349 for details.
  • Fix exception in See PR 346 for details.
  • Always return a vector from the all accumulator. See issue 338 for details.
  • Refactored session inspection in PR 339, which is also expected to improve the performance of session inspection.


  • Eliminate laziness that broke internal contracts around order of execution, causing an exception to be thrown when executing queries with negation conditions in some edge cases. See issue 303 for details.


  • Fix a bug in the distinct accumulator. See issue 325.


  • Do not resolve condition type symbols in the Clojure environment. See issue 300.
  • Add def-rules-test macro. See issue 296.
  • Support tracing in ClojureScript. See issue 308.
  • Upgrade Schema version.


  • Provide information on facts accumulated over, not just the result of the accumulation, in session inspection. This is a breaking change to the structure of the record. The information available in the Explanation record now is a superset of that available in 0.14.0. See issue 276 for further details.
  • Fix a memory leak in which the memory held references to bindings from retracted facts. Fixing this leak also fixed some incorrect return data in session inspection. See issue 280 for details.
  • Added a feature that uses data from session inspection to create a directed graph of facts to logical insertions as a result of those facts. See issue 277 for details.
  • Remove the unused input-condition field from the clara.rules.engine.Accumulator record. See issue 287 for details.
  • Return information on matches for negation conditions in session inspection. See issue 289 for details.
  • Extend the fix for incorrect handling of nested complex negation conditions issue 149 to ClojureScript; see issue 241 for details.


  • Fixed a bug where variables bindings created in constraints could be missed by subsequent constraints in the same condition. See issue 267 for details.
  • Delayed inserting and retracting facts until fire-rules is called. Some queries that would reflect changes to the rules network immediately after insertions and retractions now will not reflect these changes until after fire-rules is called. See issue 268 for further details and discussion of the reasons for this change.
  • Added an experimental performance optimization option to allow insertions and retractions of equal facts to cancel each other out during rules firing. See issue 249 for details.


  • This release includes all changes in the previous 0.13.0-RC releases as well as improvements to error handling in the LHS discussed at issue 255. Most notably relative to the 0.12.0 release, this replaces the previous durability implementation with a much more robust and performant one as discussed at issue 198.


  • The work to improve batching in order to improve performance at issue 236 didn't actually improve performance for reasons discussed and fixed at issue 257.


This release is mostly for performance improvements to durability over 0.13.0-RC5.

  • Lookup of the record factory functions during serialization is now cached. See issue 245 and issue 253.
  • Removes undesired interaction of metadata on rules and queries that are built outside defrule and defquery with Clara's compiler that caused session compilation to fail. No sessions that previously compiled should be impacted by this change. See pull request 243.
  • Elements and tokens that are identical by reference before serialization are now identical by reference after deserialization. See issue 247.
  • Replaces dynamic vars with JVM ThreadLocals in durability to improve performance. See pull request 251.
  • Fixes an edge case where a retraction could be duplicated. See issue 250.


  • The get-alphas-fn is now shared between deserialized sessions with the same rulebase to increase the performance benefit from caching. Note that this a non-passive change to the experimental durability API. See issue 234.
  • Improve performance on the JVM when productions have a type that has multiple descendant types that are found in the session. See issue 236.
  • Improve performance on the JVM by replacing internal use of Clojure's hierarchies with class-based dispatch. See issue 239.



Bug fixes over 0.13.0-RC2

  • Improve performance by processing external retractions as a batch. See issue 225.
  • Handle sorted collections in durability logic. See PR 228.
  • Remove redundant retract calls to the change listener. See PR 227.


Bug fixes and additional tracing over 0.13.0-RC2

  • Additional calls to the listener for better traceability of sessions. See PR 222.
  • Fix invalid state when retracting certain accumulator flows. See PR 223.


This is an initial release to validate revamped durability logic. Details and a path forward will be in the full 0.13.0 release.


  • Eliminate unnecessary retractions in accumulators. See issue 182.
  • Rule activations fire in the order they are given to the compiler. See issue 192.
  • Fix bug where rule constrained may be ignored. See issue 194.
  • Make rule compilation deterministic by eliminating internal iteration over unordered data structures. See issue 199.
  • Improve testing of rule firing permutations. See issue 205.
  • Optimize common retraction pattern by checking fact identity first. See issue 213.
  • Correct several accumulator edge cases. See issues 189, 190, and 102.
  • Working memory optimizations. See issue 184.
  • Clojure doc clarifications.


  • Generated code for the left-hand side should only access fields that are used. See issue 180.
  • Fix incorrect qualification of let variables on right-hand side. See issue 178.
  • Optimize fact retraction. See issue 183.


  • Add a "grouping-by" accumulator. See issue 164.
  • Fix truth maintenance when working with equal inserted facts. See issue 171.
  • Fix incorrect rule activation edge case when dealing with complex nested negations and unconditional inserts. See issue 174.
  • clara.rules/mk-session now loads rules stored in a var if given a qualified symbol for that var. See issue 177.


Clara 0.10 is compatible with previous versions, with a couple caveats. These are:

  • The intermediate representation of the Rete network changed as reflected in schema updates in clara.rules.schema. This only affects users that build tooling that inspect the network structure.
  • The order of rule ordering and the state of queries prior to (fire-rules) being called may have changed. This ordering was not guaranteed previously, but users may have depended on it accidentally.
  • ClojureScript users will need to use ClojureScript 1.7.170 or newer.

Here are the specifics on what changed since 0.9.2:

  • Fix unification bugs when dealing with nested negations. See issue 166.
  • Properly handle tests nested in negation nodes. See issue 165.
  • Improve inspect function to explain the insertion of a given fact. See issue 161.
  • Remove duplicate rules and dependency on order of rules when creating sessions. See issue 157.
  • Significantly improve performance of building the Rete network when dealing with large disjunctions. See issue 153.
  • Allow multiple binding and equality checks in a single expression. See issue 151.
  • Ensure variables bounded in a nested, negated conjunction are visible elsewhere in that conjunction. See 149.


  • Report better error and line number when parsing malformed productions. See issue 144.
  • Fix truth maintenance bug when using disjunctions. See issue 145.
  • Target Java API compilation to Java 1.6. See issue 146.
  • Catch exceptions thrown in rule actions and add context for debugging. See issue 147.


  • Allow binding of arbitrary expressions that use previous variables. See issue 142.
  • Simplify variable dependencies with a topological sort of rule conditions. See issue 133.


  • Move to Clojure 1.7 and adopt modern ClojureScript best practices, such as reader conditionals and cljs.test.
  • ClojureScript users may now use macros from clara.rules; clara.rules.macros should be considered deprecated. See issue 128.
  • Add an :exists operator. See issue 130.
  • Pre-defined accumulators now handle fact retraction. See issue 127.
  • Allow use of accumulator results in other rule conditions. See issue 132.
  • Support arbitrary comparisons in accumulators in ClojureScript, bringing it inline with the Clojure support. See issue 131.
  • Support multiple productions defined in a single var, useful for third-party macros. See issue 134.
  • Update several dependencies.
  • Mark internal namespaces as internal, as they may be moved in a future release.


  • Properly handle deeply nested conjunctions. See issue 126.
  • Report error for unbound condition variables across all condition types. See issue 124.
  • Support munged record field names. See issue 121.
  • Generalize schema used for s-expressions in rules. See issue 120.
  • Support multiple expressions on right-hand side of defrule. See issue 118.
  • Properly call retract-facts-logical! listener. See issue 117.
  • Fix retraction when using custom fact type. See issue 116.
  • Support type ancestors in ClojureScript. See issue 115.
  • Handle aliased symbols in ClojureScript. See issue 113.


  • Upgrade to Prismatic Schema 0.4.3
  • Handle use of Clojure .. macro in rule expressions. See issue 108.
  • Fix edge case yielding an NPE when analysis some expressions. See issue 109.


  • Properly qualify references to Java classes on the RHS of rules, supporting try/catch and static method calls. See issue 104.
  • Fix bug when retracting a subset of facts blocked by a negation rule. See issue 105.


  • Fix a collection of issues surrounding referencing bound variables in nested functions. See issue 90 and items referenced from there.
  • Fix a truth maintenance issue for accumulators that offer an initial value when there is nothing to accumulate over. See issue 91.
  • Fix bug that caused options to be dropped in cljs. See issue 92.
  • Allow explicitly specifying productions in CLJS. See issue 94.
  • Better handle macro-generated rules. See issue 100.
  • The :no-loop property now applies to facts retracted due to truth maintenance. See issue 99.


  • Fix specific filtered accumulator bug. See issue 89.
  • Allow binding variables in set and map literals. See issue 88.
  • Fix truth maintenance consistency when working with equal facts. See issue 84.


  • Ensure all truth maintenance updates are flushed. See issue 83.


  • Fix for truth maintenance when an accumulator produces a nil value. See issue 79.
  • Use bound facts in unification. See issue 80.
  • Improve inspection and explainability support in the namespace.


  • Batch up inserts done by rules and apply them as a group. See issue 58.
  • Optimize some internal functions based on real-world profiling.


  • Fix stack overflow under workloads with many individually inserted facts. See issue 76.


  • Support for salience. See issue 25.
  • Rule compilation is significantly faster. See issue 71.
  • Handle use cases where there are a large number of retracted facts. See issue 74.
  • Add insert-all! and insert-all-unconditional!. See issue 75.


  • Allow bound variables to be used by arbitrary functions in subsequent conditions. See issue 66
  • Add metadata to rule's right-hand side so we see line numbers in compilation errors and call stacks. See issue 69
  • Improved memory consumption in cases where rules may be retracted and re-added frequently.


  • Properly handle retractions in the presence of negation nodes; see issue 67.
  • Report error if the fact type in a rule appears to be malformed; see issue 65.


  • Reduce depth of nested function for issue 64.
  • Clean up reflection warnings.



Contains several bug fixes and some usage enhancements, including:


This is a major refactoring of the Clara engine, turning all rule and Rete network representations into well-defined data structures. Details are at these links:




A fix release with some internal optimizations, including the following:



A number of bug fixes, see the milestone summary


The initial release.