zprint icon indicating copy to clipboard operation
zprint copied to clipboard

Clara rule condition match formatting

Open arichiardi opened this issue 2 years ago • 3 comments

Dear Kim, I am trying to format clara rules and I have vector instances of both "atom" and collections inside them.

I'd like to ask if it is possible not to wrap when the contents of the vector are following some atom (like :from, see below) not collections. Alternatively if one could not wrap only after the first collection is encountered.

For instance this should not happen:

(r/defrule shared-modality-derive-ao-annulus-area
-  [?annulus <- latest :from
+  [?annulus
+   <-
+   latest
+   :from
    [CoreValue (= "data/ao/annulus" id) (= ::update source) (= ?value value)]]
   [:or [Encounter (= cs/mr modality)] [Encounter (= cs/ct modality)]]
   =>
   (calc-and-insert-elliptical-area ?annulus ?value "data/ao/annulus-area"))

and stay:

(r/defrule shared-modality-derive-ao-annulus-area
  [?annulus <- latest :from
   [CoreValue (= "data/ao/annulus" id) (= ::update source) (= ?value value)]]
   [:or [Encounter (= cs/mr modality)] [Encounter (= cs/ct modality)]]
   =>
   (calc-and-insert-elliptical-area ?annulus ?value "data/ao/annulus-area"))

It should basically follow this example.

In our case what's after :from should not be wrapped. I hope I am making sense, apologies if not.

Thank you as always!

arichiardi avatar Jul 06 '22 21:07 arichiardi

Hello! As always, thanks for asking. I'm hopeful that I can come up with something which works for you! That said, I'm so confused by what you want (and why you aren't getting what you want). The link to "this example" didn't do anything for me -- if everything fits on one line, there isn't any formatting. It helps me a lot if you show me specific things that you do want.

I'm assuming that the second example you give, prefaced with "and stay:" is what you want to get?

Interestingly, that is what I get when I format it:

(czprint i244 {:parse-string? true})
(r/defrule
  shared-modality-derive-ao-annulus-area
  [?annulus <- latest :from
   [CoreValue (= "data/ao/annulus" id) (= ::update source) (= ?value value)]]
  [:or [Encounter (= cs/mr modality)] [Encounter (= cs/ct modality)]]
  =>
  (calc-and-insert-elliptical-area ?annulus ?value "data/ao/annulus-area"))
nil

; So, maybe you want the rule name on the same line as defrule...
; Let's do that:

zprint.core=> (czprint i244 {:parse-string? true :fn-map {"defrule" :arg1}})
(r/defrule shared-modality-derive-ao-annulus-area
  [?annulus <- latest :from
   [CoreValue (= "data/ao/annulus" id) (= ::update source) (= ?value value)]]
  [:or [Encounter (= cs/mr modality)] [Encounter (= cs/ct modality)]]
  =>
  (calc-and-insert-elliptical-area ?annulus ?value "data/ao/annulus-area"))
nil

; That still seems to be working the way I think you want it?  Let's try the styles from
; the discussion topic, in case that does something different?

zprint.core=> (czprint i244 {:parse-string? true :fn-map {"defrule" :arg1} :style [:community :meta-alt :how-to-ns :binding-nl]})
(r/defrule shared-modality-derive-ao-annulus-area
 [?annulus <- latest :from
  [CoreValue (= "data/ao/annulus" id) (= ::update source) (= ?value value)]]
 [:or [Encounter (= cs/mr modality)] [Encounter (= cs/ct modality)]]
 =>
 (calc-and-insert-elliptical-area ?annulus ?value "data/ao/annulus-area"))

They all come out the way that I think you want them. So either:

  1. I'm confused as to what you want to get (likely)
  2. Something in your configuration is causing the oddness you are getting. I have no idea what your configuration is, of course.

If you give me your whole configuration, and three to five rules that are formatted the way you want them to come out of zprint, I'll see what I can do. I have a lot of possibilities, but I need to get my hands around what you really want before I can make any more progress.

Thanks!

kkinnear avatar Jul 06 '22 23:07 kkinnear

Ok let me get more examples to you, I also attach my .zprint.edn.

(r/defrule foo-rule
  [?w <- latest :from [CoreValue (= "data/physical-exam/weight" id)]]
  [?h <- latest :from [CoreValue (= "data/physical-exam/height" id)]]
  [:or [Encounter (= cs/mr modality)] [Encounter (= cs/ct modality)]]
  [:test (some #(= ::update (:source %)) [?w ?h])]
  =>
  (if (some nil-measurement? [?w ?h]) :foo :bar))

Should look better as

(r/defrule foo-rule
  [?w <- latest :from [CoreValue (= "data/physical-exam/weight" id)]]
  [?h <- latest :from [CoreValue (= "data/physical-exam/height" id)]]
  [:or
   [Encounter (= cs/mr modality)]
   [Encounter (= cs/ct modality)]]
  [:test (some #(= ::update (:source %)) [?w ?h])]
  =>
  (if (some nil-measurement? [?w ?h]) :foo :bar))

I tried a bunch of :vector customizations but I am kind of wondering if I need to go ahead and use :option-fn instead cause the vectors there are really kind of custom.

arichiardi avatar Jul 07 '22 16:07 arichiardi

Sorry it has taken me so long to get back to you.

Here is my first attempt to get you something that works for Clara rules. This is using a modified zprint.edn from one of your other issues. Here is the result:

(czprint i244 (merge-deep {:parse-string? true} om224c i224om1))
(r/defrule shared-modality-derive-ao-annulus-area
  [?annulus <- latest :from
   [CoreValue (= "data/ao/annulus" id) (= ::update source) (= ?value value)]]
  [:or [Encounter (= cs/mr modality)]
       [Encounter (= cs/ct modality)]]
  =>
  (calc-and-insert-elliptical-area ?annulus ?value "data/ao/annulus-area"))

I changed your :fn-map entry for defrule to the following to get the above output:

            ;; clara-rules
            "defrule" [:arg1-body
                       {:vector {:option-fn
                                   (fn ([] "clara-option-fn")
                                       ([opts n exprs]
                                        (cond (or (= :or (first exprs))
                                                  (= :and (first exprs)))
                                                {:vector {:fn-format :hang},
                                                 :fn-force-nl #{:hang},
                                                 :next-inner-restore
                                                   [[[:fn-force-nl] :hang]]}
                                              :else nil)))}}]

I did :or and :and. Looking briefly at the Clara Rules documentation, it looks like there are :and, :or, and :not. Maybe also :test? But it wouldn't be hard to add a few to the or in the cond above.

I'm not naive enough to think this will solve your rule formatting issues, but it might be a reasonable first step. Let me know if this works, and what else you need when you have a chance. Thanks!

kkinnear avatar Jul 22 '22 22:07 kkinnear