Open ShadowJonathan opened 1 month ago
Did @scijones see this output when he made the comment? This looks okay to me, but I could be wrong.
^one
values, so that's not an issue.I4
, with multiple links to it. That's also fine. The printout is not saying that multiple WME's have been given the ID I4
.Useless comment:
_I saw the printout.
The problem, as I see it, is that the print makes it seem as though there are truly two WMEs with the same attribute label and same value from the same parent id. Soar supports multi-valued attributes, sure, but it doesn't support multi-[the-same-value] attributes. (Consider when two rules provide support for the same WME. Soar does not create a duplicate. It just maintains that WME if either rule remains to provide support.)_
oh shoot, timetags. I missed the "-t". duh. I need to see it without the "-t" for sure.
Okay, I did it myself and it's a real issue:
print(a.ExecuteCommandLine("print I2 -d 3")) (I2 ^one hi ^one hi)
Soar supports multi-valued attributes, sure, but it doesn't support multi-[the-same-value] attributes
This is interesting. So you're saying that (I2 ^one hi bye)
is legal but (I2 ^one hi hi)
is not. I don't know how Soar de-duplicates triples now, but the IO links have special machinery attached to them, so that's somewhere for me to look.
(FWIW I don't exactly know what the SML bindings should respond with wrt this, if it should reply with the same identifier, or if it should respond with NULL
)
Something else of note, i found this piece of code in CreateSharedIdWME
which does check if the WME about to be added will duplicate the set:
However, the ==
there will miss certain created shared Ids, since i know that (at least) on every GetChild
call, SML will create a new Identifier
pointer, and that ==
would only be checking on pointer equality.
(Curiously, GetChild
does not copy constant-value WMEs, those always return the same pointer)
@ShadowJonathan where are you seeing the GetChild
call?
T_T Wish I could look at the original discussion in the ticket mentioned in the code, but I think it's all gone (was on google code).
Ah, this is with my own library code, but this should replicate it;
import soar_sml
k=soar_sml.Kernel.CreateKernelInNewThread()
a=k.CreateAgent('soar')
inp = a.GetInputLink()
i = inp.CreateIdWME("id")
i2 = inp.GetChild(0)
assert(i != i2)
print((repr(i), i.GetTimeTag()))
print((repr(i2), i2.GetTimeTag()))
It should say the two aren't the "same", and the repr
esentation of both should point to a different pointer.
(Unfortunately, DebugString
doesn't work in the default bindings, because SWIG generates code that requires (paraphrasing from memory) a std::string &
, which python cannot create; all strings are values; interned and constant)
Edit: These two should probably be separate issues, tell me if I should file them like that ^^
Thank you! We can springboard off of this to write a unit test in Soar. Then we can fix the original issue for CreateSharedIdWME
. That still leaves the string, float, and int cases.
I encountered this bug today:
Where adding multiple concrete-value WMEs result in them being duplicated:
(@scijones says that this could possibly result to internal segfaults 😬)