diff options
Diffstat (limited to 'clips/_clips_wrap.py')
-rw-r--r-- | clips/_clips_wrap.py | 4347 |
1 files changed, 4347 insertions, 0 deletions
diff --git a/clips/_clips_wrap.py b/clips/_clips_wrap.py new file mode 100644 index 0000000..dd7217b --- /dev/null +++ b/clips/_clips_wrap.py @@ -0,0 +1,4347 @@ +# _clips_wrap.py +# higher-level interface for the _clips module + +# (c) 2002-2008 Francesco Garosi/JKS +# The author's copyright is expressed through the following notice, thus +# giving effective rights to copy and use this software to anyone, as shown +# in the license text. +# +# NOTICE: +# This software is released under the terms of the GNU Lesser General Public +# license; a copy of the text has been released with this package (see file +# _license.py, where the license text also appears), and can be found on the +# GNU web site, at the following address: +# +# http://www.gnu.org/copyleft/lesser.html +# +# Please refer to the license text for any license information. This notice +# has to be considered part of the license, and should be kept on every copy +# integral or modified, of the source files. The removal of the reference to +# the license will be considered an infringement of the license itself. + +"""\ +clips - high-level interface to the CLIPS engine module + (c) 2002-2008 Francesco Garosi/JKS +""" + +__revision__ = "$Id: _clips_wrap.py 342 2008-02-22 01:17:23Z Franz $" + +# ========================================================================== # +# imports - these are hidden to module user + +# standard imports +import sys as _sys +import os as _os + +# the low-level module +import _clips as _c + +# check Python version, and issue an exception if not supported +if _sys.version[:3] < "2.4": + raise _c.ClipsError("M99: Python 2.4 or higher required") + + +# ========================================================================== # +# globals + +# clips version is defined +CLIPS_VERSION = "%s.%s" % (_c.CLIPS_MAJOR, _c.CLIPS_MINOR) +PYCLIPS_VERSION = "%s.%s.%s.%s" % ( + _c.PYCLIPS_MAJOR, + _c.PYCLIPS_MINOR, + _c.PYCLIPS_PATCHLEVEL, + _c.PYCLIPS_INCREMENTAL) + +# bring the CLIPS exception objects at top level +ClipsError = _c.ClipsError +ClipsMemoryError = _c.ClipsMemoryError + + +# redeclare manifest constants here in order to avoid having to +# reference the ones defined in the low-level module _clips + +# These manifest constants are commented out, since the user has to rely +# on the class constructors defined below in order to build values to +# pass to the CLIPS engine. Also, these names are used to implement +# the stock class objects (see below) +##INTEGER = _c.INTEGER +##FLOAT = _c.FLOAT +##STRING = _c.STRING +##SYMBOL = _c.SYMBOL +##INSTANCE_NAME = _c.INSTANCE_NAME +##MULTIFIELD = _c.MULTIFIELD +##INSTANCE_ADDRESS = _c.INSTANCE_ADDRESS +##EXTERNAL_ADDRESS = _c.EXTERNAL_ADDRESS +##FACT_ADDRESS = _c.FACT_ADDRESS + +LOCAL_SAVE = _c.LOCAL_SAVE +VISIBLE_SAVE = _c.VISIBLE_SAVE + +WHEN_DEFINED = _c.WHEN_DEFINED +WHEN_ACTIVATED = _c.WHEN_ACTIVATED +EVERY_CYCLE = _c.EVERY_CYCLE + +NO_DEFAULT = _c.NO_DEFAULT +STATIC_DEFAULT = _c.STATIC_DEFAULT +DYNAMIC_DEFAULT = _c.DYNAMIC_DEFAULT + +DEPTH_STRATEGY = _c.DEPTH_STRATEGY +BREADTH_STRATEGY = _c.BREADTH_STRATEGY +LEX_STRATEGY = _c.LEX_STRATEGY +MEA_STRATEGY = _c.MEA_STRATEGY +COMPLEXITY_STRATEGY = _c.COMPLEXITY_STRATEGY +SIMPLICITY_STRATEGY = _c.SIMPLICITY_STRATEGY +RANDOM_STRATEGY = _c.RANDOM_STRATEGY + +CONVENIENCE_MODE = _c.CONVENIENCE_MODE +CONSERVATION_MODE = _c.CONSERVATION_MODE + +AFTER = 'after' +AROUND = 'around' +BEFORE = 'before' +PRIMARY = 'primary' + + +# ========================================================================== # +# these decorators allow to verify the types of data passed to the decorated +# functions and methods (_accepts* decorators) and to force the input types +# to some defined ones (_force* decorators) + +# verify that the types passed to the decorated functions are exactly the +# ones passed as arguments to the decorator: if not, raise an appropriate +# TypeError. If a type is specified as None, then the type in the same +# position will not be checked. If a tuple containing types is passed to +# the decorator, then the decorator will verify that the function name is +# of one of the types in the tuple. Examples: +# +# @_accepts(int, int) # will raise TypeError if either x or y is not int +# def add(x, y): +# return x + y +# +# @_accepts(int, (int, float)) # will accept if y is either int or float +# def add(x, y): +# return x + y +# +# @_accepts(None, int) # will raise if y is not int, but won't check x +# def add(x, y): +# return x + y +# +def _accepts(*types): + def _DECO(f): + def _WRAPPER(*args): + i = 0 # start counting arguments at 0 + for a in args: + t = types[i] + if t is not None: # otherwise no type checking + # please note that isinstance already accepts a tuple + if not isinstance(a, t): + if type(t) == tuple: + errorstr = \ + "one of %s expected in %s, parameter %s" \ + % (", ".join(map(lambda x: str(x)[1:-1], t)), + f.__name__, i + 1) + else: + errorstr = \ + "%s expected in %s, parameter %s" \ + % (str(t)[1:-1], f.__name__, i + 1) + raise TypeError(errorstr) + i += 1 + return f(*args) + _WRAPPER.__name__ = f.__name__ + _WRAPPER.__doc__ = f.__doc__ + return _WRAPPER + return _DECO + +# same as above, but for class methods: takes the implicit self in account +def _accepts_method(*types): + def _DECO(f): + def _WRAPPER(self, *args): + i = 0 + for a in args: + t = types[i] + if t is not None: + if not isinstance(a, t): + if type(t) == tuple: + errorstr = \ + "one of %s expected in %s, parameter %s" \ + % (", ".join(map(lambda x: str(x)[1:-1], t)), + f.__name__, i + 1) + else: + errorstr = \ + "%s expected in %s, parameter %s" \ + % (str(t)[1:-1], f.__name__, i + 1) + raise TypeError(errorstr) + i += 1 + return f(self, *args) + _WRAPPER.__name__ = f.__name__ + _WRAPPER.__doc__ = f.__doc__ + return _WRAPPER + return _DECO + + +# given a list of types to the decorator, the arguments of the decorated +# function are converted (cast) to the corresponding type in the list. If +# None is given as an argument to the decorator, in the decorated function +# the corresponding parameter is left alone. Example: +# +# @_forces(None, int) # x is left as it is, while y is converted to int +# def add(x, y): +# return x + y +# +# a dict can be specified as a conversion map: in this case the keys are +# the types that will be converted, the values are the types to convert to +# and None acts differently when used as key (in which case it converts +# every type as a last resort) or as a value (when used here there is no +# conversion). An example: +# +# @_forces(None, {float: long, long: None, None: int}) +# def add(x, y): +# return x + y +# +def _forces(*types): + def _DECO(f): + def _WRAPPER(*args): + newargs = [] + i = 0 + for a in args: + t = types[i] + # when None is used as a type to convert to, no conversion + # performed at all (the argument is left as it is) + if t is None: + newargs.append(a) + # pass a dict to perform selective conversions, where... + elif type(t) == dict: + type_a = type(a) + # ...if the type of the argument is taken into account... + if t.has_key(type_a): + conv = t[type_a] + # ...when it is not None, the argument is converted + if conv is not None: + newargs.append(conv(a)) + # ...when it is None, the argument is left as it is + else: + newargs.append(a) + # ...if no other specification was found, but there is + # None as a possible type to convert to another, then + # the argument is converted anyway (ie. None acts as a + # sink that converts any type as a last resort) + elif t.has_key(None): + newargs.append(t[None](a)) + # ...but when there is no suitable specific conversion + # and None is not given the argument is left as it is + else: + newargs.append(a) + # otherwise the argument is converted to the specified type + else: + newargs.append(t(a)) + i += 1 + return f(*newargs) + _WRAPPER.__name__ = f.__name__ + _WRAPPER.__doc__ = f.__doc__ + return _WRAPPER + return _DECO + +# same as above, but for class methods: takes the implicit self in account +def _forces_method(*types): + def _DECO(f): + def _WRAPPER(self, *args): + newargs = [] + i = 0 + for a in args: + t = types[i] + if t is None: + newargs.append(a) + elif type(t) == dict: + type_a = type(a) + if t.has_key(type_a): + conv = t[type_a] + if conv is not None: + newargs.append(conv(a)) + else: + newargs.append(a) + elif t.has_key(None): + newargs.append(t[None](a)) + else: + newargs.append(a) + else: + newargs.append(t(a)) + i += 1 + return f(self, *newargs) + _WRAPPER.__name__ = f.__name__ + _WRAPPER.__doc__ = f.__doc__ + return _WRAPPER + return _DECO + +# the decorators have underscored names, because they are too raw and too +# unspecific to the module to be used outside this scope; please note that +# the environment aware module will only have to use the method specific +# versions + + +# ========================================================================== # +# High-level classes to embed clips internal types + +# 1) numeric types +class Integer(int): + """extend an int for use with CLIPS""" + def __repr__(self): + return "<Integer %s>" % int.__repr__(self) + def __add__(self, o): + return Integer(int(self) + int(o)) + def __sub__(self, o): + return Integer(int(self) - int(o)) + def __mul__(self, o): + return Integer(int(self) * int(o)) + def __floordiv__(self, o): + return Integer(int(self) // int(o)) + def __truediv__(self, o): + return Integer(int(self) / int(o)) + def __div__(self, o): + return Integer(int(self) / int(o)) + def __mod__(self, o): + return Integer(int(self) % int(o)) + def __lshift__(self, o): + return Integer(int(self) << int(o)) + def __rshift__(self, o): + return Integer(int(self) >> int(o)) + def __and__(self, o): + return Integer(int(self) & int(o)) + def __xor__(self, o): + return Integer(int(self) ^ int(o)) + def __or__(self, o): + return Integer(int(self) | int(o)) + def __pow__(self, o, m=None): + if m is not None: + return Integer((int(self) ** int(o)) % int(m)) + return Integer(int(self) ** int(o)) + def clrepr(self): + """represent this Integer for CLIPS""" + return (_c.INTEGER, int(self)) + def clsyntax(self): + """represent this Integer as it would be in CLIPS syntax""" + return str(self) + def cltypename(self): + """name of this type in CLIPS""" + return "INTEGER" +ClipsIntegerType = type(Integer(0)) + +class Float(float): + """extend a float for use with CLIPS""" + def __repr__(self): + return "<Float %s>" % float.__repr__(self) + def __add__(self, o): + return Float(float(self) + float(o)) + def __sub__(self, o): + return Float(float(self) - float(o)) + def __mul__(self, o): + return Float(float(self) * float(o)) + def __floordiv__(self, o): + return Float(float(self) // float(o)) + def __truediv__(self, o): + return Float(float(self) / float(o)) + def __div__(self, o): + return Float(float(self) / float(o)) + def __pow__(self, o, m=None): + if m is not None: + return Float((float(self) ** float(o)) % float(m)) + return Float(float(self) ** float(o)) + def clrepr(self): + """represent this Float for CLIPS""" + return (_c.FLOAT, float(self)) + def clsyntax(self): + """represent this Float as it would be in CLIPS syntax""" + return str(self) + def cltypename(self): + """name of this type in CLIPS""" + return "FLOAT" +ClipsFloatType = type(Float(0.0)) + +# 2) string types +class String(str): + """extend a str for use with CLIPS""" + def __repr__(self): + return "<String %s>" % str.__repr__(self) + def __add__(self, o): + return String(str(self) + str(o)) + def clrepr(self): + """represent this String for CLIPS""" + return (_c.STRING, str(self)) + def clsyntax(self): + """represent this String as it would be in CLIPS syntax""" + return '"%s"' % str(self).replace("\\", "\\\\").replace('"', '\\"') + def cltypename(self): + """name of this type in CLIPS""" + return "STRING" +ClipsStringType = type(String("")) + +class Symbol(str): + """extend a str for use with CLIPS as symbol""" + def __repr__(self): + return "<Symbol %s>" % str.__repr__(self) + def __nonzero__(self): + return bool(self not in ('FALSE', 'nil', '')) + def __add__(self, o): + return Symbol(str(self) + str(o)) + def clrepr(self): + """represent this Symbol for CLIPS""" + return (_c.SYMBOL, str(self)) + def clsyntax(self): + """represent this Symbol as it would be in CLIPS syntax""" + return str(self) + def cltypename(self): + """name of this type in CLIPS""" + return "SYMBOL" +ClipsSymbolType = type(Symbol("")) + +class InstanceName(str): + """extend a str for use with CLIPS as instance name""" + def __repr__(self): + return "<InstanceName %s>" % str.__repr__(self) + def __add__(self, o): + return InstanceName(str(self) + str(o)) + def clrepr(self): + """represent this InstanceName for CLIPS""" + return (_c.INSTANCE_NAME, str(self)) + def clsyntax(self): + """represent this InstanceName as it would be in CLIPS syntax""" + return "[%s]" % str(self) + def cltypename(self): + """name of this type in CLIPS""" + return "INSTANCE-NAME" +ClipsInstanceNameType = type(InstanceName("")) + +# a Nil object that might be useful in comparisons and assignments: after +# its creation the constructor is no longer necessary and is later deleted +class NilObject(Symbol): + """represent the CLIPS nil symbol""" + __created = False + def __init__(self): + if self.__created: + raise TypeError("Nil object cannot be created") + _NilObject__created = True + def __repr__(self): + return "<Nil>" + def __str__(self): + return "nil" + def __eq__(self, o): + return o is self or o == Symbol("nil") + def __ne__(self, o): + return o is not self and o != Symbol("nil") + def __nonzero__(self): + return False + def clrepr(self): + """represent the nil symbol for CLIPS""" + return (_c.SYMBOL, "nil") + def clsyntax(self): + """represent Nil as it would be in CLIPS syntax""" + return "nil" + def cltypename(self): + """name of this type in CLIPS""" + return "SYMBOL" +Nil = NilObject() +ClipsNilType = type(Nil) +del NilObject + +# the multifield type is a little bit more complex, since a list +# can contain elements of various types: at conversion time we must +# check that all elements are suitable for building a multivalue +class Multifield(list): + """extend a list for use with CLIPS as Multifield value""" + def __repr__(self): + return "<Multifield %s>" % list.__repr__(self) + def __add__(self, o): + return Multifield(list(self) + list(o)) + def clrepr(self): + """represent this Multifield for CLIPS""" + li = [] + for x in self: + t = type(x) + if t in (ClipsIntegerType, ClipsFloatType, ClipsStringType, + ClipsSymbolType, ClipsNilType, ClipsInstanceNameType): + li.append(x.clrepr()) + elif t in (int, long): + li.append(Integer(x).clrepr()) + elif t == float: + li.append(Float(x).clrepr()) + elif t in (str, unicode): + li.append(String(x).clrepr()) + elif isinstance(x, int): + li.append(Integer(x).clrepr()) + elif isinstance(x, long): + li.append(Integer(x).clrepr()) + elif isinstance(x, float): + li.append(Float(x).clrepr()) + elif isinstance(x, str): + li.append(String(x).clrepr()) + elif isinstance(x, unicode): + li.append(String(x).clrepr()) + else: + raise TypeError( + "list element of type %s cannot be converted" % t) + return (_c.MULTIFIELD, li) + def clsyntax(self): + """represent this Multifield as it would be in CLIPS syntax""" + li = [] + for x in self: + t = type(x) + if t in (ClipsIntegerType, ClipsFloatType, ClipsStringType, + ClipsSymbolType, ClipsNilType, ClipsInstanceNameType): + li.append(x.clsyntax()) + elif t in (int, long): + li.append(Integer(x).clsyntax()) + elif t == float: + li.append(Float(x).clsyntax()) + elif t in (str, unicode): + li.append(String(x).clsyntax()) + elif isinstance(x, int): + li.append(Integer(x).clsyntax()) + elif isinstance(x, long): + li.append(Integer(x).clsyntax()) + elif isinstance(x, float): + li.append(Float(x).clsyntax()) + elif isinstance(x, str): + li.append(String(x).clsyntax()) + elif isinstance(x, unicode): + li.append(String(x).clsyntax()) + else: + raise TypeError( + "list element of type %s cannot be converted" % t) + return "(create$ %s)" % " ".join(li) # only createable via this + def cltypename(self): + """name of this type in CLIPS""" + return "MULTIFIELD" +ClipsMultifieldType = type(Multifield([])) + + +# ========================================================================== # +# NOTICE: +# as of version 1.0.6 (incremental 331) we use the special markers around +# _cl2py and _py2cl, namely #{{FUNCTION and #}} in order to publish the +# above functions to the Environment class and allow passing and returning +# Fact and Instance objects from the respective pointers +# ========================================================================== # + +# Converter from internal form (type, value) of CLIPS data to the +# wrappers provided above, in order to simplify transparent conversions +#{{FUNCTION +def _cl2py(o): + """convert a well-formed tuple to one of the CLIPS wrappers""" + if o is None: return None + elif type(o) == tuple and len(o) == 2: + if o[0] == _c.INTEGER: + return Integer(o[1]) + elif o[0] == _c.FLOAT: + return Float(o[1]) + elif o[0] == _c.STRING: + return String(o[1]) + elif o[0] == _c.INSTANCE_NAME: + return InstanceName(o[1]) + elif o[0] == _c.SYMBOL: + if o[1] == "nil": + return Nil + else: + return Symbol(o[1]) + elif o[0] == _c.INSTANCE_ADDRESS: + return Instance(o[1]) + elif o[0] == _c.FACT_ADDRESS: + return Fact(o[1]) + elif o[0] == _c.MULTIFIELD: + li = [] + for (x, v) in o[1]: + if x == _c.INTEGER: + li.append(Integer(v)) + elif x == _c.FLOAT: + li.append(Float(v)) + elif x == _c.STRING: + li.append(String(v)) + elif x == _c.SYMBOL: + li.append(Symbol(v)) + elif x == _c.INSTANCE_NAME: + li.append(InstanceName(v)) + elif x == _c.INSTANCE_ADDRESS: + li.append(Instance(v)) + elif x == _c.FACT_ADDRESS: + li.append(Fact(v)) + else: + raise TypeError("list cannot be converted") + return Multifield(li) + else: + raise TypeError("malformed tuple value") + else: + raise TypeError("wrong argument type") +#}} + +# same as above, but from Python to CLIPS +#{{FUNCTION +def _py2cl(o): + """convert Python data to a well-formed tuple""" + t1 = type(o) + if t1 in (int, long): + return (_c.INTEGER, int(o)) + elif t1 == float: + return (_c.FLOAT, float(o)) + elif t1 in (str, unicode): + return (_c.STRING, str(o)) + elif t1 in (ClipsIntegerType, ClipsFloatType, ClipsStringType, + ClipsSymbolType, ClipsInstanceNameType, ClipsNilType, + ClipsMultifieldType): + return o.clrepr() + elif t1 == Fact: + return (_c.FACT_ADDRESS, o._Fact__fact) + elif t1 == Instance: + return (_c.INSTANCE_ADDRESS, o._Instance__instance) + elif isinstance(o, int): + return (_c.INTEGER, int(o)) + elif isinstance(o, long): + return (_c.INTEGER, int(o)) + elif isinstance(o, float): + return (_c.FLOAT, float(o)) + elif isinstance(o, str): + return (_c.STRING, str(o)) + elif isinstance(o, unicode): + return (_c.STRING, str(o)) + elif t1 in (list, tuple): + li = [] + for x in o: + t0 = type(x) + if t0 in (int, long): + li.append((_c.INTEGER, int(x))) + elif t0 == float: + li.append((_c.FLOAT, float(x))) + elif t0 in (str, unicode): + li.append((_c.STRING, str(x))) + elif t0 in (ClipsIntegerType, ClipsFloatType, ClipsStringType, + ClipsSymbolType, ClipsInstanceNameType, ClipsNilType): + li.append(x.clrepr()) + elif t0 == Fact: + li.append((_c.FACT_ADDRESS, o._Fact__fact)) + elif t0 == Instance: + li.append((_c.INSTANCE_ADDRESS, o._Instance__instance)) + elif isinstance(x, int): + li.append((_c.INTEGER, int(o))) + elif isinstance(x, long): + li.append((_c.INTEGER, int(o))) + elif isinstance(x, float): + li.append((_c.FLOAT, float(o))) + elif isinstance(x, str): + li.append((_c.STRING, str(o))) + elif isinstance(x, unicode): + li.append((_c.STRING, str(o))) + else: + raise TypeError( + "list element of type %s cannot be converted" % t0) + return (_c.MULTIFIELD, li) + else: + raise TypeError("value of type %s cannot be converted" % t1) +#}} + +# convert a Python value to what the python value would be in CLIPS syntax +def _py2clsyntax(o): + """convert Python data to CLIPS syntax""" + t1 = type(o) + if t1 in (int, long): + return Integer(int(o)).clsyntax() + elif t1 == float: + return Float(o).clsyntax() + elif t1 in (str, unicode): + return String(o).clsyntax() + elif t1 in (ClipsIntegerType, ClipsFloatType, ClipsStringType, + ClipsSymbolType, ClipsInstanceNameType, ClipsNilType, + ClipsMultifieldType): + return o.clsyntax() + elif isinstance(o, int): + return Integer(int(o)).clsyntax() + elif isinstance(o, long): + return Integer(int(o)).clsyntax() + elif isinstance(o, float): + return Float(o).clsyntax() + elif isinstance(o, str): + return String(o).clsyntax() + elif t1 in (list, tuple): + li = [] + for x in o: + t0 = type(x) + if t0 in (int, long): + li.append(Integer(int(x)).clsyntax()) + elif t0 == float: + li.append(Float(x).clsyntax()) + elif t0 == str: + li.append(String(x).clsyntax()) + elif t0 in (ClipsIntegerType, ClipsFloatType, ClipsStringType, + ClipsSymbolType, ClipsInstanceNameType, ClipsNilType): + li.append(x.clsyntax()) + elif isinstance(x, int): + li.append(Integer(int(x)).clsyntax()) + elif isinstance(x, long): + li.append(Integer(int(x)).clsyntax()) + elif isinstance(x, float): + li.append(Float(x).clsyntax()) + elif isinstance(x, str): + li.append(String(x).clsyntax()) + elif isinstance(x, unicode): + li.append(String(x).clsyntax()) + else: + raise TypeError( + "list element of type %s cannot be converted" % t0) + return Multifield(li).clsyntax() + else: + raise TypeError("value of type %s cannot be converted" % t1) + + + +# ========================================================================== # +# NOTICE: +# as of version 1.0.5 (incremental 324) every class that should also appear +# in the environment-aware submodule must be surrounded by special comments, +# namely '#{{CLASS' and '#}}'; the same has to be done for functions: the +# surrounding comments in this case are '#{{FUNCTION' and '#}}'; this allows +# the setup process to be more readable and avoid certain 'tricks' +# ========================================================================== # + + +# ========================================================================== # +# 0.1) Status functions and classes - as of APG section 4.1 + +# as we did above, we group all the status functions under a class and then +# create a single instance of the class itself prohibiting further instances +#{{CLASS +class _clips_Status(object): + """object to access global status functions""" + + __created = False + + def __init__(self): + """raise an exception if an object of this type has been created""" + if(self.__created): + raise TypeError("cannot create this object twice") + self.__created = True + + def __repr__(self): + return "<Configuration Management Object>" + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle engine status") + + def __property_setFactDuplication(self, v): + _c.setFactDuplication(v) + def __property_getFactDuplication(self, v): + return bool(_c.getFactDuplication()) + FactDuplication = property( + __property_getFactDuplication, + __property_setFactDuplication, + None, "Fact duplication behaviour") + + def __property_setAutoFloatDividend(self, v): + _c.setAutoFloatDividend(v) + def __property_getAutoFloatDividend(self): + return bool(_c.getAutoFloatDividend()) + AutoFloatDividend = property( + __property_getAutoFloatDividend, + __property_setAutoFloatDividend, + None, "AutoFloatDividend behaviour") + + def __property_setDynamicConstraintChecking(self, v): + _c.setDynamicConstraintChecking(v) + def __property_getDynamicConstraintChecking(self): + return bool(_c.getDynamicConstraintChecking()) + DynamicConstraintChecking = property( + __property_getDynamicConstraintChecking, + __property_setDynamicConstraintChecking, + None, "Dynamic constraint checking behaviour") + + def __property_setSequenceOperatorRecognition(self, v): + _c.setSequenceOperatorRecognition(v) + def __property_getSequenceOperatorRecognition(self): + return bool(_c.getSequenceOperatorRecognition()) + SequenceOperatorRecognition = property( + __property_getSequenceOperatorRecognition, + __property_setSequenceOperatorRecognition, + None, "Sequence operator recognition behaviour") + + def __property_setStaticConstraintChecking(self, v): + _c.setStaticConstraintChecking(v) + def __property_getStaticConstraintChecking(self): + return bool(_c.getStaticConstraintChecking()) + StaticConstraintChecking = property( + __property_getStaticConstraintChecking, + __property_setStaticConstraintChecking, + None, "Static constraint checking behaviour") + + def __property_setIncrementalReset(self, v): + _c.setIncrementalReset(v) + def __property_getIncrementalReset(self): + return bool(_c.getIncrementalReset()) + IncrementalReset = property( + __property_getIncrementalReset, + __property_setIncrementalReset, + None, "Incremental reset behaviour") + + def __property_setResetGlobals(self, v): + _c.setResetGlobals(v) + def __property_getResetGlobals(self): + return bool(_c.getResetGlobals()) + ResetGlobals = property( + __property_getResetGlobals, + __property_setResetGlobals, + None, "ResetGlobals behaviour") + + def __property_setStrategy(self, v): + _c.setStrategy(v) + def __property_getStrategy(self): + return _c.getStrategy() + Strategy = property( + __property_getStrategy, + __property_setStrategy, + None, "strategy behaviour") + + def __property_setSalienceEvaluation(self, v): + _c.setSalienceEvaluation(v) + def __property_getSalienceEvaluation(self): + return _c.getSalienceEvaluation() + SalienceEvaluation = property( + __property_getSalienceEvaluation, + __property_setSalienceEvaluation, + None, "salience evaluation behaviour") + + def __property_setClassDefaultsMode(self, v): + _c.setClassDefaultsMode(v) + def __property_getClassDefaultsMode(self): + return _c.getClassDefaultsMode() + ClassDefaultsMode = property( + __property_getClassDefaultsMode, + __property_setClassDefaultsMode, + None, "class defaults mode") +#}} + + + +# ========================================================================== # +# 0.2) Debugging functions and classes - as of APG section 4.2 + +# we group all debugging function under a class, then we prohibit +# creation of items of that class but provide an object able to +# access debugging status and to toggle debugging features +#{{CLASS +class _clips_Debug(object): + """object to enable/disable debugging features""" + + __created = False + + def __init__(self): + """one-time initializer""" + if(self.__created): + raise TypeError("cannot create this object twice") + self.__created = True + self.__watchitems = ['facts', 'rules', 'activations', 'compilations', + 'statistics', 'globals', 'slots', 'instances', + 'messages', 'message-handlers', + 'generic-functions', 'methods', 'deffunctions',] + # the following would modify the engine status on instantiation, + # which would disallow storing current environment for swapping + ##for x in self.__watchitems: _c.unwatch(x) + ##_c.dribbleOff() + + def __repr__(self): + return "<Debug Management Object>" + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle debug status") + + def DribbleOn(self, fn): + """enable dribble on given file""" + _c.dribbleOn(fn) + def DribbleOff(self): + """turn off dribble""" + _c.dribbleOff() + def DribbleActive(self): + """tell whether or not dribble is active""" + return bool(_c.dribbleActive()) + + def __property_setFactsWatched(self, v): + if(v): + _c.watch("facts") + else: + _c.unwatch("facts") + def __property_getFactsWatched(self): + return bool(_c.getWatchItem("facts")) + FactsWatched = property(__property_getFactsWatched, + __property_setFactsWatched, + None, "Facts watch status") + + def __property_setRulesWatched(self, v): + if(v): + _c.watch("rules") + else: + _c.unwatch("rules") + def __property_getRulesWatched(self): + return bool(_c.getWatchItem("rules")) + RulesWatched = property(__property_getRulesWatched, + __property_setRulesWatched, + None, "Rules watch status") + + def __property_setActivationsWatched(self, v): + if(v): + _c.watch("activations") + else: + _c.unwatch("activations") + def __property_getActivationsWatched(self): + return bool(_c.getWatchItem("activations")) + ActivationsWatched = property(__property_getActivationsWatched, + __property_setActivationsWatched, + None, "Activations watch status") + + def __property_setCompilationsWatched(self, v): + if(v): + _c.watch("compilations") + else: + _c.unwatch("compilations") + def __property_getCompilationsWatched(self): + return bool(_c.getWatchItem("compilations")) + CompilationsWatched = property(__property_getCompilationsWatched, + __property_setCompilationsWatched, + None, "compilations watch status") + + def __property_setStatisticsWatched(self, v): + if(v): + _c.watch("statistics") + else: + _c.unwatch("statistics") + def __property_getStatisticsWatched(self): + return bool(_c.getWatchItem("statistics")) + StatisticsWatched = property(__property_getStatisticsWatched, + __property_setStatisticsWatched, + None, "statistics watch status") + + def __property_setGlobalsWatched(self, v): + if(v): + _c.watch("globals") + else: + _c.unwatch("globals") + def __property_getGlobalsWatched(self): + return bool(_c.getWatchItem("globals")) + GlobalsWatched = property(__property_getGlobalsWatched, + __property_setGlobalsWatched, + None, "Globals watch status") + + def __property_setSlotsWatched(self, v): + if(v): + _c.watch("slots") + else: + _c.unwatch("slots") + def __property_getSlotsWatched(self): + return bool(_c.getWatchItem("slots")) + SlotsWatched = property(__property_getSlotsWatched, + __property_setSlotsWatched, + None, "Slots watch status") + + def __property_setMessagesWatched(self, v): + if(v): + _c.watch("messages") + else: + _c.unwatch("messages") + def __property_getMessagesWatched(self): + return bool(_c.getWatchItem("messages")) + MessagesWatched = property(__property_getMessagesWatched, + __property_setMessagesWatched, + None, "messages watch status") + + def __property_setMessageHandlersWatched(self, v): + if(v): + _c.watch("message-handlers") + else: + _c.unwatch("message-handlers") + def __property_getMessageHandlersWatched(self): + return bool(_c.getWatchItem("message-handlers")) + MessageHandlersWatched = property(__property_getMessageHandlersWatched, + __property_setMessageHandlersWatched, + None, "MessageHandlers watch status") + + def __property_setGenericFunctionsWatched(self, v): + if(v): + _c.watch("generic-functions") + else: + _c.unwatch("generic-functions") + def __property_getGenericFunctionsWatched(self): + return bool(_c.getWatchItem("generic-functions")) + GenericFunctionsWatched = property(__property_getGenericFunctionsWatched, + __property_setGenericFunctionsWatched, + None, "Generic functions watch status") + + def __property_setMethodsWatched(self, v): + if(v): + _c.watch("methods") + else: + _c.unwatch("methods") + def __property_getMethodsWatched(self): + return bool(_c.getWatchItem("methods")) + MethodsWatched = property(__property_getMethodsWatched, + __property_setMethodsWatched, + None, "Methods watch status") + + def __property_setFunctionsWatched(self, v): + if(v): + _c.watch("deffunctions") + else: + _c.unwatch("deffunctions") + def __property_getFunctionsWatched(self): + return bool(_c.getWatchItem("deffunctions")) + FunctionsWatched = property(__property_getFunctionsWatched, + __property_setFunctionsWatched, + None, "Deffunctions watch status") + + def __property_setExternalTraceback(self, v): + _c.setPrintExternalTraceback(bool(v)) + def __property_getExternalTraceback(self): + return bool(_c.getPrintExternalTraceback()) + ExternalTraceback = property(__property_getExternalTraceback, + __property_setExternalTraceback, + None, + "traceback of Python functions in CLIPS") + + def WatchAll(self): + """watch all items""" + for x in self.__watchitems: + _c.watch(x) + def UnwatchAll(self): + """unwatch all items""" + for x in self.__watchitems: + _c.unwatch(x) +#}} + + + +# ========================================================================== # +# High-level class for deftemplate objects +# Treat a deftemplate as an object having an Object-Oriented interface. +# Implements all the functions needed to access deftemplate objects. +#{{CLASS +class Template(object): + """high-level Template class (represents: deftemplate)""" + + def __init__(self, o=None): + """create a Template object (internal)""" + if _c.isDeftemplate(o): + self.__deftemplate = o + else: + raise _c.ClipsError("M01: cannot directly create Template") + + class __template_Slots: + """define a structure for Class Slots""" + def __init__(self, o): + self.__deftemplate = o + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle template slots") + + @_accepts_method((str, unicode)) + @_forces_method(str) + def AllowedValues(self, name): + """return allowed values for specified Slot""" + rv = _cl2py( + _c.deftemplateSlotAllowedValues(self.__deftemplate, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def Cardinality(self, name): + """return cardinality for specified Slot""" + rv = _cl2py( + _c.deftemplateSlotCardinality(self.__deftemplate, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def HasDefault(self, name): + """one of NO_DEFAULT, STATIC_DEFAULT or DYNAMIC_DEFAULT""" + return _c.deftemplateSlotDefaultP(self.__deftemplate, name) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def DefaultValue(self, name): + """return default value for specified Slot""" + rv = _cl2py( + _c.deftemplateSlotDefaultValue(self.__deftemplate, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def Exists(self, name): + """return True if specified Slot exists""" + return bool( + _c.deftemplateSlotExistP(self.__deftemplate, name)) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def IsMultifield(self, name): + """return True if specified Slot is a multifield one""" + return bool( + _c.deftemplateSlotMultiP(self.__deftemplate, name)) + + def Names(self): + """return the list of Slot names""" + rv = _cl2py(_c.deftemplateSlotNames(self.__deftemplate)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def Range(self, name): + """return numeric range information of specified Slot""" + rv = _cl2py(_c.deftemplateSlotRange(self.__deftemplate, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def IsSinglefield(self, name): + """return True if specified Slot is a single field one""" + return bool( + _c.deftemplateSlotSingleP(self.__deftemplate, name)) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def Types(self, name): + """return names of primitive types for specified Slot""" + rv = _cl2py(_c.deftemplateSlotTypes(self.__deftemplate, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + self.__Slots = __template_Slots(self.__deftemplate) + try: + self.__Slots._template_Slots__env = self.__env + except AttributeError: pass + try: + self.__Slots._template_Slots__envobject = self.__envobject + except AttributeError: pass + + def __str__(self): + """string form of Template""" + return _c.getDeftemplateName(self.__deftemplate) + + def __repr__(self): + """representation of Template""" + s = repr(self.__deftemplate)[1:-1] + return "<Template '%s': %s>" % ( + _c.getDeftemplateName(self.__deftemplate), s) + + def __getstate__(self): + raise _c.ClipsError( + "M03: cannot pickle objects of type '%s'" + % self.__class__.__name__) + + # Interface + def Next(self): + """return next Template""" + o = _c.getNextDeftemplate(self.__deftemplate) + if(o): + return Template(o) + else: + return None + + def PPForm(self): + """return the pretty-print form of Template""" + return _c.getDeftemplatePPForm(self.__deftemplate) + + def Remove(self): + """remove Template""" + _c.undeftemplate(self.__deftemplate) + + def BuildFact(self): + """create a fact from this Template without asserting it""" + return Fact(self.__deftemplate) + + def InitialFact(self): + """find initial Fact for this Template""" + return Fact(_c.getNextFactInTemplate(self.__deftemplate)) + + def NextFact(self, fact): + """find initial Fact for this Template""" + return Fact( + _c.getNextFactInTemplate(self.__deftemplate, fact._Fact__fact)) + + def __property_getDeletable(self): + return bool(_c.isDeftemplateDeletable(self.__deftemplate)) + Deletable = property(__property_getDeletable, None, None, + "verify if this Template can be deleted") + + def __property_getName(self): + return Symbol(_c.getDeftemplateName(self.__deftemplate)) + Name = property(__property_getName, None, None, "retrieve Template name") + + def __property_getModule(self): + return Symbol(_c.deftemplateModule(self.__deftemplate)) + Module = property(__property_getModule, None, None, + "retrieve Template Module name") + + # access class slots through the internal object + def __property_getSlots(self): return self.__Slots + Slots = property(__property_getSlots, None, None, + "Template Slots information") + + # debugging functions and properties + def __property_setWatch(self, v): + _c.setDeftemplateWatch(v, self.__deftemplate) + def __property_getWatch(self): + return _c.getDeftemplateWatch(self.__deftemplate) + Watch = property(__property_getWatch, __property_setWatch, + None, "watch status of this Template") +#}} + + + +# ========================================================================== # +# High-level class for fact objects +# Treat a fact as an object having an Object-Oriented interface. All functions +# that normally refer to a fact use the underlying low-level fact object to +# interact with the system. +#{{CLASS +class Fact(object): + """high-level Fact class (represents: fact)""" + + # class constructor - we want to initialize the fact in several ways, ie. + # by creation (using a Template or its underlying __deftemplate), by + # copy (using a Fact or its underlying __fact), or by assertion using a + # string; besides this, we also want to initialize some internal structs + # that help use the fact "the Python way" (eg. the fact slots should be + # grouped in a string-addressed dictionary, as it would naturally be) + def __init__(self, o): + """create a Fact object""" + # this on-the-fly class takes the underlying fact object, which + # should already exist, and accesses its slots through the functions + # provided by the low-level module, thus exposing a dictionary-like + # interface that can be used to access slots at high level + # NOTE: there is a hack that allows the environment version to work + # by trying to access the underlying environment object + class __fact_Slots: + """access fact Slots""" + def __init__(self, fo): + self.__fact = fo + + @_accepts_method((str, unicode), None) + @_forces_method(str, None) + def __setitem__(self, name, v): + _c.putFactSlot(self.__fact, name, _py2cl(v)) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def __getitem__(self, name): + if not name: + return _cl2py(_c.getFactSlot(self.__fact)) + else: + return _cl2py(_c.getFactSlot(self.__fact, name)) + + def keys(self): + return _cl2py(_c.factSlotNames(self.__fact)) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def has_key(self, k): + return k in map(str, _cl2py(_c.factSlotNames(self.__fact))) + + def __repr__(self): + return "<Fact '%s' Slots>" \ + % _c.getFactPPForm(self.__fact).split()[0] + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle fact slots") + + # now we can instance an object of this kind, and throw the class + # away; however the instance must be created at the end of function + # body since the fact has to be created at lower level + if _c.isFact(o): + self.__fact = o + elif '_Fact__fact' in dir(o) and _c.isFact(o.__fact): + self.__fact = o.__fact + elif _c.isDeftemplate(o): + self.__fact = _c.createFact(o) + elif '_Template__deftemplate' in dir(o) and \ + _c.isDeftemplate(o._Template__deftemplate): + self.__fact = _c.createFact(o._Template__deftemplate) + elif type(o) == str: + try: + self.__fact = _c.assertString(o) + except: + raise ValueError("invalid assertion string") + else: + raise TypeError("argument should be Fact, Template or str") + # here the fact is created: we create an instance of it and do not + # care about internal class definition destiny, since it's useful + # that this class definition disappears from Fact dictionary + self.__Slots = __fact_Slots(self.__fact) + try: + self.__Slots._fact_Slots__env = self.__env + except AttributeError: pass + try: + self.__Slots._fact_Slots__envobject = self.__envobject + except AttributeError: pass + + def __str__(self): + """string form of Fact""" + return _c.getFactPPForm(self.__fact).split()[0] + + def __repr__(self): + """representation of Fact""" + s = repr(self.__fact)[1:-1] + return "<Fact '%s': %s>" % ( + _c.getFactPPForm(self.__fact).split()[0], s) + + def __getstate__(self): + raise _c.ClipsError( + "M03: cannot pickle objects of type '%s'" + % self.__class__.__name__) + + # interface + def Assert(self): + """assert this Fact""" + self.__fact = _c.assertFact(self.__fact) + + def Retract(self): + """retract this Fact""" + _c.retract(self.__fact) + + def AssignSlotDefaults(self): + """assign Fact Slot defaults""" + _c.assignFactSlotDefaults(self.__fact) + + def Next(self): + """return next Fact""" + o = _c.getNextFact(self.__fact) + if(o): + return Fact(o) + else: + return None + + def PPForm(self): + """return the pretty-print form of Fact""" + return _c.getFactPPForm(self.__fact) + + def PPrint(self, ignoredefaults=True): + """pretty-print fact, possibly including slot default values""" + _c.routerClear("temporary") + _c.ppFact(self.__fact, "temporary", ignoredefaults) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + def CleanPPForm(self): + """return the pretty-print form of Fact""" + return _c.getFactPPForm(self.__fact).split(None, 1)[1].strip() + + # return the relation field + def __property_getRelation(self): + return Symbol( + _c.getFactPPForm(self.__fact).split( + None, 1)[1].strip()[1:-1].split(None, 1)[0]) + Relation = property(__property_getRelation, None, None, + "fact relation symbol") + + # the list of implied slots + def __property_getImpliedSlots(self): + try: + mli = _cl2py(_c.getFactSlot(self.__fact)) + except: + mli = Multifield([]) + return mli + ImpliedSlots = property(__property_getImpliedSlots, None, None, + "list of implied Slots") + + # access fact index, read only property + def __property_getIndex(self): + return _c.factIndex(self.__fact) + Index = property(__property_getIndex, None, None, "index of this Fact") + + # access fact slots through the internal object + def __property_getSlots(self): + return self.__Slots + Slots = property(__property_getSlots, None, None, + """Fact Slots dictionary""") + + # access Template of this Fact, read only property + def __property_getTemplate(self): + return Template(_c.factDeftemplate(self.__fact)) + Template = property(__property_getTemplate, None, None, + """Template for this Fact""") + + # tell whether or not this Fact has been retracted (if asserted) + def __property_getExists(self): + return bool(_c.factExistp(self.__fact)) + Exists = property(__property_getExists, None, None, + "determine if Fact has been asserted and not retracted") +#}} + + + +# ========================================================================== # +# High-level class for deffacts objects +# Treat a deffacts as an object having an Object-Oriented interface. +# Implements all the functions needed to access deffacts objects. +#{{CLASS +class Deffacts(object): + """high-level Deffacts class (represents: deffacts)""" + + def __init__(self, o): + """create a Deffacts object (internal)""" + if _c.isDeffacts(o): + self.__deffacts = o + else: + raise _c.ClipsError("M01: cannot directly create Deffacts") + + def __str__(self): + """string form of Deffacts""" + return _c.getDeffactsName(self.__deffacts) + + def __repr__(self): + """representation of Deffacts""" + s = repr(self.__deffacts)[1:-1] + return "<Deffacts '%s': %s>" % ( + _c.getDeffactsName(self.__deffacts), s) + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle objects of type '%s'" + % self.__class__.__name__) + + # Interface + def Next(self): + """return next Deffacts""" + o = _c.getNextDeffacts(self.__deffacts) + if(o): + return Deffacts(o) + else: + return None + + def PPForm(self): + """return the pretty-print form of Deffacts""" + return _c.getDeffactsPPForm(self.__deffacts) + + def Remove(self): + """remove Deffacts""" + _c.undeffacts(self.__deffacts) + + def __property_getName(self): + return Symbol(_c.getDeffactsName(self.__deffacts)) + Name = property(__property_getName, None, None, "retrieve Deffacts name") + + def __property_getModule(self): + return Symbol(_c.deffactsModule(self.__deffacts)) + Module = property(__property_getModule, None, None, + "retrieve Deffacts Module name") + + def __property_getDeletable(self): + return bool(_c.isDeffactsDeletable(self.__deffacts)) + Deletable = property(__property_getDeletable, None, None, + "verify if this Deffacts can be deleted") +#}} + + + +# ========================================================================== # +# High-level class for defrule objects +# Treat a defrule as an object having an Object-Oriented interface. +# Implements all the functions needed to access defrule objects. +#{{CLASS +class Rule(object): + """high-level Rule class (represents: defrule)""" + + def __init__(self, o): + """create a Rule object (internal)""" + if _c.isDefrule(o): + self.__defrule = o + else: + raise _c.ClipsError("M01: cannot directly create Rule") + + def __str__(self): + """string form of Rule""" + return _c.getDefruleName(self.__defrule) + + def __repr__(self): + """representation of Rule""" + s = repr(self.__defrule)[1:-1] + return "<Rule '%s': %s>" % ( + _c.getDefruleName(self.__defrule), s) + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle objects of type '%s'" + % self.__class__.__name__) + + # Interface + def Next(self): + """return next Rule""" + o = _c.getNextDefrule(self.__defrule) + if o: + return Rule(o) + else: + return None + + def PPForm(self): + """return the pretty-print form of Rule""" + return _c.getDefrulePPForm(self.__defrule) + + def Refresh(self): + """refresh Rule""" + _c.refresh(self.__defrule) + + def PrintMatches(self): + """print partial matches to standard output""" + _c.routerClear("temporary") + _c.matches("temporary", self.__defrule) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + def Remove(self): + """remove Rule""" + _c.undefrule(self.__defrule) + + def __property_getName(self): + return Symbol(_c.getDefruleName(self.__defrule)) + Name = property(__property_getName, None, None, "retrieve Rule name") + + def __property_getModule(self): + return Symbol(_c.defruleModule(self.__defrule)) + Module = property(__property_getModule, None, None, + "retrieve Rule Module name") + + def __property_setBreak(self, v): + if v: + _c.setBreak(self.__defrule) + else: + if _c.defruleHasBreakpoint(self.__defrule): + _c.removeBreak(self.__defrule) + def __property_getBreak(self): + return bool(_c.defruleHasBreakpoint(self.__defrule)) + Breakpoint = property(__property_getBreak, __property_setBreak, + None, "set or remove breakpoint from Rule") + + def __property_getDeletable(self): + return bool(_c.isDefruleDeletable(self.__defrule)) + Deletable = property(__property_getDeletable, None, None, + "verify if this Rule can be deleted") + + def __property_setWatchActivations(self, v): + _c.setDefruleWatchActivations(self.__defrule, v) + def __property_getWatchActivations(self): + return bool(_c.getDefruleWatchActivations(self.__defrule)) + WatchActivations = property(__property_getWatchActivations, + __property_setWatchActivations, + None, "Rule Activations debug status") + + def __property_setWatchFirings(self, v): + _c.setDefruleWatchFirings(self.__defrule, v) + def __property_getWatchFirings(self): + return bool(_c.getDefruleWatchFirings(self.__defrule)) + WatchFirings = property(__property_getWatchFirings, + __property_setWatchFirings, + None, "Rule firings debug status") +#}} + + + +# ========================================================================== # +# High-level class for activation objects +# Treat an activation as an object having an Object-Oriented interface. +# Implements all the functions needed to access activation objects. +#{{CLASS +class Activation(object): + """high-level Activation class (represents: activation)""" + + def __init__(self, o): + """create an Activation object (internal)""" + if _c.isActivation(o): + self.__activation = o + else: + raise _c.ClipsError("M01: cannot directly create Activation") + + def __str__(self): + """string form of Activation""" + return _c.getActivationName(self.__activation) + + def __repr__(self): + """representation of Activation""" + return "<Activation '%s'>" % _c.getActivationName(self.__activation) + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle objects of type '%s'" + % self.__class__.__name__) + + # Interface + def Next(self): + """return next Activation""" + o = _c.getNextActivation(self.__activation) + if o: + return Activation(o) + else: + return None + + def PPForm(self): + """return the pretty-print form of Activation""" + return _c.getActivationPPForm(self.__activation) + + def Remove(self): + """remove this Activation""" + _c.deleteActivation(self.__activation) + + def __property_getName(self): + return Symbol(_c.getActivationName(self.__activation)) + Name = property(__property_getName, None, None, + "retrieve Activation name") + + def __property_setSalience(self, v): + _c.setActivationSalience(self.__activation, v) + def __property_getSalience(self): + return _c.getActivationSalience(self.__activation) + Salience = property(__property_getSalience, __property_setSalience, + None, "retrieve Activation salience") +#}} + + + +# ========================================================================== # +# High-level class for defglobal objects +# Treat a defglobal as an object having an Object-Oriented interface. +# Implements all the functions needed to access defglobal objects. +#{{CLASS +class Global(object): + """high-level Global class (represents: defglobal)""" + + def __init__(self, o): + """create a Global object (internal)""" + if _c.isDefglobal(o): + self.__defglobal = o + else: + raise _c.ClipsError("M01: cannot directly create Global") + + def __str__(self): + """string form of Global""" + return _c.getDefglobalName(self.__defglobal) + + def __repr__(self): + """representation of Global""" + s = repr(self.__defglobal)[1:-1] + return "<Global '%s': %s>" % ( + _c.getDefglobalName(self.__defglobal), s) + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle objects of type '%s'" + % self.__class__.__name__) + + # Interface + def Next(self): + """return next Global""" + o = _c.getNextDefglobal(self.__defglobal) + if o: + return Global(o) + else: + return None + + def PPForm(self): + """return the pretty-print form of Global""" + return _c.getDefglobalPPForm(self.__defglobal) + + def ValueForm(self): + """return a 'printed' form of Global value""" + return _c.getDefglobalValueForm(self.__defglobal) + + def Remove(self): + """remove this Global""" + _c.undefglobal(self.__defglobal) + + def __property_getName(self): + return Symbol(_c.getDefglobalName(self.__defglobal)) + Name = property(__property_getName, None, None, "retrieve Global name") + + def __property_getModule(self): + return Symbol(_c.defglobalModule(self.__defglobal)) + Module = property(__property_getModule, None, None, + "retrieve Global Module name") + + def __property_setValue(self, v): + _c.setDefglobalValue(self.Name, _py2cl(v)) + def __property_getValue(self): + return _cl2py(_c.getDefglobalValue(self.Name)) + Value = property(__property_getValue, __property_setValue, + None, "set/retrieve Global value") + + def __property_getDeletable(self): + return bool(_c.isDefglobalDeletable(self.__defglobal)) + Deletable = property(__property_getDeletable, None, None, + "verify if this Global can be deleted") + + def __property_setWatch(self, v): + _c.setDefglobalWatch(v, self.__defglobal) + def __property_getWatch(self): + return _c.getDefglobalWatch(self.__defglobal) + Watch = property(__property_getWatch, __property_setWatch, + None, "set/retrieve Global debug status") +#}} + + + +# ========================================================================== # +# High-level class for deffunction objects +# Treat a deffunction as an object having an Object-Oriented interface. +# Implements all the functions needed to access deffunction objects. +#{{CLASS +class Function(object): + """high-level Function class (represents: deffunction)""" + + def __init__(self, o): + """create a Function object (internal)""" + if _c.isDeffunction(o): + self.__deffunction = o + else: + raise _c.ClipsError("M01: cannot directly create Function") + + def __str__(self): + """string form of Function""" + return _c.getDeffunctionName(self.__deffunction) + + def __repr__(self): + """representation of Function""" + s = repr(self.__deffunction)[1:-1] + return "<Function '%s': %s>" % ( + _c.getDeffunctionName(self.__deffunction), s) + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle objects of type '%s'" + % self.__class__.__name__) + + # Interface + def Next(self): + """return next Function""" + o = _c.getNextDeffunction(self.__deffunction) + if o: + return Function(o) + else: + return None + + def PPForm(self): + """return the pretty-print form of Function""" + return _c.getDeffunctionPPForm(self.__deffunction) + + def Remove(self): + """remove this Function""" + _c.undeffunction(self.__deffunction) + + def Call(self, *args): + """call this Function with given arguments""" + func = _c.getDeffunctionName(self.__deffunction) + if args: + if(len(args) == 1 and type(args[0]) == str): + sargs = args[0] + else: + li = [] + for x in args: + t1 = type(x) + if t1 in (ClipsIntegerType, ClipsFloatType, + ClipsStringType, ClipsSymbolType, ClipsNilType, + ClipsInstanceNameType, ClipsMultifieldType): + li.append(_py2clsyntax(x)) + elif t1 in (int, long): + li.append(Integer(x).clsyntax()) + elif t1 == float: + li.append(Float(x).clsyntax()) + elif t1 in (str, unicode): + li.append(String(x).clsyntax()) + elif isinstance(x, int): + li.append(Integer(x).clsyntax()) + elif isinstance(x, long): + li.append(Integer(x).clsyntax()) + elif isinstance(x, float): + li.append(Float(x).clsyntax()) + elif isinstance(x, str): + li.append(String(x).clsyntax()) + elif isinstance(x, unicode): + li.append(String(x).clsyntax()) + else: + li.append(str(x)) + sargs = " ".join(li) + return _cl2py(_c.functionCall(func, sargs)) + else: + return _cl2py(_c.functionCall(func)) + __call__ = Call + + def __property_getName(self): + return Symbol(_c.getDeffunctionName(self.__deffunction)) + Name = property(__property_getName, None, None, "retrieve Function name") + + def __property_getModule(self): + return Symbol(_c.deffunctionModule(self.__deffunction)) + Module = property(__property_getModule, None, None, + "retrieve Function Module name") + + def __property_getDeletable(self): + return bool(_c.isDeffunctionDeletable(self.__deffunction)) + Deletable = property(__property_getDeletable, None, None, + "verify if this Function can be deleted") + + def __property_setWatch(self, v): + _c.setDeffunctionWatch(v, self.__deffunction) + def __property_getWatch(self): + return bool(_c.getDeffunctionWatch(self.__deffunction)) + Watch = property(__property_getWatch, __property_setWatch, + None, "set/retrieve Function debug status") +#}} + + + +# ========================================================================== # +# High-level class for defgeneric objects +# Treat a defgeneric as an object having an Object-Oriented interface. +# Implements all the functions needed to access defgeneric objects. +#{{CLASS +class Generic(object): + """high-level Generic class (represents: defgeneric)""" + + def __init__(self, o): + """create a Generic function object (internal)""" + if _c.isDefgeneric(o): + self.__defgeneric = o + else: + raise _c.ClipsError("M01: cannot directly create Generic") + + def __str__(self): + """string form of Generic""" + return _c.getDefgenericName(self.__defgeneric) + + def __repr__(self): + """representation of Generic""" + s = repr(self.__defgeneric)[1:-1] + return "<Generic '%s': %s>" % ( + _c.getDefgenericName(self.__defgeneric), s) + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle objects of type '%s'" + % self.__class__.__name__) + + # Interface + def Next(self): + """return next Generic""" + o = _c.getNextDefgeneric(self.__defgeneric) + if o: + return Generic(o) + else: + return None + + def PPForm(self): + """return the pretty-print form of Generic""" + return _c.getDefgenericPPForm(self.__defgeneric) + + def Remove(self): + """remove this Generic""" + _c.undefgeneric(self.__defgeneric) + + def Call(self, *args): + """call this Generic with given arguments""" + func = _c.getDefgenericName(self.__defgeneric) + if args: + if(len(args) == 1 and type(args[0]) in (str, unicode)): + sargs = str(args[0]) + else: + li = [] + for x in args: + t1 = type(x) + if t1 in (ClipsIntegerType, ClipsFloatType, + ClipsStringType, ClipsSymbolType, ClipsNilType, + ClipsInstanceNameType, ClipsMultifieldType): + li.append(_py2clsyntax(x)) + elif t1 in (int, long): + li.append(Integer(int(x)).clsyntax()) + elif t1 == float: + li.append(Float(x).clsyntax()) + elif t1 in (str, unicode): + li.append(String(x).clsyntax()) + elif isinstance(x, int): + li.append(Integer(x).clsyntax()) + elif isinstance(x, long): + li.append(Integer(x).clsyntax()) + elif isinstance(x, float): + li.append(Float(x).clsyntax()) + elif isinstance(x, str): + li.append(String(x).clsyntax()) + elif isinstance(x, unicode): + li.append(String(x).clsyntax()) + else: + li.append(str(x)) + sargs = " ".join(li) + return _cl2py(_c.functionCall(func, sargs)) + else: + return _cl2py(_c.functionCall(func)) + __call__ = Call + + def __property_getName(self): + return Symbol(_c.getDefgenericName(self.__defgeneric)) + Name = property(__property_getName, None, None, "retrieve Generic name") + + def __property_getModule(self): + return Symbol(_c.defgenericModule(self.__defgeneric)) + Module = property(__property_getModule, None, None, + "retrieve Generic Module name") + + def __property_getDeletable(self): + return bool(_c.isDefgenericDeletable(self.__defgeneric)) + Deletable = property(__property_getDeletable, None, None, + "verify if this Generic can be deleted") + + def __property_setWatch(self, v): + _c.setDefgenericWatch(v, self.__defgeneric) + def __property_getWatch(self): + return bool(_c.getDefgenericWatch(self.__defgeneric)) + Watch = property(__property_getWatch, __property_setWatch, + None, "set/retrieve Generic debug status") + + # Method functions + def MethodList(self): + """return the list of Method indices for this Generic""" + o = _c.getDefmethodList(self.__defgeneric) + li, mli = Multifield(_cl2py(o)), Multifield([]) + l = len(li) / 2 + for x in range(0, l): + mli.append(li[2 * x + 1]) + return mli + + def MethodDescription(self, midx): + """return the synopsis of specified Method restrictions""" + return _c.getDefmethodDescription(midx, self.__defgeneric) + + def MethodPPForm(self, midx): + """return the pretty-print form of specified Method""" + return _c.getDefmethodPPForm(midx, self.__defgeneric) + + def MethodRestrictions(self, midx): + """return the restrictions of specified Method""" + return Multifield( + _cl2py(_c.getMethodRestrictions(midx, self.__defgeneric))) + + def InitialMethod(self): + """return the index of first Method in this Generic""" + try: + return _c.getNextDefmethod(0, self.__defgeneric) + except: + raise _c.ClipsError("M02: could not find any Method") + + def NextMethod(self, midx): + """return the index of next Method in this Generic""" + return _c.getNextDefmethod(midx, self.__defgeneric) + + def PrintMethods(self): + """print out Method list for this Generic""" + _c.routerClear("temporary") + _c.listDefmethods("temporary", self.__defgeneric) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + @_accepts_method(None, None, (int, long), None) + def AddMethod(self, restrictions, actions, midx=None, comment=None): + """Add a method to this Generic, given restrictions and actions""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + if midx: + indstr = str(midx) + else: + indstr = "" + if type(restrictions) in (tuple, list): + rstr = "" + for x in restrictions: + if type(x) not in (tuple, str, unicode): + raise TypeError("tuple or string expected as restriction") + if type(x) == str: + rstr += "(%s)" % x + elif type(x) == unicode: + rstr += "(%s)" % str(x) + else: + if len(x) < 2: + raise ValueError("tuple must be at least a pair") + v1, v2 = str(x[0]), [] + for y in range(1, len(x)): + z = x[y] + if z == str: + v2.append("STRING") + elif z == ClipsStringType: + v2.append("STRING") + elif z == ClipsSymbolType: + v2.append("SYMBOL") + elif z == ClipsInstanceNameType: + v2.append("INSTANCE-NAME") + elif z == int: + v2.append("INTEGER") + elif z == ClipsIntegerType: + v2.append("INTEGER") + elif z == float: + v2.append("FLOAT") + elif z == ClipsFloatType: + v2.append("FLOAT") + elif z == list: + v2.append("MULTIFIELD") + elif z == ClipsMultifieldType: + v2.append("MULTIFIELD") + elif type(z) == str: + v2.append(z) + elif type(z) == unicode: + v2.append(str(z)) + else: + raise TypeError("unexpected value '%s'" % z) + rstr += "(%s %s)" % (v1, " ".join(v2)) + elif type(restrictions) == str: + rstr = restrictions + else: + raise TypeError("tuple or string expected as restriction") + _c.build("(defmethod %s %s %s (%s) %s)" % ( + self.Name, indstr, cmtstr, rstr, actions)) + + def RemoveMethod(self, midx): + """remove specified Method""" + _c.undefmethod(midx, self.__defgeneric) + + # these are peculiar, since defmethods cannot be rendered as classes + def WatchMethod(self, midx): + """activate watch on specified Method""" + _c.setDefmethodWatch(True, midx, self.__defgeneric) + + def UnwatchMethod(self, midx): + """deactivate watch on specified Method""" + _c.setDefmethodWatch(False, midx, self.__defgeneric) + + def MethodWatched(self, midx): + """test whether or not specified Method is being watched""" + return bool(_c.getDefmethodWatch(midx, self.__defgeneric)) + + def MethodDeletable(self, midx): + """test whether or not specified Method can be deleted""" + return bool(_c.isDefmethodDeletable(midx, self.__defgeneric)) +#}} + + + +# ========================================================================== # +# High-level class for defclass objects +# Treat a defclass as an object having an Object-Oriented interface. +# Implements all the functions needed to access defclass objects. +#{{CLASS +class Class(object): + """high-level Class class (represents: defclass)""" + + def __init__(self, o): + """create a Class object (internal)""" + if _c.isDefclass(o): + self.__defclass = o + else: + raise _c.ClipsError("M01: cannot directly create Class") + # define a class to group slots information + # NOTE: there is a hack that allows the environment version to work + # by trying to access the underlying environment object + class __class_Slots: + """define a structure for Class Slots""" + def __init__(self, o): + self.__defclass = o + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle class slots") + + def Names(self): + """return the list of Slot names""" + rv = _cl2py(_c.classSlots(self.__defclass, 1)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + def NamesDefined(self): + """return the list of Slot names""" + rv = _cl2py(_c.classSlots(self.__defclass, 0)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def AllowedValues(self, name): + """return allowed values for specified Slot""" + rv = _cl2py(_c.slotAllowedValues(self.__defclass, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def AllowedClasses(self, name): + """return allowed classes for specified Slot""" + rv = _cl2py(_c.slotAllowedClasses(self.__defclass, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def Cardinality(self, name): + """return cardinality for specified Slot""" + rv = _cl2py(_c.slotCardinality(self.__defclass, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def DefaultValue(self, name): + """return default value for specified Slot""" + rv = _cl2py(_c.slotDefaultValue(self.__defclass, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def Facets(self, name): + """return facet values for specified Slot""" + rv = _cl2py(_c.slotFacets(self.__defclass, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def Range(self, name): + """return numeric range information of specified Slot""" + rv = _cl2py(_c.slotRange(self.__defclass, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def Sources(self, name): + """return source class names for specified Slot""" + rv = _cl2py(_c.slotSources(self.__defclass, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def Types(self, name): + """return names of primitive types for specified Slot""" + rv = _cl2py(_c.slotTypes(self.__defclass, name)) + if type(rv) in (tuple, list): + return Multifield(rv) + else: + return rv + + @_accepts_method((str, unicode)) + @_forces_method(str) + def HasDirectAccess(self, name): + """return True if specified Slot is directly accessible""" + return bool(_c.slotDirectAccessP(self.__defclass, name)) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def Exists(self, name): + """return True if specified Slot exists or is inherited""" + return bool(_c.slotExistP(self.__defclass, name, 1)) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def ExistsDefined(self, name): + """return True if specified Slot is defined in this Class""" + return bool(_c.slotExistP(self.__defclass, name, 0)) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def IsInitable(self, name): + """return True if specified Slot is initable""" + return bool(_c.slotInitableP(self.__defclass, name)) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def IsPublic(self, name): + """return True if specified Slot is public""" + return bool(_c.slotPublicP(self.__defclass, name)) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def IsWritable(self, name): + """return True if specified Slot is writable""" + return bool(_c.slotWritableP(self.__defclass, name)) + + self.__Slots = __class_Slots(self.__defclass) + # the following try/except blocks are to enable companion versions + try: + self.__Slots._class_Slots__env = self.__env + except AttributeError: pass + try: + self.__Slots._class_Slots__envobject = self.__envobject + except AttributeError: pass + + def __str__(self): + """string form of Class""" + return _c.getDefclassName(self.__defclass) + + def __repr__(self): + """representation of Class""" + s = repr(self.__defclass)[1:-1] + return "<Class '%s': %s>" % ( + _c.getDefclassName(self.__defclass), s) + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle objects of type '%s'" + % self.__class__.__name__) + + # Interface + def Next(self): + """return next Class""" + o = _c.getNextDefclass(self.__defclass) + if o: + return Class(o) + else: + return None + + def PPForm(self): + """return the pretty-print form of Class""" + return _c.getDefclassPPForm(self.__defclass) + + def Description(self): + """return a summary of Class description""" + _c.routerClear("temporary") + _c.describeClass("temporary", self.__defclass) + return _c.routerRead("temporary").strip() + + def IsSubclassOf(self, o): + """test whether this Class is a subclass of specified Class""" + return bool(_c.subclassP(self.__defclass, o.__defclass)) + + def IsSuperclassOf(self, o): + """test whether this Class is a superclass of specified Class""" + return bool(_c.superclassP(self.__defclass, o.__defclass)) + + def Subclasses(self, inherit=True): + """return the names of subclasses""" + return Multifield( + _cl2py(_c.classSubclasses(self.__defclass, inherit))) + + def Superclasses(self, inherit=True): + """return the names of superclasses""" + return Multifield( + _cl2py(_c.classSuperclasses(self.__defclass, inherit))) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def RawInstance(self, name): + """create an empty Instance of this Class with specified name""" + return Instance(_c.createRawInstance(self.__defclass, name)) + + def InitialInstance(self): + """return initial Instance of this Class""" + try: + return Instance(_c.getNextInstanceInClass(self.__defclass)) + except: + raise _c.ClipsError("M02: could not find any Instance") + + def NextInstance(self, instance): + """return next Instance of this Class""" + i = _c.getNextInstanceInClass( + self.__defclass, instance._Instance__instance) + if _c.isInstance(i): + return Instance(i) + else: + return None + + def InitialSubclassInstance(self): + """return initial instance of this Class and subclasses""" + try: + return Instance(_c.getNextInstanceInClassAndSubclasses( + self.__defclass)) + except: + raise _c.ClipsError("M02: could not find any Instance") + + def NextSubclassInstance(self, instance): + """return next instance of this Class and subclasses""" + i = _c.getNextInstanceInClassAndSubclasses( + self.__defclass, instance._Instance__instance) + if _c.isInstance(i): + return Instance(i) + else: + return None + + def Remove(self): + """remove this Class""" + _c.undefclass(self.__defclass) + + @_accepts_method((str, unicode), (str, unicode), None) + @_forces_method(str, str, None) + def BuildSubclass(self, name, text="", comment=None): + """build a subclass of this Class with specified name and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + clname = _c.getDefclassName(self.__defclass) + cltext = "(is-a %s)" % clname + text + construct = "(defclass %s %s %s)" % (name, cmtstr, cltext) + _c.build(construct) + return Class(_c.findDefclass(name)) + + @_accepts_method((str, unicode), (str, unicode)) + @_forces_method(str, str) + def BuildInstance(self, name, overrides=""): + """build an instance of this class overriding specified slots""" + clname = _c.getDefclassName(self.__defclass) + cmdstr = "(%s of %s %s)" % (name, clname, overrides) + return Instance(_c.makeInstance(cmdstr)) + + def __property_getName(self): + return Symbol(_c.getDefclassName(self.__defclass)) + Name = property(__property_getName, None, None, "retrieve Class name") + + def __property_getModule(self): + return Symbol(_c.defclassModule(self.__defclass)) + Module = property(__property_getModule, None, None, + "retrieve Class Module name") + + def __property_getDeletable(self): + return bool(_c.isDefclassDeletable(self.__defclass)) + Deletable = property(__property_getDeletable, None, None, + "verify if this Class can be deleted") + + def __property_getAbstract(self): + return bool(_c.classAbstractP(self.__defclass)) + Abstract = property(__property_getAbstract, None, None, + "verify if this Class is abstract or not") + + def __property_getReactive(self): + return bool(_c.classReactiveP(self.__defclass)) + Reactive = property(__property_getReactive, None, None, + "verify if this Class is reactive or not") + + def __property_setWatchSlots(self, v): + _c.setDefclassWatchSlots(v, self.__defclass) + def __property_getWatchSlots(self): + return bool(_c.getDefclassWatchSlots(self.__defclass)) + WatchSlots = property(__property_getWatchSlots, __property_setWatchSlots, + None, "set/retrieve Slot debug status") + + def __property_setWatchInstances(self, v): + _c.setDefclassWatchInstances(v, self.__defclass) + def __property_getWatchInstances(self): + return bool(_c.getDefclassWatchInstances(self.__defclass)) + WatchInstances = property(__property_getWatchInstances, + __property_setWatchInstances, + None, "set/retrieve Instance debug status") + + # access class slots through the internal object + def __property_getSlots(self): return self.__Slots + Slots = property(__property_getSlots, None, None, + "Class Slots information") + + # message-handler functions + @_accepts_method((str, unicode), (str, unicode), (str, unicode), None, None) + @_forces_method(str, str, str, None, None) + def AddMessageHandler(self, name, args, text, htype=PRIMARY, comment=None): + """build a MessageHandler for this class with arguments and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + htype = htype.lower() + if not htype in (AROUND, BEFORE, PRIMARY, AFTER): + raise ValueError("htype must be AROUND, BEFORE, PRIMARY or AFTER") + if type(args) in (tuple, list): + sargs = " ".join(args) + elif args is None: + sargs = "" + else: + sargs = str(args) + hclass = _c.getDefclassName(self.__defclass) + construct = "(defmessage-handler %s %s %s %s (%s) %s)" % ( + hclass, name, htype, cmtstr, sargs, text) + _c.build(construct) + return _c.findDefmessageHandler(self.__defclass, name, htype) + + @_accepts_method((str, unicode), None) + @_forces_method(str, None) + def MessageHandlerIndex(self, name, htype=PRIMARY): + """find the specified MessageHandler""" + htype = htype.lower() + if htype in (AROUND, BEFORE, PRIMARY, AFTER): + return _c.findDefmessageHandler(self.__defclass, name, htype) + else: + raise ValueError( + "htype must be in AROUND, BEFORE, PRIMARY, AFTER") + + def MessageHandlerName(self, index): + """return name of specified MessageHandler""" + return Symbol(_c.getDefmessageHandlerName(self.__defclass, index)) + + def MessageHandlerPPForm(self, index): + """return the pretty-print form of specified MessageHandler""" + return _c.getDefmessageHandlerPPForm(self.__defclass, index) + + def MessageHandlerType(self, index): + """return type of specified MessageHandler""" + return _c.getDefmessageHandlerType(self.__defclass, index) + + def MessageHandlerWatched(self, index): + """return watch status of specified MessageHandler""" + return bool(_c.getDefmessageHandlerWatch(self.__defclass, index)) + + def MessageHandlerDeletable(self, index): + """return True if specified MessageHandler can be deleted""" + return bool(_c.isDefmessageHandlerDeletable(self.__defclass, index)) + + def NextMessageHandlerIndex(self, index): + """return index of next MessageHandler wrt. specified""" + return _c.getNextDefmessageHandler(self.__defclass, index) + + def RemoveMessageHandler(self, index): + """remove the specified MessageHandler""" + return _c.undefmessageHandler(self.__defclass, index) + + def WatchMessageHandler(self, index): + """watch specified MessageHandler""" + return _c.setDefmessageHandlerWatch(True, self.__defclass, index) + + def UnwatchMessageHandler(self, index): + """unwatch specified MessageHandler""" + return _c.setDefmessageHandlerWatch(False, self.__defclass, index) + + def MessageHandlerList(self): + """return list of MessageHandler constructs of this Class""" + o = _c.getDefmessageHandlerList(self.__defclass, False) + li, rv = Multifield(_cl2py(o)), [] + l = len(li) / 3 + for x in range(0, l): + rv.append(Multifield([li[x * 3], li[x * 3 + 1], li[x * 3 + 2]])) + return Multifield(rv) + + def AllMessageHandlerList(self): + """return list of MessageHandlers of this Class and superclasses""" + o = _c.getDefmessageHandlerList(self.__defclass, True) + li, rv = Multifield(_cl2py(o)), [] + l = len(li) / 3 + for x in range(0, l): + rv.append(Multifield([li[x * 3], li[x * 3 + 1], li[x * 3 + 2]])) + return Multifield(rv) + + def PrintMessageHandlers(self): + """print list of all MessageHandlers of this Class""" + _c.routerClear("temporary") + _c.listDefmessageHandlers("temporary", self.__defclass) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + def PrintAllMessageHandlers(self): + """print list of MessageHandlers of this Class and superclasses""" + _c.routerClear("temporary") + _c.listDefmessageHandlers("temporary", self.__defclass, 1) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def PreviewSend(self, msgname): + """print list of MessageHandlers suitable for specified message""" + _c.routerClear("temporary") + _c.previewSend("temporary", self.__defclass, msgname) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + + + +# ========================================================================== # +# High-level class for instance objects +# Treat an instance as an object having an Object-Oriented interface. +# Implements all the functions needed to access instance objects. +#{{CLASS +class Instance(object): + """high-level Instance class (represents: instance)""" + + def __init__(self, o): + """create an Instance object (internal)""" + # this on-the-fly class takes the underlying instance object, which + # should already exist, and accesses its slots through the functions + # provided by the low-level module, thus exposing a dictionary-like + # interface that can be used to access slots at high level + # NOTE: there is a hack that allows the environment version to work + # by trying to access the underlying environment object + class __instance_Slots: + """access instance Slots""" + def __init__(self, io): + self.__instance = io + + @_accepts_method((str, unicode), None) + @_forces_method(str, None) + def __setitem__(self, name, v): + _c.directPutSlot(self.__instance, name, _py2cl(v)) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def __getitem__(self, name): + return _cl2py(_c.directGetSlot(self.__instance, name)) + + def keys(self): + return map( + str, list(Instance(self.__instance).Class.Slots.Names())) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def has_key(self, k): + return bool( + k in map(str, list( + Instance(self.__instance).Class.Slots.Names()))) + + def __repr__(self): + return "<Instance [%s] Slots>" \ + % _c.getInstanceName(self.__instance) + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle instance slots") + if _c.isInstance(o): self.__instance = o + else: + raise _c.ClipsError("M01: cannot directly create Instance") + self.__Slots = __instance_Slots(self.__instance) + # the following try/except blocks are to enable companion versions + try: + self.__Slots._instance_Slots__env = self.__env + except AttributeError: pass + try: + self.__Slots._instance_Slots__envobject = self.__envobject + except AttributeError: pass + + def __str__(self): + """string form of Instance""" + return _c.getInstanceName(self.__instance) + + def __repr__(self): + """representation of Instance""" + s = repr(self.__instance)[1:-1] + return "<Instance [%s]: %s>" % ( + _c.getInstanceName(self.__instance), s) + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle objects of type '%s'" + % self.__class__.__name__) + + # Interface + def Next(self): + """return next Instance""" + o = _c.getNextInstance(self.__instance) + if o: + return Instance(o) + else: + return None + + def PPForm(self): + """return the pretty-print form of Instance""" + return _c.getInstancePPForm(self.__instance) + + def IsValid(self): + """determine if this Instance is still valid""" + return bool(_c.validInstanceAddress(self.__instance)) + + def Remove(self): + """remove this Instance""" + _c.unmakeInstance(self.__instance) + + def DirectRemove(self): + """directly remove this Instance""" + _c.deleteInstance(self.__instance) + + @_accepts_method((str, unicode)) + @_forces_method(str) + def GetSlot(self, slotname): + """retrieve value of specified Slot""" + return _cl2py(_c.directGetSlot(self.__instance, slotname)) + SlotValue = GetSlot + + @_accepts_method((str, unicode), None) + @_forces_method(str, None) + def PutSlot(self, slotname, value): + """set value of specified Slot""" + _c.directPutSlot(self.__instance, slotname, _py2cl(value)) + SetSlotValue = PutSlot + + @_accepts_method((str, unicode), None) + @_forces_method(str, None) + def Send(self, msg, args=None): + """send specified message with the given arguments to Instance""" + if args is not None: + t = type(args) + if t == str: + sargs = args + elif t == unicode: + sargs = str(args) + elif isinstance(args, str): + sargs = str(args) + elif isinstance(args, unicode): + sargs = str(args) + elif t in (ClipsIntegerType, ClipsFloatType, ClipsStringType, + ClipsSymbolType, ClipsNilType, ClipsInstanceNameType, + ClipsMultifieldType): + sargs = _py2clsyntax(args) + elif t in (tuple, list): + li = [] + for x in args: + t1 = type(x) + if t1 in (ClipsIntegerType, ClipsFloatType, + ClipsStringType, ClipsSymbolType, ClipsNilType, + ClipsInstanceNameType, ClipsMultifieldType): + li.append(_py2clsyntax(x)) + elif t1 in (int, long): + li.append(Integer(int(x)).clsyntax()) + elif t1 == float: + li.append(Float(x).clsyntax()) + elif t1 in (str, unicode): + li.append(String(x).clsyntax()) + elif isinstance(x, int): + li.append(Integer(x).clsyntax()) + elif isinstance(x, long): + li.append(Integer(x).clsyntax()) + elif isinstance(x, float): + li.append(Float(x).clsyntax()) + elif isinstance(x, str): + li.append(String(x).clsyntax()) + elif isinstance(x, unicode): + li.append(String(x).clsyntax()) + else: + li.append(str(x)) + sargs = " ".join(li) + elif t in (int, long): + sargs = Integer(args).clsyntax() + elif t == float: + sargs = Float(args).clsyntax() + elif isinstance(args, str): + sargs = str(args) + elif isinstance(args, unicode): + sargs = str(args) + elif isinstance(args, int): + sargs = Integer(args).clsyntax() + elif isinstance(args, long): + sargs = Integer(args).clsyntax() + elif isinstance(args, float): + sargs = Float(args).clsyntax() + else: + sargs = str(args) + return _cl2py(_c.send(self.__instance, msg, sargs)) + else: + return _cl2py(_c.send(self.__instance, msg)) + + def __property_getName(self): + return InstanceName(_c.getInstanceName(self.__instance)) + Name = property(__property_getName, None, None, "retrieve Instance name") + + def __property_getClass(self): + return Class(_c.getInstanceClass(self.__instance)) + Class = property(__property_getClass, None, None, + "retrieve Instance class") + + # access instance slots through the internal object + def __property_getSlots(self): return self.__Slots + Slots = property(__property_getSlots, None, None, + "Instance Slots information") +#}} + + + +# ========================================================================== # +# High-level class for definstances objects +# Treat definstances as an object having an Object-Oriented interface. +# Implements all the functions needed to access definstances objects. +#{{CLASS +class Definstances(object): + """high-level Definstances class (represents: definstances)""" + + def __init__(self, o): + """create a Definstances object (internal)""" + if _c.isDefinstances(o): self.__definstances = o + else: raise _c.ClipsError("M01: cannot directly create Definstances") + + def __str__(self): + """string form of Definstances""" + return _c.getDefinstancesName(self.__definstances) + + def __repr__(self): + """representation of Definstances""" + s = repr(self.__definstances)[1:-1] + return "<Definstances '%s': %s>" % ( + _c.getDefinstancesName(self.__definstances), s) + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle objects of type '%s'" + % self.__class__.__name__) + + # Interface + def Next(self): + """return next Definstances""" + o = _c.getNextDefinstances(self.__definstances) + if o: + return Definstances(o) + else: + return None + + def PPForm(self): + """return the pretty-print form of Definstances""" + return _c.getDefinstancesPPForm(self.__definstances) + + def Remove(self): + """delete this Definstances object""" + _c.undefinstances(self.__definstances) + + def __property_getModule(self): + return Symbol(_c.definstancesModule(self.__definstances)) + Module = property(__property_getModule, None, None, + "retrieve Definstances module") + + def __property_getName(self): + return Symbol(_c.getDefinstancesName(self.__definstances)) + Name = property(__property_getName, None, None, + "retrieve Definstances name") + + def __property_getDeletable(self): + return bool(_c.isDefinstancesDeletable(self.__definstances)) + Deletable = property(__property_getDeletable, None, None, + "verify if this Definstances can be deleted") +#}} + + + +# ========================================================================== # +# High-level class for defmodule objects +# Treat a defmodule as an object having an Object-Oriented interface. +# Implements all the functions needed to access defmodule objects. +#{{CLASS +class Module(object): + """high-level Module class (represents: defmodule)""" + + def __init__(self, o): + """create a Module object (internal)""" + if _c.isDefmodule(o): + self.__defmodule = o + else: raise _c.ClipsError("M01: cannot directly create Module") + + def __str__(self): + """string form of Module""" + return _c.getDefmoduleName(self.__defmodule) + + def __repr__(self): + """representation of Module""" + s = repr(self.__defmodule)[1:-1] + return "<Module '%s': %s>" % ( + _c.getDefmoduleName(self.__defmodule), s) + + def __getstate__(self): + raise _c.ClipsError("M03: cannot pickle objects of type '%s'" + % self.__class__.__name__) + + # Interface + def Next(self): + """return next Module""" + o = _c.getNextDefmodule(self.__defmodule) + if(o): + return Module(o) + else: + return None + + def PPForm(self): + """return the pretty-print form of Module""" + return _c.getDefmodulePPForm(self.__defmodule) + + def SetCurrent(self): + """make this the current Module""" + _c.setCurrentModule(self.__defmodule) + + def SetFocus(self): + """set focus to this Module""" + _c.focus(self.__defmodule) + + def __property_getName(self): + return Symbol(_c.getDefmoduleName(self.__defmodule)) + Name = property(__property_getName, None, None, "return Module name") + + # Functions involving other entities + + # Templates + @_accepts_method((str, unicode), (str, unicode), None) + @_forces_method(str, str, None) + def BuildTemplate(self, name, text, comment=None): + """build a Template object with specified name and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + mname = self.Name + construct = "(deftemplate %s::%s %s %s)" % (mname, name, cmtstr, text) + _c.build(construct) + return Template(_c.findDeftemplate("%s::%s" % (mname, name))) + + def TemplateList(self): + """return list of Template names""" + o = _c.getDeftemplateList(self.__defmodule) + return Multifield(_cl2py(o)) + + def PrintTemplates(self): + """print Templates to standard output""" + _c.routerClear("temporary") + _c.listDeftemplates("temporary", self.__defmodule) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + # Facts + def FactList(self): + """return list of Facts in this Module""" + o, li = _c.getFactList(self.__defmodule), [] + if o is not None: + for x in o[1]: + if x[0] == _c.FACT_ADDRESS: + li.append(Fact(x[1])) + return li + + # Deffacts + @_accepts_method((str, unicode), (str, unicode), None) + @_forces_method(str, str, None) + def BuildDeffacts(self, name, text, comment=None): + """build a Deffacts object with specified name and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + mname = self.Name + construct = "(deffacts %s::%s %s %s)" % (mname, name, cmtstr, text) + _c.build(construct) + return Deffacts(_c.findDeffacts("%s::%s" % (mname, name))) + + def DeffactsList(self): + """return a list of Deffacts names in this Module""" + o = _c.getDeffactsList(self.__defmodule) + return Multifield(_cl2py(o)) + + def PrintDeffacts(self): + """print Deffacts to standard output""" + _c.routerClear("temporary") + _c.listDeffacts("temporary", self.__defmodule) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + # Rules + @_accepts_method((str, unicode), (str, unicode), (str, unicode), None) + @_forces_method(str, str, str, None) + def BuildRule(self, name, lhs, rhs, comment=None): + """build a Rule object with specified name and LHS/RHS""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + mname = self.Name + construct = "(defrule %s::%s %s %s => %s)" % ( + mname, name, cmtstr, lhs, rhs) + _c.build(construct) + return Rule(_c.findDefrule("%s::%s" % (mname, name))) + + def RuleList(self): + """return a list of Rule names in this Module""" + o = _c.getDefruleList(self.__defmodule) + return Multifield(_cl2py(o)) + + def PrintRules(self): + """print Rules to standard output""" + _c.routerClear("temporary") + _c.listDefrules("temporary", self.__defmodule) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + def PrintBreakpoints(self): + """print breakpoints to standard output""" + _c.routerClear("temporary") + _c.showBreaks("temporary", self.__defmodule) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + # Agenda + def PrintAgenda(self): + """print Agenda Rules to standard output""" + _c.routerClear("temporary") + _c.agenda("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + def RefreshAgenda(self): + """refresh Agenda for this Module""" + _c.refreshAgenda(self.__defmodule) + + def ReorderAgenda(self): + """reorder Agenda for this Module""" + _c.reorderAgenda(self.__defmodule) + + # Globals + @_accepts_method((str, unicode), None) + @_forces_method(str, None) + def BuildGlobal(self, name, value=Nil): + """build a Global variable with specified name and value""" + mname = self.Name + if type(value) in (str, ClipsStringType): + value = '"%s"' % value + construct = "(defglobal %s ?*%s* = %s)" % (mname, name, value) + _c.build(construct) + return Global(_c.findDefglobal("%s::%s" % (mname, name))) + + def GlobalList(self): + """return the list of Global variable names""" + o = _c.getDefglobalList(self.__defmodule) + return Multifield(_cl2py(o)) + + def PrintGlobals(self): + """print list of Global variables to standard output""" + _c.routerClear("temporary") + _c.listDefglobals("temporary", self.__defmodule) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + def ShowGlobals(self): + """print list of Global variables and values to standard output""" + _c.routerClear("temporary") + _c.showDefglobals("temporary", self.__defmodule) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + # Functions + @_accepts_method((str, unicode), None, (str, unicode), None) + @_forces_method(str, None, str, None) + def BuildFunction(self, name, args, text, comment=None): + """build a Function with specified name, body and arguments""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + mname = self.Name + if type(args) in (tuple, list): + args = " ".join(args) + elif args is None: + args = "" + construct = "(deffunction %s::%s %s (%s) %s)" % ( + mname, name, cmtstr, args, text) + _c.build(construct) + return Function(_c.findDeffunction("%s::%s" % (mname, name))) + + def FunctionList(self): + """return the list of Function names""" + o = _c.getDeffunctionList(self.__defmodule) + return Multifield(_cl2py(o)) + + def PrintFunctions(self): + """print list of Functions to standard output""" + _c.routerClear("temporary") + _c.listDeffunctions("temporary", self.__defmodule) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + # Generics + @_accepts_method((str, unicode), None) + @_forces_method(str, None) + def BuildGeneric(self, name, comment=None): + """build a Generic with specified name""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + mname = self.Name + construct = "(defgeneric %s::%s %s)" % (mname, name, cmtstr) + _c.build(construct) + return Generic(_c.findDefgeneric("%s::%s" % (mname, name))) + + def GenericList(self): + """return the list of Generic names""" + o = _c.getDefgenericList(self.__defmodule) + return Multifield(_cl2py(o)) + + def PrintGenerics(self): + """print list of Generics to standard output""" + _c.routerClear("temporary") + _c.listDefgenerics("temporary", self.__defmodule) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + # Classes + @_accepts_method((str, unicode), (str, unicode), None) + @_forces_method(str, str, None) + def BuildClass(self, name, text, comment=None): + """build a Class with specified name and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + mname = self.Name + construct = "(defclass %s::%s %s %s)" % (mname, name, cmtstr, text) + _c.build(construct) + return Class(_c.findDefclass("%s::%s" % (mname, name))) + + def ClassList(self): + """return the list of Class names""" + o = _c.getDefclassList(self.__defmodule) + return Multifield(_cl2py(o)) + + def PrintClasses(self): + """print list of Class to standard output""" + _c.routerClear("temporary") + _c.listDefclasses("temporary", self.__defmodule) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + # Instances + @_accepts_method((str, unicode), None, None) + @_forces_method(str, str, None) + def BuildInstance(self, name, defclass, overrides=""): + """build an Instance of given Class overriding specified Slots""" + mname = self.Name + cmdstr = "(%s::%s of %s %s)" % (mname, name, defclass, overrides) + return Instance(_c.makeInstance(cmdstr)) + + @_forces_method(str) + def PrintInstances(self, classname=None): + """print Instances to standard output""" + _c.routerClear("temporary") + if classname: + _c.instances("temporary", self.__defmodule, classname, False) + else: + _c.instances("temporary", self.__defmodule) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + @_forces_method(str) + def PrintSubclassInstances(self, classname): + """print Instances to standard output""" + _c.routerClear("temporary") + _c.instances("temporary", self.__defmodule, classname, True) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) + + # Definstances + @_accepts_method((str, unicode), (str, unicode), None) + @_forces_method(str, str, None) + def BuildDefinstances(self, name, text, comment=None): + """build a Definstances with specified name and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + mname = self.Name + construct = "(definstances %s::%s %s %s)" % ( + mname, name, cmtstr, text) + _c.build(construct) + return Definstances(_c.findDefinstances(name)) + + def DefinstancesList(self): + """retrieve list of all Definstances names""" + o = _c.getDefinstancesList(self.__defmodule) + return Multifield(_cl2py(o)) + + def PrintDefinstances(self): + """print list of all Definstances to standard output""" + _c.routerClear("temporary") + _c.listDefinstances("temporary", self.__defmodule) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + + + +# ========================================================================== # +# some toplevel functions +# ========================================================================== # + + +# ========================================================================== # +# 1) functions involving Templates + +#{{FUNCTION +def InitialTemplate(): + """return first Template in environment""" + try: + return Template(_c.getNextDeftemplate()) + except: + raise _c.ClipsError("M02: could not find any Template") +#}} + +#{{FUNCTION +def PrintTemplates(): + """print Templates to standard output""" + _c.routerClear("temporary") + _c.listDeftemplates("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + +#{{FUNCTION +def TemplateList(): + """return a list of Template names""" + o = _c.getDeftemplateList() + return Multifield(_cl2py(o)) # should be all strings +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def FindTemplate(s): + """find a Template by name""" + return Template(_c.findDeftemplate(s)) +#}} + +#{{FUNCTION +@_accepts((str, unicode), (str, unicode), None) +@_forces(str, str, None) +def BuildTemplate(name, text, comment=None): + """build a Template object with specified name and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + construct = "(deftemplate %s %s %s)" % (name, cmtstr, text) + _c.build(construct) + return Template(_c.findDeftemplate(name)) +#}} + + + +# ========================================================================== # +# 2) functions involving facts + +#{{FUNCTION +def Assert(o): + """assert a Fact from a string or constructed Fact object""" + if '_Fact__fact' in dir(o) and _c.isFact(o._Fact__fact): + return o.Assert() + elif type(o) in (str, unicode): + return Fact(_c.assertString(str(o))) + else: + raise TypeError("expected a string or a Fact") +#}} + +#{{FUNCTION +def InitialFact(): + """return first Fact in environment""" + try: + return Fact(_c.getNextFact()) + except: + raise _c.ClipsError("M02: could not find any Fact") +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def LoadFacts(filename): + """load Facts from file""" + _c.loadFacts(_os.path.normpath(filename)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def LoadFactsFromString(s): + """load Fact objects from a string""" + _c.loadFactsFromString(s) +#}} + +#{{FUNCTION +@_accepts((str, unicode), (str, unicode)) +@_forces(str, str) +def SaveFacts(filename, mode=LOCAL_SAVE): + """save current Facts to file""" + _c.saveFacts(_os.path.normpath(filename), mode) +#}} + +#{{FUNCTION +def PrintFacts(): + """print Facts to standard output""" + _c.routerClear("temporary") + _c.facts("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + +#{{FUNCTION +def FactListChanged(): + """test whether Fact list is changed since last call""" + rv = bool(_c.getFactListChanged()) + _c.setFactListChanged(False) + return rv +#}} + +#{{FUNCTION +def FactList(): + """return list of Facts in current module""" + o, li = _c.getFactList(), [] + if o is not None: + for x in o[1]: + if x[0] == _c.FACT_ADDRESS: + li.append(Fact(x[1])) + return li +#}} + + + +# ========================================================================== # +# 3) functions involving deffacts + +#{{FUNCTION +def InitialDeffacts(): + """return first Deffacts""" + try: + return Deffacts(_c.getNextDeffacts()) + except: + raise _c.ClipsError("M02: could not find any Deffacts") +#}} + +#{{FUNCTION +def DeffactsList(): + """return a list of Deffacts names in current module""" + o = _c.getDeffactsList() + return Multifield(_cl2py(o)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def FindDeffacts(s): + """find a Deffacts by name""" + try: + return Deffacts(_c.findDeffacts(s)) + except: + raise _c.ClipsError("M02: could not find Deffacts '%s'" % s) +#}} + +#{{FUNCTION +@_accepts((str, unicode), (str, unicode), None) +@_forces(str, str, None) +def BuildDeffacts(name, text, comment=None): + """build a Deffacts object with specified name and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + construct = "(deffacts %s %s %s)" % (name, cmtstr, text) + _c.build(construct) + return Deffacts(_c.findDeffacts(name)) +#}} + +#{{FUNCTION +def PrintDeffacts(): + """print Deffacts to standard output""" + _c.routerClear("temporary") + _c.listDeffacts("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + + + +# ========================================================================== # +# 4) functions involving Rules + +#{{FUNCTION +def InitialRule(): + """return first Rule""" + try: + return Rule(_c.getNextDefrule()) + except: + raise _c.ClipsError("M02: could not find any Rule") +#}} + +#{{FUNCTION +def RuleList(): + """return a list of Rule names in current module""" + o = _c.getDefruleList() + return Multifield(_cl2py(o)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def FindRule(s): + """find a Rule by name""" + try: + return Rule(_c.findDefrule(s)) + except: + raise _c.ClipsError("M02: could not find defrule '%s'" % s) +#}} + +#{{FUNCTION +@_accepts((str, unicode), (str, unicode), (str, unicode), None) +@_forces(str, str, str, None) +def BuildRule(name, lhs, rhs, comment=None): + """build a Rule object with specified name and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + construct = "(defrule %s %s %s => %s)" % (name, cmtstr, lhs, rhs) + _c.build(construct) + return Rule(_c.findDefrule(name)) +#}} + +#{{FUNCTION +def PrintRules(): + """print Rules to standard output""" + _c.routerClear("temporary") + _c.listDefrules("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + +#{{FUNCTION +def PrintBreakpoints(): + """print breakpoints to standard output""" + _c.routerClear("temporary") + _c.showBreaks("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + + + +# ========================================================================== # +# 5) functions involving Modules + +#{{FUNCTION +def InitialModule(): + """return first Module""" + try: + return Module(_c.getNextDefmodule()) + except: + raise _c.ClipsError("M02: could not find any Module") +#}} + +#{{FUNCTION +def ModuleList(): + """return the list of Module names""" + o = _c.getDefmoduleList() + return Multifield(_cl2py(o)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def FindModule(name): + """find a Module by name""" + return Module(_c.findDefmodule(name)) +#}} + +#{{FUNCTION +@_accepts((str, unicode), (str, unicode), None) +@_forces(str, str, None) +def BuildModule(name, text="", comment=None): + """build a Module with specified name and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + construct = "(defmodule %s %s %s)" % (name, cmtstr, text) + _c.build(construct) + return Module(_c.findDefmodule(name)) +#}} + +#{{FUNCTION +def PrintModules(): + """print list of Modules to standard output""" + _c.routerClear("temporary") + _c.listDefmodules("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + + + +# ========================================================================== # +# 6) functions involving defglobals + +#{{FUNCTION +def InitialGlobal(): + """return first Global variable""" + try: + return Global(_c.getNextDefglobal()) + except: + raise _c.ClipsError("M02: could not find any Global") +#}} + +#{{FUNCTION +def GlobalList(): + """return the list of Global variable names""" + o = _c.getDefglobalList() + return Multifield(_cl2py(o)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def FindGlobal(name): + """find a Global variable by name""" + return Global(_c.findDefglobal(name)) +#}} + +#{{FUNCTION +@_accepts((str, unicode), None) +@_forces(str, None) +def BuildGlobal(name, value=Nil): + """build a Global variable with specified name and body""" + if type(value) in (str, unicode, ClipsStringType): + value = '"%s"' % str(value) + construct = "(defglobal ?*%s* = %s)" % (name, value) + _c.build(construct) + return Global(_c.findDefglobal("%s" % name)) +#}} + +#{{FUNCTION +def GlobalsChanged(): + """test whether or not Global variables have changed since last call""" + rv = bool(_c.getGlobalsChanged()) + _c.setGlobalsChanged(False) + return rv +#}} + +#{{FUNCTION +def PrintGlobals(): + """print list of Global variables to standard output""" + _c.routerClear("temporary") + _c.listDefglobals("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + +#{{FUNCTION +def ShowGlobals(): + """print list of Global variables and values to standard output""" + _c.routerClear("temporary") + _c.showDefglobals("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + + + +# ========================================================================== # +# 7) functions involving Functions + +#{{FUNCTION +def InitialFunction(): + """return first Function""" + try: + return Function(_c.getNextDeffunction()) + except: + raise _c.ClipsError("M02: could not find any Function") +#}} + +#{{FUNCTION +def FunctionList(): + """return the list of Function names""" + o = _c.getDeffunctionList() + return Multifield(_cl2py(o)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def FindFunction(name): + """find a Function by name""" + return Function(_c.findDeffunction(name)) +#}} + +#{{FUNCTION +@_accepts((str, unicode), None, (str, unicode), None) +@_forces(str, None, str, None) +def BuildFunction(name, args, text, comment=None): + """build a Function with specified name, body and arguments""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + if type(args) in (tuple, list): + args = " ".join(args) + elif args is None: + args = "" + construct = "(deffunction %s %s (%s) %s)" % (name, cmtstr, args, text) + _c.build(construct) + return Function(_c.findDeffunction(name)) +#}} + +#{{FUNCTION +def PrintFunctions(): + """print list of Functions to standard output""" + _c.routerClear("temporary") + _c.listDeffunctions("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + + + +# ========================================================================== # +# 8) functions involving Generics + +#{{FUNCTION +def InitialGeneric(): + """return first Generic""" + try: + return Generic(_c.getNextDefgeneric()) + except: + raise _c.ClipsError("M02: could not find any Generic") +#}} + +#{{FUNCTION +def GenericList(): + """return the list of Generic names""" + o = _c.getDefgenericList() + return Multifield(_cl2py(o)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def FindGeneric(name): + """find a Generic by name""" + return Generic(_c.findDefgeneric(name)) +#}} + +#{{FUNCTION +@_accepts((str, unicode), None) +@_forces(str, None) +def BuildGeneric(name, comment=None): + """build a Generic with specified name and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + construct = "(defgeneric %s %s)" % (name, cmtstr) + _c.build(construct) + return Generic(_c.findDefgeneric(name)) +#}} + +#{{FUNCTION +def PrintGenerics(): + """print list of Generics to standard output""" + _c.routerClear("temporary") + _c.listDefgenerics("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + +#{{FUNCTION +def MethodList(): + """return the list of all Methods""" + o = _cl2py(_c.getDefmethodList()) + li = Multifield([]) + l = len(o) / 2 + for x in range(l): + li.append(Multifield([o[2 * x], o[2 * x + 1]])) + return li +#}} + + + +# ========================================================================== # +# 9) functions involving Classes + +#{{FUNCTION +def InitialClass(): + """retrieve first Class""" + try: + return Class(_c.getNextDefclass()) + except: + raise _c.ClipsError("M02: could not find any Class") +#}} + +#{{FUNCTION +def ClassList(): + """return the list of Class names""" + o = _c.getDefclassList() + return Multifield(_cl2py(o)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def FindClass(name): + """find a Class by name""" + return Class(_c.findDefclass(name)) +#}} + +#{{FUNCTION +@_accepts((str, unicode), (str, unicode), None) +@_forces(str, str, None) +def BuildClass(name, text, comment=None): + """build a Class with specified name and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + construct = "(defclass %s %s %s)" % (name, cmtstr, text) + _c.build(construct) + return Class(_c.findDefclass(name)) +#}} + +#{{FUNCTION +def PrintClasses(): + """print list of Classes to standard output""" + _c.routerClear("temporary") + _c.listDefclasses("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def BrowseClasses(classname): + """print list of Classes that inherit from specified one""" + _c.routerClear("temporary") + defclass = _c.findDefclass(str(classname)) + _c.browseClasses("temporary", defclass) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + +#{{FUNCTION +@_accepts((str, unicode), None, None, (str, unicode), None, None) +@_forces(str, str, None, str, None, None) +def BuildMessageHandler(name, hclass, args, text, htype=PRIMARY, comment=None): + """build a MessageHandler for specified class with arguments and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: cmtstr = "" + htype = htype.lower() + if not htype in (AROUND, BEFORE, PRIMARY, AFTER): + raise ValueError("htype must be in AROUND, BEFORE, PRIMARY, AFTER") + if type(args) in (tuple, list): + sargs = " ".join(args) + elif args is None: + sargs = "" + else: + sargs = str(args) + construct = "(defmessage-handler %s %s %s %s (%s) %s)" % ( + hclass, name, htype, cmtstr, sargs, text) + _c.build(construct) + defclass = _c.findDefclass(hclass) + return _c.findDefmessageHandler(defclass, name, htype) +#}} + +#{{FUNCTION +def MessageHandlerList(): + """return list of MessageHandler constructs""" + o = _c.getDefmessageHandlerList() + li, rv = Multifield(_cl2py(o)), [] + l = len(li) / 3 + for x in range(0, l): + rv.append(Multifield([li[x * 3], li[x * 3 + 1], li[x * 3 + 2]])) + return Multifield(rv) +#}} + +#{{FUNCTION +def PrintMessageHandlers(): + """print list of all MessageHandlers""" + _c.routerClear("temporary") + _c.listDefmessageHandlers("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + + + +# ========================================================================== # +# 10) functions involving instances + +#{{FUNCTION +def InitialInstance(): + """retrieve first Instance""" + try: + return Instance(_c.getNextInstance()) + except: + raise _c.ClipsError("M02: could not find any Instance") +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def BLoadInstances(filename): + """load Instances from binary file""" + _c.binaryLoadInstances(_os.path.normpath(filename)) +#}} + +#{{FUNCTION +@_accepts((str, unicode), None) +@_forces(str, None) +def BSaveInstances(filename, mode=LOCAL_SAVE): + """save Instances to binary file""" + _c.binarySaveInstances(_os.path.normpath(filename), mode) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def LoadInstances(filename): + """load Instances from file""" + _c.loadInstances(_os.path.normpath(filename)) +#}} + +#{{FUNCTION +@_accepts((str, unicode), None) +@_forces(str, None) +def SaveInstances(filename, mode=LOCAL_SAVE): + """save Instances to file""" + _c.saveInstances(_os.path.normpath(filename), mode) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def LoadInstancesFromString(s): + """load Instances from the specified string""" + _c.loadInstancesFromString(s) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def RestoreInstancesFromString(s): + """restore Instances from the specified string""" + _c.restoreInstancesFromString(s) +#}} + +#{{FUNCTION +def InstancesChanged(): + """test if Instances have changed since last call""" + rv = bool(_c.getInstancesChanged()) + _c.setInstancesChanged(False) + return rv +#}} + +#{{FUNCTION +@_accepts((str, unicode), None, (str, unicode)) +@_forces(str, str, str) +def BuildInstance(name, defclass, overrides=""): + """build an Instance of given class overriding specified slots""" + cmdstr = "(%s of %s %s)" % (name, str(defclass), overrides) + return Instance(_c.makeInstance(cmdstr)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def FindInstance(name): + """find an Instance in all modules (including imported)""" + return Instance(_c.findInstance(name, True)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def FindInstanceLocal(name): + """find an Instance in non imported modules""" + return Instance(_c.findInstance(name, False)) +#}} + +#{{FUNCTION +@_forces(str) +def PrintInstances(classname=None): + """print Instances to standard output""" + _c.routerClear("temporary") + if classname: + _c.instances("temporary", classname, False) + else: + _c.instances("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + +#{{FUNCTION +@_forces(str) +def PrintSubclassInstances(classname): + """print subclass Instances to standard output""" + _c.routerClear("temporary") + if classname: + _c.instances("temporary", classname, True) + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + + + +# ========================================================================== # +# 11) functions involving definstances + +#{{FUNCTION +def InitialDefinstances(): + """retrieve first Definstances""" + try: + return Definstances(_c.getNextDefinstances()) + except: + raise _c.ClipsError("M02: could not find any Definstances") +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def FindDefinstances(name): + """find Definstances by name""" + return Definstances(_c.findDefinstances(name)) +#}} + +#{{FUNCTION +@_accepts((str, unicode), (str, unicode), None) +@_forces(str, str, None) +def BuildDefinstances(name, text, comment=None): + """build a Definstances with specified name and body""" + if comment: + cmtstr = '"%s"' % str(comment).replace('"', '\\"') + else: + cmtstr = "" + construct = "(definstances %s %s %s)" % (name, cmtstr, text) + _c.build(construct) + return Definstances(_c.findDefinstances(name)) +#}} + +#{{FUNCTION +def DefinstancesList(): + """retrieve list of all Definstances names""" + o = _c.getDefinstancesList() + return Multifield(_cl2py(o)) +#}} + +#{{FUNCTION +def PrintDefinstances(): + """print list of all Definstances to standard output""" + _c.routerClear("temporary") + _c.listDefinstances("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + + + +# ========================================================================== # +# 12) Agenda functions + +#{{FUNCTION +def PrintAgenda(): + """print Agenda Rules to standard output""" + _c.routerClear("temporary") + _c.agenda("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + +#{{FUNCTION +def AgendaChanged(): + """test whether or not Agenda is changed since last call""" + rv = bool(_c.getAgendaChanged()) + _c.setAgendaChanged(False) + return rv +#}} + +#{{FUNCTION +def RefreshAgenda(): + """refresh Agenda Rules for current Module""" + _c.refreshAgenda() +#}} + +#{{FUNCTION +def ReorderAgenda(): + """reorder Agenda Rules for current Module""" + _c.reorderAgenda() +#}} + +#{{FUNCTION +def Run(limit=None): + """execute Rules up to limit (if any)""" + if limit is None: + return _c.run() + else: + return _c.run(limit) +#}} + +#{{FUNCTION +def ClearFocusStack(): + """clear focus stack""" + _c.clearFocusStack() +#}} + +#{{FUNCTION +def FocusStack(): + """return list of Module names in focus stack""" + return _cl2py(_c.getFocusStack()) +#}} + +#{{FUNCTION +def PrintFocusStack(): + """print focus stack to standard output""" + _c.routerClear("temporary") + _c.listFocusStack("temporary") + s = _c.routerRead("temporary") + if s: + _sys.stdout.write(s) +#}} + +#{{FUNCTION +def PopFocus(): + """pop focus""" + _c.popFocus() +#}} + +#{{FUNCTION +def InitialActivation(): + """return first Activation object""" + try: + return Activation(_c.getNextActivation()) + except: + raise _c.ClipsError("M02: could not find any Activation") +#}} + +#{{FUNCTION +def CurrentModule(): + """return current Module""" + return Module(_c.getCurrentModule()) +#}} + + + +# ========================================================================== # +# 13) True "current environment" functions - as of APG section 4.1 + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def BLoad(filename): + """binary load the constructs from a file""" + _c.bload(_os.path.normpath(filename)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def BSave(filename): + """binary save constructs to a file""" + _c.bsave(_os.path.normpath(filename)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def Load(filename): + """load constructs from a file""" + _c.load(_os.path.normpath(filename)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def Save(filename): + """save constructs to a file""" + _c.save(_os.path.normpath(filename)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def BatchStar(filename): + """execute commands stored in file""" + _c.batchStar(_os.path.normpath(filename)) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def Build(construct): + """build construct given in argument""" + _c.build(construct) +#}} + +#{{FUNCTION +@_accepts((str, unicode)) +@_forces(str) +def Eval(expr): + """evaluate expression passed as argument""" + return _cl2py(_c.eval(expr)) +#}} + +#{{FUNCTION +@_accepts((str, unicode), None) +@_forces(str, None) +def Call(func, args=None): + """call a function with the given argument string or tuple""" + if args is not None: + t = type(args) + if t == str: + sargs = args + if t == unicode: + sargs = str(args) + elif t in (ClipsIntegerType, ClipsFloatType, ClipsStringType, + ClipsSymbolType, ClipsNilType, ClipsInstanceNameType, + ClipsMultifieldType): + sargs = _py2clsyntax(args) + elif isinstance(args, str): + sargs = str(args) + elif isinstance(args, unicode): + sargs = str(args) + elif t in (tuple, list): + li = [] + for x in args: + t1 = type(x) + if t1 in (ClipsIntegerType, ClipsFloatType, ClipsStringType, + ClipsSymbolType, ClipsNilType, + ClipsInstanceNameType, ClipsMultifieldType): + li.append(_py2clsyntax(x)) + elif t1 in (int, long): + li.append(Integer(int(x)).clsyntax()) + elif t1 == float: + li.append(Float(x).clsyntax()) + elif t1 in (str, unicode): + li.append(String(x).clsyntax()) + elif isinstance(x, int): + li.append(Integer(x).clsyntax()) + elif isinstance(x, long): + li.append(Integer(x).clsyntax()) + elif isinstance(x, float): + li.append(Float(x).clsyntax()) + elif isinstance(x, str): + li.append(String(x).clsyntax()) + elif isinstance(x, unicode): + li.append(String(x).clsyntax()) + else: + li.append(str(x)) + sargs = " ".join(li) + elif t in (int, long): + sargs = Integer(int(args)).clsyntax() + elif t == float: + sargs = Float(args).clsyntax() + elif isinstance(args, int): + sargs = Integer(args).clsyntax() + elif isinstance(args, long): + sargs = Integer(args).clsyntax() + elif isinstance(args, float): + sargs = Float(args).clsyntax() + else: + sargs = str(args) + return _cl2py(_c.functionCall(func, sargs)) + else: + return _cl2py(_c.functionCall(func)) +#}} + +#{{FUNCTION +@_accepts((str, unicode), None) +@_forces(str, None) +def SendCommand(command, verbose=False): + """send a command to the engine as if typed at the CLIPS prompt""" + _c.sendCommand(command, verbose) +#}} + +#{{FUNCTION +def Reset(): + """reset Environment""" + _c.reset() + +# the environment-aware and toplevel versions of Clear() behave differently +# as only the toplevel version reinitializes stock classes (see below): this +# is why a check is performed to test whether or not the 'self' identifier +# is present (which only happens in the environment-aware version)#}} + +#{{FUNCTION +def Clear(): + """clear Environment""" + _c.clear() + if not 'self' in locals().keys(): + _setStockClasses() +#}} + + + + +# define the only object of the Status type and remove the class definition +EngineConfig = _clips_Status() +del _clips_Status + +# define the only object of the Debug type and remove the class definition +DebugConfig = _clips_Debug() +del _clips_Debug + + + +# the following is a mechanism to keep stock class names up to date: +# when the importing module sets this, then its dictionary is modified +# by the _setStockClasses() function directly; please note that, since +# the first time this module is imported the stock class names are +# correct, the __parent_module_dict__ should be set up after importing +__parent_module_dict__ = None +def _setParentModuleDict(d): + global __parent_module_dict__ + __parent_module_dict__ = d + + +# provide a way for Environments to do the same as they become current +def _setStockClasses(): + """reset stock classes to the ones of current Environment""" + global FLOAT_CLASS, INTEGER_CLASS, SYMBOL_CLASS, STRING_CLASS, \ + MULTIFIELD_CLASS, EXTERNAL_ADDRESS_CLASS, FACT_ADDRESS_CLASS, \ + INSTANCE_ADDRESS_CLASS, INSTANCE_NAME_CLASS, OBJECT_CLASS, \ + PRIMITIVE_CLASS, NUMBER_CLASS, LEXEME_CLASS, ADDRESS_CLASS, \ + INSTANCE_CLASS, USER_CLASS, INITIAL_OBJECT_CLASS + # the following definitions are only valid at submodule level + FLOAT_CLASS = Class(_c.findDefclass("FLOAT")) + INTEGER_CLASS = Class(_c.findDefclass("INTEGER")) + SYMBOL_CLASS = Class(_c.findDefclass("SYMBOL")) + STRING_CLASS = Class(_c.findDefclass("STRING")) + MULTIFIELD_CLASS = Class(_c.findDefclass("MULTIFIELD")) + EXTERNAL_ADDRESS_CLASS = Class(_c.findDefclass("EXTERNAL-ADDRESS")) + FACT_ADDRESS_CLASS = Class(_c.findDefclass("FACT-ADDRESS")) + INSTANCE_ADDRESS_CLASS = Class(_c.findDefclass("INSTANCE-ADDRESS")) + INSTANCE_NAME_CLASS = Class(_c.findDefclass("INSTANCE-NAME")) + OBJECT_CLASS = Class(_c.findDefclass("OBJECT")) + PRIMITIVE_CLASS = Class(_c.findDefclass("PRIMITIVE")) + NUMBER_CLASS = Class(_c.findDefclass("NUMBER")) + LEXEME_CLASS = Class(_c.findDefclass("LEXEME")) + ADDRESS_CLASS = Class(_c.findDefclass("ADDRESS")) + INSTANCE_CLASS = Class(_c.findDefclass("INSTANCE")) + USER_CLASS = Class(_c.findDefclass("USER")) + INITIAL_OBJECT_CLASS = Class(_c.findDefclass("INITIAL-OBJECT")) + # modify the importing package namespace using the provided dictionary + if __parent_module_dict__: + __parent_module_dict__['FLOAT_CLASS'] = FLOAT_CLASS + __parent_module_dict__['INTEGER_CLASS'] = INTEGER_CLASS + __parent_module_dict__['SYMBOL_CLASS'] = SYMBOL_CLASS + __parent_module_dict__['STRING_CLASS'] = STRING_CLASS + __parent_module_dict__['MULTIFIELD_CLASS'] = MULTIFIELD_CLASS + __parent_module_dict__['EXTERNAL_ADDRESS_CLASS'] = EXTERNAL_ADDRESS_CLASS + __parent_module_dict__['FACT_ADDRESS_CLASS'] = FACT_ADDRESS_CLASS + __parent_module_dict__['INSTANCE_ADDRESS_CLASS'] = INSTANCE_ADDRESS_CLASS + __parent_module_dict__['INSTANCE_NAME_CLASS'] = INSTANCE_NAME_CLASS + __parent_module_dict__['OBJECT_CLASS'] = OBJECT_CLASS + __parent_module_dict__['PRIMITIVE_CLASS'] = PRIMITIVE_CLASS + __parent_module_dict__['NUMBER_CLASS'] = NUMBER_CLASS + __parent_module_dict__['LEXEME_CLASS'] = LEXEME_CLASS + __parent_module_dict__['ADDRESS_CLASS'] = ADDRESS_CLASS + __parent_module_dict__['INSTANCE_CLASS'] = INSTANCE_CLASS + __parent_module_dict__['USER_CLASS'] = USER_CLASS + __parent_module_dict__['INITIAL_OBJECT_CLASS'] = INITIAL_OBJECT_CLASS + + + +# set up stock classes now for the module level; please notice that this only +# is useful when the module is imported directly, thus in the "import clips" +# form, as it is impossible to modify names defined in the global namespace +_setStockClasses() + + + +# ========================================================================== # +# 14) Functions and classes to access CLIPS input/output + +# the simple class to access CLIPS output +class _clips_Stream(object): + """object to access CLIPS output streams""" + + def __init__(self, stream, name=None): + """stream object constructor""" + self.__stream = stream + if name is None: + self.__name = 'Internal' + else: + self.__name = name + + def __repr__(self): + return "<%s Stream>" % self.__name + + def Read(self): + """read current output from stream""" + return _c.routerRead(self.__stream) + + +# the class to write to CLIPS standard input +class _clips_WriteStream(object): + """object to access CLIPS input streams""" + + def __init__(self, stream, name=None): + """stream object constructor""" + self.__stream = stream + if name is None: + self.__name = 'Internal' + else: + self.__name = name + + def __repr__(self): + return "<%s Stream>" % self.__name + + def Write(self, s): + """write string to stream""" + _c.routerWrite(self.__stream, str(s)) + + +# actual objects the module user can read from +StdoutStream = _clips_Stream("stdout", "General Output") +StdinStream = _clips_WriteStream("stdin", "General Input") +PromptStream = _clips_Stream("wprompt") # should not be used +DialogStream = _clips_Stream("wdialog") # should not be used +DisplayStream = _clips_Stream("wdisplay") # should not be used +ErrorStream = _clips_Stream("werror", "Error Output") +WarningStream = _clips_Stream("wwarning", "Warning Output") +TraceStream = _clips_Stream("wtrace", "Trace Output") + +# class definitions can be removed as all possible objects have been built +del _clips_Stream +del _clips_WriteStream + + + +# ========================================================================== # +# 15) Memory Management - for CLIPS gurus +class _clips_Memory(object): + """object for memory management""" + + __created = False + + def __init__(self): + """raise an exception if an object of this type has been created""" + if(_clips_Memory.__created): + raise TypeError("cannot recreate this object") + _clips_Memory.__created = True + + def __repr__(self): + return "<Memory Management Object>" + + def __property_getUsed(self): + return _c.memUsed() + Used = property(__property_getUsed, None, None, + "amount in bytes of memory used by CLIPS") + + def __property_getRequests(self): + return _c.memRequests() + Requests = property(__property_getRequests, None, None, + "number of requests for memory made by CLIPS") + + def __property_setConserve(self, v): + _c.setConserveMemory(v) + def __property_getConserve(self): + return bool(_c.getConserveMemory()) + Conserve = property(__property_getConserve, __property_setConserve, + None, "enable/disable caching of some informations") + + def __property_setPPBufferSize(self, v): + _c.setPPBufferSize(v) + def __property_getPPBufferSize(self): + return _c.getPPBufferSize() + PPBufferSize = property(__property_getPPBufferSize, + __property_setPPBufferSize, + None, "size of pretty-print buffers") + + def __property_setEnvironmentErrorsEnabled(self, v): + _c.setEnableEnvironmentFatalMessages(v) + def __property_getEnvironmentErrorsEnabled(self): + return bool(_c.getEnableEnvironmentFatalMessages()) + EnvironmentErrorsEnabled = property( + __property_getEnvironmentErrorsEnabled, + __property_setEnvironmentErrorsEnabled, + None, "whether or not fatal environment errors are printed") + + def __property_getNumberOfEnvironments(self): + return _c.getNumberOfEnvironments() + NumberOfEnvironments = property(__property_getNumberOfEnvironments, None, + None, "current number of Environments") + + def Free(self): + """free up unneeded memory""" + _c.releaseMem(False) + + +# define one only actual object of this type to access memory functions +Memory = _clips_Memory() +del _clips_Memory + + + +# ========================================================================== # +# 16) External Functions - "all sorts of new and shiny evil" +@_accepts(None, (str, unicode)) +@_forces(None, str) +def RegisterPythonFunction(func, name=None): + """register an external (Python) function to call from within CLIPS""" + def _extcall_retval(rv): + if rv is None: + return Nil.clrepr() + else: + return _py2cl(rv) + if not name: + name = func.__name__ + f = lambda *args: _extcall_retval(func(*tuple(map(_cl2py, list(args))))) + _c.addPythonFunction(name, f) + +def UnregisterPythonFunction(name): + """unregister the given Python function from CLIPS""" + if type(name) in (str, unicode): + _c.removePythonFunction(str(name)) + else: + _c.removePythonFunction(name.__name__) + +def ClearPythonFunctions(): + """unregister all Python functions from CLIPS""" + _c.clearPythonFunctions() + +# set or test whether CLIPS python calls should print a traceback or not +def ExternalTracebackEnabled(): + """return True if printing tracebacks from within CLIPS is enabled""" + return bool(_c.getPrintExternalTraceback()) +def SetExternalTraceback(enable=True): + """call with a True value to enable printing tracebacks from CLIPS""" + _c.setPrintExternalTraceback(bool(enable)) + + + +# end. |