This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-05-12
Channels
- # aleph (6)
- # announcements (11)
- # babashka (24)
- # beginners (127)
- # calva (33)
- # chlorine-clover (5)
- # cider (7)
- # clara (9)
- # cljs-dev (54)
- # cljsrn (5)
- # clojure (61)
- # clojure-australia (8)
- # clojure-bay-area (11)
- # clojure-europe (36)
- # clojure-italy (3)
- # clojure-nl (3)
- # clojure-spec (6)
- # clojure-taiwan (1)
- # clojure-uk (8)
- # clojurescript (94)
- # code-reviews (2)
- # community-development (6)
- # conjure (26)
- # core-typed (1)
- # cursive (3)
- # datahike (4)
- # datomic (14)
- # events (1)
- # graphql (1)
- # honeysql (49)
- # introduce-yourself (5)
- # jobs-discuss (15)
- # kaocha (6)
- # lsp (8)
- # malli (1)
- # meander (5)
- # nrepl (1)
- # off-topic (21)
- # other-languages (1)
- # pathom (13)
- # podcasts-discuss (1)
- # polylith (1)
- # reitit (16)
- # shadow-cljs (50)
- # spacemacs (11)
- # sql (11)
- # tools-deps (21)
- # unrepl (1)
- # vim (9)
Hi, I ran into some unexpected behavior today. I managed to replicate it in a small example (not sure if it's minimal):
(defrecord A [n])
(defrecord B [m])
(defrecord C [m n])
(defrule loop-rule
[B (= ?m m)]
[C (= ?m m) (= ?n n)]
[:not [A (= ?n n)]]
=>
(println (str "A: " ?n))
(insert! (->A ?n)))
(-> (mk-session :cache false)
(insert (->B 1))
(insert (->C 1 2))
(insert (->C 1 3))
(fire-rules))
This results in an infinite loop. So I guess the rule is triggering on each insertion of a new A, always finding the other C to make things fire? I expected the A to be inserted just twice. Note that in my real life use case, the A type is also coming from another source, so that's why I'm checking it. Am I simply not understanding the :not?I think http://www.clara-rules.org/docs/truthmaint/ might be a good start.
Ah, yes, now I get it
thanks for the fast reply!
and thanks for clara: I'm building a pretty product and it's been a joy to work with 🙂
❤️ 5
*pretty complex product
The minimal example of the looping behavior would probably be something like:
(defrecord A [n])
(clara/defrule not-a
[:not [A]]
=>
(clara/insert! (->A 12)))
Typically to prevent this loop i would use something like a “reason” field on the fact if possible to denote default from other facts.
Something like:
(defrecord A [n reason])
(r/defrule not-a
[:not [A (not= ::default reason)]]
=>
(r/insert! (->A 12 ::default)))
đź‘Ť 2