def _non_history_list_simulate(simpack_grokker, state, iterations, step_profile): ''' Simulate from the given state for the given number of iterations. (Internal function for non-history-dependent simulations only.) Returns a list that spans all the states, from the initial one given to the final one. ''' tree = garlicsim.data_structures.Tree() root = tree.add_state(state, parent=None) path = root.make_containing_path() iterator = simpack_grokker.get_step_iterator(state, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_node = root current_state = current_node.state world_ended = False try: for current_state in finite_iterator: current_node = tree.add_state(current_state, parent=current_node) except garlicsim.misc.WorldEnded: world_ended = True # Not doing anything with `world_ended` yet return [node.state for node in path]
def _history_iter_simulate(simpack_grokker, state, iterations, step_profile): ''' Simulate from the given state for the given number of iterations. (Internal function for history-dependent simulations only.) This returns a generator that yields all the states one-by-one, from the initial state to the final one. ''' tree = garlicsim.data_structures.Tree() root = tree.add_state(state, parent=None) path = root.make_containing_path() history_browser = history_browser_module.HistoryBrowser(path) iterator = simpack_grokker.get_step_iterator(history_browser, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_node = root current_state = current_node.state yield current_state world_ended = False try: for current_state in finite_iterator: yield current_state current_node = tree.add_state(current_state, parent=current_node) except garlicsim.misc.WorldEnded: world_ended = True # Not doing anything with `world_ended` yet raise StopIteration
def _non_history_iter_simulate(simpack_grokker, state, iterations, step_profile): ''' Simulate from the given state for the given number of iterations. (Internal function for non-history-dependent simulations only.) This returns a generator that yields all the states one-by-one, from the initial state to the final one. ''' iterator = simpack_grokker.get_step_iterator(state, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_state = state yield current_state world_ended = False try: for current_state in finite_iterator: yield current_state except garlicsim.misc.WorldEnded: world_ended = True # Not doing anything with `world_ended` yet raise StopIteration
def __history_simulate(simpack_grokker, state, iterations=1, step_profile=None): """ For history-dependent simulations only: Simulate from the given state for the given number of iterations. A simpack must be passed as the first parameter. A step profile may be passed to be used with the step function. Returns the final state of the simulation. """ if step_profile is None: step_profile = garlicsim.misc.StepProfile() tree = garlicsim.data_structures.Tree() root = tree.add_state(state, parent=None) path = root.make_containing_path() history_browser = history_browser_module.HistoryBrowser(path) iterator = simpack_grokker.step_generator(history_browser, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_node = root for current_state in finite_iterator: current_node = tree.add_state(current_state, parent=current_node) final_state = current_state # Which is still here as the last value from the for loop return final_state
def __non_history_dependent_simulate(self, node, iterations, step_profile=None): ''' Simulate from the given node for the given number of iterations. (Internal function for non-history-dependent simulations only.) The results are implemented the results into the tree. Note that the crunching for this is done synchronously, i.e. in the currrent thread. A step profile may be passed to be used with the step function. Returns the final node. ''' if step_profile is None: step_profile = garlicsim.misc.StepProfile() state = node.state iterator = self.simpack_grokker.step_generator(state, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_node = node try: for current_state in finite_iterator: current_node = self.tree.add_state(current_state, parent=current_node, step_profile=step_profile) except garlicsim.misc.WorldEnd: self.tree.make_end(current_node, step_profile) return current_node
def __history_simulate(simpack_grokker, state, iterations, step_profile): ''' Simulate from the given state for the given number of iterations. (Internal function, for history-dependent simulations only) Returns the final state of the simulation. ''' tree = garlicsim.data_structures.Tree() root = tree.add_state(state, parent=None) path = root.make_containing_path() history_browser = history_browser_module.HistoryBrowser(path) iterator = simpack_grokker.get_step_iterator(history_browser, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_node = root current_state = current_node.state try: for current_state in finite_iterator: current_node = tree.add_state(current_state, parent=current_node) except garlicsim.misc.WorldEnded: pass final_state = current_state # Which is still here as the last value from the `for` loop. return final_state
def __non_history_simulate(simpack_grokker, state, iterations=1, step_profile=None): ''' Simulate from the given state for the given number of iterations. (Internal function, for non-history-dependent simulations only.) A simpack grokker must be passed as the first parameter. A step profile may be passed to be used with the step function. Returns the final state of the simulation. ''' if step_profile is None: step_profile = garlicsim.misc.StepProfile() iterator = simpack_grokker.step_generator(state, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_state = state try: for current_state in finite_iterator: pass except garlicsim.misc.WorldEnd: pass final_state = current_state # Which is still here as the last value from the for loop return final_state
def __non_history_list_simulate(simpack_grokker, state, iterations, step_profile=None): ''' For non-history-dependent simulations only: Simulate from the given state for the given number of iterations. A simpack must be passed as the first parameter. Any extraneous parameters will be passed to the step function. Returns a list that spans all the states, from the initial one given to the final one. ''' if step_profile is None: step_profile = garlicsim.misc.StepProfile() tree = garlicsim.data_structures.Tree() root = tree.add_state(state, parent=None) path = root.make_containing_path() iterator = simpack_grokker.step_generator(state, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_node = root for current_state in finite_iterator: current_node = tree.add_state(current_state, parent=current_node) return [node.state for node in path]
def __history_dependent_simulate(self, node, iterations, step_profile=None): ''' For history-dependent simulations only: Simulate from the given node for the given number of iterations. The results are implemented the results into the tree. Note that the crunching for this is done synchronously, i.e. in the currrent thread. A step profile may be passed to be used with the step function. Returns the final node. ''' if step_profile is None: step_profile = garlicsim.misc.StepProfile() path = node.make_containing_path() history_browser = \ garlicsim.synchronous_crunching.HistoryBrowser(path, end_node=node) iterator = self.simpack_grokker.step_generator(history_browser, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_node = node for current_state in finite_iterator: current_node = self.tree.add_state(current_state, parent=current_node, step_profile=step_profile) history_browser.end_node = current_node return current_node
def test_dont_pull_extra_item(): '''Test that `shorten` doesn't pull an extra member from the iterable.''' def generator(): yield 1 yield 2 yield 3 raise Exception nose.tools.assert_raises(Exception, lambda: list(generator())) iterator_1 = shorten(generator(), 4) nose.tools.assert_raises(Exception, lambda: list(iterator_1)) iterator_2 = shorten(generator(), infinity) nose.tools.assert_raises(Exception, lambda: list(iterator_2)) iterator_3 = shorten(generator(), 3) list(iterator_3) # Pulling exactly three so we avoid the exception.
def __history_dependent_iter_simulate(self, node, iterations, step_profile): ''' Simulate from the given node for the given number of iterations. (Internal function for history-dependent simulations only.) The results are implemented into the tree. Note that the crunching for this is done synchronously, i.e. in the currrent thread. This returns a generator that yields all the nodes one-by-one, from the initial node to the final one. A step profile may be passed to be used with the step function. ''' path = node.make_containing_path() history_browser = garlicsim.synchronous_crunching.HistoryBrowser( path, tail_node=node ) iterator = self.simpack_grokker.get_step_iterator(history_browser, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) finite_iterator_with_lock = cute_iter_tools.iter_with( finite_iterator, self.tree.lock.write ) current_node = node yield current_node try: for current_state in finite_iterator_with_lock: current_node = self.tree.add_state(current_state, parent=current_node, step_profile=step_profile) history_browser.tail_node = current_node history_browser.path = current_node.make_containing_path() # Similarly to the `__history_dependent_simulate` method, here # we also need to recreate the path. But in this case we need # to do it not only on the first run, but on *each* run of the # loop, because this is a generator, and the user may wreak # havoc with the tree between `yield`s, causing our original # path not to lead to the `tail_node` anymore. # todo optimize: The fact we recreate a path every time might # be costly. yield current_node except garlicsim.misc.WorldEnded: self.tree.make_end(current_node, step_profile)
def __history_dependent_simulate(self, node, iterations, step_profile): ''' Simulate from the given node for the given number of iterations. (Internal function for history-dependent simulations only.) The results are implemented the results into the tree. Note that the crunching for this is done synchronously, i.e. in the currrent thread. A step profile may be passed to be used with the step function. Returns the final node. ''' step_profile = self.build_step_profile() path = node.make_containing_path() history_browser = garlicsim.synchronous_crunching.HistoryBrowser( path, tail_node=node ) iterator = self.simpack_grokker.get_step_iterator(history_browser, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_node = node first_run = True try: for current_state in finite_iterator: current_node = self.tree.add_state(current_state, parent=current_node, step_profile=step_profile) history_browser.tail_node = current_node if first_run: history_browser.path = current_node.make_containing_path() # Just once, after the first run, we set the path of the # history browser to be the new tail_node's path. Why? # Because just after the first run we've created the first # new node, possibly causing a fork. Because of the new # fork, the original path that we created at the beginning # of this method will get confused and take the old # timeline instead of the new timeline. (And it wouldn't # even have the `tail_node` to stop it, because that would # be on the new timeline.) So we create a new path for the # history browser. We only need to do this once, because # after the first node we work on one straight timeline and # we don't fork the tree any more. except garlicsim.misc.WorldEnded: self.tree.make_end(current_node, step_profile) return current_node
def test(): '''Test basic workings of `shorten`.''' my_range = [0, 1, 2, 3, 4] short_iterator = shorten(my_range, 3) assert short_iterator.__iter__() is short_iterator assert list(shorten(my_range, 0)) == [] assert list(shorten(my_range, 1)) == list(range(1)) assert list(shorten(my_range, 2)) == list(range(2)) assert list(shorten(my_range, 3)) == list(range(3)) assert list(shorten(my_range, 4)) == list(range(4)) assert list(shorten(my_range, infinity)) == my_range assert list(shorten(iter(my_range), infinity)) == my_range
def test(): '''Test basic workings of `shorten`.''' my_range = [0, 1, 2, 3, 4] short_iterator = shorten(my_range, 3) assert short_iterator.__iter__() is short_iterator assert list(shorten(my_range, 0)) == [] assert list(shorten(my_range, 1)) == range(1) assert list(shorten(my_range, 2)) == range(2) assert list(shorten(my_range, 3)) == range(3) assert list(shorten(my_range, 4)) == range(4) assert list(shorten(my_range, infinity)) == my_range assert list(shorten(iter(my_range), infinity)) == my_range
def __history_dependent_simulate(self, node, iterations, step_profile=None): ''' For history-dependent simulations only: Simulate from the given node for the given number of iterations. The results are implemented the results into the tree. Note that the crunching for this is done synchronously, i.e. in the currrent thread. A step profile may be passed to be used with the step function. Returns the final node. ''' if step_profile is None: step_profile = garlicsim.misc.StepProfile() path = node.make_containing_path() history_browser = \ garlicsim.synchronous_crunching.HistoryBrowser(path, end_node=node) iterator = self.simpack_grokker.step_generator(history_browser, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_node = node first_run = True for current_state in finite_iterator: current_node = self.tree.add_state(current_state, parent=current_node, step_profile=step_profile) history_browser.end_node = current_node if first_run: history_browser.path = current_node.make_containing_path() # Just once, after the first run, we set the path of the history # browser to be the new end_node's path. Why? # Because just after the first run we've created the first new # node, possibly causing a fork. Because of the new fork, the # original path that we created at the beginning of this method # will get confused and take the old timeline instead of the new # timeline. (And it wouldn't even have the end_node to stop it, # because that would be on the new timeline.) So we create a new # path for the history browser. We only need to do this once, # because after the first node we work on one straight timeline # and we don't fork the tree any more. return current_node
def __non_history_dependent_iter_simulate(self, node, iterations, step_profile=None): ''' Simulate from the given node for the given number of iterations. (Internal function for non-history-dependent simulations only.) The results are implemented into the tree. Note that the crunching for this is done synchronously, i.e. in the currrent thread. This returns a generator that yields all the nodes one-by-one, from the initial node to the final one. A step profile may be passed to be used with the step function. ''' state = node.state iterator = self.simpack_grokker.get_step_iterator(state, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) finite_iterator_with_lock = cute_iter_tools.iter_with( finite_iterator, self.tree.lock.write ) current_node = node yield current_node try: for current_state in finite_iterator_with_lock: current_node = self.tree.add_state(current_state, parent=current_node, step_profile=step_profile) yield current_node except garlicsim.misc.WorldEnded: self.tree.make_end(current_node, step_profile)
def __history_list_simulate(simpack_grokker, state, iterations, step_profile=None): ''' Simulate from the given state for the given number of iterations. (Internal function for history-dependent simulations only.) A simpack grokker must be passed as the first parameter. Any extraneous parameters will be passed to the step function. Returns a list that spans all the states, from the initial one given to the final one. ''' if step_profile is None: step_profile = garlicsim.misc.StepProfile() tree = garlicsim.data_structures.Tree() root = tree.add_state(state, parent=None) path = root.make_containing_path() history_browser = history_browser_module.HistoryBrowser(path) iterator = simpack_grokker.step_generator(history_browser, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_node = root current_state = current_node.state world_ended = False try: for current_state in finite_iterator: current_node = tree.add_state(current_state, parent=current_node) except garlicsim.misc.WorldEnd: world_ended = True # Not doing anything with `world_ended` yet return [node.state for node in path]
def __non_history_simulate(simpack_grokker, state, iterations, step_profile): ''' Simulate from the given state for the given number of iterations. (Internal function, for non-history-dependent simulations only.) Returns the final state of the simulation. ''' # We try to get an inplace step iterator, if our simpack supplies one. # Otherwise we use a regular one. The reason we do it here in # `__non_history_simulate` is because this function gives the user only the # final state, without keeping any states in between. Therefore we can # afford doing the steps inplace, and we get better performance because we # don't deepcopy states. if simpack_grokker.is_inplace_iterator_available(step_profile) is True: state_copy = garlicsim.misc.state_deepcopy.state_deepcopy(state) iterator = \ simpack_grokker.get_inplace_step_iterator(state_copy, step_profile) else: # Inplace iterator is not available iterator = simpack_grokker.get_step_iterator(state, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_state = state try: for current_state in finite_iterator: pass except garlicsim.misc.WorldEnded: pass final_state = current_state # Which is still here as the last value from the `for` loop. return final_state
def _non_history_iter_simulate(simpack_grokker, state, iterations, step_profile=None): ''' Simulate from the given state for the given number of iterations. (Internal function for non-history-dependent simulations only.) A simpack grokker must be passed as the first parameter. Any extraneous parameters will be passed to the step function. This returns a generator that yields all the states one-by-one, from the initial state to the final one. Returns a list that spans all the states, from the initial one given to the final one. ''' if step_profile is None: step_profile = garlicsim.misc.StepProfile() iterator = simpack_grokker.step_generator(state, step_profile) finite_iterator = cute_iter_tools.shorten(iterator, iterations) current_state = state yield current_state world_ended = False try: for current_state in finite_iterator: yield current_state except garlicsim.misc.WorldEnd: world_ended = True # Not doing anything with `world_ended` yet raise StopIteration