def produce_bindings(universe, order, plan, greedy, shared, dfs): if dfs: bindings = dfs_bindings(order, universe, greedy=greedy, shared=shared) else: bindings = single_bindings(order, universe, greedy=greedy, shared=shared) if bindings is None: return None bound_plan = [] for action, args in plan: bound_args = replace_abstract_constants(args, bindings) assert bound_args is not None bound_plan.append((action, bound_args)) return bound_plan
def dfs_bindings(order, universe, bindings={}, greedy=True, shared=True): if not order: return bindings stream = order[0] if shared or not stream.shared: inputs = replace_abstract_constants(stream.inputs, bindings) #dependent_goals = get_dependent_streams(stream, order, bindings) dependent_atoms = get_dependent_goals(stream, order, bindings) outputs_list = list( bind_stream_outputs(stream, inputs, universe, dependent_atoms=dependent_atoms)) for outputs in outputs_list: new_bindings = bindings.copy( ) # TODO - what if this is the same as bindings? local_failure = False for abs_const, real_const in outputs.iteritems(): assert stream.shared or abs_const not in new_bindings if new_bindings.get(abs_const, real_const) == real_const: new_bindings[abs_const] = real_const else: local_failure = True result_bindings = dfs_bindings(order[1:], universe, bindings=new_bindings, greedy=greedy, shared=shared) if not local_failure and result_bindings is not None: return result_bindings if not outputs_list and not greedy: dfs_bindings(order[1:], universe, bindings=bindings, greedy=greedy, shared=shared) elif not greedy: dfs_bindings(order[1:], universe, bindings=bindings, greedy=greedy, shared=shared) return None
def single_bindings(order, universe, greedy=True, shared=True): failure = False bindings = {} for stream in order: local_failure = True if shared or not stream.shared: inputs = replace_abstract_constants(stream.inputs, bindings) outputs = next(bind_stream_outputs(stream, inputs, universe), None) if outputs is not None: # NOTE - by checking stream validity before applying, we allow for previously bound things local_failure = False for abs_const, real_const in outputs.iteritems(): assert stream.shared or abs_const not in bindings if bindings.get(abs_const, real_const) == real_const: bindings[abs_const] = real_const else: local_failure = True failure |= local_failure if greedy and failure: break return bindings if not failure else None