This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-28
Channels
- # aws (1)
- # beginners (30)
- # boot (7)
- # cider (52)
- # clara (91)
- # cljs-dev (33)
- # cljsjs (1)
- # clojure (447)
- # clojure-brasil (3)
- # clojure-dev (16)
- # clojure-dusseldorf (5)
- # clojure-filipino (1)
- # clojure-italy (29)
- # clojure-sanfrancisco (5)
- # clojure-spec (62)
- # clojure-uk (37)
- # clojurescript (145)
- # clojurewerkz (1)
- # code-reviews (12)
- # community-development (157)
- # cursive (5)
- # datascript (1)
- # datomic (27)
- # editors (42)
- # emacs (5)
- # fulcro (31)
- # hoplon (2)
- # jobs (2)
- # keechma (1)
- # lumo (31)
- # off-topic (2)
- # om (1)
- # onyx (13)
- # parinfer (8)
- # re-frame (13)
- # reagent (32)
- # remote-jobs (4)
- # shadow-cljs (103)
- # spacemacs (15)
- # specter (10)
- # sql (1)
- # tools-deps (35)
- # unrepl (13)
Is there a way to have a short circuiting :or in clara, not sure why it is designed that way
@talgiat they aren’t meant for that. They are mostly just syntax sugar for multiple rules
In the case of you were sharing the stuff around the :or
(prior conditions) and the RHS
you can implement a “short circuit ” pattern via multiple rules by making rules that are prioritized over one another
here is one I made for unrelated reasons mostly https://gist.github.com/mrrodriguez/6a6f8373b25d69826b3efe154c928fac
(r/defrule short-circuit
[X] ;; whatever here
=>
(r/insert! <your fact here>
:rule-marker/short-circuit))
(defrule fallback
[:not [:rule-marker/short-circuit]]
[Y]
=>
(r/insert! <your fact here>))
I don’t know that I see it as hackish. I do understand it could be brittle to more rules added
(defrule premium-video [Video (= ?id id)] [:or [PremiumChannels (= id ?id)] [LessThanTwoHours (= id ?id)] [PremiumTopics (= id ?id)]] => (insert! (create-rule-result ->MarketplacePremiumVideoContent ?id (->Rule 1 “Premium Video” :points 6)))))
however a big short-circuiting :or
would also be just order dependent on all the logic pushed into it
(defrule premium-video
[Video (= ?id id)]
[:not [MarketplacePremiumVideoContent (= id ?id)]]
[:or
[PremiumChannels (= id ?id)]
[LessThanTwoHours (= id ?id)]
[PremiumTopics (= id ?id)]]
=>
(insert! (create-rule-result ->MarketplacePremiumVideoContent ?id (->Rule 1 "Premium Video" :points 6)))))
(r/defrule rule-with-or
[:or
[A]
[B]
[C]]
=>
(r/insert! (->FoundIt)))
(r/defrule aggregate-found
[?found <- (acc/all) :from [FoundIt]]
[:test (seq ?found)]
=>
(r/insert! (do-aggregation ?found)))
(r/defrule aggregate-found
[?found <- (acc/all) :from [FoundIt]]
[:test (seq ?found)]
=>
;; They are all the same, so I dont' care
(r/insert! (first ?found)))
if somehow the RHS (or later rule) leads to a MarketplacePremiumVideoContent
to be inserted with that ?id
then you’d get a loop
but then :not
would be true again, so it’d get reinserted, but then :not
would be false again, so it’d be retracted - and repeat
and their job is to bring working memory into a steady and logically consistent state with all of the LHS of all rules
I think the main takeaway is that the rules don’t short-circuit or control “duplcates” for you
So rule-with-multiple-duplicate-inserts-possible
and aggregate-the-duplicates
rules with an intermediate/ephemeral fact between the two
Later on, there may be more complex reasoning in the aggregate-the-duplicates
than just “take one”
if for example, they are no longer complete duplicates, or perhaps you want to count how many times it was “true” by counting the duplicates
where there were never duplicates inserted, etc. Drools does that by default with logical insert (managed by truth maintenance). However, it does have a performance cost to manage a set for working memory (frequent hash code calculations etc) and also, it isn’t always what people want
also, there is nothing stopping you from making a higher-level macro that did the short-circuit rule generation pattern to normal Clara rules
Agreed on all @mikerod’s comments - I just wanted to mention that you don’t necessarily have to use a macro generating “defrule” calls, Clara can take rules as data structures if you prefer to go that way (easier in clj than cljs though)
It seems the infinite looping behavior has tripped a lot of people up - we should probably add a page to the http://clara-rules.org site on that somewhere. I’ve also logged an issue before to fail in that scenario analogously to StackOverflowException, just haven’t ever gotten around to it
May have seen this. Was the proposal for a max number of iterations per rule?