Menu

#1 CLIPS 6.30: asserting a fact corrupts symbols in unasserted facts

1.0
closed
nobody
None
2014-07-23
2014-07-22
Uri Barkai
No

The other symbol is garbage-collected during EnvAssert().

~~~~~~
void env = CreateEnvironment(), template, fact1, fact2;
DATA_OBJECT dobj;

EnvBuild(env, "(deftemplate t1 (slot x (type SYMBOL)))");
template = EnvFindDeftemplate(env, "t1");
fact1 = EnvCreateFact(env, template);
dobj.type = SYMBOL;
dobj.value = EnvAddSymbol(env, "Hello");
EnvPutFactSlot(env, fact1, "x", &dobj);
fact2 = EnvCreateFact(env, template);
dobj.value = EnvAddSymbol(env, "World");
EnvPutFactSlot(env, fact2, "x", &dobj);
EnvPPFact(env, fact2, "wdisplay", 0); // OK
EnvAssert(env, fact1);
EnvPPFact(env, fact2, "wdisplay", 0); // Corrupted

~~~~~~~

This came up running the unit tests for PyCLIPS compiled with CLIPS 6.30.
(Following Gary's suggestion here)

Discussion

  • Gary Riley

    Gary Riley - 2014-07-23

    It's not safe to create garbage that needs to persist (such as the World symbol with EnvAddSymbol) and then call a function such as EnvAssert that triggers garbage collection. This code will work most of the time in older versions of CLIPS because the garbage collector will only kick in if a certain amount of garbage has been created, but if you put this code in a loop and generate thousands of facts you'll eventually get the same corruption behavior. The new garbage collector tracks garbage more efficiently, so it can be called more frequently resulting in more predictable behavior.

    If you're asserting multiple facts, the recommended approach is to create and assert each fact before moving on to the next. The EnvAssert will remove any data associated with the fact from the garbage collection list before performing garbage collection. Alternately you can use the EnvIncrementGCLocks/EnvDecrementGCLocks (using r172 or later) to wrap sections of your code to temporarily prevent garbage collection of values returned to you by CLIPS.

     
  • Gary Riley

    Gary Riley - 2014-07-23
    • status: new --> closed
     

Log in to post a comment.