This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # aws (3)
- # beginners (18)
- # boot (3)
- # cider (47)
- # clara (54)
- # cljs-dev (62)
- # clojure (104)
- # clojure-berlin (1)
- # clojure-denver (1)
- # clojure-italy (1)
- # clojure-nl (22)
- # clojure-russia (30)
- # clojure-spec (28)
- # clojure-uk (95)
- # clojurescript (31)
- # cloverage (1)
- # cursive (1)
- # datomic (17)
- # duct (4)
- # emacs (27)
- # fulcro (36)
- # graphql (1)
- # hoplon (1)
- # jobs-discuss (1)
- # lein-figwheel (1)
- # lumo (2)
- # off-topic (44)
- # om-next (5)
- # onyx (29)
- # precept (1)
- # re-frame (8)
- # reagent (7)
- # ring (1)
- # ring-swagger (2)
- # schema (4)
- # shadow-cljs (185)
- # spacemacs (21)
- # specter (59)
- # tools-deps (7)
- # vim (15)
- # yada (1)
http://www.clara-rules.org/docs/fact_type_customization/ Is it possible to set a fact type in such a way that this isn't needed?
@dominicm Could you give a minimal failing example? That doesn’t sound like something that should happen but we might be thinking about different things.
That might not be my problem actually. But when my type-fn is
:a I get an error about alpha nodes if I try and refer to
@dominicm I don’t see any context in your question. Did you post an example? You said where “this isn’t needed”, what were you referring to?
FYI I posted an example snippet overriding the fact type for something like tuples above. Well I put them in maps for key access by name.
You can’t refer to bare symbols that “represent” lookup keys in a rule condition if you are asking that though with regard to “referring to
e. Clara currently only offers special syntactic access directly to record or “Java bean” field/accessors. If you are using generic types it doesn’t attempt to resolve like the symbol
This may be what you’re asking
It’d actually be interesting to explore making Clara offer that sort of syntax though on more generic data.
Sorry. I got distracted when I got in and forgot to post it. On phone again, once I'm at the keyboard I will do it.
Hi, can someone point me to some literature on how to write my own rules engine? I have trouble finding usefull stuff.
clara is heavily based on this paper if you really want to write your own "engine" http://reports-archive.adm.cs.cmu.edu/anon/1995/CMU-CS-95-113.pdf
Caveat: that paper is really old. There are many modern day rete extensions that Clara uses too. The paper is really good at explaining the foundations of rete though.
Then there is also this great blog about Clara/rete here http://www.metasimple.org/2017/02/28/clarifying-rules-engines.html (I wrote it 😛 )
@mikerod the first line in the defrule doesn't work.
(ns roll-alt (:require [clara.rules :refer :all] [clara.tools.fact-graph :as fg] [clara.rules.accumulators :as accum] [rhizome.viz :as rhizome])) (defrecord D [e a v]) (defrule todos-done-invisible ;; [:todo/title (= ?e e)] [:todo/done (= (:v this) false) (= ?e (:e this))] => (insert! (->D ?e :todo/visible true))) (comment (-> (mk-session :fact-type-fn :a :ancestors-fn (constantly [:all])) (insert (->D "foo" :todo/title "FOO!") (->D "foo" :todo/title "FOOBAR!") (->D "foo" :todo/done true) (->D "blah" :todo/done false)) (fire-rules) (query visible-datoms)))
@dominicm that seems related to the explanation I at least attempted to give above about when you can refer to “field name” symbols directly in a rule
Clara compiler cannot statically/compile time know what those symbols mean since the rule condition has a custom type that can’t be introspected
It’d be interesting if Clara added support for you to explicitly state “fields” that go with custom fact types. But nothing like that right now. You’d have to do
(:e this) instead of
e or use destructuring as you have in the past
When rules have records or other types of classes directly in the rule condition Clara compiler will reflect on the class to determine its available field names. When it can do that, you can refer to field names directly as their name symbol.
> Clara compiler cannot statically/compile time know what those symbols mean since the rule condition has a custom type that can’t be introspected That explains it to me, that's entirely what I was missing. It obviously worked when I wrote the form this way:
Which has a trade-off.
(defrule todos-done-invisible [?d <- D (= a :todo/title)] => (insert! (->D (:e ?d) :todo/visible true)))
I was a bit confused because it was still a record, ergo it should work (in my head).
I looked for something to provide a custom keys function, and when I didn't find it, I presumed I was missing something.
@dominicm It’d be interesting to have a fn that takes your custom “type” and returns a set of “field keys”
and that’d be caleld when the compiler was compiling rules and then it’d allow for the shorter accessors
Yeah, Clara just has built-in special casing to class types since they have reflection utilities available to find out how to resolve those symbols
I’ll add that you probably don’t want to write all your rules against a single type like
D, so that isn’t a pattern I’d advocate
It’d lead to a lot of thrash in the rules since every insert/retract would potentially affect every rule
The fact type serves as, what I’d call, the first level of discrimination/partitioning in the network.
My data set isn't particularly large I think. I'm struggling to come up with good fact types for my domain. But that's likely a thing on my side.
The problem I have is that I'm operating in a large domain, and I'm asserting facts on a per-key level, instead of whole entities.
I suppose I could generate something like S3BucketFact which takes an id, key and value. But it's not so different from my datom record.
Haven’t read through all this, but FYI the ancestors-fn sounds like it could help you as well. So you could have rules matching all S3BucketFact as well as more rules matching only “subtypes” of S3BucketFact
I've introduced a meta "Resource" which goes into the "e" slot too, to make it easier to query for resources without getting the duplicates from props.
maybe the “fact type” should be the “attribute” slot of these sorts of facts? I’m not sure
the fact type is just a useful way to group facts across the network that are coming from an external and also to categorize derived data
I don’t see the fact types as being a closed off concept. They are just what the rules refer to to match things, join things, and check other constraints. All of this is probably too vague though. I don’t have a good enough understand of what your data might be looking like and the sorts of things you want to do with it.
I've been thinking the same, and also how certain problems of querying are solved, particularly around duplicate entities, potentially. There must be a few additional aspects to the querying in precept over what Clara provides alone.
It was interesting to see several rules disappear when I got rid of the D record in favour of XFact records. I'm interested to see what happens with X-Y records.
Without having at least the concept of "S3Bucket" and "S3BucketFact" it's quite difficult to do "All S3 buckets must have
:foo 2", because the
?e is duplicated across so many facts. I could perhaps use an accumulator, but it seems more natural to have strict types.
I've written a macro which is run like
(defType Box) will generate:
(derive Box ::Type)
(derive BoxFact ::Fact)
- Function for converting to Box from other types
- Function for "scoping" a series of
[a v] into Facts.
I'm moving rather fast. I haven't gone really deep yet, but I'm going to see how far I can get without declaring every possible attribute on a Box as a type.
It's certainly cool to see the addition of a route to an app cause the subnet to change, and the route53 records & load balancers to be created.
Sorry, I'm tripping over things I don't understand again,
I'm getting back a result where
(defquery created-by [:?for] [?fact <- ::Fact (= ?by (:e this)) (= (:a this) :roll/created-for) (= (:v this) ?for)])
:?foris different to what I input as a parameter:
(query s created-by :?for (->Box "app" nil)). I don't really understand why, any advice?