clara

http://www.clara-rules.org/
PB 2020-12-01T19:18:05.141800Z

Is there a way to update a record? I want to specifically use this with rules that deal with total amounts. I.e. A previous rule would consume part of the total

ethanc 2020-12-01T19:25:15.144100Z

Can you give a small example of the use-case? From my knowledge, clara doesn’t play nice with stateful manipulations. That being said, it sounds as if you might be able to use an accumulator, but that depends on the use-case

PB 2020-12-01T20:21:09.145800Z

I go shopping, and I have $100 to spend. I want to buy 10 items, which total $200. Each item has a priority, which items can I buy?

PB 2020-12-01T20:22:04.146700Z

I'm thinking I'm going to have to create a new fact and use an accumulator to sort by priority

2020-12-01T20:23:26.148Z

I’ve only casually used clara but its seems like having $100 will be a fact and if that fact changes it’d cause the session to undo it’s fired rules and re-fire.

PB 2020-12-01T20:23:29.148200Z

My hope was that it if I could update the root fact with the amount of money left and use salience to trigger rules, and when I ran out of money, the rest of the rules wouldn't trigger

PB 2020-12-01T20:23:48.148500Z

@jeff.engebretsen that's my understanding as well

2020-12-01T20:26:40.149600Z

I think like @ethanc said, the accumulator would take in that $100 fact and 10 item priority list fact and spit out 0-10 items

PB 2020-12-01T20:27:04.149800Z

Yep

PB 2020-12-01T20:27:18.150200Z

Thank you both

PB 2020-12-01T21:29:10.151300Z

So it looks like I'll likely need my own reducer here. I only want to include the items I can buy. But I'm not really sure how to pass in a sentinel amount.

(defrule find-what-i-can-get
  [:money (= ?amount (:amount this))]
  [?items <- (acc/reduce-to-accum
              (fn [coll item]
                ;; some way to access `?amount` variable?
                ...))])

PB 2020-12-01T21:30:11.151800Z

I have also tried to pass this into the convert and combine fns

PB 2020-12-01T21:31:43.152500Z

Is there a way to do this. Or do I need to add the total amount I have available to the items i'm iterating over?

PB 2020-12-01T21:46:45.152900Z

It also strikes me that I'd need to sort by priority before the reduce

PB 2020-12-01T21:49:39.153300Z

I am not sure this is possible to do in accumulators

PB 2020-12-01T21:54:20.157400Z

I guess I could use the combine-fn to sort, but I still can't find a way to pass the ?amount into that fn to limit which items are put out

ethanc 2020-12-01T21:55:31.158300Z

Accumulators do not allow access of constraint bound vars. It might require doing some of this logic in RHS of the rule. Something like:

(defrule find-what-i-can-get
  [:money (= ?amount (:amount this))]
  [?items <- (acc/all) :from [:item (< (:cost this) ?amount)]]
  [:test (seq ?items)]
  =>
  (let [sorted-priority (sort-by ... ?items)
        ... <reduce logic>]
  <insert statement>)

PB 2020-12-01T21:56:26.159Z

I don't know why I didn't consider that. Too much tunnel vision I think

PB 2020-12-01T21:56:27.159200Z

Thank you

ethanc 2020-12-01T21:56:58.159800Z

added a test node to eliminate execution where all items are unaffordable

PB 2020-12-01T21:59:12.160600Z

Hmm (< (:cost this) ?amount) would just ensure the cost of 1 item isn't greater than the total amount I have, yes?

ethanc 2020-12-01T21:59:40.161100Z

correct