def _instantiate(self, index, new_result): if not new_result.is_successful(): return None # TODO: check if satisfies target certified opt_result = self.remaining_results[index] #if not isinstance(new_result, StreamResult) or not new_result.output_objects: # self.stream_indices = puncture(self.stream_indices, index) # self.stream_attempts = puncture(self.stream_attempts, index) # self.bound_results[self.stream_indices[index]] = new_result # self.cost = update_cost(self.cost, opt_result, new_result) # self._remaining_results = puncture(self._remaining_results, index) # self.queue.disable_binding(self) # self.queue.new_binding(self) # return self bound_results = self.bound_results.copy() bound_results[self.stream_indices[index]] = new_result binding = Binding( self.queue, self.skeleton, puncture(self.stream_indices, index), puncture(self.stream_attempts, index), bound_results, update_bindings(self.bindings, opt_result, new_result), update_cost(self.cost, opt_result, new_result)) #if not isinstance(new_result, StreamResult) or not new_result.output_objects: # binding._remaining_results = puncture(self._remaining_results, index) if len(binding.stream_indices) < len( self.skeleton.best_binding.stream_indices): self.skeleton.best_binding = binding self.children.append(binding) self.queue.new_binding(binding) #if not isinstance(new_result, StreamResult) or not new_result.output_objects: # # The binding is dominated # self.enumerated = True # self.queue.update_enabled(self) return binding
def _process_binding(self, binding): is_new = False if binding.is_dominated(): return False, is_new if binding.is_bound(): action_plan = bind_action_plan(binding.skeleton.action_plan, binding.mapping) self.store.add_plan(action_plan, binding.cost) return False, True binding.attempts += 1 instance = binding.result.instance if PRUNE_BINDINGS and not binding.do_evaluate(): # TODO: causes redudant plan skeletons to be identified (along with complexity using attempts instead of calls) # Do I need to reenable this stream in case another skeleton needs it? # TODO: should I perform this when deciding to sample something new instead? #if instance.enumerated: # return False, is_new return None, is_new #if not is_instance_ready(self.evaluations, instance): # raise RuntimeError(instance) if binding.up_to_date(): new_results, _ = process_instance(self.store, self.domain, instance, disable=self.disable) is_new = bool(new_results) for call_idx in range(binding.calls, instance.num_calls): for new_result in instance.results_history[ call_idx]: # TODO: don't readd if successful already if new_result.is_successful(): new_mapping = update_bindings(binding.mapping, binding.result, new_result) new_cost = update_cost(binding.cost, binding.result, new_result) new_history = binding.history + [call_idx] new_binding = Binding(binding.skeleton, new_cost, new_history, new_mapping, binding.index + 1) binding.children.append(new_binding) heappush(self.queue, new_binding.get_element()) binding.calls = instance.num_calls binding.attempts = max(binding.attempts, binding.calls) binding.complexity = None readd = not instance.enumerated return readd, is_new
def update_bindings(self): new_bindings = [] instance = self.result.instance for call_idx in range(self.calls, instance.num_calls): for new_result in instance.results_history[call_idx]: # TODO: don't readd if successful already if new_result.is_successful(): new_bindings.append(Binding( skeleton=self.skeleton, cost=update_cost(self.cost, self.result, new_result), history=self.history + [call_idx], mapping=update_bindings(self.mapping, self.result, new_result), index=self.index + 1, # TODO: history instead of results_history parent=self, parent_result=new_result)) self.calls = instance.num_calls self.visits = max(self.visits, self.calls) self.complexity = None # Forces re-computation #self.skeleton.visualize_bindings() return new_bindings