oracle-samples/clara-rules

Session inspection should return empty collections when no matches are present

Closed this issue · 1 comments

The following test fails that I'd expect to pass:

(deftest test-matches-retracted-fact
  (let [temp-query (dsl/parse-query [] [[Temperature (= ?t temperature)]])
        session (-> (mk-session [temp-query] :cache false)
                    (insert (->Temperature 10 "MCI"))
                    fire-rules
                    (retract (->Temperature 10 "MCI"))
                    fire-rules)
        condition-matching-facts (-> session
                                     inspect
                                     :condition-matches
                                     vals)

        query-matches (-> session
                          inspect
                          :query-matches
                          vals)]
    
    (is (every? empty? query-matches))
    (is (every? empty? condition-matching-facts))))

Exploring this some in a REPL, with "session" defined to be the session created in the test above:

clara.tools.test-inspect> (-> session inspect :condition-matches)
{{:type clara.rules.testfacts.Temperature, :constraints [(= ?t temperature)]} (nil)}

clara.tools.test-inspect> (-> session inspect :query-matches)
{{:lhs [{:type clara.rules.testfacts.Temperature, :constraints [(= ?t temperature)]}], :params #{}} ({:matches (), :bindings {}})}

clara.tools.test-inspect> (-> session .memory :alpha-memory)
{1 {{} nil}}

clara.tools.test-inspect> (-> session .memory :beta-memory)
{2 {{} nil}}

clara.tools.test-inspect> (-> session .memory (clara.rules.memory/get-elements-all {:id 1}))
(nil)

clara.tools.test-inspect> (-> session .memory (clara.rules.memory/get-tokens-all {:id 2}))
(nil)

When there are no condition matches for a condition or no query matches for a query I'd expect clara.tools.inspect/inspect to return an empty collection for the condition or query.

It appears that we are calling flatten on a structure that is expected to like [[element1 element2] [element3 element4]] to get back [element1 element2 element3 element4] but which actually looks like [nil] and is already flat. Furthermore, we still have binding groups in the memory that could be removed entirely. This isn't particularly important for cases where the bindings are just an empty map as here, but in cases where the condition created bindings we'd be holding a hard reference to values of those bindings even if the fact they correspond was retracted. This is a memory leak, although probably small in most cases.

I have merged #281 which addresses this. I am closing this issue.