Segfault with IMPutSlot of subclass instance
Yes, if you intend to share an environment across multiple threads, you shall protect it from mutual access of its API. From the 1.2 Threads and Concurrency chapter of the Advanced Programming Guidelines: Each environment can have at most one thread of execution. The CLIPS internal data structures can become corrupted if two CLIPS API calls are executing at the same time for a single environment. For example, you can’t have one thread executing rules and another thread asserting facts for the same...
Are you asserting facts concurrently from different threads? CLIPS does not support multithreading on single environments. Il giorno lun 13 set 2021 alle ore 07:11 Faraz Zabihian farazex@users.sourceforge.net ha scritto: That "clock =" is meant to be " tick". My bad embedded clips, Assertstring and segmentation fault https://sourceforge.net/p/clipsrules/discussion/776945/thread/7887a94397/?limit=25#8927 Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/clipsrules/discussion/776945/...
CLIPSPy 1.0.0 has been released. This version is based on CLIPS 6.40. The APIs have been refactored based on the learnings with CLIPS 6.30 and to better reflect the changes in the C ones. Test coverage has also been increased. Python 2 support has been dropped and the minimum supported Python version is now 3.6. iCLIPS as well has been ported to the new library version. clipspy: https://pypi.org/project/clipspy/ iCLIPS: https://pypi.org/project/iCLIPS/ Thanks @garyriley for releasing CLIPS 6.40!
Feature request: defconstruct docstrings
Thanks! I already updated the Python bindings Makefile to use the new release.
Release CLIPS 6.32
Hello, I would ask you to open a separate issue on GitHub as these seem bugs at first sight. Let's keep this forum for more generic discussions.
I confused the instance name as the class name, so I was left wondering why it was removed when undefining the instance. My apologies. As in Python everything is an object, I wrapped all CLIPS structures (templates, classes, globals, functions, etc...) in related objects. I did not encounter the problems you report with C++/.NET as I simply hooked the release of the objects memory to the interpreter's GC process. Hence, every time a fact/instance object goes out of scope, the GC will decrease the...
My bad, I used the new APIs in clipspy 6.40 where that specific method was turned into a property.
You can ask questions on stackoverflow. For issues, bugs or feature requests you can refer to the related Github project. There's not a way to get a slot type directly from a class. The common Use Case for reading slot types is to build a mapping for some sort of JSON or XML schema. Therefore, I always end up reading them all with something like this. {s.name: s.types for s in defclass.slots} > {'birth-date': ('SYMBOL',), 'name': ('STRING',), 'surname': ('STRING',)} You can easily come up with a...
You can ask questions on stackoverflow. For issues, bugs or feature requests you can refer to the related Github project. There's not a way to get a slot type directly from a class. The common Use Case for reading slot types is to build a mapping for some sort of JSON or XML schema. Therefore, I always end up reading them all with something like this. {s.name: s.types for s in class.slots} > {'birth-date': ('SYMBOL',), 'name': ('STRING',), 'surname': ('STRING',)} You can easily come up with a one...
You can ask questions on stackoverflow. For issues, bugs or feature requests you can refer to the related Github project. There's not a way to get a slot type directly from a class. The common Use Case for reading slot types is to build a mapping for some sort of JSON or XML schema. Therefore, I always end up reading them all with something like this. {s.name: s.types for s in template.slots} > {'birth-date': ('SYMBOL',), 'name': ('STRING',), 'surname': ('STRING',)} You can easily come up with a...
Adding to the list the RouterExitFunction router callback which lacks the router name among the given parameters. As all other callbacks receive the router name, it makes the API look a bit odd. It can be passed within the context parameter but would be preferrable to receive it as per the other callbacks.
CLIPSPy support for CLIPS 6.40 is ready. You can find it in its dedicated branch. Noticeable changes: Several improvements and features brought by new CLIPS 6.40 APIs such as support for facts modification Improved error handling Improved I/O and logging via CLIPS routers Added Makefile to simplify the build and installation of CLIPSPy on Linux OSes (windows will get CLIPSPy shipped as wheel packages) Improved documentation (source code here) Once CLIPS 6.40 will be released I will release CLIPSPy...
I was playing with the idea of providing compatibility in the Python bindings for both CLIPS and FuzzyCLIPS but I encountered an issue when building it. The makefile requires a file "extobj.h" which was removed in commit f7397d7. There is a Pull Request attempting to fix it but it has been haging open. Would it be possible to get it merged? Furthermore, is there a reason the two code bases are kept separated? Wouldn't be simpler to integrate fuzzy support in mainline CLIPS and maintain a single code...
CLIPS 6.40 C API issues
Inconsistences in Advanced Programming Guide v6.40
Wrong parameter type in apg MBAppendInstance
Advanced Programming Guide small typo
Thanks for taking the time to give these insights, they really help understanding the rationale behind certain design choices. I already started porting the Python bindings to CLIPS 6.40 but as the whole APIs have changed it will require a fair amount of time. I have one last question: in this stackoverflow issue the user encountered a problem with the modify function used with fact-indexes. It seems they cannot be used in the Eval() functions but just through the CLIPS console. Is this still the...
Thanks for taking the time to give these insights, they really help understanding the rationale behind certain design choices. I already started porting the Python bindings to CLIPS 6.40 but as the whole APIs have changed it will require a fair amount of time. I have one last question: in this stackoverflow issue the user encountered a problem with the modify function used with fact-indexes. It seems they cannot be used in the Eval() functions but just through the CLIPS console. Is this still the...
Greetings, I took some time to add PERL regular expressions support in CLIPS 6.30. I shared the code here: https://github.com/noxdafox/clips/tree/regex In case there is interest to get this feature merged upstream, please let me know. I'll be glad to contribute.
I am simply listing all the deftemplate and pretty printing them. This is quite common when exploring the engine capabilities in Pyhton via its REPL. import clips env = clips.environment() env.build("(deftemplate foo (slot bar))") list(env.templates()) # this on the REPL will automatically call the PP functions I just recently stumbled over this issue and I am wondering whether I shall follow 1to1 the C APIs and return None in case there's no PP version or just re-construct the PP myself. Right now...
I am simply listing all the deftemplate and pretty printing them. This is quite common when exploring the engine capabilities in Pyhton via its REPL. import clips env = clips.environment() env.build("(deftemplate foo (slot bar))") list(env.templates()) # this on the REPL will automatically call the PP functions I just recently stumbled over this issue and I am wondering whether I shall follow 1to1 the C APIs and return None in case there's no PP version or just re-construct the PP myself. Right now...
I am simply listing all the deftemplate and pretty printing them. This is quite common when exploring the engine capabilities in Pyhton via its REPL. import clips env = clips.environment() env.build("(deftemplate foo (slot bar))") list(env.templates()) # this on the REPL will automatically call the PP functions I just recently stumbled over this issue and I am wondering whether I shall follow 1to1 the C APIs and return None in case there's no PP version or just re-construct the PP myself. Right now...
It could actually be fixed easily by retieving the module name via EnvDeftemplateModule and the template name with EnvGetDeftemplateName. Something on the line: modname = EnvDeftemplateModule(env, tmpl); tmplname = EnvGetDeftemplateName(env, tmpl); sprintf(pp_format, "(deftemplate %s::%s)", modname, tmplname); I can provide a patch if needed.
Nevermind I again forgot that the initial-fact is actually a deftemplate fact and not an implied one. I was already covering the NULL returned by implied facts. Thanks.
What other templates are created automatically?
Tried to open a Bug issue but it seems I don't have permission to do so. It seems that calling EnvGetDeftemplatePPForm on the template of the initial-fact returns NULL. Other templates work.
Greetings, I've been working for a while on a Python binding library for CLIPS. I started writing it few years ago to overcome a memory leak in PyCLIPS. https://github.com/noxdafox/clipspy The core difference between this library and PyCLIPS is the fact that it relies on the C Foreign Function Interface for Python (CFFI) instead of using the Python C native extension APIs. This results in a much smaller code base which should simplify the maintenance of the library making the transition to CLIPS...
Just FYI, now CLIPSPy allows to embed Python function and call them directly. You can check the documentation for an example. I also built an interactive console iCLIPS based on the Jupyter notebook.
Feature request: deftemplate inheritance
I did not think about using symbols as return values of functions actually. Yet the error code sounds more familiar to programmers. Thanks!
I see few issues in your design. As you noticed yourself, your execution is not asynchronous as no output is produced if CLIPS is not running. Therefore, the select is overkill. It is not clear how the actual flow works. You are not in control over when input is coming in as it's implicitely piped via the input pipe. You might, for example, want to filter certain facts if they don't meet your criterias. This is much easier to do in Python rather than in CLIPS. Pipes get full pretty fast, this might...
I see few issues in your design. As you noticed yourself, your execution is not asynchronous as no output is produced if CLIPS is not running. Therefore, the select is overkill. It is not clear how the actual flow works. You are not in control over when input is coming in as it's implicitely piped via the input pipe. You might, for example, want to filter certain facts if they don't meet your criterias. This is much easier to do in Python rather than in CLIPS. Pipes get full pretty fast, this might...
I see few issues in your design. As you noticed yourself, your execution is not asynchronous as no output is produced if CLIPS is not running. Therefore, the select is overkill. It is not clear how the actual flow works. You are not in control over when input is coming in as it's implicitely piped in via the input pipe. You might, for example, want to filter certain facts if they don't meet your criterias. This is much easier to do in Python rather than in CLIPS. Pipes get full pretty fast, this...
I am not sure I fully understand what is your use case. You want to send command to a running CLIPS engine and read its status (which facts are asserted, enable disable watch)? I'd recommend to limit the CLIPS language to the business rules only and use the CLIPS APIs (exposed in Python) to control the engine. De-coupling the rules and the engine management simplifies a lot the architecture and allows the experts to focus on the business rules while ignoring how the engine is configured. Otherwise...
I am not sure I fully understand what is your use case. You want to send command to a running CLIPS engine and read its status (which facts are asserted, enable disable watch)? I'd recommend to limit the CLIPS language to the business rules only and use the CLIPS APIs (exposed in Python) to control the engine. De-coupling the rules and the engine management simplifies a lot the architecture and allows the experts to focus on the business rules while ignoring how the engine is configured. Otherwise...
I am not sure I fully understand what is your use case. You want to send command to a running CLIPS engine and read its status (which facts are asserted, enable disable watch)? I'd recommend to limit the CLIPS language to the business rules only and use the CLIPS APIs (exposed in Python) to control the engine. De-coupling the rules and the engine management simplifies a lot the architecture and allows the experts to focus on the business rules while ignoring how the engine is configured. Otherwise...
CLIPS exposes IO facilities via Routers which are described in Section 7 of the Advanced Programming Guide. clipspy exposes a pretty dummy implementation of CLIPS Routers. Main reason for its simplicity is the lack of proper documentation about their use. If you are planning to capture CLIPS output messages, I'd rather suggest you to use the provided LoggingRouter which re-directs all CLIPS output to the standard Python logging facilities. In this way, you can control the logs of your service like...
CLIPS exposes IO facilities via Routers which are described in Section 7 of the Advanced Programming Guide. clipspy exposes a pretty dummy implementation of CLIPS Routers. Main reason for its simplicity is the lack of proper documentation about their use. If you are planning to capture CLIPS output messages, I'd rather suggest you to use the provided LoggingRouter which re-directs all CLIPS output to the standard Python logging facilities. In this way, you can control the logs of your service like...
CLIPS exposes IO facilities via Routers which are described in Section 7 of the Advanced Programming Guide. clipspy exposes a pretty dummy implementation of CLIPS Routers. Main reason for its simplicity is the lack of proper documentation about their use. If you are planning to capture CLIPS output messages, I'd rather suggest you to use the provided LoggingRouter which re-directs all CLIPS output to the standard Python logging facilities. In this way, you can control the logs of your service as...
CLIPS exposes IO facilities via Routers which are described in Section 7 of the Advanced Programming Guide. clipspy exposes a pretty dummy implementation of CLIPS Routers. Main reason for its simplicity is the lack of proper documentation about their use. If you are planning to capture CLIPS output messages, I'd rather suggest you to use the provided LoggingRouter which re-directs all CLIPS output to the standard Python logging facilities. In this way, you can control the logs of your service as...
CLIPS exposes IO facilities via Routers which are described in Section 7 of the Advanced Programming Guide. clipspy exposes a pretty dummy implementation of CLIPS Routers. Main reason for its simplicity is the lack of proper documentation about their use. If you are planning to capture CLIPS output messages, I'd rather suggest you to use the provided LoggingRouter which re-directs all CLIPS output to the standard Python logging facilities. In this way, you can control the logs of your service as...
Greetings, I've been working for a while on a Python binding library for CLIPS. I started writing it few years ago to overcome a memory leak in PyCLIPS. https://github.com/noxdafox/clipspy The core difference between this library and PyCLIPS is the fact that it relies on the C Foreign Function Interface for Python (CFFI) instead of using the Python C native extension APIs. This results in a much smaller code base which should make it easier to maintain the library making the transition to CLIPS 6.40...
Evaluation of CLIPS code is supported via the eval method. Python functions can be defined within a CLIPS engine with the define_function method. Example: from clips import Environment def function(arg): print("I am within a Python function, argument: %f" % arg) return arg env = Environment() env.define_function(function) ret = env.eval('(python-function function 42.2)') print("Eval returned %f" % ret) I am within a Python function, argument: 42.200000 Eval returned 42.200000
Greetings, I've been working for a while on a Python binding library for CLIPS. I started writing it few years ago to overcome a memory leak in PyCLIPS. https://github.com/noxdafox/clipspy The core difference between this library and PyCLIPS is the fact that it relies on the C Foreign Function Interface for Python (CFFI) instead of using the Python C native extension APIs. This results in a much smaller code base which should make it easier to maintain the library making the transition to CLIPS 6.40...
EnvFunctionCall crashes if no parameters are passed
It seems SF does not allow to edit a ticket and I clicked Post by mistake. The above provided code reproduces the issue. The output when run is: [INSFILE2] /tmp/test_save_instances file is not a binary instances file. Loading as binary failed with error: -1 Saved: 1 - Loaded: 0 As explained, calling EnvLoadInstances after a failing EnvBinaryLoadInstances results in 0 instances loaded.
Unable to load instances after EnvBinaryLoadInstances error
Same issue applies for other Undefine functions such as EnvUndefglobal.
EnvUndefrule segfault on undefined rule
One of the issues with the APIs is the difficulty to deal with errors. For example: is PutFactSlot returning FALSE because I am violating a deftemplate constraint or because I am setting a slot of an already asserted fact? Currently, the way I am solving it is by adding a custom router which captures the WERROR messages. The captured messages are then wrapped within a Python exception which gets raised in case of error. The process is less than ideal but works for most of the cases. In cases like...
One of the issues with the APIs is the difficulty to deal with errors. For example: is PutFactSlot returning FALSE because I am violating a deftemplate constraint or because I am setting a slot of an already asserted fact? Currently, the way I am solving it is by adding a custom router which captures the WERROR messages. The captured messages are then wrapped within a Python exception which gets raised in case of error. The process is less than ideal but works for most of the cases. In cases like...
Thanks. I too first looked at the fact index but I noticed in CLIPS 6.30 the initial fact was created with index 0 and I wanted to avoid ambiguity. Where shall I open this reports? Do you prefer them in this section or as a SF ticket?
Thanks! Tested and working, just one note: no error gets printed on the WERROR router. The following error gets instead printed if asserting the fact as string: [CSTRNCHK1] A literal slot value found in the assert command does not match the allowed types for slot name.
Thanks!
Other related issues: EnvRetract over a non asserted fact will segfault: https://github.com/noxdafox/clips/commit/584ad7d8491dc128129a553c1da0f98d1f2fa83d EnvPutFactSlot allows to change value of already asserted facts: https://github.com/noxdafox/clips/commit/99b55d5f5b52a4d28949871fe66690356749299b
The EnvFactExistp only checks whether the given fact is a NULL pointer of has been garbage collected. Therefore, facts which have been create with EnvCreateFact but have not been asserted yet will cause EnvFactExistp to return TRUE. The following commit addresses the issue: https://github.com/noxdafox/clips/commit/2d913d93895d295873498277a972bef9f04f1fcf
I observed that facts created via EnvCreateFact and populated using EnvPutFactSlot somehow bypass the constraints set in the deftemplate. The following code snippet should fail asserting the fact but it actually successfully does. #include "clips.h" void AddExampleFact2(void *); int main() { void *theEnv; DATA_OBJECT rv; char *cs; theEnv = CreateEnvironment(); cs = "(deftemplate example (slot test (type STRING) (allowed-values \"test\")))"; EnvBuild(theEnv,cs); AddExampleFact2(theEnv); EnvEval(theEnv,"(facts)",&rv);...
I observed that facts created via EnvCreateFact and populated using EnvPutFactSlot somehow bypass the constraints set in the deftemplate. The following code snippet should fail asserting the fact but it actually successfully does. #include "clips.h" void AddExampleFact2(void *); int main() { void *theEnv; DATA_OBJECT rv; char *cs; theEnv = CreateEnvironment(); cs = "(deftemplate example (slot test (type STRING) (allowed-values \"test\")))"; EnvBuild(theEnv,cs); AddExampleFact2(theEnv); EnvEval(theEnv,"(facts)",&rv);...
Thanks. A bit unrelated question: I see that the logic seems to distinguish whether the engine is used in embedded mode or not. !CommandLineData(theEnv)->EvaluatingTopLevelCommand Is there any plan to de-couple this? I mean a core library providing the rule engine and a top layer using it to implement the CLIPS language and its REPL. That would allow several customisations and improvements such as better REPL logic (using modern terminal support for example) or the implementation of different rule...
That makes sense. Is there a programmatic way to see whether a fact (or a deftemplate) is implied or not? Right now I am using EnvFactSlotNames which is less than ideal as it requires the parsing of a Multifield (which would be empty in case of an implied fact). I could indeed test deftemplatePtr->implied but I'd rather not tamper with the internal structures either.
That makes sense. Is there a programmatic way to see whether a fact (or a deftemplate) is implied or not? Right now I am using EnvFactSlotNames which is less than Ideal as it requires the parsing of a Multifield (which would be empty in case of an implied fact). I could indeed test deftemplatePtr->implied but I'd rather not tamper with the internal structures either.
The following code snipped shows a curious behaviour. #include <stdio.h> #include <clips.h> int main() { int ret; DATA_OBJECT data; void *env = CreateEnvironment(); /* Not really relevant here */ EnvIncrementGCLocks(env); /* This call succeeds */ ret = EnvEval(env, "(time)", &data); printf("%d\n", ret); /* This call fails as no error function exists */ ret = EnvEval(env, "(error)", &data); printf("%d\n", ret); /* From now on, no more successful calls to Eval */ ret = EnvEval(env, "(time)", &data);...
Greetings, as the title says, calling the following code on the initial fact segfaults: EnvGetFactSlot(env, fact, NULL, &data); This does not happen if called on implied facts with a single element such as, for example, (foo). I could reproduce this on CLIPS 6.30.
You can check the Basic Programming Guide to see how to use the bind function. CLIPS> (bind ?x (- 3 2)) 1 CLIPS> (+ ?x 1) 2
Greetings, I took some time to add PERL regular expressions support in CLIPS 6.30. I shared the code here: https://github.com/noxdafox/clips In case there is interest to get this feature merged upstream, please let me know. I'll be glad to contribute.
Maybe worth trying using jemalloc to validate such theory? http://jemalloc.net
Greetings, I was wondering if rules inheritance would be beneficial to be added to...
What about porting FuzzyCLIPS functionalities into CLIPS? To me it makes little sense...
What porting FuzzyCLIPS functionalities into CLIPS? To me it makes little sense to...
Wrapped my head a bit around it and realised where the issue is. The rule gets evaluated...
Wrapped my head a bit around it and realised where the issue is. The rule gets evaluated...
Greetings, I was playing around the idea of building a time-aware expert system but...
Among the newest features added to CLIPS there's the possibility to retrieve the...
What would be the requirements to add such a feature? How could it be integrated...
I'm writing a user function which is supposed to return a multifield value containing...
The "quick and dirty" explanation I gave myself was that pre C89 there were no global...
The code is quite readable and well commented. If you remove all the comments, the...
I'm not very familiar with COOL. I guess custom events could just inherit from EVENT...
Something useful and quite simple to implement, would be a mechanism for handling...
Greetings, I'd like to contribute to CLIPS with some small feature. Is CLIPS opened...
Have the abovementioned feature been ever taken into consideration? How much effort...
Now that CLIPS 6.30 has been released, the natural question is: what is the direction...