clara

http://www.clara-rules.org/
Oliver George 2018-03-03T06:13:26.000012Z

Newbie question... I'm struggling to write a rule which boils down to "This or that".

Oliver George 2018-03-03T06:13:32.000015Z

(defrecord This [x])
  (defrecord That [y])
  (defrule this-or-that
    "Print This if fact exists, else print That."
    [:or [?x <- This] [?x <- That]]
    =>
    (println :this-or-that ?x))

  (-> (mk-session 'labs-costs-clara.core)
      (insert
        (->This 1)
        (->That 2))
      (fire-rules))

Oliver George 2018-03-03T06:13:47.000114Z

This will print twice which isn't what I'm after.

Oliver George 2018-03-03T06:14:10.000083Z

(my real example is patching data... if X exists use it else use some other facts to fill in the gap)

zylox 2018-03-03T06:14:25.000005Z

ya, or isnt a xor, it can indeed follow both paths

zylox 2018-03-03T06:14:48.000086Z

i tend to think of it as if you had two disjunct rules

zylox 2018-03-03T06:14:57.000063Z

because that is pretty close to what it does

zylox 2018-03-03T06:15:34.000058Z

if you want one but not the other...well you are going to want to use two rules with :not on This in one and That on the other

Oliver George 2018-03-03T06:15:47.000077Z

That makes sense. My rules got a bit verbose which is what got me wondering.

Oliver George 2018-03-03T06:15:49.000014Z

Thanks

Oliver George 2018-03-03T06:16:15.000065Z

The only alternative I could imagine was some kind of maybe accumulator

Oliver George 2018-03-03T06:16:24.000030Z

(e.g. distinct but expecting one fact)

zylox 2018-03-03T06:17:00.000024Z

are you expecting only one, or potentially many

Oliver George 2018-03-03T06:17:42.000013Z

My code was really "if summary value exists use it, else calculate from many other facts" but that's not critical to the general question.

Oliver George 2018-03-03T06:18:46.000002Z

Thanks for your thoughts @zylox that makes me feel more confident

zylox 2018-03-03T06:20:09.000059Z

gotcha. id suggest something like

(defrule with-summary
  ""
  [Summary (= ?data data)]
  =>
  (println ?data))

(defrule without-summary
  ""
  [:not [Summary]]
  [?others <- (acc/all) :from [SecondaryFacts]]
  
  =>
  (println ?others))
then

zylox 2018-03-03T06:20:15.000060Z

best of luck

Oliver George 2018-03-03T06:20:34.000001Z

Thank you

zylox 2018-03-03T06:21:40.000026Z

without all the horrible syntax errors i just edited out haha