Esempio n. 1
0
def get_plan_cost(function_evaluations, action_plan, domain, unit_costs):
    if action_plan is None:
        return INF
    if unit_costs:
        return len(action_plan)
    action_cost = 0.
    results_from_head = get_results_from_head(function_evaluations)
    for name, args in action_plan:
        action_cost += get_action_cost(domain, results_from_head, name, args)
    return action_cost
Esempio n. 2
0
def get_plan_cost(function_evaluations, action_plan, domain, unit_costs):
    # TODO: deprecate in favor of using the raw action instances
    if action_plan is None:
        return INF
    if unit_costs:
        return len(action_plan)
    results_from_head = get_results_from_head(function_evaluations)
    return sum([0.] + [
        get_action_cost(domain, results_from_head, name, args)
        for name, args in action_plan
    ])
Esempio n. 3
0
def extract_function_plan(function_evaluations, action_plan, domain,
                          unit_costs):
    if unit_costs:
        return []
    function_plan = set()
    results_from_head = get_results_from_head(function_evaluations)
    for name, args in action_plan:
        action = find_unique(lambda a: a.name == name, domain.actions)
        pddl_args = tuple(map(pddl_from_object, args))
        result = extract_function_results(results_from_head, action, pddl_args)
        if result is not None:
            function_plan.add(result)
    return list(function_plan)
Esempio n. 4
0
def compute_function_plan(opt_evaluations, action_plan, unit_costs):
    function_plan = set()
    if unit_costs:
        return function_plan
    results_from_head = get_results_from_head(opt_evaluations)
    for action_instance in action_plan:
        action = action_instance.action
        if action is None:
            continue
        args = [action_instance.var_mapping[p.name] for p in action.parameters]
        function_result = extract_function_results(results_from_head, action,
                                                   args)
        if function_result is not None:
            function_plan.add(function_result)
    return function_plan
Esempio n. 5
0
def simplify_actions(opt_evaluations, action_plan, task, actions, unit_costs):
    # TODO: add ordering constraints to simplify the optimization
    import pddl
    import instantiate

    fluent_facts = MockSet()
    init_facts = set()
    type_to_objects = instantiate.get_objects_by_type(task.objects, task.types)
    results_from_head = get_results_from_head(opt_evaluations)

    action_from_name = {}
    function_plan = set()
    for i, (name, args) in enumerate(action_plan):
        action = find_unique(lambda a: a.name == name, actions)
        assert (len(action.parameters) == len(args))
        # parameters = action.parameters[:action.num_external_parameters]
        var_mapping = {p.name: a for p, a in zip(action.parameters, args)}
        new_name = '{}-{}'.format(name, i)
        new_parameters = action.parameters[len(args):]
        new_preconditions = []
        action.precondition.instantiate(var_mapping, init_facts, fluent_facts, new_preconditions)
        new_effects = []
        for eff in action.effects:
            eff.instantiate(var_mapping, init_facts, fluent_facts, type_to_objects, new_effects)
        new_effects = [pddl.Effect([], pddl.Conjunction(conditions), effect)
                       for conditions, effect in new_effects]
        cost = pddl.Increase(fluent=pddl.PrimitiveNumericExpression(symbol=TOTAL_COST, args=[]),
                             expression=pddl.NumericConstant(1))
        # cost = None
        task.actions.append(pddl.Action(new_name, new_parameters, len(new_parameters),
                                        pddl.Conjunction(new_preconditions), new_effects, cost))
        action_from_name[new_name] = (name, map(obj_from_pddl, args))
        if not unit_costs:
            function_result = extract_function_results(results_from_head, action, args)
            if function_result is not None:
                function_plan.add(function_result)
    return action_from_name, list(function_plan)
Esempio n. 6
0
def recover_stream_plan(evaluations, goal_expression, domain, stream_results, action_plan, negative, unit_costs):
    import pddl
    import instantiate
    # Universally quantified conditions are converted into negative axioms
    # Existentially quantified conditions are made additional preconditions
    # Universally quantified effects are instantiated by doing the cartesian produce of types (slow)
    # Added effects cancel out removed effects

    real_task = task_from_domain_problem(domain, get_problem(evaluations, goal_expression, domain, unit_costs))
    node_from_atom = get_achieving_streams(evaluations, stream_results)
    opt_evaluations = apply_streams(evaluations, stream_results)
    opt_task = task_from_domain_problem(domain, get_problem(opt_evaluations, goal_expression, domain, unit_costs))
    function_assignments = {fact.fluent: fact.expression for fact in opt_task.init  # init_facts
                            if isinstance(fact, pddl.f_expression.FunctionAssignment)}
    type_to_objects = instantiate.get_objects_by_type(opt_task.objects, opt_task.types)
    results_from_head = get_results_from_head(opt_evaluations)
    action_instances = instantiate_actions(opt_task, type_to_objects, function_assignments, action_plan)
    negative_from_name = get_negative_predicates(negative)
    axioms_from_name = get_derived_predicates(opt_task.axioms)

    opt_task.init = set(opt_task.init)
    real_states = [set(real_task.init)] # TODO: had old way of doing this (~July 2018)
    preimage_plan = []
    function_plan = set()
    for layer in action_instances:
        for pair, action_instance in layer:
            axiom_plan = extract_axiom_plan(opt_task, action_instance, negative_from_name,
                                            static_state=real_states[-1])
            if axiom_plan is None:
                continue
            simplify_conditional_effects(real_states[-1], opt_task.init, action_instance, axioms_from_name)
            preimage_plan.extend(axiom_plan + [action_instance])
            apply_action(opt_task.init, action_instance)
            real_states.append(set(real_states[-1]))
            apply_action(real_states[-1], action_instance)
            if not unit_costs and (pair is not None):
                function_result = extract_function_results(results_from_head, *pair)
                if function_result is not None:
                    function_plan.add(function_result)
            break
        else:
            raise RuntimeError('No action instances are applicable')

    # TODO: could instead just accumulate difference between real and opt
    full_preimage = plan_preimage(preimage_plan, [])
    stream_preimage = set(full_preimage) - real_states[0]
    negative_preimage = set(filter(lambda a: a.predicate in negative_from_name, stream_preimage))
    positive_preimage = stream_preimage - negative_preimage
    function_plan.update(convert_negative(negative_preimage, negative_from_name, full_preimage, real_states))

    step_from_fact = {fact_from_fd(l): full_preimage[l] for l in positive_preimage if not l.negated}
    target_facts = list(step_from_fact.keys())
    #stream_plan = reschedule_stream_plan(evaluations, target_facts, domain, stream_results)
    stream_plan = []
    extract_stream_plan(node_from_atom, target_facts, stream_plan)
    stream_plan = prune_stream_plan(evaluations, stream_plan, target_facts)
    stream_plan = convert_fluent_streams(stream_plan, real_states, step_from_fact, node_from_atom)
    # visualize_constraints(map(fact_from_fd, stream_preimage))

    if DO_RESCHEDULE: # TODO: detect this based on unique or not
        # TODO: maybe test if partial order between two ways of achieving facts, if not prune
        new_stream_plan = reschedule_stream_plan(evaluations, target_facts, domain, stream_plan)
        if new_stream_plan is not None:
            stream_plan = new_stream_plan
    return stream_plan + list(function_plan)