Ejemplo n.º 1
0
 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.ModelError(
             "Only chunks can be added as attributes to Declarative Memory; '%s' is not a chunk"
             % key)
Ejemplo n.º 2
0
 def decmem(self, value):
     try:
         self.dm = value
     except ValueError:
         raise utilities.ModelError(
             'The default harvest set in the retrieval buffer is not a possible declarative memory'
         )
Ejemplo n.º 3
0
    def __init__(self, environment=None, **model_parameters):
        self.chunktype = chunks.chunktype
        start_goal = goals.Goal()
        self.goals = {"g": start_goal}

        self.__buffers = {"g": start_goal}

        start_retrieval = declarative.DecMemBuffer()
        self.retrievals = {"retrieval": start_retrieval}

        self.__buffers["retrieval"] = start_retrieval

        start_dm = declarative.DecMem()
        self.decmems = {"decmem": start_dm}

        self.__similarities = {}

        self.model_parameters = self.MODEL_PARAMETERS.copy()

        try:
            if not set(model_parameters.keys()).issubset(
                    set(self.MODEL_PARAMETERS.keys())):
                raise (utilities.ModelError(
                    "Incorrect model parameter(s) %s. The only possible model parameters are: '%s'"
                    % (set(model_parameters.keys()).difference(
                        set(self.MODEL_PARAMETERS.keys())),
                       set(self.MODEL_PARAMETERS.keys()))))
            self.model_parameters.update(model_parameters)
        except TypeError:
            pass

        self.__env = environment
Ejemplo n.º 4
0
def makechunk(nameofchunk="",
              typename="",
              text_value="",
              criterion="",
              **dictionary):
    if not nameofchunk:
        nameofchunk = "unnamedchunk"
    if not typename:
        typename = "undefined" + str(Chunk._undefinedchunktypecounter)
        Chunk._undefinedchunktypecounter += 1
    if not criterion:
        criterion = "criterion"
    if not text_value:
        text_value = "no_text"
    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]))
                # print(temp_dict)
            except utilities.ModelError as e:
                raise utilities.ModelError(
                    "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, text_value, criterion, **dictionary)
    created_chunk._chunks[nameofchunk] = created_chunk
    return created_chunk
Ejemplo n.º 5
0
    def retrieve(self, time, otherchunk, actrvariables, buffers, extra_tests,
                 model_parameters):
        """
        Retrieve a chunk from declarative memory that matches otherchunk.
        """
        model_parameters = model_parameters.copy()
        model_parameters.update(self.model_parameters)

        if actrvariables == None:
            actrvariables = {}
        try:
            mod_attr_val = {
                x[0]: utilities.check_bound_vars(actrvariables,
                                                 x[1],
                                                 negative_impossible=False)
                for x in otherchunk.removeunused()
            }
        except utilities.ModelError as arg:
            raise utilities.ModelError(
                "Retrieving the chunk '%s' is impossible; %s" %
                (otherchunk, arg))
        chunk_tobe_matched = chunks.Chunk(otherchunk.typename, **mod_attr_val)

        max_A = float("-inf")

        retrieved = None
        for chunk in self.dm:
            try:
                if extra_tests["recently_retrieved"] == False or extra_tests[
                        "recently_retrieved"] == 'False':
                    if self.__finst and chunk in self.recent:
                        continue

                else:
                    if self.__finst and chunk not in self.recent:
                        continue
            except KeyError:
                pass

            if model_parameters[
                    "subsymbolic"]:  # if subsymbolic, check activation
                A_pm = 0
                if model_parameters["partial_matching"]:
                    A_pm = chunk_tobe_matched.match(
                        chunk,
                        partialmatching=True,
                        mismatch_penalty=model_parameters["mismatch_penalty"])
                else:
                    if not chunk_tobe_matched <= chunk:
                        continue

                try:
                    A_bll = utilities.baselevel_learning(
                        time,
                        self.dm[chunk],
                        model_parameters["baselevel_learning"],
                        model_parameters["decay"],
                        self.dm.activations.get(chunk),
                        optimized_learning=model_parameters[
                            "optimized_learning"])  # bll
                except UnboundLocalError:
                    continue
                A_sa = utilities.spreading_activation(
                    chunk, buffers, self.dm,
                    model_parameters["buffer_spreading_activation"],
                    model_parameters["strength_of_association"],
                    model_parameters["spreading_activation_restricted"],
                    model_parameters["association_only_from_chunks"])
                inst_noise = utilities.calculate_instantanoues_noise(
                    model_parameters["instantaneous_noise"])
                A = A_bll + A_sa + A_pm + inst_noise  # chunk.activation is the manually specified activation, potentially used by the modeller

                if utilities.retrieval_success(
                        A,
                        model_parameters["retrieval_threshold"]) and max_A < A:
                    max_A = A
                    self.activation = max_A
                    retrieved = chunk
                    extra_time = utilities.retrieval_latency(
                        A, model_parameters["latency_factor"],
                        model_parameters["latency_exponent"])

                    if model_parameters["activation_trace"]:
                        print("(Partially) matching chunk:", chunk)
                        print("Base level learning:", A_bll)
                        print("Spreading activation", A_sa)
                        print("Partial matching", A_pm)
                        print("Noise:", inst_noise)
                        print("Total activation", A)
                        print("Time to retrieve", extra_time)
            else:  # otherwise, just standard time for rule firing, so no extra calculation needed
                if chunk_tobe_matched <= chunk and self.dm[chunk][
                        0] != time:  # the second condition ensures that the chunk that was created are not retrieved at the same time
                    retrieved = chunk
                    extra_time = model_parameters["rule_firing"]

        if not retrieved:
            if model_parameters["subsymbolic"]:
                extra_time = utilities.retrieval_latency(
                    model_parameters["retrieval_threshold"],
                    model_parameters["latency_factor"],
                    model_parameters["latency_exponent"])
            else:
                extra_time = model_parameters["rule_firing"]
        if self.__finst:
            self.recent.append(retrieved)
            if self.__finst < len(self.recent):
                self.recent.popleft()
        return retrieved, extra_time
Ejemplo n.º 6
0
    def __init__(self, typename, text_value, criterion, **dictionary):
        self.typename = typename
        self.criterion = criterion
        self.text_value = text_value
        self.boundvars = {}  #dict of bound variables
        self.dict = dictionary

        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.Sequence)
                           or isinstance(getattr(dictionary[key], x),
                                         collections.MutableSequence)):
                        raise TypeError(
                            "Negvalues and negvariables must be tuples")

            elif (isinstance(dictionary[key], collections.Iterable)
                  and not isinstance(dictionary[key], str)) or not isinstance(
                      dictionary[key], collections.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.ModelError as e:
                    raise utilities.ModelError(
                        "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)