Example #1
0
def simulation2(start,
                end,
                init_time,
                results,
                timing,
                time_stamps,
                feedback=True,
                learning=False):
    """
    Second simulation, using production learning.
    """

    attempts = collections.Counter()

    if learning:

        addition.productionstring(name="retrieve_addition",
                                  string="""
        =g>
        isa     add
        state   reading
        arg1    =num1
        arg2    =num2
        sum     None
        ?retrieval>
        state   free
        buffer  empty
        ==>
        =g>
        isa     add
        state   None
        +retrieval>
        isa     add
        arg1     =num1
        arg2     =num2""",
                                  utility=1)

        addition.productionstring(name="terminate_addition",
                                  string="""
        =g>
        isa     add
        state   None
        =retrieval>
        isa     add
        arg1    ~None
        sum     =v7
        ==>
        ~retrieval>
        =g>
        isa     add
        sum     =v7""",
                                  utility=1)

        addition.productionstring(name="done",
                                  string="""
        =g>
        isa     add
        state   None
        sum     =v7
        sum     ~None
        ==>
        =g>
        isa     add
        state   None""",
                                  reward=15)

        addition.model_parameters["production_compilation"] = True
        addition.model_parameters["utility_learning"] = True
        addition.model_parameters["utility_noise"] = 0.8

    for loop in range(start + 1, end + 1):
        x = random.uniform(0, 1)  #what problem should be used
        for i in range(len(PROB2)):
            if x < PROB2[i]:
                break
        else:
            i = UPTO
        x = random.uniform(0, 1)  #what problem should be used
        for j in range(len(PROB2)):
            if x < PROB2[j]:
                break
        else:
            j = UPTO
        #print(i, j)
        correct = i + j
        attempts.update([(i, j)])
        addition.goal.add(
            actr.makechunk("",
                           "add",
                           state="reading",
                           arg1=numbers[i],
                           arg2=numbers[j]))

        sim = addition.simulation(initial_time=init_time,
                                  trace=False,
                                  gui=False)
        addition.used_productions.rules.used_rulenames = {}
        while True:
            try:
                sim.step()
            except simpy.core.EmptySchedule:
                break
            if re.search("RETRIEVED: None", sim.current_event.action):
                results.setdefault((str(i), str(j)),
                                   collections.Counter()).update('X')
                if feedback and random.randint(0, 1) == 1:
                    addition.retrieval.add(
                        actr.makechunk("",
                                       "add",
                                       arg1=numbers[i],
                                       arg2=numbers[j],
                                       sum=numbers[correct]))
                    addition.retrieval.clear(sim.show_time(
                    ))  #advise -- teacher tells the correct answer
                break
            if re.search("RULE FIRED: done", sim.current_event.action):
                x = addition.goal.copy().pop()
                addition.goal.clear(sim.show_time())
                x = x._asdict()
                results.setdefault(
                    (str(i), str(j)),
                    collections.Counter()).update([str(x["sum"])])
                if str(x["sum"]) != str(numbers[correct]):
                    if feedback and random.randint(0, 1) == 1:
                        addition.retrieval.add(
                            actr.makechunk("",
                                           "add",
                                           arg1=numbers[i],
                                           arg2=numbers[j],
                                           sum=numbers[correct]))
                        addition.retrieval.clear(
                            sim.show_time()
                        )  #advise -- teacher tells the correct answer in roughly 50% of cases if incorrect
                        if learning:
                            utilities.modify_utilities(
                                sim.show_time(), -15,
                                addition.used_productions.rules.used_rulenames,
                                addition.used_productions.rules,
                                addition.used_productions.model_parameters)
                elif timing:
                    time_stamps.setdefault(
                        (str(i), str(j)),
                        []).append(sim.show_time() - init_time)
                break
        addition.retrieval.state = addition.retrieval._FREE
        addition.retrieval.clear()
        init_time = loop * DELAY
    return results, time_stamps, init_time
Example #2
0
    def procedural_process(self, start_time=0):
        """
        Process that is carrying a production. Proceeds in steps: conflict resolution -> rule selection -> rule firing; or conflict resolution -> no rule found. Start_time specifies when production starts in discrete event simulation.
        """
        time = start_time

        self.procs.append(self._PROCEDURAL,)
        
        self.__actrvariables = {}
        yield Event(roundtime(time), self._PROCEDURAL, 'CONFLICT RESOLUTION')

        max_utility = float("-inf")
        used_rulename = None
        self.used_rulename = None
        self.extra_tests = {}
        
        self.last_rule_slotvals = self.current_slotvals.copy()

        for rulename in self.ordered_rulenames:
            self.used_rulename = rulename
            production = self.rules[rulename]["rule"]()
            utility = self.rules[rulename]["utility"]

            pro = next(production)

            if self.model_parameters["subsymbolic"]:
                inst_noise = utilities.calculate_instantanoues_noise(self.model_parameters["utility_noise"])
                utility += inst_noise
            if max_utility <= utility and self.LHStest(pro, self.__actrvariables.copy()):
                max_utility = utility
                used_rulename = rulename
                if not self.model_parameters["subsymbolic"] or not self.model_parameters["utility_noise"]:
                    break #breaking after finding a rule, to speed up the process
        if used_rulename:
            self.used_rulename = used_rulename
            production = self.rules[used_rulename]["rule"]()
            self.rules.used_rulenames.setdefault(used_rulename, []).append(time)
            
            yield Event(roundtime(time), self._PROCEDURAL, 'RULE SELECTED: %s' % used_rulename)
            time = time + self.model_parameters["rule_firing"]
            yield Event(roundtime(time), self._PROCEDURAL, self._UNKNOWN)

            pro = next(production)

            if not self.LHStest(pro, self.__actrvariables.copy(), True):
                yield Event(roundtime(time), self._PROCEDURAL, 'RULE STOPPED FROM FIRING: %s' % used_rulename)
            else:
                if self.model_parameters["utility_learning"] and self.rules[used_rulename]["reward"] != None:
                    utilities.modify_utilities(time, self.rules[used_rulename]["reward"], self.rules.used_rulenames, self.rules, self.model_parameters)
                    self.rules.used_rulenames = {}
                compiled_rulename, re_created = self.compile_rules()
                self.compile = []
                if re_created:
                    yield Event(roundtime(time), self._PROCEDURAL, 'RULE %s: %s' % (re_created, compiled_rulename))
                self.current_slotvals = {key: None for key in self.buffers}
                yield Event(roundtime(time), self._PROCEDURAL, 'RULE FIRED: %s' % used_rulename)
                try:
                    yield from self.update(next(production), time)
                except utilities.ACTRError as e:
                    raise utilities.ACTRError("The following rule is not defined correctly according to ACT-R: '%s'. The following error occured: %s" % (self.used_rulename, e))
                if self.last_rule and self.last_rule != used_rulename:
                    self.compile = [self.last_rule, used_rulename, self.last_rule_slotvals.copy()]
                    self.last_rule_slotvals = {key: None for key in self.buffers}

                self.last_rule = used_rulename
        else:
            self.procs.remove(self._PROCEDURAL,)
            yield Event(roundtime(time), self._PROCEDURAL, 'NO RULE FOUND')
        return self.procs #returns processes activated by PROCEDURAL