FMModify

55 views
Skip to first unread message

Ryan Johnston

unread,
Mar 10, 2023, 6:49:39 PM3/10/23
to CLIPSESG
I'm trying to modify a fact with a multislot that has multiple values. I'm trying to set it to an "empty" state
by doing something like this:

FactModifier *fm = CreateFactModifier(env, fact);
MultifieldBuilder *mb = CreateMultifieldBuilder(env, 0);
FMPutSlotMultifield(fm, "foo", MBCreate(mb));
MBDispose(mb);
FMModify(fm);


However, this does not seem to set the multislot to an empty value.

CLIPS Support

unread,
Mar 11, 2023, 4:00:33 PM3/11/23
to CLIPSESG
There's a bug. I've added a fix at the SourceForge repository: https://sourceforge.net/p/clipsrules/code/HEAD/tree/branches/64x/core/

The relevant fix is in factmngr.c in the FMPutSlot function. Change these lines

      if (MultifieldsEqual(oldValue.multifieldValue,slotValue->multifieldValue))
        { return PSE_NO_ERROR; }

to 

      if ((oldValue.header->type == MULTIFIELD_TYPE) &&
          MultifieldsEqual(oldValue.multifieldValue,slotValue->multifieldValue))
        { return PSE_NO_ERROR; }

Ryan Johnston

unread,
Mar 11, 2023, 7:51:26 PM3/11/23
to CLIPSESG
Thanks for the quick bug fix, Gary! I'll test this when I next have a moment :)

Ryan Johnston

unread,
Mar 12, 2023, 9:32:40 PM3/12/23
to CLIPSESG
That seems to have fixed one issue around this. Now I'm able to set the multislot field to an "empty" multifieldValue. Nice!

I'm now running into a different issue. When I try to set that multifield value twice in a row, I get the following error:

[PRNTUTIL3]
*** CLIPS SYSTEM ERROR ***
ID = SYMBOL6
CLIPS data structures are in an inconsistent or corrupted state.
This error may have occurred from errors in user defined code.

Replace the `main` function in `main.c` to reproduce:

int main(
  int argc,
  char *argv[])
  {
   mainEnv = CreateEnvironment();

   Build(mainEnv, "(deftemplate foo (multislot bar))");
   Fact *f = AssertString(mainEnv, "(foo (bar 1 2 \"Foo!\"))");

   FactModifier *fm = CreateFactModifier(mainEnv, f);
   MultifieldBuilder *mb = CreateMultifieldBuilder(mainEnv, 1);
   MBAppendInteger(mb, 1);
   Multifield *mf = MBCreate(mb);
   MBDispose(mb);
   FMPutSlotMultifield(fm, "bar", mf);
   Fact *f2 = FMModify(fm);
   FMDispose(fm);

   FactModifier *fm2 = CreateFactModifier(mainEnv, f2);
   MultifieldBuilder *mb2 = CreateMultifieldBuilder(mainEnv, 1);
   MBAppendInteger(mb2, 2);
   Multifield *mf2 = MBCreate(mb2);
   MBDispose(mb2);
   FMPutSlotMultifield(fm2, "bar", mf2);
   Fact *f3 = FMModify(fm2);
   FMDispose(fm2);

   FactModifier *fm3 = CreateFactModifier(mainEnv, f3);
   MultifieldBuilder *mb3 = CreateMultifieldBuilder(mainEnv, 1);
   MBAppendInteger(mb3, 3);
   Multifield *mf3 = MBCreate(mb3);
   MBDispose(mb3);
   FMPutSlotMultifield(fm3, "bar", mf3);
   Fact *f4 = FMModify(fm3);
   FMDispose(fm3);

   Facts(mainEnv, "stdout", NULL, -1, -1, -1);
   DestroyEnvironment(mainEnv);

   return -1;
  }

Ryan Johnston

unread,
Mar 12, 2023, 9:46:40 PM3/12/23
to CLIPSESG
Sorry, that's "three times" in a row. If I attempt 2 times in a row, (remove the block starting with `fm3`), I get a Segfault when destroying the environment. Output from the above program with the third block commented out:

f-1     (foo (bar 2))
For a total of 1 fact.
Segmentation fault (core dumped)

Ryan Johnston

unread,
Mar 12, 2023, 10:12:59 PM3/12/23
to CLIPSESG
Please pardon the spam on this thread. Just as a sanity check: I'm changing line 3054 in  factmngr.c so that it looks like this:

      if ((oldValue.header->type == MULTIFIELD_TYPE) &&
          MultifieldsEqual(oldValue.multifieldValue,slotValue->multifieldValue))
        { return PSE_NO_ERROR; }
     }
Additionally, I've discovered if I update the 2nd block in my above debugging code to look like this, the program hangs indefinitely:

   FactModifier *fm2 = CreateFactModifier(mainEnv, f2);
   MultifieldBuilder *mb2 = CreateMultifieldBuilder(mainEnv, 0);
   //MBAppendInteger(mb2, 2);

   Multifield *mf2 = MBCreate(mb2);
   MBDispose(mb2);
   FMPutSlotMultifield(fm2, "bar", mf2);
   Fact *f3 = FMModify(fm2);
   FMDispose(fm2);

CLIPS Support

unread,
Mar 13, 2023, 3:54:36 PM3/13/23
to CLIPSESG
I can reproduce the first two issues. I'll look into it.

Ryan Johnston

unread,
Mar 14, 2023, 1:00:55 PM3/14/23
to CLIPSESG
Thanks, Gary!

CLIPS Support

unread,
Mar 15, 2023, 4:43:58 PM3/15/23
to CLIPSESG
Try this replacement file.
factmngr.c

Ryan Johnston

unread,
Mar 15, 2023, 5:12:54 PM3/15/23
to CLIPSESG
Very nice, this seems to have resolved my issue :) Thank you again, Gary!
Reply all
Reply to author
Forward
0 new messages