예제 #1
0
def retrace_instantiation(fact, streams, evaluations, free_parameters,
                          visited_facts, planned_results):
    # Makes two assumptions:
    # 1) Each stream achieves a "primary" fact that uses all of its inputs + outputs
    # 2) Outputs are only free parameters (no constants)
    if (evaluation_from_fact(fact) in evaluations) or (fact in visited_facts):
        return
    visited_facts.add(fact)
    for stream in streams:
        for cert in stream.certified:
            if get_prefix(fact) == get_prefix(cert):
                mapping = get_mapping(get_args(cert),
                                      get_args(fact))  # Should be same anyways
                if not all(p in mapping
                           for p in (stream.inputs + stream.outputs)):
                    # TODO: assumes another effect is sufficient for binding
                    # Create arbitrary objects for inputs/outputs that aren't mentioned
                    # Can lead to incorrect ordering
                    continue

                input_objects = safe_apply_mapping(stream.inputs, mapping)
                output_objects = safe_apply_mapping(stream.outputs, mapping)
                if not all(out in free_parameters for out in output_objects):
                    # Can only bind if free
                    continue
                instance = stream.get_instance(input_objects)
                for new_fact in instance.get_domain():
                    retrace_instantiation(new_fact, streams, evaluations,
                                          free_parameters, visited_facts,
                                          planned_results)
                planned_results.append(instance.get_result(output_objects))
예제 #2
0
    def fn(literal, action):
        if literal.predicate not in predicate_map:
            return literal
        # TODO: other checks on only inputs
        stream = predicate_map[literal.predicate]
        mapping = remap_certified(literal, stream)
        if mapping is None:
            # TODO: this excludes typing. This is not entirely safe
            return literal
        output_args = set(mapping[arg] for arg in stream.outputs)
        if isinstance(action, pddl.Action): # TODO: unified Action/Axiom effects
            for effect in action.effects:
                if isinstance(effect, pddl.Effect) and (output_args & set(effect.literal.args)):
                    raise RuntimeError('Fluent stream outputs cannot be in action effects: {}'.format(
                        effect.literal.predicate))
        elif not stream.is_negated:
            axiom = action
            raise RuntimeError('Fluent stream outputs cannot be in an axiom: {}'.format(axiom.name))

        blocked_args = safe_apply_mapping(stream.inputs, mapping)
        blocked_literal = literal.__class__(stream.blocked_predicate, blocked_args).negate()
        if stream.is_negated:
            conditions = [blocked_literal]
            conditions.extend(pddl.Atom(get_prefix(fact), safe_apply_mapping(get_args(fact), mapping)) # fd_from_fact
                              for fact in stream.domain) # TODO: be careful when using imply
            return pddl.Conjunction(conditions) # TODO: prune redundant conditions
        return pddl.Conjunction([literal, blocked_literal])
예제 #3
0
 def _add_combinations(self, stream, atoms):
     if not all(atoms):
         return
     domain = list(map(head_from_fact, stream.domain))
     # Most constrained variable/atom to least constrained
     for combo in product(*atoms):
         mapping = test_mapping(domain, combo)
         if mapping is not None:
             input_objects = safe_apply_mapping(stream.inputs, mapping)
             self.push_instance(stream.get_instance(input_objects))
예제 #4
0
def opt_from_graph(names, orders, infos={}):
    param_from_order = {order: PARAM_TEMPLATE.format(*order) for order in orders}
    fact_from_order = {order: (PREDICATE, param_from_order[order]) for order in orders}
    object_from_param = {param: parse_value(param) for param in param_from_order.values()}

    incoming_from_edges, outgoing_from_edges = neighbors_from_orders(orders)
    stream_plan = []
    for i, n in enumerate(names):
        #info = infos.get(n, StreamInfo(p_success=1, overhead=0, verbose=True))
        inputs = [param_from_order[n2, n] for n2 in incoming_from_edges[n]]
        outputs = [param_from_order[n, n2] for n2 in outgoing_from_edges[n]]
        #gen = get_gen(outputs=outputs, p_success=info.p_success)
        #gen = get_gen(infos[i], outputs=outputs)
        stream = Stream(
            name=n,
            #gen_fn=DEBUG,
            #gen_fn=from_gen(gen),
            gen_fn=from_gen_fn(get_gen_fn(outputs=outputs, **infos[i])),
            inputs=inputs,
            domain=[fact_from_order[n2, n] for n2 in incoming_from_edges[n]],
            fluents=[],
            outputs=outputs,
            certified=[fact_from_order[n, n2] for n2 in outgoing_from_edges[n]],
            #info=info,
            info=StreamInfo(),
        )
        # TODO: dump names

        print()
        print(stream)
        input_objects = safe_apply_mapping(stream.inputs, object_from_param)
        instance = stream.get_instance(input_objects)
        print(instance)
        output_objects = safe_apply_mapping(stream.outputs, object_from_param)
        result = instance.get_result(output_objects)
        print(result)
        stream_plan.append(result)

    opt_plan = OptPlan(action_plan=[], preimage_facts=[])
    opt_solution = OptSolution(stream_plan, opt_plan, cost=1)
    return opt_solution
예제 #5
0
 def _add_combinations_relation(self, stream, atoms):
     if not all(atoms):
         return
     # TODO: might be a bug here?
     domain = list(map(head_from_fact, stream.domain))
     # TODO: compute this first?
     relations = [
         Relation(filter(is_parameter, domain[index].args), [
             tuple(a for a, b in safe_zip(atom.args, domain[index].args)
                   if is_parameter(b)) for atom in atoms[index]
         ]) for index in compute_order(domain, atoms)
     ]
     solution = solve_satisfaction(relations)
     for element in solution.body:
         mapping = solution.get_mapping(element)
         input_objects = safe_apply_mapping(stream.inputs, mapping)
         self.push_instance(stream.get_instance(input_objects))
예제 #6
0
def select_inputs(instance, inputs):
    external = instance.external
    assert set(inputs) <= set(external.inputs)
    mapping = get_mapping(external.inputs, instance.input_objects)
    return safe_apply_mapping(inputs, mapping)