예제 #1
0
    def verify_expression(aexp):
        #         print("Verifying ",str(aexp))
        if isinstance(aexp, pddl.PrimitiveNumericExpression):
            #             print("- it is a PNE with fluent",aexp.symbol)
            if not aexp.symbol in function_names:
                msg = (
                    "WARNING: Function symbol '%s' appears in a numeric expression but is not defined in domain file.\n"
                    "Adding new symbol '%s' with arity %d.") % (
                        aexp.symbol, aexp.symbol, len(aexp.args))
                print(msg, file=sys.stderr)
                if len(aexp.args) == 0:
                    newfunction = pddl.Function(aexp.symbol, [], "number")
                    task.functions.append(newfunction)
                    initassignment = pddl.Assign(aexp,
                                                 pddl.NumericConstant(0.0))
                    task.num_init.append(initassignment)
                else:  # if this occurs in an actual domain, maybe we could also determine the type of the parameters of higher-arity functions
                    raise Error(
                        "Don't know the parameters of function %s with arity %d"
                        % (aexp.symbol, len(aexp.args)))
                    assert False


#         elif isinstance(aexp, pddl.NumericConstant):
#             print("- it is a constant: ",aexp.value)
        elif isinstance(aexp, pddl.AdditiveInverse):
            #             print("- it is an additive inverse: ",aexp)
            assert len(parts) == 1
            verify_expression(aexp.parts[0])
        elif isinstance(aexp, pddl.ArithmeticExpression):
            #             print("- it is an arithmetic expression: ",aexp)
            for part in aexp.parts:
                verify_expression(part)
예제 #2
0
def parse_assignment(alist):
    assert len(alist) == 3
    op = alist[0]
    head = parse_expression(alist[1])
    exp = parse_expression(alist[2])
    if op == "=":
        return pddl.Assign(head, exp)
    elif op == "increase":
        return pddl.Increase(head, exp)
    else:
        assert False, "Assignment operator not supported."
예제 #3
0
def remove_duration_variable(task):
    def recurse(condition, act, time, duration, pnes):
        if isinstance(condition, pddl.FunctionComparison):
            parts = [
                exp.remove_duration_variable(act, time, duration, pnes)
                for exp in condition.parts
            ]
            return condition.__class__(condition.comparator, parts)
            # return pddl.FunctionComparison(condition.comparator,parts)
        else:
            new_parts = [
                recurse(part, act, time, duration, pnes)
                for part in condition.parts
            ]
            return condition.change_parts(new_parts)

    for act in task.durative_actions:
        assert len(act.duration[1]) == 0, "at end durations are not supported"
        assert len(act.duration[0]) == 1 and act.duration[0][0][0] == "="
        duration = act.duration[0][0][1]
        duration_functions = []

        # remove from action conditions
        condition = []
        for time, cond in enumerate(act.condition):
            condition.append(
                recurse(cond, act, time, duration, duration_functions))
        act.condition = condition

        for time in range(2):
            for eff in act.effects[time]:
                # remove from effect condition
                condition = []
                for eff_time, cond in enumerate(eff.condition):
                    condition.append(
                        recurse(cond, act, eff_time, duration,
                                duration_functions))
                eff.condition = condition
                # remove from effect
                if isinstance(eff.peffect, pddl.FunctionAssignment):
                    assign = eff.peffect
                    assign.expression = assign.expression.remove_duration_variable(
                        act, time, duration, duration_functions)
        for pne in duration_functions:
            assign = pddl.Assign(pne, duration)
            condition = [pddl.Truth(), pddl.Truth(), pddl.Truth()]
            effect = pddl.Effect([], condition, assign)
            act.effects[0].append(effect)
            task.function_symbols[pne.symbol] = "number"
예제 #4
0
def parse_assignment(alist):
    assert len(alist) == 3
    op = alist[0]
    head = parse_expression(alist[1])
    exp = parse_expression(alist[2])
    if op == "assign" or op == "=":
        return pddl.Assign(head, exp)
    elif op == "scale-up":
        return pddl.ScaleUp(head, exp)
    elif op == "scale-down":
        return pddl.ScaleDown(head, exp)
    elif op == "increase":
        return pddl.Increase(head, exp)
    elif op == "decrease":
        return pddl.Decrease(head, exp)
    else:
        assert False, "Assignment operator not supported."
예제 #5
0
def instantiate(task, model):
  relaxed_reachable = False
  fluent_facts = get_fluent_facts(task, model)
  fluent_functions = get_fluent_functions(model)

  ## HACK: This is a not very clean way of initializing the previously
  ## added functions that store the duration of an action to a haphazardly value
  for atom in model:
  	if isinstance(atom.predicate,str) and atom.predicate.startswith("defined!duration_"):
		pne = pddl.PrimitiveNumericExpression(atom.predicate.replace("defined!","",1),atom.args)
		value = pddl.NumericConstant(1.0)
		init_assign = pddl.Assign(pne, value)
		task.init.append(init_assign)

  init_facts = set(task.init) # TODO adapt
  init_function_vals = init_function_values(init_facts)

#  print "** fluent functions"
#  for function in fluent_functions:
#    function.dump()
#  print "** fluent facts"
#  for fact in fluent_facts:
#    print fact
#  print "** init facts"
#  for fact in init_facts:
#    print fact

  type_to_objects = get_objects_by_type(task.objects,task.types)

  instantiated_actions = []
  instantiated_durative_actions = []
  instantiated_axioms = []
  instantiated_numeric_axioms = set()
  new_constant_numeric_axioms = set()
  reachable_action_parameters = defaultdict(list)
  for atom in model:
    if isinstance(atom.predicate, pddl.Action):
      action = atom.predicate
      parameters = action.parameters
      if isinstance(action.condition, pddl.ExistentialCondition):
        parameters = list(parameters)
        parameters += action.condition.parameters
      variable_mapping = dict([(pddl.Variable(par.name), arg)
                               for par, arg in zip(parameters, atom.args)])
      inst_action = action.instantiate(variable_mapping, init_facts,
                                       fluent_facts, init_function_vals, fluent_functions,
                                       task, new_constant_numeric_axioms, type_to_objects)
      if inst_action:
        instantiated_actions.append(inst_action)
    elif isinstance(atom.predicate, pddl.DurativeAction):
      action = atom.predicate
      parameters = action.parameters
      reachable_action_parameters[action.name].append(parameters)
      for condition in action.condition:
        if isinstance(condition,pddl.ExistentialCondition):
          parameters = list(parameters)
          parameters += condition.parameters
      variable_mapping = dict([(pddl.Variable(par.name), arg)
                               for par, arg in zip(parameters, atom.args)])
      inst_action = action.instantiate(variable_mapping, init_facts, fluent_facts,
                                       init_function_vals, fluent_functions,
                                       task, new_constant_numeric_axioms, type_to_objects)
      if inst_action:
        instantiated_durative_actions.append(inst_action)
    elif isinstance(atom.predicate, pddl.Axiom):
      axiom = atom.predicate
      parameters = axiom.parameters
      if isinstance(axiom.condition, pddl.ExistentialCondition):
        parameters = list(parameters)
        parameters += axiom.condition.parameters
      variable_mapping = dict([(pddl.Variable(par.name), arg)
                               for par, arg in zip(parameters, atom.args)])
      inst_axiom = axiom.instantiate(variable_mapping, init_facts, fluent_facts,
                                     fluent_functions, init_function_vals, task,
                                     new_constant_numeric_axioms)
      if inst_axiom:
        instantiated_axioms.append(inst_axiom)
    elif isinstance(atom.predicate, pddl.NumericAxiom):
      axiom = atom.predicate
      variable_mapping = dict([(pddl.Variable(par.name), arg)
                               for par, arg in zip(axiom.parameters, atom.args)])
      new_constant_numeric_axioms = set()
      inst_axiom = axiom.instantiate(variable_mapping, fluent_functions, init_function_vals, 
                                     task, new_constant_numeric_axioms)
      instantiated_numeric_axioms.add(inst_axiom)
    elif atom.predicate == "@goal-reachable":
      relaxed_reachable = True
    instantiated_numeric_axioms |= new_constant_numeric_axioms
      
  return (relaxed_reachable, fluent_facts, fluent_functions, instantiated_actions, 
          instantiated_durative_actions, instantiated_axioms,
          instantiated_numeric_axioms, reachable_action_parameters)
예제 #6
0
def instantiate(task, model):
    relaxed_reachable = False
    fluent_facts = get_fluent_facts(task, model)
    fluent_functions = get_fluent_functions(model)

    ## HACK: This is a not very clean way of initializing the previously
    ## added functions that store the duration of an action to a haphazardly value
    for atom in model:
        if isinstance(atom.predicate,
                      str) and atom.predicate.startswith("defined!duration_"):
            pne = pddl.PrimitiveNumericExpression(
                atom.predicate.replace("defined!", "", 1), atom.args)
            value = pddl.NumericConstant(1.0)
            init_assign = pddl.Assign(pne, value)
            task.init.append(init_assign)

    init_facts = set(task.init)  # TODO adapt
    init_function_vals = init_function_values(init_facts)

    # Determine initial facts, that are not fluents => constant facts, that a module might need
    init_constant_fluents = set(init_function_vals)
    init_constant_fluents.difference_update(
        fluent_functions
    )  # all fluents that are in init, but are NOT a fluent -> constant

    # Now get the assigned values from the init_facts for the constant fluents
    init_constant_numeric_facts = set(
    )  # This will hold Assigns that assign the fluents
    for i in init_constant_fluents:
        for j in init_facts:
            if isinstance(j, pddl.Assign):
                if isinstance(j.fluent, pddl.PrimitiveNumericExpression):
                    if j.fluent is i:  # Assign in init_fact assign this (i) fluent
                        init_constant_numeric_facts.add(j)

    # Now get predicates that are in init, but are not fluent_facts
    init_constant_predicate_facts = set()
    for i in init_facts:
        if isinstance(i, pddl.Atom):  # do NOT consider PNEs, etc.
            if i not in fluent_facts:  # only consider non-fluents
                if i.predicate is not "=":  # hack to remove the intermediate '=' fluents
                    init_constant_predicate_facts.add(i)


#  print "** fluent functions"
#  for function in fluent_functions:
#    function.dump()
#  print "** fluent facts"
#  for fact in fluent_facts:
#    print fact
#  print "** init facts"
#  for fact in init_facts:
#    print fact

    type_to_objects = get_objects_by_type(task.objects, task.types)

    instantiated_actions = []
    instantiated_durative_actions = []
    instantiated_axioms = []
    instantiated_numeric_axioms = set()
    new_constant_numeric_axioms = set()
    reachable_action_parameters = defaultdict(list)
    instantiated_modules = set()
    for atom in model:
        if isinstance(atom.predicate, pddl.Action):
            action = atom.predicate
            parameters = action.parameters
            if isinstance(action.condition, pddl.ExistentialCondition):
                parameters = list(parameters)
                parameters += action.condition.parameters
            variable_mapping = dict([
                (pddl.Variable(par.name), arg)
                for par, arg in zip(parameters, atom.args)
            ])
            inst_action = action.instantiate(variable_mapping, init_facts,
                                             fluent_facts, init_function_vals,
                                             fluent_functions, task,
                                             new_constant_numeric_axioms,
                                             instantiated_modules,
                                             type_to_objects)
            if inst_action:
                instantiated_actions.append(inst_action)
        elif isinstance(atom.predicate, pddl.DurativeAction):
            action = atom.predicate
            parameters = action.parameters
            reachable_action_parameters[action.name].append(parameters)
            for condition in action.condition:
                if isinstance(condition, pddl.ExistentialCondition):
                    parameters = list(parameters)
                    parameters += condition.parameters
            variable_mapping = dict([
                (pddl.Variable(par.name), arg)
                for par, arg in zip(parameters, atom.args)
            ])
            inst_action = action.instantiate(variable_mapping, init_facts,
                                             fluent_facts, init_function_vals,
                                             fluent_functions, task,
                                             new_constant_numeric_axioms,
                                             instantiated_modules,
                                             type_to_objects)
            if inst_action:
                instantiated_durative_actions.append(inst_action)
        elif isinstance(atom.predicate, pddl.Axiom):
            axiom = atom.predicate
            parameters = axiom.parameters
            if isinstance(axiom.condition, pddl.ExistentialCondition):
                parameters = list(parameters)
                parameters += axiom.condition.parameters
            variable_mapping = dict([
                (pddl.Variable(par.name), arg)
                for par, arg in zip(parameters, atom.args)
            ])
            inst_axiom = axiom.instantiate(variable_mapping, init_facts,
                                           fluent_facts, fluent_functions,
                                           init_function_vals, task,
                                           new_constant_numeric_axioms,
                                           instantiated_modules)
            if inst_axiom:
                instantiated_axioms.append(inst_axiom)
        elif isinstance(atom.predicate, pddl.NumericAxiom):
            axiom = atom.predicate
            variable_mapping = dict([
                (pddl.Variable(par.name), arg)
                for par, arg in zip(axiom.parameters, atom.args)
            ])
            new_constant_numeric_axioms = set()
            inst_axiom = axiom.instantiate(variable_mapping, fluent_functions,
                                           init_function_vals, task,
                                           new_constant_numeric_axioms)
            instantiated_numeric_axioms.add(inst_axiom)
        elif atom.predicate == "@goal-reachable":
            relaxed_reachable = True
        instantiated_numeric_axioms |= new_constant_numeric_axioms

    return (relaxed_reachable, fluent_facts, fluent_functions,
            instantiated_actions, instantiated_durative_actions,
            instantiated_axioms, instantiated_numeric_axioms,
            instantiated_modules, init_constant_predicate_facts,
            init_constant_numeric_facts, reachable_action_parameters)