コード例 #1
0
def simple_from_durative_action(durative_actions, fluents):
    from pddlstream.algorithms.algorithm import get_predicates
    import pddl
    simple_actions = {}
    for action in durative_actions:
        parameters = convert_parameters(action.parameters)
        conditions = list(map(convert_condition, action.condition))
        start_effects, end_effects = action.effects
        over_effects = []
        effects = list(
            map(convert_effects, [start_effects, over_effects, end_effects]))

        static_condition = pddl.Conjunction(
            list({
                part
                for condition in conditions
                for part in get_conjunctive_parts(condition.simplified())
                if not isinstance(part, pddl.Truth)
                and not (get_predicates(part) & fluents)
            }))
        # TODO: deal with case where there are fluents
        actions = []
        for i, (condition, effect) in enumerate(safe_zip(conditions, effects)):
            # TODO: extract the durations by pretending they are action costs
            actions.append(
                pddl.Action(
                    SIMPLE_TEMPLATE.format(action.name, i), parameters,
                    len(parameters),
                    pddl.Conjunction([static_condition,
                                      condition]).simplified(), effect, None))
            #actions[-1].dump()
        simple_actions[action] = actions
    return simple_actions
コード例 #2
0
ファイル: fluent.py プロジェクト: Khodeir/pddlstream
    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
ファイル: temporal.py プロジェクト: Jonekee/pddlstream
def simple_from_durative_action(durative_actions, fluents):
    import pddl
    simple_actions = {}
    for action in durative_actions:
        parameters = convert_parameters(action.parameters)
        conditions = list(map(convert_condition, action.condition))
        start_effects, end_effects = action.effects
        over_effects = []
        effects = list(
            map(convert_effects, [start_effects, over_effects, end_effects]))

        static_condition = pddl.Conjunction(
            list({
                literal
                for condition in conditions
                for literal in get_conjunctive_parts(condition.simplified())
                if literal.predicate not in fluents
            }))
        actions = []
        for i, (condition, effect) in enumerate(safe_zip(conditions, effects)):
            actions.append(
                pddl.Action(
                    SIMPLE_TEMPLATE.format(action.name, i), parameters,
                    len(parameters),
                    pddl.Conjunction([static_condition,
                                      condition]).simplified(), effect, None))
            #actions[-1].dump()
        simple_actions[action] = actions
    return simple_actions
コード例 #4
0
def parse_action(alist, type_dict, predicate_dict):
    if DEBUG: print("parsing action %s" % [alist])
    iterator = iter(alist)
    action_tag = next(iterator)
    assert action_tag == ":action", "Expected ':action' got '%s'" % action_tag
    name = next(iterator)
    parameters_tag_opt = next(iterator)
    if parameters_tag_opt == ":parameters":
        parameters = parse_typed_list(next(iterator), only_variables=True)
        precondition_tag_opt = next(iterator)
    else:
        parameters = []
        precondition_tag_opt = parameters_tag_opt
    if precondition_tag_opt == ":precondition":
        precondition_list = next(iterator)
        if not precondition_list:
            # Note that :precondition () is allowed in PDDL.
            precondition = pddl.Conjunction([])
        else:
            precondition = parse_condition(precondition_list, type_dict,
                                           predicate_dict)
            precondition = precondition.simplified()
        effect_tag = next(iterator)
    else:
        precondition = pddl.Conjunction([])
        effect_tag = precondition_tag_opt
    assert effect_tag == ":effect"
    effect_list = next(iterator)
    eff = []
    if effect_list:
        try:
            cost = parse_effects(effect_list, eff, type_dict, predicate_dict)
            if cost is None and eff:
                if DEBUG:
                    print(
                        "adding artificial effect (increase total-cost 1) to %s"
                        % name)
                cost = pddl.NumericEffect(
                    parse_assignment(['increase', 'total-cost', 1])
                )  # artificially add a numeric effect that increases the total cost by one
                add_effect(cost, eff)
            assert (isinstance(cost, pddl.NumericEffect)
                    ), "instance of cost is %s " % cost.__class__
        except ValueError as e:
            raise SystemExit("Error in Action %s\nReason: %s." % (name, e))
    for rest in iterator:
        assert False, rest
    if eff:
        return pddl.Action(name, parameters, len(parameters), precondition,
                           eff, cost)
    else:
        return None
コード例 #5
0
def parse_action(alist, type_dict, predicate_dict):
    iterator = iter(alist)
    action_tag = next(iterator)
    assert action_tag == ":action"
    name = next(iterator)
    parameters_tag_opt = next(iterator)
    if parameters_tag_opt == ":parameters":
        parameters = parse_typed_list(next(iterator), only_variables=True)
        precondition_tag_opt = next(iterator)
    else:
        parameters = []
        precondition_tag_opt = parameters_tag_opt
    parameters_dict = dict((p.name, p) for p in parameters)
    if precondition_tag_opt == ":precondition":
        precondition_list = next(iterator)
        if not precondition_list:
            # Note that :precondition () is allowed in PDDL.
            precondition = pddl.Conjunction([])
        else:
            precondition = parse_condition(precondition_list, type_dict,
                                           predicate_dict)
            precondition = precondition.simplified()
        effect_tag = next(iterator)
    else:
        precondition = pddl.Conjunction([])
        effect_tag = precondition_tag_opt
    assert effect_tag == ":effect"
    effect_list = next(iterator)
    eff = []
    if effect_list:
        try:
            cost = parse_effects(effect_list, eff, type_dict, predicate_dict)
        except ValueError as e:
            raise SystemExit("Error in Action %s\nReason: %s." % (name, e))
    for rest in iterator:
        # Parse cost function
        if rest == ":cost":
            outer_op = None
            cost_list = next(iterator)
            cost = cost_node.CostNode("")
            cost = cost.parse_cost(cost_list, outer_op, predicate_dict,
                                   parameters_dict, cost)
            break
    for rest in iterator:
        assert False, rest
    if eff:
        return pddl.Action(name, parameters, len(parameters), precondition,
                           eff, cost)
    else:
        return None
コード例 #6
0
ファイル: reinstantiate.py プロジェクト: Khodeir/pddlstream
def instantiate_unsatisfiable(state,
                              action,
                              var_mapping,
                              negative_from_name={}):
    precondition = []
    for effect in action.effects:
        if effect.literal.predicate == UNSATISFIABLE:
            # Condition must be false for plan to succeed
            conditions = set(get_conjunctive_parts(effect.condition))
            negative = {
                literal
                for literal in conditions
                if literal.predicate in negative_from_name
            }
            if not negative:
                continue
            assert len(negative) == 1
            # TODO: handle the case where negative is not used (not (CFree ..))
            normal_conjunction = pddl.Conjunction(conditions - negative)
            # TODO: assumes that can instantiate with just predicate_to_atoms
            normal_effect = pddl.Effect(effect.parameters, normal_conjunction,
                                        effect.literal)
            # TODO: avoid recomputing these
            objects_by_type = instantiate.get_objects_by_type([], [])
            predicate_to_atoms = instantiate.get_atoms_by_predicate(state)
            result = []
            normal_effect.instantiate(var_mapping, state, {effect.literal},
                                      objects_by_type, predicate_to_atoms,
                                      result)
            for _, _, _, mapping in result:
                for literal in negative:
                    new_literal = literal.rename_variables(mapping).negate()
                    assert (not new_literal.free_variables())
                    precondition.append(new_literal)
    return precondition
コード例 #7
0
ファイル: simultaneous.py プロジェクト: jingxixu/pddlstream
def get_stream_action(result, name, unit_cost, effect_scale=1):
    #from pddl_parser.parsing_functions import parse_action
    import pddl

    parameters = []
    preconditions = [
        fd_from_fact(fact) for fact in result.instance.get_domain()
    ]
    precondition = pddl.Conjunction(preconditions)
    effects = [
        pddl.Effect(parameters=[],
                    condition=pddl.Truth(),
                    literal=fd_from_fact(fact))
        for fact in result.get_certified()
    ]

    effort = 1 if unit_cost else result.instance.get_effort()
    if effort == INF:
        return None
    fluent = pddl.PrimitiveNumericExpression(symbol=TOTAL_COST, args=[])
    expression = pddl.NumericConstant(int_ceil(effect_scale *
                                               effort))  # Integer
    cost = pddl.Increase(fluent=fluent,
                         expression=expression)  # Can also be None

    return pddl.Action(name=name,
                       parameters=parameters,
                       num_external_parameters=len(parameters),
                       precondition=precondition,
                       effects=effects,
                       cost=cost)
コード例 #8
0
    def recurse(condition):
        existential_parts = []
        other_parts = []
        for part in condition.parts:
            part = recurse(part)
            if isinstance(part, pddl.ExistentialCondition):
                existential_parts.append(part)
            else:
                other_parts.append(part)
        if not existential_parts:
            return condition

        # Rule (1): Combine nested quantifiers.
        if isinstance(condition, pddl.ExistentialCondition):
            new_parameters = condition.parameters + existential_parts[
                0].parameters
            new_parts = existential_parts[0].parts
            return pddl.ExistentialCondition(new_parameters, new_parts)

        # Rule (2): Pull quantifiers out of conjunctions.
        assert isinstance(condition, pddl.Conjunction)
        new_parameters = []
        new_conjunction_parts = other_parts
        for part in existential_parts:
            new_parameters += part.parameters
            new_conjunction_parts += part.parts
        new_conjunction = pddl.Conjunction(new_conjunction_parts)
        return pddl.ExistentialCondition(new_parameters, (new_conjunction, ))
コード例 #9
0
ファイル: advanced.py プロジェクト: Khodeir/pddlstream
def optimizer_conditional_effects(domain, externals):
    import pddl
    #from pddlstream.algorithms.scheduling.negative import get_negative_predicates
    # TODO: extend this to predicates
    if UNIVERSAL_TO_CONDITIONAL:
        negative_streams = list(filter(lambda e: e.is_negated, externals))
    else:
        negative_streams = list(
            filter(lambda e: isinstance(e, ConstraintStream) and e.is_negated,
                   externals))
    negative_from_predicate = get_predicate_map(negative_streams)
    if not negative_from_predicate:
        return
    for action in domain.actions:
        universal_to_conditional(action)
        new_effects = []
        for effect in action.effects:
            if effect.literal.predicate != UNSATISFIABLE:
                new_effects.append(effect)
                continue
            new_parts, stream_facts = process_conditional_effect(
                effect, negative_from_predicate)
            if not stream_facts:
                new_effects.append(effect)
            for stream_fact in stream_facts:
                new_effects.append(
                    pddl.Effect(effect.parameters, pddl.Conjunction(new_parts),
                                stream_fact))
        action.effects = new_effects
コード例 #10
0
def parse_online_goals(alist, type_dict, predicate_dict, subgoal):
    """Parse a PDDL condition when goals appear online. The condition is translated into NNF on the fly."""
    online_goals = []
    online_goals_availability = []

    if subgoal:
        goals = alist
    else:
        goals = alist[1:]

    for goal in goals:
        tag = goal[0]
        args = goal[1:]

        if not tag == "and":
            if tag.isdigit():
                online_goals_availability.append(tag)
            elif subgoal:
                return parse_literal(alist, type_dict, predicate_dict, negated=False)
            else:
                parsed = parse_literal(goal, type_dict, predicate_dict, negated=False)
                parsed.uniquify_variables({})
                online_goals.append(parsed)
        else:
            inner_parts = [parse_online_goals(part, type_dict, predicate_dict, True)
                           for part in args]
            conj = pddl.Conjunction(inner_parts)
            conj.uniquify_variables({})
            online_goals.append(conj)

    return online_goals, online_goals_availability
コード例 #11
0
ファイル: normalize.py プロジェクト: Milton761/FD-Planner
    def recurse(condition):

        if isinstance(condition, pddl.UniversalCondition):

            assert 1 == len(condition.parts)
            template = recurse(condition.parts[0])

            type_lists = []
            for param in condition.parameters:
                type_lists.append(
                    filter(lambda obj: obj.type == param.type, task.objects))

            object_combos = list(product(*type_lists))
            types = [param.name for param in condition.parameters]
            copies = []

            for combo in object_combos:
                copies.append(
                    lit_replacement(
                        template, dict(zip(types,
                                           [obj.name for obj in combo]))))

            return pddl.Conjunction(copies)
        else:
            new_parts = [recurse(part) for part in condition.parts]
            return condition.change_parts(new_parts)
コード例 #12
0
    def add_inequality_preconds(self, action, reachable_action_params):
        if reachable_action_params is None or len(action.parameters) < 2:
            return action
        inequal_params = []
        combs = itertools.combinations(range(len(action.parameters)), 2)
        for pos1, pos2 in combs:
            for params in reachable_action_params[action]:
                if params[pos1] == params[pos2]:
                    break
            else:
                inequal_params.append((pos1, pos2))

        if inequal_params:
            precond_parts = [action.precondition]
            for pos1, pos2 in inequal_params:
                param1 = action.parameters[pos1].name
                param2 = action.parameters[pos2].name
                new_cond = pddl.NegatedAtom("=", (param1, param2))
                precond_parts.append(new_cond)
            precond = pddl.Conjunction(precond_parts).simplified()
            return pddl.Action(
                action.name, action.parameters, action.num_external_parameters,
                precond, action.effects, action.cost)
        else:
            return action
コード例 #13
0
 def add_inequality_preconds(self, action, reachable_action_params):
     if reachable_action_params is None or len(action.parameters) < 2:
         return action
     new_cond_parts = []
     combs = itertools.combinations(range(len(action.parameters)), 2)
     for pos1, pos2 in combs:
         for params in reachable_action_params[action.name]:
             if params[pos1] == params[pos2]:
                 break
         else:
             param1 = pddl.Variable(action.parameters[pos1].name)
             param2 = pddl.Variable(action.parameters[pos2].name)
             new_cond = pddl.NegatedAtom("=", (param1, param2))
             new_cond_parts.append(new_cond)
     if new_cond_parts:
         new_cond = list(action.condition)
         for time in (0, 2):  # add inequalities to start and end condition
             cond_parts = list(action.condition[time].parts)
             if isinstance(action.condition[time], pddl.Literal):
                 cond_parts = [action.condition[time]]
             cond_parts.extend(new_cond_parts)
             cond = pddl.Conjunction(cond_parts)
             new_cond[time] = cond
         return pddl.DurativeAction(action.name, action.parameters,
                                    action.grounding_call, action.duration,
                                    new_cond, action.effects)
     else:
         return action
コード例 #14
0
def parse_action(alist, type_dict, predicate_dict):
    iterator = iter(alist)
    action_tag = next(iterator)
    assert action_tag == ":action" or action_tag == ':action'
    name = next(iterator)
    parameters_tag_opt = next(iterator)
    if parameters_tag_opt == ":parameters":
        parameters = parse_typed_list(next(iterator), only_variables=True)
        precondition_tag_opt = next(iterator)
    else:
        parameters = []
        precondition_tag_opt = parameters_tag_opt
    if precondition_tag_opt == ":precondition":
        precondition_list = next(iterator)
        if not precondition_list:
            # Note that :precondition () is allowed in PDDL.
            precondition = pddl.Conjunction([])
        else:
            precondition = parse_condition(precondition_list, type_dict,
                                           predicate_dict)
            precondition = precondition.simplified()
        effect_tag = next(iterator)
    else:
        precondition = pddl.Conjunction([])
        effect_tag = precondition_tag_opt
    assert effect_tag == ":effect"
    effect_list = next(iterator)
    eff = []
    if effect_list:
        try:
            cost = parse_effects(effect_list, eff, type_dict, predicate_dict)
        except ValueError as e:
            raise SystemExit("Error in Action %s\nReason: %s." % (name, e))
    next(iterator) == ":duration"
    duration = next(iterator)
    if len(duration[2]) == 1:
        duration = pddl.NumericConstant(int(duration[2]))
    else:
        duration = pddl.f_expression.PrimitiveNumericExpression(
            duration[2][0], duration[2][1:])
    for rest in iterator:
        assert False, rest
    if eff:
        return pddl.Action(name, parameters, len(parameters), precondition,
                           eff, cost, duration)
    else:
        return None
コード例 #15
0
def parse_action(alist, type_dict, predicate_dict):
    iterator = iter(alist)
    action_tag = next(iterator)
    assert action_tag == ":action"
    name = next(iterator)
    parameters_tag_opt = next(iterator)
    if parameters_tag_opt == ":parameters":
        parameters = parse_typed_list(next(iterator),
                                      only_variables=True)
        precondition_tag_opt = next(iterator)
    else:
        parameters = []
        precondition_tag_opt = parameters_tag_opt
    if precondition_tag_opt == ":precondition":
        precondition_list = next(iterator)
        if not precondition_list:
            # Note that :precondition () is allowed in PDDL.
            precondition = pddl.Conjunction([])
        else:
            precondition = parse_condition(
                precondition_list, type_dict, predicate_dict)
            precondition = precondition.simplified()
        effect_tag = next(iterator)
    else:
        precondition = pddl.Conjunction([])
        effect_tag = precondition_tag_opt
    assert effect_tag == ":effect"
    effect_list = next(iterator)
    eff = []
    if effect_list:
        try:
            cost = parse_effects(
                effect_list, eff, type_dict, predicate_dict)
        except ValueError as e:
            raise SystemExit("Error in Action %s\nReason: %s." % (name, e))
    for rest in iterator:
        assert False, rest
    # if eff:
    #     return pddl.Action(name, parameters, len(parameters),
    #                        precondition, eff, cost)
    # else:
    #     return None

    return pddl.Action(name, parameters, len(parameters),
                           precondition, eff, None)
コード例 #16
0
def append_precondition(action, precondition):
    # action: pddl.Action
    if isinstance(action.precondition, pddl.Conjunction):
        action.precondition.parts += (copy.deepcopy(precondition), )
    else:
        action.precondition = pddl.Conjunction(
            [action.precondition,
             copy.deepcopy(precondition)])
    return
コード例 #17
0
def add_unsatisfiable_to_goal(domain, goal_expression):
    import pddl
    from pddlstream.language.optimizer import UNSATISFIABLE
    add_predicate(domain, make_predicate(UNSATISFIABLE, []))
    negated_atom = pddl.NegatedAtom(UNSATISFIABLE, tuple())
    for action in domain.actions:
        if negated_atom not in action.precondition.parts:
            action.precondition = pddl.Conjunction(
                [action.precondition, negated_atom]).simplified()
    return And(goal_expression, Not((UNSATISFIABLE, )))
コード例 #18
0
def add_unsatisfiable_to_goal(domain, goal_expression, negate_actions=False):
    import pddl
    add_predicate(domain, make_predicate(UNSATISFIABLE, []))
    if negate_actions:
        negated_atom = pddl.NegatedAtom(UNSATISFIABLE, tuple())
        for action in domain.actions:
            if negated_atom not in action.precondition.parts:
                action.precondition = pddl.Conjunction(
                    [action.precondition, negated_atom]).simplified()
    return And(goal_expression, Not((UNSATISFIABLE, )))
コード例 #19
0
 def recurse(condition, used_variables):
     if isinstance(condition, pddl.Literal):
         typed_vars = []
         conjunction_parts = []
         new_args = []
         for term in condition.args:
             typed, parts, new_term = term.compile_objectfunctions_aux(
                 used_variables)
             typed_vars += typed
             conjunction_parts += parts
             new_args.append(new_term)
         if conjunction_parts == []:
             return condition
         else:
             new_literal = condition.__class__(condition.predicate,
                                               new_args)
             conjunction_parts.append(new_literal)
             conjunction = pddl.Conjunction(conjunction_parts)
             return pddl.ExistentialCondition(typed_vars, [conjunction])
     elif isinstance(condition, pddl.FunctionComparison):
         typed_vars = []
         conjunction_parts = []
         new_parts = []
         for part in condition.parts:
             typed, parts, new_part = part.compile_objectfunctions_aux(
                 used_variables)
             typed_vars += typed
             conjunction_parts += parts
             new_parts.append(new_part)
         if conjunction_parts == []:
             return condition
         else:
             new_comparison = condition.__class__(condition.comparator,
                                                  new_parts)
             conjunction_parts.append(new_comparison)
             conjunction = pddl.Conjunction(conjunction_parts)
             return pddl.ExistentialCondition(typed_vars, [conjunction])
     else:
         new_parts = [
             recurse(part, used_variables) for part in condition.parts
         ]
         return condition.change_parts(new_parts)
コード例 #20
0
ファイル: recover_axioms.py プロジェクト: aiyi2099/pddlstream
def get_necessary_axioms(conditions, axioms, negative_from_name):
    if not conditions or not axioms:
        return {}
    axioms_from_name = get_derived_predicates(axioms)
    atom_queue = []
    processed_atoms = set()

    def add_literals(literals):
        for lit in literals:
            atom = lit.positive()
            if atom not in processed_atoms:
                atom_queue.append(
                    atom)  # Previously was lit.positive() for some reason?
                processed_atoms.add(atom)

    import pddl
    add_literals(conditions)
    axiom_from_action = {}
    partial_instantiations = set()
    while atom_queue:
        literal = atom_queue.pop()
        for axiom in axioms_from_name[literal.predicate]:
            derived_parameters = axiom.parameters[:axiom.
                                                  num_external_parameters]
            var_mapping = {
                p.name: a
                for p, a in zip(derived_parameters, literal.args)
                if not is_parameter(a)
            }
            key = (axiom, frozenset(var_mapping.items()))
            if key in partial_instantiations:
                continue
            partial_instantiations.add(key)
            parts = [
                l.rename_variables(var_mapping)
                for l in get_literals(axiom.condition)
                if l.predicate not in negative_from_name
            ]  # Assumes a conjunction?
            # new_condition = axiom.condition.uniquify_variables(None, var_mapping)
            effect_args = [
                var_mapping.get(a.name, a.name) for a in derived_parameters
            ]
            effect = pddl.Effect([], pddl.Truth(),
                                 pddl.conditions.Atom(axiom.name, effect_args))
            free_parameters = [
                p for p in axiom.parameters if p.name not in var_mapping
            ]
            new_action = pddl.Action(axiom.name, free_parameters,
                                     len(free_parameters),
                                     pddl.Conjunction(parts), [effect], None)
            # Creating actions so I can partially instantiate (impossible with axioms)
            axiom_from_action[new_action] = (axiom, var_mapping)
            add_literals(parts)
    return axiom_from_action
コード例 #21
0
ファイル: relaxed.py プロジェクト: jingxixu/pddlstream
def get_necessary_axioms(instance, axioms, negative_from_name):
    import pddl

    axioms_from_name = get_derived_predicates(axioms)
    atom_queue = []
    processed_atoms = set()

    def add_literals(literals):
        for literal in literals:
            atom = literal.positive()
            if atom not in processed_atoms:
                atom_queue.append(literal.positive())
                processed_atoms.add(atom)

    add_literals(instance.precondition)
    for (cond, _) in (instance.add_effects + instance.del_effects):
        add_literals(cond)

    axiom_from_action = {}
    partial_instantiations = set()
    while atom_queue:
        literal = atom_queue.pop()
        for axiom in axioms_from_name[literal.predicate]:
            derived_parameters = axiom.parameters[:axiom.
                                                  num_external_parameters]
            var_mapping = {
                p.name: a
                for p, a in zip(derived_parameters, literal.args)
                if a[0] != '?'
            }
            key = (axiom, frozenset(var_mapping.items()))
            if key in partial_instantiations:
                continue
            partial_instantiations.add(key)
            parts = []
            for literal in get_literals(axiom.condition):
                if literal.predicate in negative_from_name:
                    continue
                parts.append(literal.rename_variables(var_mapping))
            # new_condition = axiom.condition.uniquify_variables(None, var_mapping)
            effect_args = [
                var_mapping.get(a.name, a.name) for a in derived_parameters
            ]
            effect = pddl.Effect([], pddl.Truth(),
                                 pddl.conditions.Atom(axiom.name, effect_args))
            free_parameters = [
                p for p in axiom.parameters if p.name not in var_mapping
            ]
            new_action = pddl.Action(axiom.name, free_parameters, 0,
                                     pddl.Conjunction(parts), [effect], None)
            # Creating actions so I can partially instantiate (impossible with axioms)
            axiom_from_action[new_action] = (axiom, var_mapping)
            add_literals(parts)
    return axiom_from_action
コード例 #22
0
ファイル: attachments.py プロジェクト: longhongc/pddlstream
def compile_fluents_as_attachments(domain, externals):
    import pddl
    state_streams = set(
        filter(lambda e: isinstance(e, Stream) and e.is_fluent(),
               externals))  # is_special
    if not state_streams:
        return externals

    predicate_map = get_predicate_map(state_streams)
    if predicate_map and (get_pyplanners_path() is None):
        # TODO: fluent streams with outputs
        # Could convert the free parameter to a constant
        raise NotImplementedError(
            'Algorithm does not support fluent streams: {}'.format(
                [stream.name for stream in state_streams]))

    domain.constants.append(make_object(PLACEHOLDER.pddl))
    for action in domain.actions:
        for effect in action.effects:
            # TODO: conditional effects
            if any(literal.predicate in predicate_map
                   for literal in get_literals(effect.condition)):
                raise ValueError(
                    'Attachments cannot be in action effects: {}'.format(
                        effect))
        action.attachments = {}
        preconditions = set()
        for literal in get_conjunctive_parts(action.precondition):
            #if not isinstance(literal, pddl.Literal):
            #    raise NotImplementedError('Only literals are supported: {}'.format(literal))
            if not get_predicates(literal) & set(predicate_map):
                preconditions.add(literal)
                continue
            if not isinstance(literal, pddl.Literal):
                raise NotImplementedError(literal)
            # Drops the original precondition
            stream = predicate_map[literal.predicate]
            mapping = remap_certified(literal, stream)
            assert mapping is not None
            action.attachments[literal] = stream
            preconditions.update(
                pddl.Atom(EQ, (mapping[out], PLACEHOLDER.pddl))
                for out in stream.outputs)
            preconditions.update(
                fd_from_fact(substitute_fact(fact, mapping))
                for fact in stream.domain)
        action.precondition = pddl.Conjunction(preconditions).simplified()
        #fn = lambda l: pddl.Truth() if l.predicate in predicate_map else l
        #action.precondition = replace_literals(fn, action.precondition).simplified()
        #action.dump()
    return [
        external for external in externals if external not in state_streams
    ]
コード例 #23
0
    def recurse(condition):
        disjunctive_parts = []
        other_parts = []
        for part in condition.parts:
            part = recurse(part)
            if isinstance(part, pddl.Disjunction):
                disjunctive_parts.append(part)
            else:
                other_parts.append(part)
        if not disjunctive_parts:
            return condition

        # Rule (1): Associativity of disjunction.
        if isinstance(condition, pddl.Disjunction):
            result_parts = other_parts
            for part in disjunctive_parts:
                result_parts.extend(part.parts)
            return pddl.Disjunction(result_parts)

        # Rule (2): Distributivity disjunction/existential quantification.
        if isinstance(condition, pddl.ExistentialCondition):
            parameters = condition.parameters
            result_parts = [
                pddl.ExistentialCondition(parameters, (part, ))
                for part in disjunctive_parts[0].parts
            ]
            return pddl.Disjunction(result_parts)

        # Rule (3): Distributivity disjunction/conjunction.
        assert isinstance(condition, pddl.Conjunction)
        result_parts = [pddl.Conjunction(other_parts)]
        while disjunctive_parts:
            previous_result_parts = result_parts
            result_parts = []
            parts_to_distribute = disjunctive_parts.pop().parts
            for part1 in previous_result_parts:
                for part2 in parts_to_distribute:
                    result_parts.append(pddl.Conjunction((part1, part2)))
        return pddl.Disjunction(result_parts)
コード例 #24
0
ファイル: algorithm.py プロジェクト: OolongQian/Robotics
def universal_to_conditional(action):
    import pddl
    new_parts = []
    unsatisfiable = fd_from_fact((UNSATISFIABLE,))
    for quant in get_conjunctive_parts(action.precondition):
        if isinstance(quant, pddl.UniversalCondition):
            condition = quant.parts[0]
            # TODO: normalize first?
            if isinstance(condition, pddl.Disjunction) or isinstance(condition, pddl.Literal):
                action.effects.append(pddl.Effect(quant.parameters, condition.negate(), unsatisfiable))
                continue
        new_parts.append(quant)
    action.precondition = pddl.Conjunction(new_parts)
コード例 #25
0
ファイル: algorithm.py プロジェクト: ultrainren/pddlstream
def optimizer_conditional_effects(domain, externals):
    import pddl
    #from pddlstream.algorithms.scheduling.negative import get_negative_predicates
    # TODO: extend this to predicates
    if UNIVERSAL_TO_CONDITIONAL:
        negative_streams = list(filter(lambda e: e.is_negated(), externals))
    else:
        negative_streams = list(
            filter(
                lambda e: isinstance(e, ConstraintStream) and e.is_negated(),
                externals))
    negative_from_predicate = get_predicate_map(negative_streams)
    if not negative_from_predicate:
        return
    for action in domain.actions:
        universal_to_conditional(action)
        new_effects = []
        for effect in action.effects:
            if effect.literal.predicate != UNSATISFIABLE:
                new_effects.append(effect)
                continue
            new_parts = []
            stream_facts = []
            for disjunctive in get_conjunctive_parts(effect.condition):
                for literal in get_disjunctive_parts(disjunctive):
                    # TODO: assert only one disjunctive part
                    if isinstance(literal, pddl.Literal) and (
                            literal.predicate in negative_from_predicate):
                        stream = negative_from_predicate[literal.predicate]
                        if not isinstance(stream, ConstraintStream):
                            new_parts.append(literal)
                            continue
                        certified = find_unique(
                            lambda f: get_prefix(f) == literal.predicate,
                            stream.certified)
                        mapping = get_mapping(get_args(certified),
                                              literal.args)
                        stream_facts.append(
                            fd_from_fact(
                                substitute_expression(stream.stream_fact,
                                                      mapping)))
                        # TODO: add the negated literal as precondition here?
                    else:
                        new_parts.append(literal)
            if not stream_facts:
                new_effects.append(effect)
            for stream_fact in stream_facts:
                new_effects.append(
                    pddl.Effect(effect.parameters, pddl.Conjunction(new_parts),
                                stream_fact))
        action.effects = new_effects
コード例 #26
0
def parse_condition_aux(alist, negated, type_dict, predicate_dict):
    """Parse a PDDL condition. The condition is translated into NNF on the fly."""
    #    if DEBUG: print ("parsing condition aux %s" % [alist])
    tag = alist[0]
    if is_function_comparison(
            alist
    ):  # NFD conditions are always comparisons between 2 numeric expressions
        args = [parse_expression(arg) for arg in alist[1:]]
        assert len(args) == 2, args
        if negated:
            return pddl.NegatedFunctionComparison(tag, args, True)
        else:
            return pddl.FunctionComparison(tag, args, True)
    elif tag in ("and", "or", "not", "imply"):
        args = alist[1:]
        if tag == "imply":
            assert len(args) == 2
        if tag == "not":
            assert len(args) == 1
            return parse_condition_aux(args[0], not negated, type_dict,
                                       predicate_dict)
    elif tag in ("forall", "exists"):
        parameters = parse_typed_list(alist[1])
        args = alist[2:]
        assert len(args) == 1
    else:
        #         if is_object_comparison(alist):
        #              print("DEBUG: Object comparison!")
        #              print(alist)
        return parse_literal(alist, type_dict, predicate_dict, negated=negated)
    if tag == "imply":
        parts = [
            parse_condition_aux(args[0], not negated, type_dict,
                                predicate_dict),
            parse_condition_aux(args[1], negated, type_dict, predicate_dict)
        ]
        tag = "or"
    else:
        parts = [
            parse_condition_aux(part, negated, type_dict, predicate_dict)
            for part in args
        ]

    if tag == "and" and not negated or tag == "or" and negated:
        return pddl.Conjunction(parts)
    elif tag == "or" and not negated or tag == "and" and negated:
        return pddl.Disjunction(parts)
    elif tag == "forall" and not negated or tag == "exists" and negated:
        return pddl.UniversalCondition(parameters, parts)
    elif tag == "exists" and not negated or tag == "forall" and negated:
        return pddl.ExistentialCondition(parameters, parts)
コード例 #27
0
ファイル: sequential.py プロジェクト: yijiangh/pddlstream
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)
コード例 #28
0
ファイル: exogenous.py プロジェクト: m1sk/pddlstream
def compile_to_exogenous_axioms(evaluations, domain, streams):
    import pddl
    fluent_predicates = get_fluents(domain)
    domain_predicates = {get_prefix(a) for s in streams for a in s.domain}
    if not (domain_predicates & fluent_predicates):
        return

    certified_predicates = {get_prefix(a) for s in streams for a in s.certified}
    future_map = {p: 'f-{}'.format(p) for p in certified_predicates}
    augment_evaluations(evaluations, future_map)
    rename_future = lambda a: rename_atom(a, future_map)
    derived_map = {p: 'd-{}'.format(p) for p in certified_predicates}
    rename_derived = lambda a: rename_atom(a, derived_map)

    for action in domain.actions:
        action.precondition = replace_predicates(derived_map, action.precondition)
        for effect in action.effects:
            assert(isinstance(effect, pddl.Effect))
            effect.condition = replace_predicates(derived_map, effect.condition)
    for axiom in domain.axioms:
        axiom.condition = replace_predicates(derived_map, axiom.condition)

    #fluent_predicates.update(certified_predicates)
    for stream in list(streams):
        if not isinstance(stream, Stream):
            raise NotImplementedError(stream)
        streams.append(create_static_stream(stream, evaluations, fluent_predicates, rename_future))
        stream_atom = streams[-1].certified[0]
        domain.predicate_dict[get_prefix(stream_atom)] = pddl.Predicate(get_prefix(stream_atom), get_args(stream_atom))
        precondition = pddl.Conjunction(tuple(map(fd_from_fact, (stream_atom,) + tuple(map(rename_derived, stream.domain)))))
        for fact in stream.certified:
            derived_fact = fd_from_fact(rename_derived(fact))
            external_params = derived_fact.args
            internal_params = tuple(p for p in (stream.inputs + stream.outputs)
                                        if p not in derived_fact.args)
            parameters = tuple(pddl.TypedObject(p, 'object')
                                     for p in (external_params + internal_params))
            #precondition = pddl.Conjunction(tuple(map(fd_from_fact, [stream_atom] +
            #                                        list(map(rename_derived, stream.domain)))))
            #precondition = pddl.Disjunction([fd_from_fact(fact), precondition]) # TODO: quantifier
            domain.axioms.extend([
                pddl.Axiom(name=derived_fact.predicate, parameters=parameters,
                           num_external_parameters=len(external_params),
                           condition=precondition),
                pddl.Axiom(name=derived_fact.predicate,  parameters=parameters[:len(external_params)],
                           num_external_parameters=len(external_params),
                           condition=fd_from_fact(fact))])
        stream.certified = tuple(set(stream.certified) |
                                 set(map(rename_future, stream.certified)))
コード例 #29
0
def augment_goal(domain, goal_expression, negate_actions=False):
    # TODO: only do this if optimizers are present
    #return goal_expression
    import pddl
    predicate = pddl.predicates.Predicate(UNSATISFIABLE, tuple())
    if predicate.name not in domain.predicate_dict:
        domain.predicates.append(predicate)
        domain.predicate_dict[predicate.name] = predicate
    if negate_actions:
        negated_atom = pddl.NegatedAtom(UNSATISFIABLE, tuple())
        for action in domain.actions:
            if negated_atom not in action.precondition.parts:
                action.precondition = pddl.Conjunction(
                    [action.precondition, negated_atom]).simplified()
    return And(goal_expression, Not((UNSATISFIABLE, )))
コード例 #30
0
ファイル: temporal.py プロジェクト: omrylmz/pddlstream
def convert_effects(effects):
    import pddl
    new_effects = make_effects([('_noop',)]) # To ensure the action has at least one effect
    for effect in effects:
        class_name = effect.__class__.__name__
        if class_name == 'Effect':
            peffect_name = effect.peffect.__class__.__name__
            if peffect_name in ('Increase', 'Decrease'):
                # TODO: currently ignoring numeric conditions
                continue
            new_effects.append(pddl.Effect(convert_parameters(effect.parameters),
                                           pddl.Conjunction(list(map(convert_condition, effect.condition))).simplified(),
                                           convert_condition(effect.peffect)))
        else:
            raise NotImplementedError(class_name)
    return new_effects