def translate_task(strips_to_sas, ranges, translation_key,
                   mutex_dict, mutex_ranges, mutex_key,
                   init, goals,
                   actions, axioms, metric, implied_facts):
    with timers.timing("Processing axioms", block=True):
        axioms, axiom_init, axiom_layer_dict = axiom_rules.handle_axioms(
            actions, axioms, goals)
    init = init + axiom_init
    #axioms.sort(key=lambda axiom: axiom.name)
    #for axiom in axioms:
    #  axiom.dump()

    if options.dump_task:
        # Remove init facts that don't occur in strips_to_sas: they're constant.
        nonconstant_init = filter(strips_to_sas.get, init)
        dump_task(nonconstant_init, goals, actions, axioms, axiom_layer_dict)

    init_values = [rang - 1 for rang in ranges]
    # Closed World Assumption: Initialize to "range - 1" == Nothing.
    for fact in init:
        pairs = strips_to_sas.get(fact, [])  # empty for static init facts
        for var, val in pairs:
            curr_val = init_values[var]
            if curr_val != ranges[var] - 1 and curr_val != val:
                assert False, "Inconsistent init facts! [fact = %s]" % fact
            init_values[var] = val
    init = sas_tasks.SASInit(init_values)

    goal_dict_list = translate_strips_conditions(goals, strips_to_sas, ranges,
                                                 mutex_dict, mutex_ranges)
    if goal_dict_list is None:
        # "None" is a signal that the goal is unreachable because it
        # violates a mutex.
        return unsolvable_sas_task("Goal violates a mutex")

    assert len(goal_dict_list) == 1, "Negative goal not supported"
    ## we could substitute the negative goal literal in
    ## normalize.substitute_complicated_goal, using an axiom. We currently
    ## don't do this, because we don't run into this assertion, if the
    ## negative goal is part of finite domain variable with only two
    ## values, which is most of the time the case, and hence refrain from
    ## introducing axioms (that are not supported by all heuristics)
    goal_pairs = list(goal_dict_list[0].items())
    goal = sas_tasks.SASGoal(goal_pairs)

    operators = translate_strips_operators(actions, strips_to_sas, ranges,
                                           mutex_dict, mutex_ranges,
                                           implied_facts)
    axioms = translate_strips_axioms(axioms, strips_to_sas, ranges, mutex_dict,
                                     mutex_ranges)

    axiom_layers = [-1] * len(ranges)
    for atom, layer in axiom_layer_dict.items():
        assert layer >= 0
        [(var, val)] = strips_to_sas[atom]
        axiom_layers[var] = layer
    variables = sas_tasks.SASVariables(ranges, axiom_layers, translation_key)
    mutexes = [sas_tasks.SASMutexGroup(group) for group in mutex_key]
    return sas_tasks.SASTask(variables, mutexes, init, goal,
                             operators, axioms, metric)
예제 #2
0
def translate_task(strips_to_sas, ranges, translation_key, mutex_key,
                   init, goals, actions, axioms, metric):
    axioms, axiom_init, axiom_layer_dict = axiom_rules.handle_axioms(
      actions, axioms, goals)
    init = init + axiom_init
    #axioms.sort(key=lambda axiom: axiom.name)
    #for axiom in axioms:
    #  axiom.dump()

    init_values = [rang - 1 for rang in ranges]
    # Closed World Assumption: Initialize to "range - 1" == Nothing.
    for fact in init:
        pairs = strips_to_sas.get(fact, [])  # empty for static init facts
        for var, val in pairs:
            assert init_values[var] == ranges[var] - 1, "Inconsistent init facts!"
            init_values[var] = val
    init = sas_tasks.SASInit(init_values)

    goal_pairs = list(translate_strips_conditions(goals, strips_to_sas, ranges).items())
    goal = sas_tasks.SASGoal(goal_pairs)

    operators = translate_strips_operators(actions, strips_to_sas, ranges)
    axioms = translate_strips_axioms(axioms, strips_to_sas, ranges)

    axiom_layers = [-1] * len(ranges)
    for atom, layer in axiom_layer_dict.items():
        assert layer >= 0
        [(var, val)] = strips_to_sas[atom]
        axiom_layers[var] = layer
    variables = sas_tasks.SASVariables(ranges, axiom_layers, translation_key)
    mutexes = [sas_tasks.SASMutexGroup(group) for group in mutex_key]
    return sas_tasks.SASTask(variables, mutexes, init, goal,
                             operators, axioms, metric)
예제 #3
0
def translate_task(strips_to_sas, ranges, mutex_dict, mutex_ranges, init, goals,
                   actions, axioms, metric, implied_facts):
    with timers.timing("Processing axioms", block=True):
        axioms, axiom_init, axiom_layer_dict = axiom_rules.handle_axioms(
            actions, axioms, goals)
    init = init + axiom_init
    #axioms.sort(key=lambda axiom: axiom.name)
    #for axiom in axioms:
    #  axiom.dump()

    init_values = [rang - 1 for rang in ranges]
    # Closed World Assumption: Initialize to "range - 1" == Nothing.
    for fact in init:
        pair = strips_to_sas.get(fact)
        pairs = strips_to_sas.get(fact, [])  # empty for static init facts
        for var, val in pairs:
            assert init_values[var] == ranges[var] - 1, "Inconsistent init facts!"
            init_values[var] = val
    init = sas_tasks.SASInit(init_values)

    goal_dict_list = translate_strips_goal(goals, strips_to_sas, ranges, mutex_dict, mutex_ranges)
    assert len(goal_dict_list) == 1, "Negative goal not supported"
    ## we could substitute the negative goal literal in
    ## normalize.substitute_complicated_goal, using an axiom. We currently
    ## don't do this, because we don't run into this assertion, if the
    ## negative goal is part of finite domain variable with only two
    ## values, which is most of the time the case, and hence refrain from
    ## introducing axioms (that are not supported by all heuristics)
    goal_pairs = goal_dict_list[0].items()
    goal = sas_tasks.SASGoal(goal_pairs)

    operators = translate_strips_operators(actions, strips_to_sas, ranges, mutex_dict, mutex_ranges, implied_facts)
    axioms = translate_strips_axioms(axioms, strips_to_sas, ranges, mutex_dict, mutex_ranges)

    axiom_layers = [-1] * len(ranges)
    for atom, layer in axiom_layer_dict.iteritems():
        assert layer >= 0
        [(var, val)] = strips_to_sas[atom]
        axiom_layers[var] = layer
    variables = sas_tasks.SASVariables(ranges, axiom_layers)

    return sas_tasks.SASTask(variables, init, goal, operators, axioms, metric)
예제 #4
0
def translate_task(strips_to_sas, ranges, translation_key,
                   mutex_dict, mutex_ranges, mutex_key,
                   init, init_unknown, init_oneof, init_formula, goals,
                   actions, observation_actions, axioms, metric, implied_facts):
    with timers.timing("Processing axioms", block=True):
        axioms, axiom_init, axiom_layer_dict = axiom_rules.handle_axioms(
            actions, axioms, goals)
    init = init + axiom_init
    #axioms.sort(key=lambda axiom: axiom.name)
    #for axiom in axioms:
    #  axiom.dump()

    if DUMP_TASK:
        # Remove init facts that don't occur in strips_to_sas: they're constant.
        nonconstant_init = filter(strips_to_sas.get, init)
        dump_task(nonconstant_init, goals, actions, axioms, axiom_layer_dict)

    # Closed World Assumption
    false_facts = list(range(len(ranges)))
    for fact in init_unknown:
        pairs = strips_to_sas.get(fact, [])
        for pair in pairs:
            false_facts.remove(pair[0])

    facts = []
    for fact in init:
        assert fact not in init_unknown
        pairs = strips_to_sas.get(fact, [])
        for pair in pairs:
            false_facts.remove(pair[0])
        if pairs:
            facts = facts + pairs
    for var in false_facts:
        assert fact not in init_unknown
        facts.append((var, ranges[var] - 1))
    facts_oneof = []   
    for oneof in init_oneof:
        assert len(oneof) >= 2
        for fact in oneof:
            assert fact in init_unknown
        l = []
        for one in oneof:
            l = l + strips_to_sas.get(one, [])
        facts_oneof.append(l)

    # move to conditions.py?
    def translate_formula(formula, result, strips_to_sas, ranges, mutex_dict, mutex_ranges):
        if isinstance(formula, pddl.conditions.Atom):
            assert formula in init_unknown
            result.append(strips_to_sas.get(formula, []))
        elif isinstance(formula, pddl.conditions.NegatedAtom):
            dict_list = translate_strips_conditions([formula], strips_to_sas, ranges, mutex_dict, mutex_ranges)
            assert len(dict_list) == 1
            result.append(dict_list[0].items())
        elif isinstance(formula, pddl.conditions.Disjunction):
            result.append("or(")
            for part in formula.parts:
                translate_formula(part, result, strips_to_sas, ranges, mutex_dict, mutex_ranges)
            result.append(")")
        elif isinstance(formula, pddl.conditions.Conjunction):
            result.append("and(")
            for part in formula.parts:
                translate_formula(part, result, strips_to_sas, ranges, mutex_dict, mutex_ranges)
            result.append(")")
        else:
            assert False, print(formula)
    formulae = []
    for formula in init_formula:
        result = []
        translate_formula(formula, result, strips_to_sas, ranges, mutex_dict, mutex_ranges)
        formulae.append(result)
    init = sas_tasks.SASInit(facts, facts_oneof, formulae)

    goal_dict_list = translate_strips_conditions(goals, strips_to_sas, ranges,
                                                 mutex_dict, mutex_ranges)
    if goal_dict_list is None:
        # "None" is a signal that the goal is unreachable because it
        # violates a mutex.
        return unsolvable_sas_task("Goal violates a mutex")

    assert len(goal_dict_list) == 1, "Negative goal not supported"
    ## we could substitute the negative goal literal in
    ## normalize.substitute_complicated_goal, using an axiom. We currently
    ## don't do this, because we don't run into this assertion, if the
    ## negative goal is part of finite domain variable with only two
    ## values, which is most of the time the case, and hence refrain from
    ## introducing axioms (that are not supported by all heuristics)
    goal_pairs = list(goal_dict_list[0].items())
    goal = sas_tasks.SASGoal(goal_pairs)

    operators = translate_strips_operators(actions, strips_to_sas, ranges,
                                           mutex_dict, mutex_ranges,
                                           implied_facts)
    observation_operators = translate_strips_operators(observation_actions, 
                                                       strips_to_sas, ranges, 
                                                       mutex_dict, mutex_ranges,
                                                       implied_facts)
    axioms = translate_strips_axioms(axioms, strips_to_sas, ranges, mutex_dict,
                                     mutex_ranges)

    axiom_layers = [-1] * len(ranges)
    for atom, layer in axiom_layer_dict.items():
        assert layer >= 0
        [(var, val)] = strips_to_sas[atom]
        axiom_layers[var] = layer
    variables = sas_tasks.SASVariables(ranges, axiom_layers, translation_key)
    mutexes = [sas_tasks.SASMutexGroup(group) for group in mutex_key]
    return sas_tasks.SASTask(variables, mutexes, init, goal,
                             operators + observation_operators, 
                             axioms, metric)
예제 #5
0
def translate_task(strips_to_sas, ranges, init, goals, actions,
                   durative_actions, axioms, num_axioms, num_axioms_by_layer,
                   max_num_layer, num_axiom_map, const_num_axioms):

    axioms, axiom_init, axiom_layer_dict, true_atoms, false_atoms = axiom_rules.handle_axioms(
        actions, durative_actions, axioms, goals)

    init = init + axiom_init

    # filter trivial true_atoms from goal
    goals = [g for g in goals if g not in true_atoms
             ]  # FIXME: empty goal would be handled nicely by search
    # if any atom in goal is false, the task is unsolvable
    for fa in false_atoms:
        if fa in goals:
            print "False atom in goal:"
            fa.dump()
            return unsolvable_sas_task("False atom in goal")

    comp_axioms = [{}, []]
    goal_dict_list = translate_strips_conditions(goals, strips_to_sas, ranges,
                                                 comp_axioms)
    assert len(goal_dict_list) == 1, "Negative goal not supported"
    ## we could substitute the negative goal literal in
    ## normalize.substitute_complicated_goal, using an axiom. We currently
    ## don't do this, because we don't run into this assertion, if the
    ## negative goal is part of finite domain variable with only two
    ## values, which is most of the time the case, and hence refrain from
    ## introducing axioms (that are not supported by all heuristics)
    goal_pairs = goal_dict_list[0].items()
    goal = sas_tasks.SASGoal(goal_pairs)

    # FIXME: remove this, defunct anyways
    operators = translate_strips_operators(actions, strips_to_sas, ranges,
                                           comp_axioms)
    temp_operators = translate_temporal_strips_operators(
        durative_actions, strips_to_sas, ranges, comp_axioms, true_atoms,
        false_atoms)

    axioms = translate_strips_axioms(axioms, strips_to_sas, ranges,
                                     comp_axioms)
    sas_num_axioms = [
        translate_numeric_axiom(axiom, strips_to_sas) for axiom in num_axioms
        if axiom not in const_num_axioms and axiom.effect not in num_axiom_map
    ]

    axiom_layers = [-1] * len(ranges)

    ## each numeric axiom gets its own layer (a wish of a colleague for
    ## knowledge compilation or search. If you use only the translator,
    ## you can change this)
    num_axiom_layer = 0
    for layer in num_axioms_by_layer:
        num_axioms_by_layer[layer].sort(lambda x, y: cmp(x.name, y.name))
        for axiom in num_axioms_by_layer[layer]:
            if axiom.effect not in num_axiom_map:
                [(var, val)] = strips_to_sas[axiom.effect]
                if layer == -1:
                    axiom_layers[var] = -1
                else:
                    axiom_layers[var] = num_axiom_layer
                    num_axiom_layer += 1
    for axiom in comp_axioms[1]:
        axiom_layers[axiom.effect] = num_axiom_layer
    for atom, layer in axiom_layer_dict.iteritems():
        assert layer >= 0
        [(var, val)] = strips_to_sas[atom]
        axiom_layers[var] = layer + num_axiom_layer + 1
    variables = sas_tasks.SASVariables(ranges, axiom_layers)

    init_values = [rang - 1 for rang in ranges]
    # Closed World Assumption: Initialize to "range - 1" == Nothing.
    for fact in init:
        if isinstance(fact, pddl.Atom):
            pairs = strips_to_sas.get(fact, [])  # empty for static init facts
            for var, val in pairs:
                assert init_values[
                    var] == ranges[var] - 1, "Inconsistent init facts!"
                init_values[var] = val
        else:  # isinstance(fact,pddl.FunctionAssignment)
            pairs = strips_to_sas.get(fact.fluent,
                                      [])  #empty for constant functions
            for (var, _) in pairs:
                val = fact.expression.value
                assert init_values[
                    var] == ranges[var] - 1, "Inconsistent init facts!"
                init_values[var] = val
    for axiom in const_num_axioms:
        var = strips_to_sas.get(axiom.effect)[0][0]
        val = axiom.parts[0].value
        init_values[var] = val
    init = sas_tasks.SASInit(init_values)

    return sas_tasks.SASTask(variables, init, goal, operators, temp_operators,
                             axioms, sas_num_axioms, comp_axioms[1])
예제 #6
0
def translate_task(strips_to_sas, ranges, translation_key, mutex_dict,
                   mutex_ranges, mutex_key, init, init_unknown, init_oneof,
                   init_formula, goals, actions, observation_actions, axioms,
                   metric, implied_facts):
    with timers.timing("Processing axioms", block=True):
        axioms, axiom_init, axiom_layer_dict = axiom_rules.handle_axioms(
            actions, axioms, goals)
    init = init + axiom_init
    #axioms.sort(key=lambda axiom: axiom.name)
    #for axiom in axioms:
    #  axiom.dump()

    if DUMP_TASK:
        # Remove init facts that don't occur in strips_to_sas: they're constant.
        nonconstant_init = filter(strips_to_sas.get, init)
        dump_task(nonconstant_init, goals, actions, axioms, axiom_layer_dict)

    # Closed World Assumption
    false_facts = list(range(len(ranges)))
    for fact in init_unknown:
        pairs = strips_to_sas.get(fact, [])
        for pair in pairs:
            false_facts.remove(pair[0])
    facts = []
    for fact in init:
        assert fact not in init_unknown
        pairs = strips_to_sas.get(fact, [])
        for pair in pairs:
            false_facts.remove(pair[0])
        if pairs:
            facts = facts + pairs
    for var in false_facts:
        for fact in init_unknown:
            assert not var == strips_to_sas.get(fact, [])[0][0]
        facts.append((var, ranges[var] - 1))
    facts_oneof = []
    for oneof in init_oneof:
        assert len(oneof) >= 2
        for fact in oneof:
            assert fact in init_unknown
        l = []
        for one in oneof:
            l = l + strips_to_sas.get(one, [])
        facts_oneof.append(l)

    # move to conditions.py?
    def translate_formula(formula, result, strips_to_sas, ranges, mutex_dict,
                          mutex_ranges):
        if isinstance(formula, pddl.conditions.Atom):
            assert formula in init_unknown
            result.append(strips_to_sas.get(formula, []))
        elif isinstance(formula, pddl.conditions.NegatedAtom):
            dict_list = translate_strips_conditions([formula], strips_to_sas,
                                                    ranges, mutex_dict,
                                                    mutex_ranges)
            assert len(dict_list) == 1
            result.append(dict_list[0].items())
        elif isinstance(formula, pddl.conditions.Disjunction):
            result.append("or(")
            for part in formula.parts:
                translate_formula(part, result, strips_to_sas, ranges,
                                  mutex_dict, mutex_ranges)
            result.append(")")
        elif isinstance(formula, pddl.conditions.Conjunction):
            result.append("and(")
            for part in formula.parts:
                translate_formula(part, result, strips_to_sas, ranges,
                                  mutex_dict, mutex_ranges)
            result.append(")")
        else:
            assert False, print(formula)

    formulae = []
    for formula in init_formula:
        result = []
        translate_formula(formula, result, strips_to_sas, ranges, mutex_dict,
                          mutex_ranges)
        formulae.append(result)
    init = sas_tasks.SASInit(facts, facts_oneof, formulae)

    goal_dict_list = translate_strips_conditions(goals, strips_to_sas, ranges,
                                                 mutex_dict, mutex_ranges)
    if goal_dict_list is None:
        # "None" is a signal that the goal is unreachable because it
        # violates a mutex.
        return unsolvable_sas_task("Goal violates a mutex")

    assert len(goal_dict_list) == 1, "Negative goal not supported"
    ## we could substitute the negative goal literal in
    ## normalize.substitute_complicated_goal, using an axiom. We currently
    ## don't do this, because we don't run into this assertion, if the
    ## negative goal is part of finite domain variable with only two
    ## values, which is most of the time the case, and hence refrain from
    ## introducing axioms (that are not supported by all heuristics)
    goal_pairs = list(goal_dict_list[0].items())
    goal = sas_tasks.SASGoal(goal_pairs)

    operators = translate_strips_operators(actions, strips_to_sas, ranges,
                                           mutex_dict, mutex_ranges,
                                           implied_facts)
    observation_operators = translate_strips_operators(observation_actions,
                                                       strips_to_sas, ranges,
                                                       mutex_dict,
                                                       mutex_ranges,
                                                       implied_facts)
    axioms = translate_strips_axioms(axioms, strips_to_sas, ranges, mutex_dict,
                                     mutex_ranges)

    axiom_layers = [-1] * len(ranges)
    for atom, layer in axiom_layer_dict.items():
        assert layer >= 0
        [(var, val)] = strips_to_sas[atom]
        axiom_layers[var] = layer
    variables = sas_tasks.SASVariables(ranges, axiom_layers, translation_key)
    mutexes = [sas_tasks.SASMutexGroup(group) for group in mutex_key]
    return sas_tasks.SASTask(variables, mutexes, init, goal,
                             operators + observation_operators, axioms, metric)
예제 #7
0
def translate_task(strips_to_sas, ranges, translation_key,
                   mutex_dict, mutex_ranges, mutex_key,
                   init, goals,
                   actions, axioms, metric, implied_facts):
    with timers.timing("Processing axioms", block=True):
        axioms, axiom_init, axiom_layer_dict = axiom_rules.handle_axioms(
            actions, axioms, goals)
    init = init + axiom_init
    #axioms.sort(key=lambda axiom: axiom.name)
    #for axiom in axioms:
    #  axiom.dump()

    if options.dump_task:
        # Remove init facts that don't occur in strips_to_sas: they're constant.
        nonconstant_init = filter(strips_to_sas.get, init)
        dump_task(nonconstant_init, goals, actions, axioms, axiom_layer_dict)

    init_values = [rang - 1 for rang in ranges]
    # Closed World Assumption: Initialize to "range - 1" == Nothing.
    for fact in init:
        pairs = strips_to_sas.get(fact, [])  # empty for static init facts
        for var, val in pairs:
            curr_val = init_values[var]
            if curr_val != ranges[var] - 1 and curr_val != val:
                assert False, "Inconsistent init facts! [fact = %s]" % fact
            init_values[var] = val
    init = sas_tasks.SASInit(init_values)

    goal_dict_list = translate_strips_conditions(goals, strips_to_sas, ranges,
                                                 mutex_dict, mutex_ranges)
    if goal_dict_list is None:
        # "None" is a signal that the goal is unreachable because it
        # violates a mutex.
        return unsolvable_sas_task("Goal violates a mutex")

    assert len(goal_dict_list) == 1, "Negative goal not supported"
    ## we could substitute the negative goal literal in
    ## normalize.substitute_complicated_goal, using an axiom. We currently
    ## don't do this, because we don't run into this assertion, if the
    ## negative goal is part of finite domain variable with only two
    ## values, which is most of the time the case, and hence refrain from
    ## introducing axioms (that are not supported by all heuristics)
    goal_pairs = list(goal_dict_list[0].items())
    if not goal_pairs:
        return solvable_sas_task("Empty goal")
    goal = sas_tasks.SASGoal(goal_pairs)

    operators = translate_strips_operators(actions, strips_to_sas, ranges,
                                           mutex_dict, mutex_ranges,
                                           implied_facts)
    axioms = translate_strips_axioms(axioms, strips_to_sas, ranges, mutex_dict,
                                     mutex_ranges)

    axiom_layers = [-1] * len(ranges)
    for atom, layer in axiom_layer_dict.items():
        assert layer >= 0
        [(var, val)] = strips_to_sas[atom]
        axiom_layers[var] = layer
    variables = sas_tasks.SASVariables(ranges, axiom_layers, translation_key)
    mutexes = [sas_tasks.SASMutexGroup(group) for group in mutex_key]
    return sas_tasks.SASTask(variables, mutexes, init, goal,
                             operators, axioms, metric)
예제 #8
0
def translate_task(strips_to_sas, module_effects_to_sas,
                   module_groundings_to_sas, ranges, init, goals, actions,
                   durative_actions, axioms, num_axioms, num_axioms_by_layer,
                   max_num_layer, num_axiom_map, const_num_axioms, oplinit,
                   objects, modules, module_inits, module_exits,
                   subplan_generators, init_constant_predicates,
                   init_constant_numerics):

    axioms, axiom_init, axiom_layer_dict, true_atoms, false_atoms = axiom_rules.handle_axioms(
        actions, durative_actions, axioms, goals)

    init = init + axiom_init

    # filter trivial true_atoms from goal
    goals = [g for g in goals if g not in true_atoms
             ]  # FIXME: empty goal would be handled nicely by search
    # if any atom in goal is false, the task is unsolvable
    for fa in false_atoms:
        if fa in goals:
            print "False atom in goal:"
            fa.dump()
            return unsolvable_sas_task("False atom in goal")

    comp_axioms = [{}, []]
    goal_dict_list = translate_strips_conditions(goals, strips_to_sas, ranges,
                                                 comp_axioms)
    assert len(goal_dict_list) == 1, "Negative goal not supported"
    ## we could substitute the negative goal literal in
    ## normalize.substitute_complicated_goal, using an axiom. We currently
    ## don't do this, because we don't run into this assertion, if the
    ## negative goal is part of finite domain variable with only two
    ## values, which is most of the time the case, and hence refrain from
    ## introducing axioms (that are not supported by all heuristics)
    goal_pairs = goal_dict_list[0].items()
    goal = sas_tasks.SASGoal(goal_pairs)

    # FIXME: remove this, defunct anyways
    operators = translate_strips_operators(actions, strips_to_sas,
                                           module_effects_to_sas, ranges,
                                           comp_axioms)
    temp_operators = translate_temporal_strips_operators(
        durative_actions, strips_to_sas, module_effects_to_sas,
        module_groundings_to_sas, ranges, comp_axioms, true_atoms, false_atoms)

    axioms = translate_strips_axioms(axioms, strips_to_sas, ranges,
                                     comp_axioms)
    sas_num_axioms = [
        translate_numeric_axiom(axiom, strips_to_sas) for axiom in num_axioms
        if axiom not in const_num_axioms and axiom.effect not in num_axiom_map
    ]

    axiom_layers = [-1] * len(ranges)

    ## each numeric axiom gets its own layer (a wish of a colleague for
    ## knowledge compilation or search. If you use only the translator,
    ## you can change this)
    num_axiom_layer = 0
    for layer in num_axioms_by_layer:
        num_axioms_by_layer[layer].sort(lambda x, y: cmp(x.name, y.name))
        for axiom in num_axioms_by_layer[layer]:
            if axiom.effect not in num_axiom_map:
                [(var, val)] = strips_to_sas[axiom.effect]
                if layer == -1:
                    axiom_layers[var] = -1
                else:
                    axiom_layers[var] = num_axiom_layer
                    num_axiom_layer += 1
    for axiom in comp_axioms[1]:
        axiom_layers[axiom.effect] = num_axiom_layer
    for atom, layer in axiom_layer_dict.iteritems():
        assert layer >= 0
        [(var, val)] = strips_to_sas[atom]
        axiom_layers[var] = layer + num_axiom_layer + 1
    variables = sas_tasks.SASVariables(ranges, axiom_layers)

    init_values = [rang - 1 for rang in ranges]
    # Closed World Assumption: Initialize to "range - 1" == Nothing.
    for fact in init:
        if isinstance(fact, pddl.Atom):
            pairs = strips_to_sas.get(fact, [])  # empty for static init facts
            for var, val in pairs:
                assert init_values[
                    var] == ranges[var] - 1, "Inconsistent init facts!"
                init_values[var] = val
        else:  # isinstance(fact,pddl.FunctionAssignment)
            pairs = strips_to_sas.get(fact.fluent,
                                      [])  #empty for constant functions
            for (var, _) in pairs:
                val = fact.expression.value
                assert init_values[
                    var] == ranges[var] - 1, "Inconsistent init facts!"
                init_values[var] = val
    for axiom in const_num_axioms:
        var = strips_to_sas.get(axiom.effect)[0][0]
        val = axiom.parts[0].value
        init_values[var] = val
    init = sas_tasks.SASInit(init_values)

    # TODO: move this block to translate_modules
    strips_condition_modules = [
        module for module in modules if module.type == "conditionchecker"
    ]
    strips_effect_modules = [
        module for module in modules if module.type == "effect"
    ]
    strips_cost_modules = [
        module for module in modules if module.type == "cost"
    ]
    strips_grounding_modules = [
        module for module in modules if module.type == "grounding"
    ]
    strips_condition_modules.sort(lambda x, y: cmp(str(x), str(y)))
    strips_effect_modules.sort(lambda x, y: cmp(str(x), str(y)))
    strips_cost_modules.sort(lambda x, y: cmp(str(x), str(y)))
    strips_grounding_modules.sort(lambda x, y: cmp(str(x), str(y)))
    condition_modules = []
    effect_modules = []
    cost_modules = []
    grounding_modules = []

    for mod in strips_condition_modules:
        assert mod.parent is not None
        sas_params = []
        for (ground_param, pddl_param) in zip(mod.parameters,
                                              mod.parent.parameters):
            sas_params.append(
                (pddl_param.name, ground_param.type, ground_param.name))
        # strips_to_sas call is very hacky
        assert len(strips_to_sas[mod.toModuleCall()]) == 1
        assert len(strips_to_sas[mod.toModuleCall()][0]) == 2
        mod_var = strips_to_sas[mod.toModuleCall()][0][0]
        condition_modules.append(
            sas_tasks.SASConditionModule(mod.modulecall, sas_params, mod_var))
    for mod in strips_effect_modules:
        assert mod.parent is not None
        sas_params = []
        for (ground_param, pddl_param) in zip(mod.parameters,
                                              mod.parent.parameters):
            sas_params.append(
                (pddl_param.name, ground_param.type, ground_param.name))
        sas_effs = []
        for eff in mod.effects:
            assert len(strips_to_sas[eff]) == 1
            assert len(strips_to_sas[eff][0]) == 2
            sas_effs.append(strips_to_sas[eff][0][0])
        # missing eff num + eff vars
        effect_modules.append(
            sas_tasks.SASEffectModule(
                mod.modulecall, sas_params,
                module_effects_to_sas[mod.toModuleCall()][0], sas_effs))
    for mod in strips_cost_modules:
        assert mod.parent is not None  # ?
        sas_params = []
        for (ground_param, pddl_param) in zip(mod.parameters,
                                              mod.parent.parameters):
            sas_params.append(
                (pddl_param.name, ground_param.type, ground_param.name))
        # make sure strips_to_sas is not mixed badly with condition modules
        assert len(strips_to_sas[mod.toModuleCall()]) == 1
        assert len(strips_to_sas[mod.toModuleCall()][0]) == 2
        mod_var = strips_to_sas[mod.toModuleCall()][0][0]
        cost_modules.append(
            sas_tasks.SASConditionModule(mod.modulecall, sas_params, mod_var))
    for mod in strips_grounding_modules:
        assert mod.parent is not None
        sas_params = []
        for (ground_param, pddl_param) in zip(mod.parameters,
                                              mod.parent.parameters):
            sas_params.append(
                (pddl_param.name, ground_param.type, ground_param.name))
        grounding_modules.append(
            sas_tasks.SASGroundingModule(
                mod.modulecall, sas_params,
                module_groundings_to_sas[mod.toModuleCall()][0]))

    return sas_tasks.SASTask(variables, init, goal, operators, temp_operators,
                             axioms, sas_num_axioms, comp_axioms[1], oplinit,
                             objects, condition_modules, effect_modules,
                             cost_modules, grounding_modules,
                             sas_tasks.SASTranslation(strips_to_sas),
                             module_inits, module_exits, subplan_generators,
                             init_constant_predicates, init_constant_numerics)
def translate_task(strips_to_sas, module_effects_to_sas, module_groundings_to_sas, ranges, init, goals, actions, 
                   durative_actions, axioms, num_axioms, num_axioms_by_layer, 
                   max_num_layer, num_axiom_map, const_num_axioms, oplinit, objects,
                   modules, module_inits, module_exits, subplan_generators, init_constant_predicates, init_constant_numerics):

    axioms, axiom_init, axiom_layer_dict, true_atoms, false_atoms = axiom_rules.handle_axioms(
      actions, durative_actions, axioms, goals)

    init = init + axiom_init

    # filter trivial true_atoms from goal
    goals = [g for g in goals if g not in true_atoms]   # FIXME: empty goal would be handled nicely by search
    # if any atom in goal is false, the task is unsolvable
    for fa in false_atoms:
        if fa in goals:
            print "False atom in goal:"
            fa.dump()
            return unsolvable_sas_task("False atom in goal")

    comp_axioms = [{},[]]
    goal_dict_list = translate_strips_conditions(goals, strips_to_sas, ranges, comp_axioms)
    assert len(goal_dict_list) == 1, "Negative goal not supported"
    ## we could substitute the negative goal literal in
    ## normalize.substitute_complicated_goal, using an axiom. We currently
    ## don't do this, because we don't run into this assertion, if the
    ## negative goal is part of finite domain variable with only two
    ## values, which is most of the time the case, and hence refrain from
    ## introducing axioms (that are not supported by all heuristics)
    goal_pairs = goal_dict_list[0].items()
    goal = sas_tasks.SASGoal(goal_pairs)

    # FIXME: remove this, defunct anyways
    operators = translate_strips_operators(actions,
                                        strips_to_sas, module_effects_to_sas, ranges, comp_axioms)
    temp_operators = translate_temporal_strips_operators(durative_actions, 
                                        strips_to_sas, module_effects_to_sas, module_groundings_to_sas, ranges, comp_axioms,
                                        true_atoms, false_atoms)
    
    axioms = translate_strips_axioms(axioms, strips_to_sas, ranges, comp_axioms)
    sas_num_axioms = [translate_numeric_axiom(axiom,strips_to_sas) for axiom in num_axioms 
                      if axiom not in const_num_axioms and
                      axiom.effect not in num_axiom_map]


    axiom_layers = [-1] * len(ranges)
    
    ## each numeric axiom gets its own layer (a wish of a colleague for 
    ## knowledge compilation or search. If you use only the translator,
    ## you can change this)
    num_axiom_layer = 0
    for layer in num_axioms_by_layer:
        num_axioms_by_layer[layer].sort(lambda x,y: cmp(x.name,y.name))
        for axiom in num_axioms_by_layer[layer]:
            if axiom.effect not in num_axiom_map:
                [(var,val)] = strips_to_sas[axiom.effect]
                if layer == -1:
                    axiom_layers[var] = -1
                else:
                    axiom_layers[var] = num_axiom_layer
                    num_axiom_layer += 1
    for axiom in comp_axioms[1]:
        axiom_layers[axiom.effect] = num_axiom_layer
    for atom, layer in axiom_layer_dict.iteritems():
        assert layer >= 0
        [(var, val)] = strips_to_sas[atom]
        axiom_layers[var] = layer + num_axiom_layer + 1
    variables = sas_tasks.SASVariables(ranges, axiom_layers)

    init_values = [rang - 1 for rang in ranges]
    # Closed World Assumption: Initialize to "range - 1" == Nothing.
    for fact in init:
        if isinstance(fact,pddl.Atom):
            pairs = strips_to_sas.get(fact, [])  # empty for static init facts
            for var, val in pairs:
                assert init_values[var] == ranges[var] - 1, "Inconsistent init facts!"
                init_values[var] = val
        else: # isinstance(fact,pddl.FunctionAssignment)
            pairs = strips_to_sas.get(fact.fluent,[]) #empty for constant functions 
            for (var, _) in pairs:
                val = fact.expression.value
                assert init_values[var] == ranges[var] - 1, "Inconsistent init facts!"
                init_values[var]=val
    for axiom in const_num_axioms:
        var = strips_to_sas.get(axiom.effect)[0][0]
        val = axiom.parts[0].value
        init_values[var]=val
    init = sas_tasks.SASInit(init_values)

    # TODO: move this block to translate_modules
    strips_condition_modules = [module for module in modules if module.type == "conditionchecker"]
    strips_effect_modules = [module for module in modules if module.type == "effect"]
    strips_cost_modules = [module for module in modules if module.type == "cost"]
    strips_grounding_modules = [module for module in modules if module.type == "grounding"]
    strips_condition_modules.sort(lambda x,y : cmp(str(x), str(y)))
    strips_effect_modules.sort(lambda x,y : cmp(str(x), str(y)))
    strips_cost_modules.sort(lambda x,y : cmp(str(x), str(y)))
    strips_grounding_modules.sort(lambda x,y : cmp(str(x), str(y)))
    condition_modules = []
    effect_modules = []
    cost_modules = []
    grounding_modules = []

    for mod in strips_condition_modules:
      assert mod.parent is not None
      sas_params = []
      for (ground_param, pddl_param) in zip(mod.parameters, mod.parent.parameters):
        sas_params.append((pddl_param.name, ground_param.type, ground_param.name))
      # strips_to_sas call is very hacky
      assert len(strips_to_sas[mod.toModuleCall()]) == 1
      assert len(strips_to_sas[mod.toModuleCall()][0]) == 2
      mod_var = strips_to_sas[mod.toModuleCall()][0][0]
      condition_modules.append(sas_tasks.SASConditionModule(mod.modulecall, sas_params, mod_var))
    for mod in strips_effect_modules:
      assert mod.parent is not None
      sas_params = []
      for (ground_param, pddl_param) in zip(mod.parameters, mod.parent.parameters):
        sas_params.append((pddl_param.name, ground_param.type, ground_param.name))
      sas_effs = []
      for eff in mod.effects:
        assert len(strips_to_sas[eff]) == 1
        assert len(strips_to_sas[eff][0]) == 2
        sas_effs.append(strips_to_sas[eff][0][0])
      # missing eff num + eff vars
      effect_modules.append(sas_tasks.SASEffectModule(mod.modulecall, sas_params, module_effects_to_sas[mod.toModuleCall()][0], sas_effs))
    for mod in strips_cost_modules:
      assert mod.parent is not None # ?
      sas_params = []
      for (ground_param, pddl_param) in zip(mod.parameters, mod.parent.parameters):
        sas_params.append((pddl_param.name, ground_param.type, ground_param.name))
      # make sure strips_to_sas is not mixed badly with condition modules
      assert len(strips_to_sas[mod.toModuleCall()]) == 1
      assert len(strips_to_sas[mod.toModuleCall()][0]) == 2
      mod_var = strips_to_sas[mod.toModuleCall()][0][0]
      cost_modules.append(sas_tasks.SASConditionModule(mod.modulecall, sas_params, mod_var))
    for mod in strips_grounding_modules:
      assert mod.parent is not None
      sas_params = []
      for (ground_param, pddl_param) in zip(mod.parameters, mod.parent.parameters):
        sas_params.append((pddl_param.name, ground_param.type, ground_param.name))
      grounding_modules.append(sas_tasks.SASGroundingModule(mod.modulecall, sas_params, module_groundings_to_sas[mod.toModuleCall()][0]))

    return sas_tasks.SASTask(variables, init, goal, operators, 
                             temp_operators, axioms, sas_num_axioms, comp_axioms[1], oplinit, objects, condition_modules, effect_modules, cost_modules, grounding_modules,
                             sas_tasks.SASTranslation(strips_to_sas), module_inits, module_exits, subplan_generators, 
                             init_constant_predicates, init_constant_numerics)
예제 #10
0
파일: relaxed.py 프로젝트: m1sk/pddlstream
def recover_stream_plan(evaluations, goal_expression, domain, stream_results, action_plan, negative,
                        unit_costs, optimize=True):
    import pddl_to_prolog
    import build_model
    import pddl
    import axiom_rules
    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

    opt_evaluations = evaluations_from_stream_plan(evaluations, stream_results)
    opt_task = task_from_domain_problem(domain, get_problem(opt_evaluations, goal_expression, domain, unit_costs))
    real_task = task_from_domain_problem(domain, get_problem(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 = []
    for name, args in action_plan: # TODO: negative atoms in actions
        candidates = []
        for action in opt_task.actions:
            if action.name != name:
                continue
            if len(action.parameters) != len(args):
                raise NotImplementedError('Existential quantifiers are not currently '
                                          'supported in preconditions: {}'.format(name))
            variable_mapping = {p.name: a for p, a in zip(action.parameters, args)}
            instance = action.instantiate(variable_mapping, set(),
                                          MockSet(), type_to_objects,
                                          opt_task.use_min_cost_metric, function_assignments)
            assert (instance is not None)
            candidates.append(((action, args), instance))
        if not candidates:
            raise RuntimeError('Could not find an applicable action {}'.format(name))
        action_instances.append(candidates)
    action_instances.append([(None, get_goal_instance(opt_task.goal))])

    axioms_from_name = get_derived_predicates(opt_task.axioms)
    negative_from_name = {n.name: n for n in negative}
    opt_task.actions = []
    opt_state = set(opt_task.init)
    real_state = set(real_task.init)
    preimage_plan = []
    function_plan = set()
    for layer in action_instances:
        for pair, instance in layer:
            nonderived_preconditions = [l for l in instance.precondition if l.predicate not in axioms_from_name]
            #nonderived_preconditions = instance.precondition
            if not conditions_hold(opt_state, nonderived_preconditions):
                continue
            opt_task.init = opt_state
            original_axioms = opt_task.axioms
            axiom_from_action = get_necessary_axioms(instance, original_axioms, negative_from_name)
            opt_task.axioms = []
            opt_task.actions = axiom_from_action.keys()
            # TODO: maybe it would just be better to drop the negative throughout this process until this end
            with Verbose(False):
                model = build_model.compute_model(pddl_to_prolog.translate(opt_task))  # Changes based on init
            opt_task.axioms = original_axioms

            opt_facts = instantiate.get_fluent_facts(opt_task, model) | (opt_state - real_state)
            mock_fluent = MockSet(lambda item: (item.predicate in negative_from_name) or
                                               (item in opt_facts))
            instantiated_axioms = instantiate_necessary_axioms(model, real_state, mock_fluent, axiom_from_action)
            with Verbose(False):
                helpful_axioms, axiom_init, _ = axiom_rules.handle_axioms([instance], instantiated_axioms, [])
            axiom_from_atom = get_achieving_axioms(opt_state, helpful_axioms, axiom_init, negative_from_name)
            axiom_plan = []  # Could always add all conditions
            extract_axioms(axiom_from_atom, instance.precondition, axiom_plan)
            # TODO: test if no derived solution

            # TODO: compute required stream facts in a forward way and allow opt facts that are already known required
            for effects in [instance.add_effects, instance.del_effects]:
                for i, (conditions, effect) in enumerate(effects[::-1]):
                    if any(c.predicate in axioms_from_name for c in conditions):
                        raise NotImplementedError('Conditional effects cannot currently involve derived predicates')
                    if conditions_hold(real_state, conditions):
                        # Holds in real state
                        effects[i] = ([], effect)
                    elif not conditions_hold(opt_state, conditions):
                        # Does not hold in optimistic state
                        effects.pop(i)
                    else:
                        # TODO: handle more general case where can choose to achieve particular conditional effects
                        raise NotImplementedError('Conditional effects cannot currently involve certified predicates')
            #if any(conditions for conditions, _ in instance.add_effects + instance.del_effects):
            #    raise NotImplementedError('Conditional effects are not currently supported: {}'.format(instance.name))

            # TODO: add axiom init to reset state?
            apply_action(opt_state, instance)
            apply_action(real_state, instance)
            preimage_plan.extend(axiom_plan + [instance])
            if not unit_costs and (pair is not None):
                function_plan.update(extract_function_results(results_from_head, *pair))
            break
        else:
            raise RuntimeError('No action instances are applicable')

    preimage = plan_preimage(preimage_plan, set())
    preimage -= set(real_task.init)
    negative_preimage = set(filter(lambda a: a.predicate in negative_from_name, preimage))
    preimage -= negative_preimage
    # visualize_constraints(map(fact_from_fd, preimage))
    # TODO: prune with rules
    # TODO: linearization that takes into account satisfied goals at each level
    # TODO: can optimize for all streams & axioms all at once

    for literal in negative_preimage:
        negative = negative_from_name[literal.predicate]
        instance = negative.get_instance(map(obj_from_pddl, literal.args))
        value = not literal.negated
        if instance.enumerated:
            assert (instance.value == value)
        else:
            function_plan.add(PredicateResult(instance, value, opt_index=instance.opt_index))

    node_from_atom = get_achieving_streams(evaluations, stream_results)
    preimage_facts = list(map(fact_from_fd, filter(lambda l: not l.negated, preimage)))
    stream_plan = []
    extract_stream_plan(node_from_atom, preimage_facts, stream_plan)
    if not optimize: # TODO: detect this based on unique or not
        return stream_plan + list(function_plan)

    # TODO: search in space of partially ordered plans
    # TODO: local optimization - remove one and see if feasible

    reschedule_problem = get_problem(evaluations, And(*preimage_facts), domain, unit_costs=True)
    reschedule_task = task_from_domain_problem(domain, reschedule_problem)
    reschedule_task.actions, stream_result_from_name = get_stream_actions(stream_results)
    new_plan, _ = solve_from_task(reschedule_task, planner='max-astar', debug=False)
    # TODO: investigate admissible heuristics
    if new_plan is None:
        return stream_plan + list(function_plan)

    new_stream_plan = [stream_result_from_name[name] for name, _ in new_plan]
    return new_stream_plan + list(function_plan)
예제 #11
0
def translate_task(strips_to_sas, ranges, translation_key,
                   numeric_strips_to_sas, num_count, mutex_dict, mutex_ranges,
                   mutex_key, init, num_init, goal_list, global_constraint,
                   actions, axioms, num_axioms, num_axioms_by_layer,
                   num_axiom_map, const_num_axioms, metric, implied_facts,
                   init_constant_predicates, init_constant_numerics):
    with timers.timing("Processing axioms", block=True):
        axioms, axiom_init, axiom_layer_dict = axiom_rules.handle_axioms(
            actions, axioms, goal_list, global_constraint)
    init = init + axiom_init
    if options.dump_task:
        # Remove init facts that don't occur in strips_to_sas: they're constant.
        nonconstant_init = filter(strips_to_sas.get, init)
        dump_task(nonconstant_init, goal_list, actions, axioms,
                  axiom_layer_dict)

    init_values = [rang - 1 for rang in ranges]
    # Closed World Assumption: Initialize to "range - 1" == Nothing.
    for fact in init:
        pairs = strips_to_sas.get(fact, [])  # empty for static init facts
        for var, val in pairs:
            curr_val = init_values[var]
            if curr_val != ranges[var] - 1 and curr_val != val:
                assert False, "Inconsistent init facts! [fact = %s]" % fact
            init_values[var] = val

    comparison_axioms = [{}, []]
    goal_dict_list = translate_strips_conditions(goal_list, strips_to_sas,
                                                 ranges, numeric_strips_to_sas,
                                                 mutex_dict, mutex_ranges,
                                                 comparison_axioms)
    global_constraint_dict_list = translate_strips_conditions(
        [global_constraint], strips_to_sas, ranges, numeric_strips_to_sas,
        mutex_dict, mutex_ranges, comparison_axioms)
    #    print("goal_dict_list = %s" % goal_dict_list)
    #    print("comparison_axioms = %s" %comparison_axioms)
    if goal_dict_list is None:
        # "None" is a signal that the goal_list is unreachable because it
        # violates a mutex.
        return unsolvable_sas_task("Goal violates a mutex")

    assert len(goal_dict_list) == 1, "Negative goal not supported"
    ## we could substitute the negative goal literal in
    ## normalize.substitute_complicated_goal, using an axiom. We currently
    ## don't do this, because we don't run into this assertion, if the
    ## negative goal is part of finite domain variable with only two
    ## values, which is most of the time the case, and hence refrain from
    ## introducing axioms (that are not supported by all heuristics)
    goal_pairs = list(goal_dict_list[0].items())
    if not goal_pairs:
        return solvable_sas_task("Empty goal")
    sas_goal = sas_tasks.SASGoal(goal_pairs)

    assert len(
        global_constraint_dict_list
    ) == 1  # the key is the axiom fluent, the value (0) the evaluation to true

    num_init_values = [0.0
                       ] * num_count  # initialize numeric varialbes with 0.0
    #     if DEBUG:
    #         print("Strips-to-sas dict is")
    #         for entry in strips_to_sas:
    #             print("%s -> %s"%(entry, strips_to_sas[entry]))
    #         print("Numeric Strips-to-sas dict is")
    #         for entry in numeric_strips_to_sas:
    #             print("%s -> %s"%(entry,numeric_strips_to_sas[entry]))

    relevant_numeric = []
    for fact in num_init:
        var = numeric_strips_to_sas.get(fact.fluent, -1)
        if var > -1:
            val = fact.expression.value
            num_init_values[var] = val
            if fact.fluent.ntype == 'R':
                # the corresponding numeric variable is "regular" and therefore relevant
                relevant_numeric.append(var)

    operators = translate_strips_operators(actions, strips_to_sas, ranges,
                                           numeric_strips_to_sas, mutex_dict,
                                           mutex_ranges, implied_facts,
                                           comparison_axioms, num_init_values,
                                           relevant_numeric)

    axioms = translate_strips_axioms(axioms, strips_to_sas, ranges,
                                     numeric_strips_to_sas, mutex_dict,
                                     mutex_ranges, comparison_axioms)

    sas_num_axioms = [
        translate_numeric_axiom(axiom, strips_to_sas, numeric_strips_to_sas)
        for axiom in num_axioms
        if axiom not in const_num_axioms and axiom.effect not in num_axiom_map
    ]

    axiom_layers = [-1] * len(ranges)  # default axiom layer is -1
    ## each numeric axiom gets its own layer (a wish of a colleague for
    ## knowledge compilation or search. If you use only the translator,
    ## you can change this)
    num_axiom_layers = [-1] * num_count
    num_axiom_layer = 0
    for layer in num_axioms_by_layer:
        num_axioms_by_layer[layer].sort(lambda x, y: cmp(x.name, y.name))
        for axiom in num_axioms_by_layer[layer]:
            if axiom.effect not in num_axiom_map:
                var = numeric_strips_to_sas[axiom.effect]
                if layer == -1:
                    num_axiom_layers[var] = -1
                else:
                    num_axiom_layers[var] = num_axiom_layer
                    num_axiom_layer += 1
#    print("comparison_axioms = %s" %comparison_axioms)
    comp_axiom_init = [2] * len(
        comparison_axioms[1]
    )  # initializing comparison axioms with value 3 (none of those)
    init_values.extend(comp_axiom_init)  #

    for axiom in comparison_axioms[1]:
        axiom_layers[axiom.effect] = num_axiom_layer
    for atom, layer in axiom_layer_dict.iteritems():
        assert layer >= 0
        [(var, val)] = strips_to_sas[atom]
        axiom_layers[var] = layer + num_axiom_layer + 1
    add_key_to_comp_axioms(comparison_axioms, translation_key)
    variables = sas_tasks.SASVariables(ranges, axiom_layers, translation_key,
                                       num_axiom_layer)

    num_variables = [-1] * num_count
    num_var_types = ['U'] * num_count  # variable type is unknown
    for entry in numeric_strips_to_sas:
        num_variables[numeric_strips_to_sas[entry]] = entry
        num_var_types[numeric_strips_to_sas[entry]] = entry.ntype
    assert num_count == len(num_variables), "%d nc <-> variables %d" % (
        num_count, len(num_variables))

    numeric_variables = sas_tasks.SASNumericVariables(num_variables,
                                                      num_axiom_layers,
                                                      num_var_types)
    mutexes = [sas_tasks.SASMutexGroup(group) for group in mutex_key]

    for axiom in const_num_axioms:
        #         print("Axiom = %s" % axiom)
        #         print("Axiom.effect = %s" % axiom.effect)
        #         print("corresponding variable = %s" % numeric_strips_to_sas.get(axiom.effect))
        var = numeric_strips_to_sas.get(axiom.effect)
        val = axiom.parts[0].value
        num_init_values[var] = val

    sas_init = sas_tasks.SASInit(init_values, num_init_values)
    #    print("SASInit is")
    #    sas_init.dump()

    # look up metric fluent
    if metric[1] == -1:
        # minimize unit cost, no metric fluent specified
        assert metric[0] == '<'
        sas_metric = metric
    else:
        assert metric[
            1] in numeric_strips_to_sas, "Metric fluent %s missing in strips_to_sas_dict" % metric[
                1]
        # look up (possibly derived) metric fluent to be optimized
        sas_metric = (metric[0], numeric_strips_to_sas[metric[1]])


#    print ("debug check metric: metric=")
#    print (metric)
#    print ("sas_metric fluent %d" % sas_metric[1])
#    print ("Returning task with global constraint = ",global_constraint_dict_list[0].items()[0])

    return sas_tasks.SASTask(variables, numeric_variables, mutexes, sas_init,
                             sas_goal, operators, axioms, comparison_axioms[1],
                             sas_num_axioms,
                             global_constraint_dict_list[0].items()[0],
                             sas_metric, init_constant_predicates,
                             init_constant_numerics)
예제 #12
0
파일: translate.py 프로젝트: aldukeman/lmtd
def translate_task(strips_to_sas, ranges, init, goals, actions, 
                   durative_actions, axioms, num_axioms, num_axioms_by_layer, 
                   max_num_layer, num_axiom_map, const_num_axioms):

    axioms, axiom_init, axiom_layer_dict = axiom_rules.handle_axioms(
      actions, durative_actions, axioms, goals)

    init = init + axiom_init

    comp_axioms = [{},[]]
    goal_pairs = translate_strips_conditions(goals, strips_to_sas, ranges, comp_axioms).items()
    goal = sas_tasks.SASGoal(goal_pairs)

    operators = translate_strips_operators(actions, strips_to_sas, ranges, comp_axioms)
    temp_operators = translate_temporal_strips_operators(durative_actions, 
                                                         strips_to_sas, ranges, comp_axioms)
    
    axioms = translate_strips_axioms(axioms, strips_to_sas, ranges, comp_axioms)
    sas_num_axioms = [translate_numeric_axiom(axiom,strips_to_sas) for axiom in num_axioms 
                      if axiom not in const_num_axioms and
                      axiom.effect not in num_axiom_map]


    axiom_layers = [-1] * len(ranges)
    
    ## each numeric axiom gets its own layer (a wish of a colleague for 
    ## knowledge compilation or search. If you use only the translator,
    ## you can change this)
    num_axiom_layer = 0
    for layer in num_axioms_by_layer:
        num_axioms_by_layer[layer].sort(lambda x,y: cmp(x.name,y.name))
        for axiom in num_axioms_by_layer[layer]:
            if axiom.effect not in num_axiom_map:
                [(var,val)] = strips_to_sas[axiom.effect]
                if layer == -1:
                    axiom_layers[var] = -1
                else:
                    axiom_layers[var] = num_axiom_layer
                    num_axiom_layer += 1
    for axiom in comp_axioms[1]:
        axiom_layers[axiom.effect] = num_axiom_layer
    for atom, layer in axiom_layer_dict.iteritems():
        assert layer >= 0
        [(var, val)] = strips_to_sas[atom]
        axiom_layers[var] = layer + num_axiom_layer + 1
    variables = sas_tasks.SASVariables(ranges, axiom_layers)

    init_values = [rang - 1 for rang in ranges]
    # Closed World Assumption: Initialize to "range - 1" == Nothing.
    for fact in init:
        if isinstance(fact,pddl.Atom):
            pairs = strips_to_sas.get(fact, [])  # empty for static init facts
            for var, val in pairs:
                assert init_values[var] == ranges[var] - 1, "Inconsistent init facts!"
                init_values[var] = val
        else: # isinstance(fact,pddl.FunctionAssignment)
            pairs = strips_to_sas.get(fact.fluent,[]) #empty for constant functions 
            for (var,dummy) in pairs:
                val = fact.expression.value
                assert init_values[var] == ranges[var] - 1, "Inconsistent init facts!"
                init_values[var]=val
    for axiom in const_num_axioms:
        var = strips_to_sas.get(axiom.effect)[0][0]
        val = axiom.parts[0].value
        init_values[var]=val
    init = sas_tasks.SASInit(init_values)

    return sas_tasks.SASTask(variables, init, goal, operators, 
                             temp_operators, axioms, sas_num_axioms, comp_axioms[1])