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
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