Fork me on GitHub
#clara
<
2021-05-27
>
Mario C.14:05:40

RE: looping If a session (rules/facts) can be thought of/represented as a directed graph. Couldn't you just check for a cycle in the graph during "compile" time? I can see how it could be difficult determining what facts are produced by a firing rule but if you can figure that out, shouldn't you have all the information you need to create a graph and check for a cycle?

ethanc15:05:53

As you have said, determining what facts a rule produces is the main blocker here. As the RHS is arbitrary clojure code, we would have to have some way to determine what a given blob of code would do. The tricky bit being that consumers could have arbitrary functions that insert facts and determining that would be practically impossible.

Mario C.15:05:40

Perhaps if you could "fact-hint" a rule. "This rule produces these fact type(s)" Then it could be possible

đź‘Ť 3
ethanc15:05:25

Additionally, its not as straight forward as just scanning the RHS as examples like: https://clojurians.slack.com/archives/C08TC9JCS/p1620850662084600 where its not technically a loop, as the writer has accounted for loop like behavior

Mario C.15:05:14

Hmm a warning like "possible loop detected" would work but I guess this starts getting convoluted when it may be easier/faster to detect loops as its done now

Mario C.15:05:45

On that note: Is it possible to detect why a rule did not fire?

Mario C.15:05:59

It almost feels like it suffers from the same problem above

ethanc15:05:11

> Is it possible to detect why a rule did not fire? > It almost feels like it suffers from the same problem above yes, it does suffer from a similar issue. From the rules engine side of things its pretty easy to say what facts match certain criteria, but the inverse is significantly more tough, as it generally requires an understanding of the constraints of the rules themselves. Typically for use-cases like this, i believe the common practice is to have a “tiered” set of rules to explain what caused a fact not to match. ex:

(r/defrule expected-rule 
  [?a <- A (> x 12)]
  => 
  (r/insert! (->B ?a)))

(r/defrule missing-fact 
  [:not [B]]
  [?a <- A]
  =>
  (r/insert! (->MissingB ?a "A had a value less than or equal to 12")))

đź‘Ť 6
Mario C.16:05:40

Ahh, I didn't even think about doing something like this facepalm