This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-01-26
Channels
- # aleph (9)
- # announcements (31)
- # babashka (23)
- # beginners (35)
- # biff (2)
- # calva (5)
- # cider (10)
- # clara (11)
- # clerk (114)
- # clj-kondo (18)
- # cljdoc (37)
- # clojars (7)
- # clojure (24)
- # clojure-austin (10)
- # clojure-europe (27)
- # clojure-nl (1)
- # clojure-norway (23)
- # clojure-uk (2)
- # clojurescript (18)
- # conjure (2)
- # core-async (6)
- # cursive (21)
- # datomic (3)
- # fulcro (15)
- # introduce-yourself (7)
- # lsp (32)
- # malli (57)
- # meander (5)
- # music (1)
- # nbb (2)
- # off-topic (17)
- # pathom (6)
- # rdf (4)
- # reagent (8)
- # releases (2)
- # shadow-cljs (4)
- # slack-help (23)
- # spacemacs (6)
- # tools-build (32)
(Please let me know if this is not clear enough — I can add more detail and some example code if necessary.) If I have a rule LHS that somehow finds a fact by running some Clojure code (outside of Clara fact matching), is it possible to add that found fact as a dependency for any facts that the RHS inserts? At the moment I am getting the LHS to search all facts of the relevant type and match on an ID, but that’s inefficient.
A little more information would probably be required for a proper answer, but my gut says that LHS bindings “should” possibly handle that.
Here’s an example:
(ns clara-example
(:require
[clara.rules :as c]))
(c/defrule create-derived-thing
[:thing-1 [{thing-1-key :key
:as thing-1}]
(= ?thing-1-key thing-1-key)
(= ?thing-2
(find-thing-2 thing-1))]
[:test (some? ?thing-2)]
[:thing-2 [{thing-2-key :key}]
(= thing-2-key (:key ?thing-2))]
=>
(c/insert! {:type :derived-thing
:thing-1-key ?thing-1-key
:thing-2-key (:key ?thing-2)}))
The rule finds a fact of type :thing-1
. It then calls find-thing-2
, which returns a fact of type :thing-2
.
I want to insert a derived fact that depends on both the fact of type :thing-1
and the fact of type :thing-2
. I’m telling Clara about the second dependency by looking at all facts of type :thing-2
and matching on the key.
Thank you, that's not at all what I was envisioning.
Would the end goal be that thing-2
is visible via session inspection(http://www.clara-rules.org/docs/inspection/)?
As a side note, i'd be interested in the performance characteristics of that join. Potentially re-writing it as something that would force a hashJoin node might help. ie.
(ns clara-example
(:require
[clara.rules :as c]))
(c/defrule create-derived-thing
[:thing-1 [{thing-1-key :key
:as thing-1}]
(= ?thing-1-key thing-1-key)
(= ?thing-2-key
(:key (find-thing-2 thing-1)))]
[:test (some? ?thing-2-key)]
[:thing-2 [{thing-2-key :key}]
(= thing-2-key ?thing-2-key)]
=>
(c/insert! {:type :derived-thing
:thing-1-key ?thing-1-key
:thing-2-key ?thing-2-key}))
Then again, even the added performance of a HashJoin node might not be enough if you were dealing with extremely large numbers of thing-1
and thing-2
.Thanks for your reply and suggestion.
The end-goal is that Clara’s truth maintenance removes the derived fact if the supporting thing-2
is retracted.
I’ve tried your suggestion in my real code, but it actually makes things slower. I think I need to check the HashJoin documentation carefully to understand the subtleties.
FWIW, I’m dealing with a few thousand thing-2
s and a few tens of thing-1
s.
And actually, a colleague has found a different approach that means I probably won’t pursue this. 🙂 (Something around having facts that wrap the data that contains the thing-1
s and thing-2
s.)
Thanks again!
Glad you found an alternative The doc on HashJoin: http://www.clara-rules.org/docs/hash_joins/ As a follow-up to the initial question, i do not believe there would be any mechanisms to inform clara that there existed additional facts that support the execution of a rule. So again, glad you found an alternative.