Fork me on GitHub
#clara
<
2018-05-25
>
jdt16:05:37

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.

mikerod17:05:06

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

mikerod17:05:19

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

jdt17:05:37

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

jdt17:05:55

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

mikerod17:05:58

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

mikerod17:05:07

because your rule becomes a logical contradiction

mikerod17:05:36

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

jdt17:05:36

yes indeed, infinite loop

mikerod17:05:12

you can do an insert-unconditional! of course

jdt17:05:19

Amending the snippet

mikerod17:05:26

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

mikerod17:05:40

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

jdt17:05:48

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

mikerod17:05:53

Your snippet now has no code, only output

jdt17:05:04

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

jdt17:05:17

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

jdt17:05:59

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-dixon17:05:41

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

mikerod17:05:13

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

mikerod17:05:36

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-dixon17:05:09

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

mikerod17:05:12

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

jdt17:05:17

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

mikerod17:05:26

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

jdt17:05:30

Doing the code snippet and output again, apologies

mikerod17:05:51

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

alex-dixon17:05:41

What about not exists?

jdt17:05:58

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

mikerod17:05:02

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

mikerod17:05:13

oh, I see what you mean

mikerod17:05:33

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

mikerod17:05:22

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

jdt17:05:46

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.

mikerod17:05:41

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

jdt17:05:45

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

mikerod17:05:52

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

mikerod17:05:22

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

mikerod17:05:39

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

mikerod17:05:06

this is a tougher case to me conceptually to think about

mikerod17:05:17

as far as a “fix” would go

jdt17:05:43

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-dixon17:05:45

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

jdt17:05:40

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.

mikerod17:05:36

@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

jdt17:05:47

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

mikerod17:05:04

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-dixon17:05:16

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

mikerod17:05:26

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

mikerod17:05:53

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

mikerod17:05:00

and the performance can be really significant

mikerod17:05:34

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

mikerod17:05:00

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.

mikerod17:05:06

I guess it would just have to be order-dependent

jdt17:05:01

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.

mikerod17:05:18

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

mikerod17:05:16

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.

jdt17:05:02

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?

mikerod17:05:39

@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.

mikerod17:05:09

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

jdt17:05:39

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

jdt17:05:42

if it's out there

mikerod17:05:36

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

alex-dixon19:05:31

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

alex-dixon19:05:22

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-dixon19:05:35

Sorry if that’s incoherent

mikerod22:05:46

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