def makechunk(nameofchunk="", typename="", **dictionary): """ Create a chunk. Three values can be specified: (i) the name of the chunk (the name could be used if the chunk appears as a value of other chunks or production rules) (ii) its type (ii) slot-value pairs. For example: >>> makechunk(nameofchunk='example0', typename='chunktype_example0', value='one') chunktype_example0(value= one) This creates a chunk of type chunk1, which has one slot (value) and the value of that slot is one. """ if not nameofchunk: nameofchunk = "unnamedchunk" if not typename: typename = "undefined" + str(Chunk._undefinedchunktypecounter) Chunk._undefinedchunktypecounter += 1 for key in dictionary: #create varval if not created explicitly, i.e., if the chunk itself is not a varval if typename == utilities.VARVAL: pass elif isinstance(dictionary[key], Chunk): pass elif dictionary[key] is None or isinstance( dictionary[key], str) or isinstance(dictionary[key], numbers.Number): temp_dict = utilities.stringsplitting(str(dictionary[key])) loop_dict = temp_dict.copy() for x in loop_dict: if loop_dict[x]: if x == "negvariables" or x == "negvalues": val = tuple(temp_dict[x]) else: val = temp_dict[x].pop() temp_dict[x] = val else: temp_dict.pop(x) dictionary[key] = Chunk(utilities.VARVAL, **temp_dict) else: raise ValueError( "The value of a chunk slot can only be a chunk, string, number or None; you are using an illegal type for the chunk slot %s, namely %s" % (key, type(dictionary[key]))) created_chunk = Chunk(typename, **dictionary) created_chunk._chunks[nameofchunk] = created_chunk return created_chunk
def makechunk(nameofchunk="", typename="", **dictionary): """ Create a chunk. Three values can be specified: (i) the name of the chunk (the name could be used if the chunk appears as a value of other chunks or production rules) (ii) its type (ii) slot-value pairs. For example: >>> makechunk(nameofchunk='example0', typename='chunktype_example0', value='one') chunktype_example0(value= one) This creates a chunk of type chunk1, which has one slot (value) and the value of that slot is one. """ if not nameofchunk: nameofchunk = "unnamedchunk" if not typename: typename = "undefined" + str(Chunk._undefinedchunktypecounter) Chunk._undefinedchunktypecounter += 1 for key in dictionary: if isinstance(dictionary[key], Chunk): pass elif isinstance(dictionary[key], utilities.VarvalClass): pass else: try: temp_dict = utilities.stringsplitting(str(dictionary[key])) except utilities.ACTRError as e: raise utilities.ACTRError( "The chunk value %s is not defined correctly; %s" % (dictionary[key], e)) loop_dict = temp_dict.copy() for x in loop_dict: if x == "negvariables" or x == "negvalues": val = tuple(temp_dict[x]) else: try: val = temp_dict[x].pop() except KeyError: val = None temp_dict[x] = val dictionary[key] = utilities.VarvalClass(**temp_dict) created_chunk = Chunk(typename, **dictionary) created_chunk._chunks[nameofchunk] = created_chunk return created_chunk
def makechunk(nameofchunk="", typename="", **dictionary): """ Create a chunk. Three values can be specified: (i) the name of the chunk (the name could be used if the chunk appears as a value of other chunks or production rules) (ii) its type (ii) slot-value pairs. For example: >>> makechunk(nameofchunk='example0', typename='chunktype_example0', value='one') chunktype_example0(value= one) This creates a chunk of type chunk1, which has one slot (value) and the value of that slot is one. """ if not nameofchunk: nameofchunk = "unnamedchunk" if not typename: typename = "undefined" + str(Chunk._undefinedchunktypecounter) Chunk._undefinedchunktypecounter += 1 for key in dictionary: if isinstance(dictionary[key], Chunk): pass elif isinstance(dictionary[key], utilities.VarvalClass): pass else: try: temp_dict = utilities.stringsplitting(str(dictionary[key])) except utilities.ACTRError as e: raise utilities.ACTRError("The chunk value %s is not defined correctly; %s" %(dictionary[key], e)) loop_dict = temp_dict.copy() for x in loop_dict: if x == "negvariables" or x == "negvalues": val = tuple(temp_dict[x]) else: try: val = temp_dict[x].pop() except KeyError: val = None temp_dict[x] = val dictionary[key] = utilities.VarvalClass(**temp_dict) created_chunk = Chunk(typename, **dictionary) created_chunk._chunks[nameofchunk] = created_chunk return created_chunk
def __init__(self, typename, **dictionary): self.typename = typename self.boundvars = {} #dict of bound variables kwargs = {} for key in dictionary: #change values (and values in a tuple) into string, when possible (when the value is not another chunk) if isinstance(dictionary[key], Chunk): dictionary[key] = utilities.VarvalClass(variables=None, values=dictionary[key], negvariables=(), negvalues=()) elif isinstance(dictionary[key], utilities.VarvalClass): for x in dictionary[key]._fields: if x in {"values", "variables"} and not isinstance( getattr(dictionary[key], x), str) and getattr( dictionary[key], x) != self.__emptyvalue and not isinstance( getattr(dictionary[key], x), Chunk): raise TypeError( "Values and variables must be strings, chunks or empty (None)" ) elif x in { "negvariables", "negvalues" } and (not isinstance(getattr(dictionary[key], x), collections.abc.Sequence) or isinstance(getattr(dictionary[key], x), collections.abc.MutableSequence)): raise TypeError( "Negvalues and negvariables must be tuples") elif (isinstance(dictionary[key], collections.abc.Iterable) and not isinstance(dictionary[key], str)) or not isinstance( dictionary[key], collections.abc.Hashable): raise ValueError( "The value of a chunk slot must be hashable and not iterable; you are using an illegal type for the value of the chunk slot %s, namely %s" % (key, type(dictionary[key]))) else: #create namedtuple varval and split dictionary[key] into variables, values, negvariables, negvalues try: temp_dict = utilities.stringsplitting(str(dictionary[key])) except utilities.ACTRError as e: raise utilities.ACTRError( "The chunk %s is not defined correctly; %s" % (dictionary[key], e)) loop_dict = temp_dict.copy() for x in loop_dict: if x == "negvariables" or x == "negvalues": val = tuple(temp_dict[x]) else: try: val = temp_dict[x].pop() except KeyError: val = None temp_dict[x] = val dictionary[key] = utilities.VarvalClass(**temp_dict) #adding _ to minimize/avoid name clashes kwargs[key + "_"] = dictionary[key] try: for elem in self._chunktypes[typename]._fields: if elem not in kwargs: kwargs[ elem] = self.__emptyvalue #emptyvalues are explicitly added to attributes that were left out dictionary[ elem[: -1]] = self.__emptyvalue #emptyvalues are also added to attributes in the original dictionary (since this might be used for chunktype creation later) if set(self._chunktypes[typename]._fields) != set(kwargs.keys()): chunktype( typename, dictionary.keys() ) #If there are more args than in the original chunktype, chunktype has to be created again, with slots for new attributes warnings.warn("Chunk type %s is extended with new attributes" % typename) except KeyError: chunktype(typename, dictionary.keys() ) #If chunktype completely missing, it is created first warnings.warn( "Chunk type %s was not defined; added automatically" % typename) finally: self.actrchunk = self._chunktypes[typename](**kwargs) self.__empty = None #this will store what the chunk looks like without empty values (the values will be stored on the first call of the relevant function) self.__unused = None #this will store what the chunk looks like without unused values self.__hash = None, self.boundvars.copy( ) #this will store the hash along with variables (hash changes if some variables are resolved)
def __init__(self, typename, **dictionary): self.typename = typename self.boundvars = {} #dict of bound variables kwargs = {} for key in dictionary: #change values (and values in a tuple) into string, when possible (when the value is not another chunk) if isinstance(dictionary[key], Chunk): dictionary[key] = utilities.VarvalClass(variables=None, values=dictionary[key], negvariables=(), negvalues=()) elif isinstance(dictionary[key], utilities.VarvalClass): for x in dictionary[key]._fields: if x in {"values", "variables"} and not isinstance(getattr(dictionary[key], x), str) and getattr(dictionary[key], x) != self.__emptyvalue and not isinstance(getattr(dictionary[key], x), Chunk): raise TypeError("Values and variables must be strings, chunks or empty (None)") elif x in {"negvariables", "negvalues"} and (not isinstance(getattr(dictionary[key], x), collections.abc.Sequence) or isinstance(getattr(dictionary[key], x), collections.abc.MutableSequence)): raise TypeError("Negvalues and negvariables must be tuples") elif (isinstance(dictionary[key], collections.abc.Iterable) and not isinstance(dictionary[key], str)) or not isinstance(dictionary[key], collections.abc.Hashable): raise ValueError("The value of a chunk slot must be hashable and not iterable; you are using an illegal type for the value of the chunk slot %s, namely %s" % (key, type(dictionary[key]))) else: #create namedtuple varval and split dictionary[key] into variables, values, negvariables, negvalues try: temp_dict = utilities.stringsplitting(str(dictionary[key])) except utilities.ACTRError as e: raise utilities.ACTRError("The chunk %s is not defined correctly; %s" %(dictionary[key], e)) loop_dict = temp_dict.copy() for x in loop_dict: if x == "negvariables" or x == "negvalues": val = tuple(temp_dict[x]) else: try: val = temp_dict[x].pop() except KeyError: val = None temp_dict[x] = val dictionary[key] = utilities.VarvalClass(**temp_dict) #adding _ to minimize/avoid name clashes kwargs[key+"_"] = dictionary[key] try: for elem in self._chunktypes[typename]._fields: if elem not in kwargs: kwargs[elem] = self.__emptyvalue #emptyvalues are explicitly added to attributes that were left out dictionary[elem[:-1]] = self.__emptyvalue #emptyvalues are also added to attributes in the original dictionary (since this might be used for chunktype creation later) if set(self._chunktypes[typename]._fields) != set(kwargs.keys()): chunktype(typename, dictionary.keys()) #If there are more args than in the original chunktype, chunktype has to be created again, with slots for new attributes warnings.warn("Chunk type %s is extended with new attributes" % typename) except KeyError: chunktype(typename, dictionary.keys()) #If chunktype completely missing, it is created first warnings.warn("Chunk type %s was not defined; added automatically" % typename) finally: self.actrchunk = self._chunktypes[typename](**kwargs) self.__empty = None #this will store what the chunk looks like without empty values (the values will be stored on the first call of the relevant function) self.__unused = None #this will store what the chunk looks like without unused values self.__hash = None, self.boundvars.copy() #this will store the hash along with variables (hash changes if some variables are resolved)