0

I have a pyclips / clips program for which I wrote some unit tests using pytest. Each test case involes an initial clips.Clear() followed by the execution of real clips COOL code via clips.Load(rule_file.clp). Running each test individually works fine.

Yet, when telling pytest to run all tests, some fail with ClipsError: S03: environment could not be cleared. In fact, it depends on the order of the tests in the .py file. There seem to be test cases, that cause the subsequent test case to throw the exception.

Maybe some clips code is still "in use" so that the clearing fails? I read here that (clear)

Clears CLIPS. Removes all constructs and all associated data structures (such as facts and instances) from the CLIPS environment. A clear may be performed safely at any time, however, certain constructs will not allow themselves to be deleted while they are in use.

Could this be the case here? What is causing the (clear) command to fail?

EDIT:

I was able to narrow down the problem. It occurs under the following circumstances:

test_case_A comes right before test_case_B. In test_case_A there is a test such as

(test (eq (type ?f_bio_puts) clips_FUNCTION))

but f_bio_puts has been set to

(slot f_bio_puts (default [nil]))

So testing the type of a slot variable, which has been set to [nil] initially, seems to cause the (clear) command to fail. Any ideas?

EDIT 2

I think I know what is causing the problem. It is the test line. I adapted my code to make it run in the clips Dialog Windows. And I got this error when loading via (batch ...)

[INSFUN2] No such instance nil in function type.
[DRIVE1] This error occurred in the join network
   Problem resided in associated join
       Of pattern #1 in rule part_1

I guess it is a bug of pyclips that this is masked.

langlauf.io
  • 3,009
  • 2
  • 28
  • 45

1 Answers1

1

Change the EnvClear function in the CLIPS source code construct.c file adding the following lines of code to reset the error flags:

globle void EnvClear(
  void *theEnv)
  {
   struct callFunctionItem *theFunction;

   /*==============================*/
   /* Clear error flags if issued  */
   /* from an embedded controller. */
   /*==============================*/

   if ((EvaluationData(theEnv)->CurrentEvaluationDepth == 0) && 
       (! CommandLineData(theEnv)->EvaluatingTopLevelCommand) &&
       (EvaluationData(theEnv)->CurrentExpression == NULL))
     {
      SetEvaluationError(theEnv,FALSE);
      SetHaltExecution(theEnv,FALSE);
     }
Gary Riley
  • 10,130
  • 2
  • 19
  • 34
  • Thanks for looking into this Gary. Does your answer mean there is a bug in clips? Will it be changed in the upcoming version? Or is it like this by design? – langlauf.io Mar 24 '17 at 21:41
  • 1
    It's a bug. When you're using CLIPS interactively with the command prompt, the error flags are reset automatically with each command issued. When embedded, the individual API calls must reset the error flag. This will be fixed in the next release, although if you encounter this issue with other API calls you can also fix the issue on the pyclips side by resetting the error flags without the additional code to check for an embedded controller. – Gary Riley Mar 25 '17 at 16:41