resource.write("".join([ str(self.resolve(funcEnv, self.semplify(funcEnv, x))) for x in args ])) return types.NullValue() def resolve(self, funcEnv, arg): """ Override Function.resolve to manage the <Symbol:crlf> conversion to NEWLINE and to remove quotes in types.String values """ if isinstance(arg, types.Symbol) and arg.pyEqual("crlf"): return "\n" else: return Function.resolve(self, funcEnv, arg) # Function definition Printout.DEFINITION = FunctionDefinition( "?SYSTEM?", "printout", Printout(), types.NullValue, Printout.do, [ Constraint_MinArgsLength(2), Constraint_ArgType(types.Symbol, 0), ], forward=False)
acts = theEnv.network.agenda.activations(theModule) actCount += len(acts) for (salience, pnode, token) in acts: theStdout.write("\t%-6d %s: %s\n" % (salience, pnode.mainRuleName, token)) else: acts = theEnv.network.agenda.activations(theModule) #acts.reverse() actCount += len(acts) for (salience, pnode, token) in acts: theStdout.write("%-6d %s: %s\n" % (salience, pnode.mainRuleName, token)) if actCount: theStdout.write("For a total of %d activations.\n" % actCount) return types.NullValue() Agenda.DEFINITION = FunctionDefinition( "?SYSTEM?", "agenda", Agenda(), types.NullValue, Agenda.do, [ Constraint_MaxArgsLength(1), Constraint_ArgType(types.Symbol, 0, False), ], forward=False)
theResult = self.resolve(theEnv, theCondition) while not (isinstance(theResult, types.Symbol) and theResult.pyEqual("FALSE")): for action in theActions: # function are executed if isinstance(action, types.FunctionCall): self.resolve(theEnv, action) if isinstance(theCondition, (types.FunctionCall, types.Variable)): theResult = self.resolve(theEnv, theCondition) except BreakException: # break caught, stop loooooooooop! pass # CLIPS documentation: # the if-then-else return value is always the value of the last execute action return returnValue WhileDo.DEFINITION = FunctionDefinition("?SYSTEM?", "while", WhileDo(), (types.Lexeme, types.Symbol, types.String, types.Number, types.Integer, types.Float, list, types.NullValue, WME ), WhileDo.do, [ Constraint_MinArgsLength(1), Constraint_ArgType((types.FunctionCall, types.Variable), 0) ],forward=False)
Function.__init__(self, *args, **kwargs) def do(self, theEnv, *args, **kargs): """ handler of the function @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.3.html#Heading232 """ concat = "" for arg in args: concat += str( self.resolve( theEnv, self.semplify(theEnv, arg, (types.BaseParsedType, WME), ("ALL", "lexeme, number or fact-address")))) return types.Symbol(concat) SymbolConcat.DEFINITION = FunctionDefinition( "?SYSTEM?", "sym-cat", SymbolConcat(), types.Symbol, SymbolConcat.do, [ Constraint_ArgType((types.Symbol, types.String, types.Float, types.Integer, types.Number, types.Lexeme, WME)) ], forward=False)
''' def __init__(self, *args, **kwargs): Function.__init__(self, *args, **kwargs) def do(self, theEnv, theNumber, *args, **kargs): """ handler of the function @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.5.html#Heading261 """ theNumber = self.resolve(theEnv, theNumber) if isinstance( theNumber, (types.FunctionCall, types.Variable)) else theNumber if not isinstance(theNumber, (types.Integer, types.Float)): raise InvalidArgTypeError( "Function abs expected argument #1 to be of type integer or float" ) return theNumber if theNumber.evaluate() >= 0 else theNumber.__class__( -1 * theNumber.evaluate()) Absolute.DEFINITION = FunctionDefinition( "?SYSTEM?", "abs", Absolute(), (types.Integer, types.Float, types.Number), Absolute.do, [Constraint_ExactArgsLength(1), Constraint_ArgType(types.Number)], forward=False)
def __init__(self, *args, **kwargs): Function.__init__(self, *args, **kwargs) def do(self, theEnv, theWme, *args, **kargs): """ function handler implementation """ theWme = self.resolveWme(theEnv, self.semplify(theEnv, theWme, (WME, types.Integer), ("1", "fact-address or i"))) import myclips.debug as debug debug.show_wme_details(theEnv.RESOURCES['wtrace'], theWme, explodeToken=True, explodeAMem=True) return types.NullValue() def resolveWme(self, theEnv, arg): if isinstance(arg, types.Integer): return theEnv.network.getWmeFromId(self.resolve(theEnv, arg)) elif isinstance(arg, WME): return arg TraceWme.DEFINITION = FunctionDefinition("?SYSTEM?", "trace-wme", TraceWme(), types.NullValue, TraceWme.do , [ Constraint_ExactArgsLength(1), Constraint_ArgType((types.Integer, WME), 0), ],forward=False)
# it's a single field theSlotValues = self.semplify(theEnv, theSlot.values[1]) theBackup[theSlotName] = theSlotValues # 6) assert the new fact theWme, isNew = theEnv.network.assertFact(theBackup) return theWme if isNew else types.Symbol("FALSE") def resolveFact(self, theEnv, arg): if isinstance(arg, types.Integer): #convert the <Interger:INT> into a <WME:f-INT> return theEnv.network.getWmeFromId(arg.evaluate()) else: return arg Modify.DEFINITION = FunctionDefinition( "?SYSTEM?", "modify", Modify(), (WME, types.Symbol), Modify.do, [ Constraint_MinArgsLength(1), Constraint_ArgType((types.Integer, WME), 0), Constraint_ArgType(types.OrderedRhsPattern, (1, None), failIfMissing=False), ], forward=False)
class Rest(Function): ''' This function returns all but the first field of a multifield value as a multifield value. (rest$ <multifield-expression>) @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.2.html#Heading229 ''' def __init__(self, *args, **kwargs): Function.__init__(self, *args, **kwargs) def do(self, theEnv, theMultifield, *args, **kargs): """ handler of the function @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.2.html#Heading229 """ theMultifield = self.semplify(theEnv, theMultifield, list, ("1", "multifield")) return theMultifield[1:None] Rest.DEFINITION = FunctionDefinition("?SYSTEM?", "rest$", Rest(), list, Rest.do, [ Constraint_ExactArgsLength(1), Constraint_ArgType(list, 0), ],forward=False)
def do(self, theEnv, theValue, theMultifield, *args, **kargs): """ handler of the function @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.2.html#Heading220 """ theValue = self.semplify(theEnv, theValue, (types.Lexeme, types.Number, WME), ("1", "number, lexeme or fact")) theMultifield = self.semplify(theEnv, theMultifield, list, ("2", "multifield")) try: theIndex = theMultifield.index(theValue) except ValueError: return types.Symbol("FALSE") else: return types.Integer(theIndex) Member.DEFINITION = FunctionDefinition( "?SYSTEM?", "member$", Member(), (types.Symbol, types.Integer), Member.do, [ Constraint_ExactArgsLength(2), Constraint_ArgType((types.Number, types.Lexeme, WME), 0), Constraint_ArgType(list, 1) ], forward=False)
def createFact(self, theEnv, arg): if isinstance(arg, types.OrderedRhsPattern): # convert it in a new Ordered Fact return OrderedFact(values=[self.semplify(theEnv, v, types.BaseParsedType) for v in arg.values], moduleName=theEnv.modulesManager.currentScope.moduleName) elif isinstance(arg, types.TemplateRhsPattern): # convert it in a new Template Fact # the fact value is a dict with (slotName, slotValue) where slotValue: # is a baseparsedtype if singlefield return TemplateFact(templateName=arg.templateName, values=dict([(v.slotName, self.semplify(theEnv, v.slotValue, types.BaseParsedType)) if isinstance(v, types.SingleFieldRhsSlot) # or a list if multifield (solved, this means is a list of base-parsed-type) else (v.slotName, self.semplify(theEnv, v.slotValue, list)) if isinstance(v, types.MultiFieldRhsSlot) else (v.slotName, v.slotValue) #don't know what to do FIXME for v in arg.templateSlots]), moduleName=theEnv.modulesManager.currentScope.templates.getDefinition(arg.templateName).moduleName) else: raise InvalidArgValueError("Unknown fact format in RHS pattern") AssertString.DEFINITION = FunctionDefinition("?SYSTEM?", "assert-string", AssertString(), (WME, types.Symbol), AssertString.do , [ Constraint_ExactArgsLength(1), Constraint_ArgType(types.String, 0) ],forward=False)
""" theStart = self.resolve( theEnv, self.semplify(theEnv, theStart, types.Integer, ("1", "integer"))) theEnd = self.resolve( theEnv, self.semplify(theEnv, theEnd, types.Integer, ("2", "integer"))) theString = self.resolve( theEnv, self.semplify(theEnv, theString, types.Lexeme, ("3", "string or symbol"))) return types.String(theString[theStart - 1:theEnd]) SubString.DEFINITION = FunctionDefinition( "?SYSTEM?", "sub-string", SubString(), types.String, SubString.do, [ Constraint_ExactArgsLength(3), Constraint_ArgType(types.Integer, 0), Constraint_ArgType(types.Integer, 1), Constraint_ArgType(types.Lexeme, 2) ], forward=False)
theFacts = [] if len(theModules) > 0: for theModule in theModules: theFacts += theEnv.network.factsForScope(theModule) else: theFacts = theEnv.network.facts # filter and cut the wme list to display theFacts = [wme for wme in theFacts if wme.factId >= theStart and wme.factId <= theEnd][:theMax] if len(theFacts): theStdout = theEnv.RESOURCES['wdisplay'] for wme in theFacts: theStdout.write("f-%-5d %s\n"%(wme.factId, wme.fact)) theStdout.write("For a total of %d facts.\n"%len(theFacts)) return types.NullValue() Facts.DEFINITION = FunctionDefinition("?SYSTEM?", "facts", Facts(), types.NullValue, Facts.do , [ Constraint_MaxArgsLength(4), Constraint_ArgType((types.Symbol, types.Integer), 0, False), Constraint_ArgType(types.Integer, (1,None), False) ],forward=False)
theLength = len(theMultifield) except InvalidArgTypeError: theLength = -1 finally: return types.Integer(theLength) else: return _Length.do(self, theEnv, theMultifield, *args, **kargs) _Length.DEFINITION = FunctionDefinition("?SYSTEM?", "length", _Length(), types.Integer, _Length.do, [ Constraint_ExactArgsLength(1), Constraint_ArgType( (list, types.Lexeme), 0), ], forward=False) Length.DEFINITION = FunctionDefinition( "?SYSTEM?", "length$", Length(), types.Integer, Length.do, [ Constraint_ExactArgsLength(1), Constraint_ArgType( (list, types.Lexeme) if not myclips.STRICT_MODE else list, 0), ], forward=False)
if theName is None: toClose = theEnv.RESOURCES.keys() elif not isinstance(theName, types.Symbol): raise InvalidArgTypeError( "Function open expected argument #1 to be of type symbol") else: toClose = [theName.evaluate()] if len(toClose) > 0: try: for resourceName in toClose: theEnv.RESOURCES[resourceName].close() del theEnv.RESOURCES[resourceName] return types.Symbol("TRUE") except KeyError: return types.Symbol("FALSE") else: return types.Symbol("FALSE") Close.DEFINITION = FunctionDefinition( "?SYSTEM?", "close", Close(), types.Symbol, Close.do, [ Constraint_MaxArgsLength(1), Constraint_ArgType(types.Symbol, 0, failIfMissing=False) ], forward=False)
''' The upcase function will return a string or symbol with uppercase alphabetic characters. @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.3.html#Heading237 ''' def __init__(self, *args, **kwargs): Function.__init__(self, *args, **kwargs) def do(self, theEnv, theString, *args, **kargs): """ handler of the function @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.3.html#Heading237 """ theSemplified = self.semplify(theEnv, theString, types.Lexeme, ('1', 'string or symbol')) theString = self.resolve(theEnv, theSemplified) return theSemplified.__class__(theString.upper()) Upcase.DEFINITION = FunctionDefinition( "?SYSTEM?", "upcase", Upcase(), (types.String, types.Symbol, types.Lexeme), Upcase.do, [ Constraint_ExactArgsLength(1), Constraint_ArgType((types.String, types.Symbol, types.Lexeme), 0), ], forward=False)
try: for theVarValue in range(theMin, theMax): if theVarBind is not None: theEnv.variables[theVarBind] = types.Integer(theVarValue) for action in theActions: # function are executed if isinstance(action, types.FunctionCall): self.resolve(theEnv, action) except BreakException: # break caught, stop loooooooooop! pass # CLIPS documentation: # the if-then-else return value is always the value of the last execute action return returnValue LoopForCount.DEFINITION = FunctionDefinition( "?SYSTEM?", "loop-for-count", LoopForCount(), (types.Lexeme, types.Symbol, types.String, types.Number, types.Integer, types.Float, list, types.NullValue, WME), LoopForCount.do, [ Constraint_MinArgsLength(1), Constraint_ArgType((types.Integer, list), 0) ], forward=False)
def do(self, theEnv, *args, **kargs): """ handler of the function @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.2.html#Heading218 """ theArgs = [] for i, theArg in enumerate(args): # semplify to a BaseParsedType if variable or function call and check types theArg = self.semplify( theEnv, theArg, (types.BaseParsedType, list, WME), (str(i + 1), "number, lexeme, multifield or WME")) if isinstance(theArg, list): theArgs += theArg else: theArgs.append(theArg) return theArgs Create.DEFINITION = FunctionDefinition( "?SYSTEM?", "create$", Create(), list, Create.do, [ Constraint_ArgType( (WME, list, types.Lexeme, types.Number), failIfMissing=False) ], forward=False)
class StringLength(Function): ''' The str-length function returns the length of a string as an integer. @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.3.html#Heading240 ''' def __init__(self, *args, **kwargs): Function.__init__(self, *args, **kwargs) def do(self, theEnv, theString, *args, **kargs): """ handler of the function @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.3.html#Heading240 """ # resolve to a python value (trim quotes from string too) theString = self.resolve(theEnv, # semplify to a BaseParsedType if variable or function call and check types self.semplify(theEnv, theString, (types.String, types.Symbol), ("1", "string or symbol"))) return types.Integer(len(theString)) StringLength.DEFINITION = FunctionDefinition("?SYSTEM?", "str-length", StringLength(), types.Integer, StringLength.do, [ Constraint_ExactArgsLength(1), Constraint_ArgType(types.Lexeme, 0), ],forward=False)
except: pass if args.has_key("all") or args.has_key("actions"): try: theEnv.network.settings.delSetting("_funcs.Watch.actions").uninstall() except: pass if args.has_key("all") or args.has_key("strategy"): try: theEnv.network.settings.delSetting("_funcs.Watch.strategy").uninstall() except: pass if args.has_key("all") or args.has_key("statistics"): try: theEnv.network.settings.delSetting("_funcs.Watch.statistics").uninstall() except: pass return types.NullValue() Unwatch.DEFINITION = FunctionDefinition("?SYSTEM?", "unwatch", Unwatch(), types.NullValue, Unwatch.do , [ Constraint_MinArgsLength(1), Constraint_ArgType(types.Lexeme, (None,None), failIfMissing=False) ],forward=False)
returnValueRaw.append( self.resolve(funcEnv, self.semplify(funcEnv, fragment))) # execute replacement of special chars: # theFormat = theFormat.replace("%n", "\n")\ .replace("%r", "\r")\ #.replace("%%", "%") # theFormat is a string returnValueRaw = theFormat % tuple(returnValueRaw) if resource is not None: resource.write(returnValueRaw) return types.String(returnValueRaw) # Function definition Format.DEFINITION = FunctionDefinition("?SYSTEM?", "format", Format(), types.String, Format.do, [ Constraint_MinArgsLength(2), Constraint_ArgType(types.Symbol, 0), Constraint_ArgType(types.String, 1), ], forward=False)
theBegin = theMultifield[0:theIndex - 1] theEnd = theMultifield[theIndex - 1:None] theInner = [] for theArg in args: theArg = self.semplify( theEnv, theArg, (list), ("1", "number, lexeme, fact-address or multifield")) if isinstance(theArg, list): theInner += theArg else: theInner.append(theArg) return theBegin + theInner + theEnd Insert.DEFINITION = FunctionDefinition( "?SYSTEM?", "insert$", Insert(), list, Insert.do, [ Constraint_MinArgsLength(3), Constraint_ArgType(list, 0), Constraint_ArgType(types.Integer, 1), Constraint_ArgType((types.Lexeme, types.Number, WME, list), 2), Constraint_ArgType((types.Lexeme, types.Number, WME, list), (3, None), failIfMissing=False) ], forward=False)
''' The oddp function returns the symbol TRUE if its argument is an odd number, otherwise it returns the symbol FALSE. ''' def __init__(self, *args, **kwargs): Function.__init__(self, *args, **kwargs) def do(self, theEnv, theValue, *args, **kargs): """ handler of the Oddp function """ # check theValue type and resolve (if needed) if isinstance(theValue, (types.FunctionCall, types.Variable)): theValue = self.resolve(theEnv, theValue) pyValue = theValue.evaluate() if bool(pyValue & 1): returnValue = types.Symbol("TRUE") else: returnValue = types.Symbol("FALSE") return returnValue Oddp.DEFINITION = FunctionDefinition("?SYSTEM?", "oddp", Oddp(), types.Symbol, Oddp.do , [ Constraint_ExactArgsLength(1), Constraint_ArgType(types.Integer, 0) ],forward=False)
''' def __init__(self, *args, **kwargs): Function.__init__(self, *args, **kwargs) def do(self, theEnv, theRuns=None, *args, **kargs): """ function handler implementation """ if theRuns is not None: theRuns = self.resolve( theEnv, self.semplify(theEnv, theRuns, types.Integer, ("1", "integer"))) theEnv.network.run(theRuns) return types.NullValue() Run.DEFINITION = FunctionDefinition( "?SYSTEM?", "run", Run(), types.NullValue, Run.do, [ Constraint_MaxArgsLength(1), Constraint_ArgType(types.Integer, 0, False), ], forward=False)
class FactIndex(Function): ''' The factindex function returns the fact- index (an integer) of a fact-address. WARNING: MyClips's version of fact-address is a WME instance @see http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.9.html#Heading306 ''' def __init__(self, *args, **kwargs): Function.__init__(self, *args, **kwargs) def do(self, theEnv, theWme, *args, **kargs): """ Function handler implementation @see http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.9.html#Heading306 """ theWme = self.semplify(theEnv, theWme, WME, ("1", "fact-address")) return types.Integer(theWme.factId) FactIndex.DEFINITION = FunctionDefinition( "?SYSTEM?", "fact-index", FactIndex(), (WME, types.Integer), FactIndex.do, [Constraint_ExactArgsLength(1), Constraint_ArgType(WME, 0)], forward=False)
modeMap = {"r": "rU", "r+": "rU+", "w": "w", "a": "a"} import myclips try: theMode = modeMap[theMode] fileResource = open(thePath, theMode) theEnv.RESOURCES[theName.evaluate()] = fileResource return types.Symbol("TRUE") except KeyError: myclips.logger.error("Invalid mode for Open: %s", theMode) return types.Symbol("FALSE") except IOError, e: myclips.logger.error("IOError in Open: %s", e) return types.Symbol("FALSE") Open.DEFINITION = FunctionDefinition( "?SYSTEM?", "open", Open(), types.Symbol, Open.do, [ Constraint_MinArgsLength(2), Constraint_MaxArgsLength(3), Constraint_ArgType((types.Symbol, types.String), 0), Constraint_ArgType(types.Symbol, 1), Constraint_ArgType(types.String, 2, failIfMissing=False) ], forward=False)
if isinstance(theFirstParsed, types.DefRuleConstruct): # add the new defrule theEnv.network.addRule(theFirstParsed) elif isinstance(theFirstParsed, types.DefFactsConstruct): theEnv.network.addDeffacts(theFirstParsed) except Exception, e: # an error? return FALSE print e returnValue = types.Symbol("FALSE") else: # construct added, return TRUE returnValue = types.Symbol("TRUE") finally: # BEFORE the end, the scope must be reverted to the original one # even if an exception was raised (deffacts and defrule names could trigger # a scope change) theEnv.modulesManager.changeCurrentScope(theScope) return returnValue Build.DEFINITION = FunctionDefinition("?SYSTEM?", "build", Build(), types.Symbol, Build.do, [ Constraint_ExactArgsLength(1), Constraint_ArgType( (types.String, types.Symbol), 0), ], forward=False)
definition.linkedType.runningValue = definition.linkedType.value returnValue = definition.linkedType.value else: # the variable is a rule-scope variable if newValue is not None: # bind the new variable funcEnv.variables[varName] = newValue returnValue = newValue else: # as for http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.6.html # in Bind documentation: # if the new value of a local variable is None, the variable must be unbound del funcEnv.variables[varName] return returnValue Bind.DEFINITION = FunctionDefinition( "?SYSTEM?", "bind", Bind(), (types.Lexeme, types.Symbol, types.String, types.Number, types.Integer, types.Float, list, types.NullValue, WME), Bind.do, [ Constraint_MinArgsLength(1), Constraint_ArgType( (types.SingleFieldVariable, types.MultiFieldVariable, types.GlobalVariable), 0), ], forward=False)
if theBegin - 1 >= len(theMultifield) or theEnd > len( theMultifield): raise IndexError() del theMultifield[theBegin - 1:theEnd] else: # remove a single item from the multifield del theMultifield[theBegin - 1] except IndexError: # invalid field! raise InvalidArgValueError( "Multifield index %s out of range 1..%d in function delete$" % (("range %d..%d" % (theBegin, theEnd) if theBegin != theEnd else str(theBegin)), len(theMultifield))) else: # no error, return the modified multifield return theMultifield Delete.DEFINITION = FunctionDefinition( "?SYSTEM?", "delete$", Delete(), list, Delete.do, [ Constraint_ExactArgsLength(3), Constraint_ArgType(list, 0), Constraint_ArgType(types.Integer, 1), Constraint_ArgType(types.Integer, 2) ], forward=False)
returnValue = self.resolve(theEnv, action) else: returnValue = action return returnValue class InvalidCaseException(MyClipsException): pass Switch.DEFINITION = FunctionDefinition("?SYSTEM?", "switch", Switch(), (types.Lexeme, types.Symbol, types.String, types.Number, types.Integer, types.Float, list, types.NullValue, WME ), Switch.do, [ Constraint_MinArgsLength(3), Constraint_ArgType(types.FunctionCall, (1,None) ) ],forward=False) Case.DEFINITION = FunctionDefinition("?SYSTEM?", "case", Case(), (types.Lexeme, types.Symbol, types.String, types.Number, types.Integer, types.Float, list, types.NullValue, WME ), Case.do, [ Constraint_MinArgsLength(3), Constraint_ArgType(types.Symbol, 1) ],forward=False) Default.DEFINITION = FunctionDefinition("?SYSTEM?", "default", Default(), (types.Lexeme, types.Symbol, types.String, types.Number, types.Integer, types.Float, list, types.NullValue, WME ), Default.do,