From cf69559709cf4a533ddf737c797305314921d280 Mon Sep 17 00:00:00 2001 From: olpc user Date: Sat, 28 Apr 2012 18:36:03 +0000 Subject: Create repository and load --- diff --git a/Desktop/dzialo/paste/HelloDoctor.activity/HelloDoctor.py b/Desktop/dzialo/paste/HelloDoctor.activity/HelloDoctor.py new file mode 100755 index 0000000..49a176e --- /dev/null +++ b/Desktop/dzialo/paste/HelloDoctor.activity/HelloDoctor.py @@ -0,0 +1,298 @@ +import sys +import os +import re +from time import gmtime, strftime +import pygtk +import gtk +import clips + +import gst +import tempfile + +GST_PIPE = ['v4l2src', 'ffmpegcolorspace', 'pngenc'] + +from sugar.activity import activity +from sugar.graphics import style + +from gettext import gettext as _ + +class HelloDoctor(activity.Activity): + def __init__(self, handle): + "Entry point" + activity.Activity.__init__(self, handle) + self._name = handle + + toolbox = activity.ActivityToolbox(self) + activity_toolbar = toolbox.get_activity_toolbar() + activity_toolbar.keep.props.visible = False + activity_toolbar.share.props.visible = False + self.set_toolbox(toolbox) + + toolbox.show() + + self.set_title(_("HelloDoctor")) +# self.window.set_border_width(5) +# self.window.set_size_request(640, 480) + self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("black")) + self.settings = gtk.Settings() + self.settings.set_string_property('gtk-font-name', 'courier bold 10', '') + self.settings.set_long_property("gtk-button-images", False, "") + self._main_view = gtk.EventBox() + self._main_view.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("khaki")) + self.set_canvas(self._main_view) + self.homescreen() + + def homescreen(self, widget=None, oldcontainer=None): + homebox=gtk.VBox() + table= gtk.Table(20, 12, True) + colorbutton = gtk.ColorButton(gtk.gdk.color_parse("khaki")) + colorbutton.connect('color-set', self.set_background_color) + color = colorbutton.get_color() + title_label=gtk.Label() + labeltext_title=(_("Hello \nDoctor!")) + title_label.set_markup("%s" % (labeltext_title)) + title_button=gtk.Button() + title_button.connect("clicked", self.symptomChose, homebox, '') + title_button_img=gtk.Image() + title_button_img.set_from_file("images/interface/start_button.svg") + title_button.set_image(title_button_img) + title_image=gtk.Image() + title_image.set_from_file("images/interface/doctor.svg") + + table.attach(colorbutton, 1, 3, 15, 18) + table.attach(title_label, 0, 4, 4, 9) + table.attach(title_image, 4, 12, 0, 15) + table.attach(title_button, 7, 10, 14, 19) + + homebox.pack_start(table) + + if oldcontainer != None: + self._main_view.remove(oldcontainer) + oldcontainer.destroy() + self._main_view.add(homebox) + self._main_view.show() + self.symptomMain() + self.show_all() + + def set_background_color(self, colorbutton): + color = colorbutton.get_color() + self._main_view.modify_bg(gtk.STATE_NORMAL, color) + + def symptomMain(self): + global curr_counter_number, counter_max, list + list = [] + rulesfile = open("rules.clp", "r") + for line in rulesfile: + matched_expr = re.search(re.escape("MAIN::symptom")+"(.*?)"+re.escape(" "),line) + if matched_expr==None: + continue + toprin = matched_expr.group(1) + list.append([toprin, '']) + finiline = line.find('))') + if finiline != -1: + break + + curr_counter_number=0 + counter_max=len(list) -1 + + def symptomChose(self, widget, oldcontainer, value): + global curr_counter_number, counter_max, list + if (value == "plus"): + curr_counter_number=curr_counter_number+1 + if (value == "minus"): + curr_counter_number=curr_counter_number-1 + + symptom = list[curr_counter_number][0] + fraction = 0.05 + (curr_counter_number/(counter_max+1.0)) + + symptombox=gtk.VBox() + symptom_table= gtk.Table(20, 14, True) + + progress=gtk.ProgressBar() + progress.set_fraction(fraction) + progress.set_text("%s/%s %s" % ((curr_counter_number+1),(counter_max+1),symptom)) + symptom_image=gtk.Image() + symptom_image.set_from_file("images/symptoms/%s.svg" % (symptom)) + + button_yes=gtk.ToggleButton() + button_no=gtk.ToggleButton() + button_yes.connect("toggled", self.toggle_callback, "yes", button_no) + button_no.connect("toggled", self.toggle_callback, "no", button_yes) + if (list[curr_counter_number][1] == 'yes'): + button_yes.set_active(True) + elif (list[curr_counter_number][1] == 'no'): + button_no.set_active(True) + + but_yes_img=gtk.Image() + but_yes_img.set_from_file("images/interface/oktick.svg") + button_yes.set_image(but_yes_img) + but_no_img=gtk.Image() + but_no_img.set_from_file("images/interface/oktick.svg") + button_no.set_image(but_no_img) + + symptom_table.attach(button_yes, 3, 5, 17, 20) + symptom_table.attach(button_no, 9, 11, 17, 20) + + button_next=gtk.Button() + but_next_img=gtk.Image() + but_next_img.set_from_file("images/interface/next_but.svg") + button_next.set_image(but_next_img) + nextcon=button_next.connect("clicked", self.symptomChose, symptombox, "plus") + + if (curr_counter_number != 0): + + button_prev=gtk.Button() + but_prev_img=gtk.Image() + but_prev_img.set_from_file("images/interface/prev_but.svg") + button_prev.connect("clicked", self.symptomChose, symptombox, "minus") + button_prev.set_image(but_prev_img) + symptom_table.attach(button_prev, 0, 2, 17, 20) + if (curr_counter_number == counter_max): + button_next.disconnect(nextcon) + button_next.connect("clicked", self.finishdialog, symptombox) + + symptom_table.attach(progress, 1, 13, 0, 1) + symptom_table.attach(symptom_image, 1, 13, 1, 17) + symptom_table.attach(button_next, 12, 14, 17, 20) + + symptombox.add(symptom_table) + + print "values in symptomChose: curr: %s max: %s" % (curr_counter_number, counter_max) + + self._main_view.remove(oldcontainer) + oldcontainer.destroy() + self._main_view.add(symptombox) + self.show_all() + + def toggle_callback(self, widget, data, secondone): + global list + if (widget.get_active()): + list[curr_counter_number][1]=data + secondone.set_active(False) + + def finishdialog(self, widget, oldcontainer): + dialog = gtk.Dialog("Finish?", None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)) +# dialog.set_modal(True) +# self._main_view.set_transient_for(dialog) + dialogimage= gtk.Image() + dialogimage.set_from_file("images/interface/to_solution.svg") + dialog.vbox.pack_start(dialogimage, True, True, 0) + + button1 = gtk.Button() + dialog.action_area.pack_start(button1, True, True, 0) + + button2 = gtk.Button() + dialog.action_area.pack_start(button2, True, True, 0) + + dialogimage.show() + + dialogresult = dialog.run() + + if (dialogresult == gtk.RESPONSE_ACCEPT): + self._main_view.remove(oldcontainer) + oldcontainer.destroy() + self.solution() + dialog.destroy() + + elif (dialogresult == gtk.RESPONSE_REJECT): + dialog.destroy() + + def solution(self): + solutionbox= gtk.EventBox() + solution_hands= gtk.HBox() + solution_table= gtk.Table(20, 14, True) + solutionbox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("white")) + + patientphoto = gtk.Image() + photo = Camera() + photo.Snap() + photopath = photo.snap_path + patientpixbuf = gtk.gdk.pixbuf_new_from_file_at_size(photopath, 500, 475) + patientphoto.set_from_pixbuf(patientpixbuf) +# patientphoto.set_from_file("%s" % photopath) +# patientpixbuf = gtk.gdk.pixbuf_new_from_file_at_size(photopath, 300, 500) +# patientpixbuf.pixbuf + + logfile = open('logfile.txt', 'a') + currtime = strftime("%H:%M:%S, %d %b %Y", gmtime()) + towrite = str('---------%s---------\n' % currtime) + logfile.write(towrite) + logfile.close() + + clips.Clear() + clips.Load("rules.clp") + clips.Reset() + beginingstate= clips.FactList() + total_diseases= 0 + for bs in beginingstate: + if bs.Relation == 'disease': + total_diseases += 1 + print total_diseases + for i in list: + sym = i[0] + occ = i[1] + if occ == '': + occ = 'no' + clips.Assert("(symptom %s %s)" % (sym,occ)) + clips.Run() + result= clips.FactList() + numof_res = 0 + for f in result: + if f.Relation == 'disease': + numof_res += 1 + dis = f.CleanPPForm() + number = re.search(re.escape("(disease ")+"(.*?)"+re.escape(" "), dis) + justonedis = number.group(1) + total = map(int, justonedis) + print total + + solution_image = gtk.Image() + if numof_res == total_diseases: +# solution_image.set_from_file("%s" % photopath) + solution_image.set_from_file("images/interface/healthy.svg") + else: + solution_image.set_from_file("images/interface/to_hospital.svg") + num_label2 = gtk.Label() + if numof_res == 0: + sollab_text = '000' + elif numof_res == 1: + sollab_text = justonedis + else: + sollab_text = 'UNK' + solution_table.attach(num_label2, 4, 7, 14, 16) + num_label2.set_markup("%s" % (sollab_text)); + solution_table.attach(patientphoto, 0, 7, 1, 10) + solution_table.attach(solution_image, 2, 14, 1, 19) + + reload_button = gtk.Button() + reload_button_img = gtk.Image() +# reload_button_img.set_from_stock(gtk.STOCK_REFRESH, gtk.ICON_SIZE_BUTTON) + reload_button_img.set_from_file("images/interface/reload.svg") + reload_button.set_image(reload_button_img) + reload_button.connect("clicked", self.homescreen, solution_table) + solution_table.attach(reload_button, 12, 14, 17, 20) + + self._main_view.add(solution_table) + self.show_all() + +class Camera(object): + + """A class repre camera""" + + def __init__(self): + snap_file, self.snap_path = tempfile.mkstemp() + pipe = GST_PIPE + ['filesink location=%s' % self.snap_path] + self.pipe = gst.parse_launch('!'.join(pipe)) + self.bus = self.pipe.get_bus() + + def Snap(self): + """Take a snapshop""" + self.pipe.set_state(gst.STATE_PLAYING) + self.bus.poll(gst.MESSAGE_EOS, -1) + self.pipe.set_state(gst.STATE_NULL) + + +# if __name__ == "__main__": +# +# HelloDoctor().main() +# gtk.main() diff --git a/Desktop/dzialo/paste/HelloDoctor.activity/MANIFEST b/Desktop/dzialo/paste/HelloDoctor.activity/MANIFEST new file mode 100644 index 0000000..6985bea --- /dev/null +++ b/Desktop/dzialo/paste/HelloDoctor.activity/MANIFEST @@ -0,0 +1,49 @@ +clips +clips/_version.pyc +clips/_version.pyo +clips/_clips.py +clips/_clips.so +clips/_clips_wrap.py +clips/_license.pyc +clips/_license.pyo +clips/_eclips_wrap.py +clips/_clips.pyc +clips/__init__.py +clips/_license.py +clips/_clips_wrap.pyc +clips/_clips_wrap.pyo +clips/_version.py +clips/_eclips_wrap.pyc +clips/_eclips_wrap.pyo +clips/__init__.pyc +clips/__init__.pyo +setup.py +HelloDoctor.py +rules.clp +images +images/symptoms +images/symptoms/Haemoptysis.svg +images/symptoms/Nausea_vomiting.svg +images/symptoms/Pyrexia.svg +images/symptoms/Haematuria.svg +images/symptoms/Suppurative_otitis_media.svg +images/symptoms/Myalgia.svg +images/symptoms/Rash.svg +images/symptoms/Diarrhoea.svg +images/symptoms/Acute_confusional_state.svg +images/symptoms/Conjunctivitis.svg +images/interface +images/interface/next_but.svg +images/interface/reload2.svg +images/interface/oktick.svg +images/interface/prev_but.svg +images/interface/reload.svg +images/interface/healthy.svg +images/interface/to_hospital.svg +images/interface/doctor.svg +images/interface/to_solution.svg +images/interface/start_button.svg +activity +activity/activity.info +activity/hello-doctor.svg +MANIFEST diff --git a/Desktop/dzialo/paste/HelloDoctor.activity/activity/activity.info b/Desktop/dzialo/paste/HelloDoctor.activity/activity/activity.info new file mode 100644 index 0000000..c0c3f04 --- /dev/null +++ b/Desktop/dzialo/paste/HelloDoctor.activity/activity/activity.info @@ -0,0 +1,10 @@ +[Activity] +name = HelloDoctor +bundle_id = com.gmail.hellodoctor.HelloDoctor +icon = hello-doctor +exec = sugar-activity HelloDoctor.HelloDoctor +show_launcher = yes +activity_version = 1 +host_version = 1 +mime_types = text/plain;image/jpeg;image/svg+xml +license = GPLv3 diff --git a/Desktop/dzialo/paste/HelloDoctor.activity/activity/hello-doctor.svg b/Desktop/dzialo/paste/HelloDoctor.activity/activity/hello-doctor.svg new file mode 100644 index 0000000..72bebac --- /dev/null +++ b/Desktop/dzialo/paste/HelloDoctor.activity/activity/hello-doctor.svg @@ -0,0 +1,215 @@ + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Desktop/dzialo/paste/HelloDoctor.activity/clips/__init__.py b/Desktop/dzialo/paste/HelloDoctor.activity/clips/__init__.py new file mode 100644 index 0000000..4f9d8df --- /dev/null +++ b/Desktop/dzialo/paste/HelloDoctor.activity/clips/__init__.py @@ -0,0 +1,56 @@ +# __init__.py +# clips wrapper module loader + +# (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 + +This work is based on the CLIPS library and interpreter, by Gary Riley and +others. Please visit its homepage at http://clipsrules.sourceforge.net +for further information and to obtain the full source code. + +Please issue 'print clips.license' at the prompt for licensing information. +""" + + +from _clips_wrap import * +from _eclips_wrap import Environment, CurrentEnvironment +from _license import license +from _version import version, version_string + + +# provide our __dict__ to the _clips_wrap in order to set up stock classes: +# the name _setParentModuleDict will be removed later +from _clips_wrap import _setParentModuleDict +_setParentModuleDict(globals()) +del _setParentModuleDict + + + +# define the __all__ list so that the module can avoid useless names: in +# fact all useful names that this part of the module begin with a letter +__all__ = filter(lambda x: x[0] != '_', dir()) + + + +# end. diff --git a/Desktop/dzialo/paste/HelloDoctor.activity/clips/__init__.pyc b/Desktop/dzialo/paste/HelloDoctor.activity/clips/__init__.pyc new file mode 100644 index 0000000..7f6fe3e --- /dev/null +++ b/Desktop/dzialo/paste/HelloDoctor.activity/clips/__init__.pyc Binary files differ diff --git a/Desktop/dzialo/paste/HelloDoctor.activity/clips/__init__.pyo b/Desktop/dzialo/paste/HelloDoctor.activity/clips/__init__.pyo new file mode 100644 index 0000000..c6bba61 --- /dev/null +++ b/Desktop/dzialo/paste/HelloDoctor.activity/clips/__init__.pyo Binary files differ diff --git a/Desktop/dzialo/paste/HelloDoctor.activity/clips/_clips.py b/Desktop/dzialo/paste/HelloDoctor.activity/clips/_clips.py new file mode 100644 index 0000000..af41f95 --- /dev/null +++ b/Desktop/dzialo/paste/HelloDoctor.activity/clips/_clips.py @@ -0,0 +1,7 @@ +def __bootstrap__(): + global __bootstrap__, __loader__, __file__ + import sys, pkg_resources, imp + __file__ = pkg_resources.resource_filename(__name__,'_clips.so') + del __bootstrap__, __loader__ + imp.load_dynamic(__name__,__file__) +__bootstrap__() diff --git a/Desktop/dzialo/paste/HelloDoctor.activity/clips/_clips.pyc b/Desktop/dzialo/paste/HelloDoctor.activity/clips/_clips.pyc new file mode 100644 index 0000000..41c6186 --- /dev/null +++ b/Desktop/dzialo/paste/HelloDoctor.activity/clips/_clips.pyc Binary files differ diff --git a/Desktop/dzialo/paste/HelloDoctor.activity/clips/_clips.so b/Desktop/dzialo/paste/HelloDoctor.activity/clips/_clips.so new file mode 100755 index 0000000..3c8e5e6 --- /dev/null +++ b/Desktop/dzialo/paste/HelloDoctor.activity/clips/_clips.so Binary files differ diff --git a/Desktop/dzialo/paste/HelloDoctor.activity/clips/_clips_wrap.py b/Desktop/dzialo/paste/HelloDoctor.activity/clips/_clips_wrap.py new file mode 100644 index 0000000..dd7217b --- /dev/null +++ b/Desktop/dzialo/paste/HelloDoctor.activity/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 "" % 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.__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 "" % 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 "" % 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 "" % 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 "" + 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 "" % 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 "" + + 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 "" + + 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 "