clara

http://www.clara-rules.org/
jdt 2018-05-25T16:57:37.000425Z

I'm guessing the second [Derived 1] is retracted after insertion, though that isn't what I want, in fact in my POC rule set I'm doing an insert-unconditional! because the fact must survive, subsequent retraction, but I still only one exactly one instance to be inserted, i.e. one-time initialization.

2018-05-25T17:04:06.000144Z

@dave.tenny you know you’re inserting a vector there right?

2018-05-25T17:04:19.000693Z

Just noticed that this seems odd (insert! [Derived ?x])

jdt 2018-05-25T17:04:37.000122Z

Lol, I looked at it thinking "something isn't right here" too

jdt 2018-05-25T17:04:55.000631Z

Just too Friday-minded to see it, thanks for looking

2018-05-25T17:04:58.000612Z

however, with insert! I think you may get in an infinite loop

2018-05-25T17:05:07.000233Z

because your rule becomes a logical contradiction

2018-05-25T17:05:36.000605Z

So I think there are just several different topics with this example, 😛

jdt 2018-05-25T17:05:36.000643Z

yes indeed, infinite loop

2018-05-25T17:06:12.000483Z

you can do an insert-unconditional! of course

jdt 2018-05-25T17:06:19.000649Z

Amending the snippet

2018-05-25T17:06:26.000419Z

I’m not a huge fan of those, because they cause rules to become more order dependent’

2018-05-25T17:06:40.000054Z

However, there are times where they are difficult to avoid I know

jdt 2018-05-25T17:07:48.000295Z

In my case, I need to add a fact to the system, once to "initialize" the absense of a missing fact. The fact needs to survive truth maintenace because I am going to retract the basis for creating it, but not the need for using it later on

2018-05-25T17:07:53.000592Z

Your snippet now has no code, only output

jdt 2018-05-25T17:08:04.000295Z

yeah, once sec, reposting the snippet, there was no "edit"

jdt 2018-05-25T17:10:17.000656Z

I deleted the first snippet, it shouldn't exist at all in slack, actually.

jdt 2018-05-25T17:11:59.000647Z

Anyway, I'm clearly not yet in the mindset of thinking the way clara wants me to think. I'd expect a rule like [:not [Foo]] => (insert-unconditional! (->Foo)) to fire exactly once, but clearly my assumptions are wrong.

alex-dixon 2018-05-25T17:13:41.000084Z

Wouldn’t call that a bad assumption but that rule effectively means when not foo foo and when foo not foo

2018-05-25T17:14:13.000136Z

if you use insert! the behavior is a contradiction, with insert-unconditional! it is different

2018-05-25T17:14:36.000225Z

There is also a property you can add to rules, I don’t typically like to add it though, but it is :no-loop

alex-dixon 2018-05-25T17:15:09.000696Z

Oops. with unconditional it should operate as you stated I think

2018-05-25T17:15:12.000289Z

it may be able to stop a logical loop from a contradicting rule like you have here with insert!, but I’d have to mess with that again

jdt 2018-05-25T17:15:17.000178Z

Oops, yes, my code snippet iwth the infinite loop isn't interesting. When I use insert-unconditional it's still firing more than once

2018-05-25T17:15:26.000066Z

@alex-dixon I haven’t seen an insert-unconditional! example yet 😛

jdt 2018-05-25T17:15:30.000011Z

Doing the code snippet and output again, apologies

2018-05-25T17:15:51.000175Z

insert-unconditional! will result in a firing for each of your Fact objects, so 3 is rigth

alex-dixon 2018-05-25T17:16:41.000363Z

What about not exists?

jdt 2018-05-25T17:16:58.000045Z

I thought [:not [Foo]] was a not-exist check?

2018-05-25T17:17:02.000428Z

The rules do not treat the working memory as something like a set. It allows “duplicates”. There are useful cases for that - scratch this

2018-05-25T17:17:13.000518Z

oh, I see what you mean

2018-05-25T17:18:33.000592Z

@dave.tenny you’re correct in what :not is

2018-05-25T17:20:22.000531Z

I think it may be an “edge case” on insert-unconditional! behavior in the engine. I’d probably call it incorrect how the engine is behaving

jdt 2018-05-25T17:20:46.000305Z

I'm confused because on the one hand, the RHS of one rule can impact the firing of another rule. But in this case it's like both checks for a [Derived 1] correpesponding to a [Fact 1] took place at the same time, neither aware of the others effect, and unsure how to bridge that.

2018-05-25T17:21:41.000429Z

Like I said, I’m not a fan of insert-unconditional! and try to not use it much because I think it makes things have order dependence and always trickier to reason about as far as “global logical consistency” across the rules

jdt 2018-05-25T17:21:45.000600Z

(reminds me of MVCC transactions, which can be a good thing ... in a database 😉 )

2018-05-25T17:21:52.000308Z

However, in this case, I think it is behaving poorly with batched inserts

2018-05-25T17:22:22.000552Z

I think all 3 matches are staged independent of one another and all perform insert-unconditional! at the “same time”

2018-05-25T17:22:39.000083Z

since they are unconditional, the truth maintenance isn’t used to remove the logical inconsistencies

2018-05-25T17:23:06.000244Z

this is a tougher case to me conceptually to think about

2018-05-25T17:23:17.000327Z

as far as a “fix” would go

jdt 2018-05-25T17:24:43.000379Z

Okay, well, I'll remedy my immediate problem by doing what is fundamentally an initialization step outside of the rule firing and add my initialization outside of the firings (i.e. not in an RHS via insert!, but via insert externally.

alex-dixon 2018-05-25T17:24:45.000512Z

Wondering if behavior is different if derived is inserted without ?x...maybe y instead

jdt 2018-05-25T17:25:40.000162Z

I'm definitely still struggling with these little things, though logic principles of [not x] => [x] is a good way ot look at it in my thinking for the future.

✅ 1
2018-05-25T17:26:36.000312Z

@dave.tenny oftentimes, and I’ve said this quite a bit here before, I try to separate the desire of “cardinality” into a different rule from the rule that has the logic to derive the fact in question

jdt 2018-05-25T17:26:47.000705Z

This particular one is very unfortunate though, if it worked it was much nicer and more foolproof when done via a rule firing.

2018-05-25T17:27:04.000030Z

So instead of worrying about a rule producing too many of something, I let it produce them, and reconcile them with a separate rule and an accumulator

alex-dixon 2018-05-25T17:27:16.000238Z

@mikerod what’s the upside to the batched unconditional insertions implementation? Is it possible to still attain those benefits without eliciting behavior like this?

2018-05-25T17:27:26.000339Z

this case is a bit different in a way, but if your real concern is only that you don’t want 2 Derived :y 1 facts, it applies

2018-05-25T17:27:53.000655Z

@alex-dixon batched <anything> upside is basically always performance

2018-05-25T17:28:00.000040Z

and the performance can be really significant

2018-05-25T17:28:34.000096Z

However, in the unconditional case, it now concerns me a bit since the truth maintenance won’t “fix it” when different unconditional inserts cause the other to become untrue

2018-05-25T17:29:00.000020Z

however, that is a really gray area to me. if it did behave right, how would it choose which unconditional insert wins, when they contradict each other? In the general case.

2018-05-25T17:29:06.000085Z

I guess it would just have to be order-dependent

jdt 2018-05-25T17:30:01.000062Z

On an unrelated topic, can you recommend tools for pretty-printing/organizing inspect and get-trace output to assist with reading it? I made my first attempt at decoding that stuff to debug, but as a raw clojure nested structure it's rough going for a first try.

2018-05-25T17:31:18.000080Z

@dave.tenny @alex-dixon is going to release a tool to show tracing stuff nicer 😛

2018-05-25T17:32:16.000577Z

Joking.. but he has said he had a better visualization thing. The trace results will be pretty verbose and clj data structures. Inspect was supposed to have a few friendlier printers I think. I haven’t used inspect much.

jdt 2018-05-25T17:34:02.000682Z

Of course what I really want is a simple movie-mode rule tracing with verbose-mode description of clause evaluation impact on rule consideration/rejection. Heh, or is that [:test (do (prn "here I am") true)] in the LHS?

2018-05-25T17:35:39.000160Z

@dave.tenny yeah, you can print stuff. I think the tracing output can be used alright, but it’s mostly just composing functions on it to show it however is useful.

2018-05-25T17:36:09.000289Z

I don’t have any great pointers there still beyond that

jdt 2018-05-25T17:36:39.000055Z

Haven't seen any "tips and tricks" documentation for the sorts of things a newbie could use for debugging

jdt 2018-05-25T17:36:42.000714Z

if it's out there

2018-05-25T17:42:36.000134Z

Yeah, I think this may be something that is lacking (and would be really nice to have).

2018-05-25T17:42:46.000182Z

The most docs I see are just from http://www.clara-rules.org/docs/inspection/

alex-dixon 2018-05-25T19:28:31.000482Z

@mikerod It’s not better according to me. And yeah…I’m working on it again this weekend 🙂

👍 1
alex-dixon 2018-05-25T19:31:22.000470Z

Might open an issue in Clara about adding Datalog syntax as a separate clara library. For something like the precept devtools concept I’m not sure how that would work….would need to think about it or have some direction from others. A lot of the way I thought about it was Precept-specific. I think the main difference is that there’s framework to manage session transitions, so there’s code that’s aware of when rules are firing and when they’re done firing that allows them to be identified and numbered

alex-dixon 2018-05-25T19:31:35.000168Z

Sorry if that’s incoherent

2018-05-25T22:20:46.000295Z

@alex-dixon Yeah, I’d have to think about that more too. I get what you are saying though I think.