clips.Clear() fails?

Help
iRiku87
2010-01-18
2013-04-25
  • iRiku87

    iRiku87 - 2010-01-18

    Hi.

    In the app I'm developing, needs to clear the environment many times. It's some kind of game, and everytime a new game is loaded i did 'clips.Clear()' to clear the environment of the previous games.

    The problem was that every time a new game do that functions, it takes more time. The first time the function is called, it takes less than 0.001 second, but 10 times later, above 12 seconds, and finish taking almost 40 seconds.

    It works fine if I do clips.Eval('(clear)') but I want to know if there is some other way, more "python way" using functions given in PyCLIPS.

    Thanks for the help!

     
  • Francesco Garosi

    Hi…

    there is a reason for that. In CLIPS, the Clear() function (and Reset() too) usually destroy facts that have been created and not asserted. The act of destroying them actually frees the associated memory, but does not give any feedback about these facts being invalid anymore. The corresponding Python Fact objects, then, will hold a pointer to a structure that is not valid anymore, and the module user has still the possibility to reference them. To minimize the problem I created a hash array of all (true, not just referenced) Fact objects that have been instanced in Python: whenever you call Clear() or Reset(), the list of all remaining facts is scanned and all these facts are tagged as invalid - in order to just raise an exception instead of segfaulting in case of a reference to them. If you evaluate the CLIPS "(clear)" function, you just bypass this mechanism. Actually, the time spent there depends on the number of stray Fact objects lying around at the time of the call to Clear(). I thought that, in a normal case (where Clear() is not called very often), the overhead would be acceptable compared to the advantages.

    If you're sure that you'll never reference old Fact objects after a Clear(), you can comment out the

    /* lock CLIPS garbage collection when there are non-asserted facts around */
    #define USE_NONASSERT_CLIPSGCLOCK
    /* allow Clear() to reset PyCLIPS garbage collection counters */
    #define USE_CLEAR_RESETGCCOUNTERS
    

    lines in clipsmodule.h: calls to Clear() should be much more responsive. I'm still using CLIPS 6.24 to develop PyCLIPS (actually I'm working on a 2.0 version that should be compatible with Python 3.1, but there are still some issues), maybe the 6.30 version will implement a mechanism to monitor invalid facts OOTB, since Gary Riley is developing a wrapper himself (for Java), but unfortunately I didn't investigate yet.

    I don't know if the modifications to the header file that I proposed here to you produce a module stable enough for use in a production system (pun not intended), for what I can see it passes the tests - and that is the way I have to see if things work. But I'd be happy to have some feedback from you in case you use the version without the PyCLIPS garbage collection.

    BTW, do you have any code to provide in order to understand why the execution time of Clear() increments so much with its use? The test suite, in fact, calls Clear() and Reset() a lot of times (twice for each test) but this seems to have little influence.

    F.

     
  • iRiku87

    iRiku87 - 2010-01-18

    Hi.

    First, thanks for the answer. I understand the problem implementing the function Clear() and also Reset(). The restriction in memory management on Python is one of the things I miss from C++. The changes that you propose works fine, but the problem is that this game will be distributed for students in my college.

    I prefer to use the official version, and will not have problems with the user. I understand that using Eval is not the best way, but don't think other way works for this case.

    The app structure is the next:

    clips.Clear()        
    clips.EngineConfig.Strategy = clips.RANDOM_STRATEGY
    random.seed()
    clips.Eval("(seed " + str(random.randint(0,9999)) + ")")
    #Loads a lot of rules, functions and facts that determines the logic of the game
    clips.Load(teamA[0])
    clips.Load(teamB[0])
    clips.Load(teamA[1])
    clips.Load(teamB[1])
    clips.Reset()
    clips.Run()
    

    The game is some kind of Stratego, or simplified chess. The teams are 2 files: one for the formation (where are pieces ubicated) and other for the rules. The thing is that when a lot of games are played (like a tournament), the function takes too long.

    Maybe there is some better way to do that, but do not figure it by myself. Anyway, clips.Eval() is a good 'patch' for now.

    Thanks.

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks