Fork me on GitHub
#clara
<
2022-10-25
>
pdmct04:10:40

Is there an typical approach to randomly applying rules? Say I want to fire a rule 30% of the time (ie 30% of object sI am creating with rules have some specific attribute), what is a good way to model this in rules ... or is that a bad idea. thx

ixemad12:10:02

@U066S7PQC, maybe just by adding the following LHS expressión: [:test (> 0.3 (rand))] ?

sashton14:10:35

alternatively, if you want it to be deterministically repeatable, maybe you could hash the some attribute of the input (unless all the attributes are somehow the same). Simplistic idea using clojure’s hash:

[:test (> 3 (mod (hash INPUT) 10))]

👍 1
ethanc14:10:02

I would highly recommend making it deterministic based on bound variables in the LHS. Clara’s Truth Maintenance relies on the repeatability of the logic in both the LHS and RHS of rules.

👍 1
mikerod19:10:04

Agreed on making it deterministic. I think the hashing idea is aligned to what I’d think too. You could do that or have a first-class key-val you put on the fact that had some value, say between 1-100, that was based on some distribution. Then you could have rules that just do an inequality like (< x 30), where that key name is :x. The generation of this key’s probabilistic value though, should be done external to the rules - not within the fire-rules loop where it’d cause non-determinism in rule-reevaluation on the same facts.

👍 2
pdmct20:10:05

Ok, thanks... that sounds like a great idea. I was worried that if I used a rand in the LHS the rules would be applied over and over again until they were satisfied (ie. probs would all tend towards 1), which is what I think @U0LK1552A is saying in the above reply.

pdmct20:10:37

The approach I was working on was to create an new object in working memory that recorded the state of random variable -ie. activated or not. The rule tests for object existence so inserting it keeps TMS happy etc

pdmct22:10:40

A hopefully basic question, we have recently split our rules into multiple namespaces to make them a bit more manageable, but I am getting a ClassNotFoundException from the mk-session call for my records (defined in a different name space) The class that is not found (in the exception) (ie. MyStruct) does not have the fully qualified classname ie. demo.my-records.MyStruct ... I am requiring and importing the record classes and the rules that I have written don't use the full classname. I am passing all of the namespaces that I split the rulebase into and the namespace for the record definitions to the mk-session call eg (mk-session 'demo.main 'demo.my-records ...). Is there something else that I need to do?

hiredman22:10:20

what is the rest of the stacktrace?

pdmct23:10:26

here is the full stack trace:

2. Unhandled clojure.lang.Compiler$CompilerException
   Error compiling pdmct/config_rules_main.clj at (200:1)
   #:clojure.error{:phase :execution,
                   :line 200,
                   :column 1,
                   :source "pdmct/config_rules_main.clj"}
             Compiler.java: 7665  clojure.lang.Compiler/load
                   RT.java:  381  clojure.lang.RT/loadResourceScript
                   RT.java:  372  clojure.lang.RT/loadResourceScript
                   RT.java:  459  clojure.lang.RT/load
                   RT.java:  424  clojure.lang.RT/load
                  core.clj: 6161  clojure.core/load/fn
                  core.clj: 6160  clojure.core/load
                  core.clj: 6144  clojure.core/load
               RestFn.java:  408  clojure.lang.RestFn/invoke
                  core.clj: 5933  clojure.core/load-one
                  core.clj: 5928  clojure.core/load-one
                  core.clj: 5975  clojure.core/load-lib/fn
                  core.clj: 5974  clojure.core/load-lib
                  core.clj: 5953  clojure.core/load-lib
               RestFn.java:  142  clojure.lang.RestFn/applyTo
                  core.clj:  669  clojure.core/apply
                  core.clj: 6016  clojure.core/load-libs
                  core.clj: 6000  clojure.core/load-libs
               RestFn.java:  137  clojure.lang.RestFn/applyTo
                  core.clj:  669  clojure.core/apply
                  core.clj: 6038  clojure.core/require
                  core.clj: 6038  clojure.core/require
               RestFn.java:  408  clojure.lang.RestFn/invoke
                      REPL:   46  user/eval5790
                      REPL:   46  user/eval5790
             Compiler.java: 7194  clojure.lang.Compiler/eval
             Compiler.java: 7149  clojure.lang.Compiler/eval
                  core.clj: 3215  clojure.core/eval
                  core.clj: 3211  clojure.core/eval
    interruptible_eval.clj:   87  nrepl.middleware.interruptible-eval/evaluate/fn/fn
                  AFn.java:  152  clojure.lang.AFn/applyToHelper
                  AFn.java:  144  clojure.lang.AFn/applyTo
                  core.clj:  667  clojure.core/apply
                  core.clj: 1990  clojure.core/with-bindings*
                  core.clj: 1990  clojure.core/with-bindings*
               RestFn.java:  425  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   87  nrepl.middleware.interruptible-eval/evaluate/fn
                  main.clj:  437  clojure.main/repl/read-eval-print/fn
                  main.clj:  437  clojure.main/repl/read-eval-print
                  main.clj:  458  clojure.main/repl/fn
                  main.clj:  458  clojure.main/repl
                  main.clj:  368  clojure.main/repl
               RestFn.java: 1523  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   84  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:   56  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:  152  nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
                  AFn.java:   22  clojure.lang.AFn/run
               session.clj:  218  nrepl.middleware.session/session-exec/main-loop/fn
               session.clj:  217  nrepl.middleware.session/session-exec/main-loop
                  AFn.java:   22  clojure.lang.AFn/run
               Thread.java:  833  java.lang.Thread/run

1. Caused by java.lang.ClassNotFoundException
   MyStruct

       URLClassLoader.java:  445  java.net.URLClassLoader/findClass
   DynamicClassLoader.java:   69  clojure.lang.DynamicClassLoader/findClass
          ClassLoader.java:  587  java.lang.ClassLoader/loadClass
   DynamicClassLoader.java:   77  clojure.lang.DynamicClassLoader/loadClass
          ClassLoader.java:  520  java.lang.ClassLoader/loadClass
              compiler.clj:  188  clara.rules.compiler/effective-type
              compiler.clj:  183  clara.rules.compiler/effective-type
              compiler.clj:  202  clara.rules.compiler/get-fields
              compiler.clj:  191  clara.rules.compiler/get-fields
              compiler.clj:  336  clara.rules.compiler/field-name->accessors-used
              compiler.clj:  332  clara.rules.compiler/field-name->accessors-used
              compiler.clj:  383  clara.rules.compiler/compile-condition
              compiler.clj:  379  clara.rules.compiler/compile-condition
              compiler.clj: 1358  clara.rules.compiler/eval12362/extract-exprs/fn/fn
     PersistentVector.java:  343  clojure.lang.PersistentVector/reduce
                  core.clj: 6885  clojure.core/reduce
                  core.clj: 6868  clojure.core/reduce
              compiler.clj: 1353  clara.rules.compiler/eval12362/extract-exprs/fn
              compiler.clj: 1336  clara.rules.compiler/eval12362/extract-exprs
              compiler.clj: 2033  clara.rules.compiler/eval12845/mk-session*/fn
              compiler.clj: 2003  clara.rules.compiler/eval12845/mk-session*
              compiler.clj: 2117  clara.rules.compiler/mk-session
              compiler.clj: 2091  clara.rules.compiler/mk-session
     config_rules_main.clj:  201  pdmct.config-rules-main/eval15700
     config_rules_main.clj:  200  pdmct.config-rules-main/eval15700
             Compiler.java: 7194  clojure.lang.Compiler/eval
             Compiler.java: 7653  clojure.lang.Compiler/load
                   RT.java:  381  clojure.lang.RT/loadResourceScript
                   RT.java:  372  clojure.lang.RT/loadResourceScript
                   RT.java:  459  clojure.lang.RT/load
                   RT.java:  424  clojure.lang.RT/load
                  core.clj: 6161  clojure.core/load/fn
                  core.clj: 6160  clojure.core/load
                  core.clj: 6144  clojure.core/load
               RestFn.java:  408  clojure.lang.RestFn/invoke
                  core.clj: 5933  clojure.core/load-one
                  core.clj: 5928  clojure.core/load-one
                  core.clj: 5975  clojure.core/load-lib/fn
                  core.clj: 5974  clojure.core/load-lib
                  core.clj: 5953  clojure.core/load-lib
               RestFn.java:  142  clojure.lang.RestFn/applyTo
                  core.clj:  669  clojure.core/apply
                  core.clj: 6016  clojure.core/load-libs
                  core.clj: 6000  clojure.core/load-libs
               RestFn.java:  137  clojure.lang.RestFn/applyTo
                  core.clj:  669  clojure.core/apply
                  core.clj: 6038  clojure.core/require
                  core.clj: 6038  clojure.core/require
               RestFn.java:  408  clojure.lang.RestFn/invoke
                      REPL:   46  user/eval5790
                      REPL:   46  user/eval5790
             Compiler.java: 7194  clojure.lang.Compiler/eval
             Compiler.java: 7149  clojure.lang.Compiler/eval
                  core.clj: 3215  clojure.core/eval
                  core.clj: 3211  clojure.core/eval
    interruptible_eval.clj:   87  nrepl.middleware.interruptible-eval/evaluate/fn/fn
                  AFn.java:  152  clojure.lang.AFn/applyToHelper
                  AFn.java:  144  clojure.lang.AFn/applyTo
                  core.clj:  667  clojure.core/apply
                  core.clj: 1990  clojure.core/with-bindings*
                  core.clj: 1990  clojure.core/with-bindings*
               RestFn.java:  425  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   87  nrepl.middleware.interruptible-eval/evaluate/fn
                  main.clj:  437  clojure.main/repl/read-eval-print/fn
                  main.clj:  437  clojure.main/repl/read-eval-print
                  main.clj:  458  clojure.main/repl/fn
                  main.clj:  458  clojure.main/repl
                  main.clj:  368  clojure.main/repl
               RestFn.java: 1523  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   84  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:   56  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:  152  nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
                  AFn.java:   22  clojure.lang.AFn/run
               session.clj:  218  nrepl.middleware.session/session-exec/main-loop/fn
               session.clj:  217  nrepl.middleware.session/session-exec/main-loop
                  AFn.java:   22  clojure.lang.AFn/run
               Thread.java:  833  java.lang.Thread/run

hiredman23:10:51

most likely issue is you have a rule defined somewhere that uses that type without importing it

pdmct23:10:09

possible ... thanks .. I will go through and check

hiredman23:10:02

but then you don't get the error from it until you run mk-session

👀 1
pdmct23:10:37

do I pass all of the namespaces where I have defined rules to the mk-session? or is it enough to require those namespaces in my main namespace and pass that?

hiredman23:10:08

but looking at the code I thing it is very unlikely your current error has anything to do with that

pdmct23:10:31

ok thx , that might be enough to get me moving

mikerod21:10:10

You should be sure to require the namespaces prior to referring to their names passed to mk-session. Beyond that it would seem like you are missing an :import

mikerod21:10:45

All symbols referenced in rules have to resolve in the namespace the rule is defined in.

pdmct21:10:28

hi, yes ... I found the culprit a missing import ... funny, I was told that the code was working when I started looking at it 🙂

😆 1
mikerod22:10:27

Yeah these types of errors can unfortunately be “sneaky” sometimes