Creating an Inference Engine Object
The engine object is your gateway into Pyke. Each engine object manages multiple knowledge bases related to accomplishing some task.
You may create multiple Pyke engines, each with it's own knowledge bases to accomplish different disconnected tasks.
When you create a Pyke engine object, Pyke scans for Pyke .kfb, .krb and .kqb source files and compiles these into .fbc pickle files, Python .py source files and .qbc pickle files, respectively.
Each time a Pyke engine object is created it checks the file modification times of the Pyke source files to see whether they need to be recompiled. If you change a Pyke source file, you may create a new Pyke engine to compile the changes and run with the new knowledge bases without having to restart your application.
Pyke also lets you zip these compiled files into Python eggs and can load the files from the egg. By including the compiled files in your application's distribution, you don't need to include your Pyke source files if you don't want to.
Once you have an engine object; generally, all of the Pyke functions that you need are provided directly by this object:
knowledge_engine.engine(*paths, **kws)
Pyke recursively searches for Pyke source files (.kfb files, .krb files, and .kqb files) starting at each source directory indicated in paths and places all of the compiled files in the associated target packages. This causes all of the knowledge bases to be loaded and made ready to activate.
Pyke source files may be spread out over multiple directories and may be compiled into one or more target packages. Multiple target packages would be used when more than one application wants to share a set of knowledge bases, perhaps adding some of its own knowledge that it compiles into its own target package.
Each path argument specifies a Pyke source directory and an optional target package. The source directories do not have to be Python package directories, but the target packages do.
The target package defaults to .compiled_krb. The leading dot (.) indicates that the compiled_krb directory will be subordinate to the lowest Python package directory on the path to the Pyke source directory. This uses Python's relative import notation, so multiple dots go up to higher directories (one per dot). If the target package does not start with a dot, it is taken to be an absolute package path and will be located using Python's sys.path like a normal Python import.
The Pyke source directory may be specified as a path (a string) or by passing a Python module. If a module is passed, its __file__ attribute is used. If the path points to a file, rather than a directory, the final filename is discarded. In the simple case, when the Pyke source files are in the same directory as the module creating the engine object, you can just pass __file__ as the sole argument.
>>> from pyke import knowledge_engine >>> my_engine = knowledge_engine.engine(__file__)Passing a package instead, this example could also be written:
>>> import doc.examples >>> my_engine = knowledge_engine.engine(doc.examples)or, you can pass a module within the desired package:
>>> from doc.examples import some_module >>> my_engine = knowledge_engine.engine(some_module)In the all three cases, the final filename is stripped from the value of the module's __file__ attribute to get the directory that the package is in. This directory will then be recursively searched for Pyke source files.
If you change some of your Pyke source files, you can create a new engine object to compile and reload the generated Python modules without restarting your program. But note that you'll need to rerun the add_universal_fact calls that you made (a reason to use .kfb files instead).
All of the compiled Python .py source files and .fbc/.qbc pickle files generated from each source directory are placed, by default, in a compiled_krb target package. You may specify a different target package for any source directory by passing that source directory along with the target package name as a 2-tuple. Thus, specifying the default target package explicitly would look like:
>>> my_engine = knowledge_engine.engine((__file__, '.compiled_krb'))You may specify the same target package for multiple source directories.
The last component of the target package will be created automatically if it does not already exist.
Note
You will probably want to add compiled_krb (or whatever you've chosen to call it) to your source code repository's list of files to ignore.
If you want to distribute your application without the knowledge bases, you can use the 2-tuple notation with None as the source directory. In this case, all of the Pyke source files must already be compiled, and Pyke will simply load these files. Also, the target package must be specified in absolute form (with no leading dots).
Finally, there are four optional keyword arguments that you may also pass to the engine constructor. These are all booleans that default to True:
- load_fb -- load fact bases
- load_fc -- load forward-chaining rules
- load_bc -- load backward-chaining rules and
- load_qb -- load question bases
These parameters must be passed as keyword parameters and let you selectively load the various kinds of compiled files.