def hash_func(): for x in self.removeempty(): varval = sorted( utilities.splitting(x[1]).items(), reverse=True ) #(neg)values and (neg)variables have to be checked for idx in range(len(varval)): for _ in range(len(varval[idx][1])): value = varval[idx][1].pop() if idx == 0 or idx == 2: #idx == 0 -> variables; idx == 2 -> negvariables try: varval[idx + 1][1].add(self.boundvars[ utilities.ACTRVARIABLE + value]) #add value based on a variable except KeyError: if x[0]: yield tuple( [ x[0], tuple( [varval[idx][0], hash(value)]) ] ) #get hash of variable if it is not bound else: yield tuple([varval[idx][0], hash(value)]) else: if x[0]: yield tuple([ x[0], tuple([varval[idx][0], hash(value)]) ]) #values get their hash directly else: yield tuple([varval[idx][0], hash(value)])
def hash_func(): for x in self.removeempty(): varval = utilities.splitting(x[1]) temp_varval = {"values": set(), "negvalues": set()} for key in ["variables", "negvariables"]: if getattr(varval, key): for value in getattr(varval, key): try: temp_varval[re.sub( "variables", "values", key )].add( self.boundvars[utilities.ACTRVARIABLE + value] ) #add (neg)value based on the (neg)variable except KeyError: if x[0]: yield tuple( [x[0], tuple([key, hash(value)])] ) #get hash of variable if it is not bound else: yield tuple([key, hash(value)]) for key in ["values", "negvalues"]: if key == "values" and getattr(varval, key) != self.__emptyvalue: temp_varval[key].update(set([getattr(varval, key)])) elif key == "negvalues": temp_varval[key].update(set(getattr(varval, key))) if temp_varval[key]: for value in temp_varval[key]: if x[0]: yield tuple([ x[0], tuple([key, hash(value)]) ]) #values get their hash directly else: yield tuple([key, hash(value)])
def hash_func(): for x in self.removeempty(): varval = utilities.splitting(x[1]) temp_varval = {"values": set(), "negvalues": set()} for key in ["variables", "negvariables"]: if getattr(varval, key): for value in getattr(varval, key): try: temp_varval[re.sub("variables", "values", key)].add(self.boundvars[utilities.ACTRVARIABLE + value]) #add (neg)value based on the (neg)variable except KeyError: if x[0]: yield tuple([x[0], tuple([key, hash(value)])]) #get hash of variable if it is not bound else: yield tuple([key, hash(value)]) for key in ["values", "negvalues"]: if key == "values" and getattr(varval, key) != self.__emptyvalue: temp_varval[key].update(set([getattr(varval, key)])) elif key == "negvalues": temp_varval[key].update(set(getattr(varval, key))) if temp_varval[key]: for value in temp_varval[key]: if x[0]: yield tuple([x[0], tuple([key, hash(value)])]) #values get their hash directly else: yield tuple([key, hash(value)])
def __setitem__(self, key, time): if self.unrestricted_number_chunks and key not in self: for x in key: if utilities.splitting(x[1]).values and utilities.splitting(x[1]).values in self.unrestricted_number_chunks: self.unrestricted_number_chunks.update([utilities.splitting(x[1]).values]) if self.restricted_number_chunks and key not in self: for x in key: if utilities.splitting(x[1]).values and (x[0], utilities.splitting(x[1]).values) in self.restricted_number_chunks: self.restricted_number_chunks.update([(x[0], utilities.splitting(x[1]).values)]) if isinstance(key, chunks.Chunk): if len(key) == 0: if isinstance(time, np.ndarray): #time is an array self._data.update({key: time}) else: try: #time is a number self._data.update({key: np.array([round(float(time), 4)])}) except TypeError: #time is a sequence self._data.update({key: np.array(time)}) for x in key.removeunused(): temp_chunk = chunks.Chunk(typename=getattr(key, "typename"), **{x[0]: x[1]}) if isinstance(time, np.ndarray): #time is an array self._data.setdefault(temp_chunk, {}).update({key: time}) else: try: #time is a number self._data.setdefault(temp_chunk, {}).update({key: np.array([round(float(time), 4)])}) except TypeError: #time is a sequence self._data.setdefault(temp_chunk, {}).update({key: np.array(time)}) else: raise utilities.ACTRError("Only chunks can be added as attributes to Declarative Memory; '%s' is not a chunk" % key)
def __setitem__(self, key, time): if self.unrestricted_number_chunks and key not in self: for x in key: if utilities.splitting(x[1]).values and utilities.splitting( x[1]).values in self.unrestricted_number_chunks: self.unrestricted_number_chunks.update( [utilities.splitting(x[1]).values]) if self.restricted_number_chunks and key not in self: for x in key: if utilities.splitting( x[1]).values and (x[0], utilities.splitting( x[1]).values) in self.restricted_number_chunks: self.restricted_number_chunks.update([ (x[0], utilities.splitting(x[1]).values) ]) if isinstance(key, chunks.Chunk): if isinstance(time, np.ndarray): self._data[key] = time else: try: self._data[key] = np.array([round(float(time), 4)]) except TypeError: self._data[key] = np.array(time) else: raise utilities.ACTRError( "Only chunks can be added as attributes to Declarative Memory; '%s' is not a chunk" % key)
def __setitem__(self, key, time): if self.unrestricted_number_chunks and key not in self: for x in key: if utilities.splitting(x[1]).values and utilities.splitting(x[1]).values in self.unrestricted_number_chunks: self.unrestricted_number_chunks.update([utilities.splitting(x[1]).values]) if self.restricted_number_chunks and key not in self: for x in key: if utilities.splitting(x[1]).values and (x[0], utilities.splitting(x[1]).values) in self.restricted_number_chunks: self.restricted_number_chunks.update([(x[0], utilities.splitting(x[1]).values)]) if isinstance(key, chunks.Chunk): if isinstance(time, np.ndarray): self._data[key] = time else: try: self._data[key] = np.array([round(float(time), 4)]) except TypeError: self._data[key] = np.array(time) else: raise utilities.ACTRError("Only chunks can be added as attributes to Declarative Memory; '%s' is not a chunk" % key)
def match(self, otherchunk, partialmatching, mismatch_penalty=1): """ Check partial match (given bound variables in boundvars). """ similarity = 0 if self == otherchunk: return similarity #below starts the check that self is proper part of otherchunk. __emptyvalue is ignored. 4 cases have to be checked separately, =x, ~=x, !1, ~!1. Also, variables and their values have to be saved in boundvars. When self is not part of otherchunk the loop adds to (dis)similarity. for x in self: try: matching_val = getattr(otherchunk.actrchunk, x[0] + "_") #get the value of attr except AttributeError: matching_val = None #if it is missing, it must be None try: if matching_val.typename == utilities.VARVAL: matching_val = matching_val.values #the value might be written using _variablesvalues chunk; in that case, get it out except AttributeError: pass varval = utilities.splitting(x[1], empty=False) #checking variables, e.g., =x if varval["variables"] != self.__emptyvalue and varval["variables"]: #if matching_val == self.__emptyvalue: # similarity -= 1 #these two lines would require that variables are matched only to existing values; uncomment if you want that for var in varval["variables"]: for each in self.boundvars.get("~=" + var, set()): if each == matching_val: if partialmatching: similarity += utilities.get_similarity( self._similarities, each, matching_val, mismatch_penalty ) #False if otherchunk's value among the values of ~=x else: return False try: if self.boundvars["=" + var] != matching_val: if partialmatching: similarity += utilities.get_similarity( self._similarities, self.boundvars["=" + var], matching_val, mismatch_penalty ) #False if =x does not match otherchunks' value else: return False except KeyError: self.boundvars.update({ "=" + var: matching_val }) #if boundvars lack =x, update and proceed #checking negvariables, e.g., ~=x if varval["negvariables"] != self.__emptyvalue and varval[ "negvariables"]: for var in varval["negvariables"]: try: if self.boundvars["=" + var] == matching_val: if partialmatching: similarity += utilities.get_similarity( self._similarities, self.boundvars["=" + var], matching_val, mismatch_penalty ) #False if =x does not match otherchunks' value else: return False except KeyError: pass self.boundvars.setdefault("~=" + var, set([])).add(matching_val) #checking values, e.g., 10 or !10 if varval["values"]: val = varval["values"].pop() if val != None and val != matching_val: #None is the misssing value of the attribute if partialmatching: similarity += utilities.get_similarity( self._similarities, val, matching_val, mismatch_penalty) else: return False #checking negvalues, e.g., ~!10 if varval["negvalues"]: for negval in varval["negvalues"]: if negval == matching_val or ( negval in {self.__emptyvalue, 'None'} and matching_val == self.__emptyvalue): if partialmatching: similarity += utilities.get_similarity( self._similarities, negval, matching_val, mismatch_penalty) else: return False if partialmatching: return similarity else: return True
def match(self, otherchunk, partialmatching, mismatch_penalty=1): """ Check partial match (given bound variables in boundvars). """ similarity = 0 if self == otherchunk: return similarity #below starts the check that self is proper part of otherchunk. __emptyvalue is ignored. 4 cases have to be checked separately, =x, ~=x, !1, ~!1. Also, variables and their values have to be saved in boundvars. When self is not part of otherchunk the loop adds to (dis)similarity. for x in self: try: matching_val = getattr(otherchunk.actrchunk, x[0] + "_") #get the value of attr except AttributeError: matching_val = None #if it is missing, it must be None if isinstance(matching_val, utilities.VarvalClass): matching_val = matching_val.values #the value might be written using _variablesvalues namedtuple; in that case, get it out varval = utilities.splitting(x[1]) #checking variables, e.g., =x if varval.variables: #if matching_val == self.__emptyvalue: # similarity -= 1 #these two lines would require that variables are matched only to existing values; uncomment if you want that var = varval.variables for each in self.boundvars.get("~=" + var, set()): if each == matching_val: if partialmatching: similarity += utilities.get_similarity(self._similarities, each, matching_val, mismatch_penalty) #False if otherchunk's value among the values of ~=x else: return False try: if self.boundvars["=" + var] != matching_val: if partialmatching: similarity += utilities.get_similarity(self._similarities, self.boundvars["=" + var], matching_val, mismatch_penalty) #False if =x does not match otherchunks' value else: return False except KeyError: self.boundvars.update({"=" + var: matching_val}) #if boundvars lack =x, update and proceed #checking negvariables, e.g., ~=x if varval.negvariables: for var in varval.negvariables: try: if self.boundvars["=" + var] == matching_val: if partialmatching: similarity += utilities.get_similarity(self._similarities, self.boundvars["=" + var], matching_val, mismatch_penalty) #False if =x does not match otherchunks' value else: return False except KeyError: pass self.boundvars.setdefault("~=" + var, set([])).add(matching_val) #checking values, e.g., 10 or !10 if varval.values: val = varval.values if val != None and val != matching_val: #None is the missing value of the attribute if partialmatching: similarity += utilities.get_similarity(self._similarities, val, matching_val, mismatch_penalty) else: return False #checking negvalues, e.g., ~!10 if varval.negvalues: for negval in varval.negvalues: if negval == matching_val or (negval in {self.__emptyvalue, 'None'} and matching_val == self.__emptyvalue): if partialmatching: similarity += utilities.get_similarity(self._similarities, negval, matching_val, mismatch_penalty) else: return False if partialmatching: return similarity else: return True