we are new pyclips users and encounter a problem.
As our program needs to use several fact databases, we use Environment
objects (really useful for us).
Now, we want to register different python functions into these environments.
Is there a way to link a python function to a specific environment?
In fact, we would like to use a method like "RegisterPythonFunction" on
Environment object (as we did directcly on the clips module).
Vincent & Yvain
unfortunately, since the only "external" function is the one that is actually mapped to python-call in CLIPS and it's defined at PyCLIPS level (that is, its code is not bound to an environment), there is no way to selectively define Python functions for different environments. A Python function, as registered using clips.RegisterPythonFunction(), is therefore defined for all environments. As I wrote before, the actual function is the one invoked using the symbol python-call, while the name of the function is just an argument to python-call: CLIPS syntax makes it easy to read a thing like "(python-call SomeFunction a1 [...] aN)" as "call the function SomeFunction with arguments a1 ... aN": it wouldn't be easy to implement the "python-call" function at environment level, and in my opinion it would also be less useful, in many cases, to have to register a function for each environment where it has to be used.
I'll think of a workaround, though, to propose to you in order to have - for instance - a function with the same name that behaves differently in different environments: I think this would be the only reason why one would want to have the ability to register Python functions at the Environment level instead of the (global) module level! ;-)
Thanks for this well-explained response.
As you suggest, we were working on creating specific functions (for each of our separate plugins) , which are called in our specific environments through clips functions that bind on these functions.
For instance, if two plugins publish "sum" functions, it will be bind as 'sum_1' in first plugin and 'sum_2' in the second one. But in each environment (of each plugin), we define new function (environement.BuildFunction) that bind "sum" to "sum_x".
==> environment.BuildFunction( "sum", [args], "(return (python-call sum_x arg1 arg2))")
(with 'sum_x' and list of arguments that are dynamically created)
Vincent & Yvain
Would it bother you to "configure" an environment from the start in order to be able to, for instance, identify it via a global variable? It's impossible to use a CLIPS function from the engine to determine the environment where some code is run. In case you'd initialize an environment identifier (say, using a symbol or a number) it could be used for a wrapper that, when registered into CLIPS, could call different functions for different environments: since you wrap the python-call "keyword" in a CLIPS native function (using BuildFunction) it could be feasible to rewrite the latter in order to take the environment into account and call the right function...
I'll try to write an example for this, in order to eventually use it in the AQ (less than a FAQ) section.
I wrote a tutorial about this subject. You can find it at the following address:
Hope this will help,