예제 #1
0
    def add_atom(self, atom):
        if not is_atom(atom):
            return False
        head = atom.head
        if head in self.atoms:
            return False
        self.atoms.add(head)
        # TODO: doing this in a way that will eventually allow constants

        for i, stream in enumerate(self.streams):
            for j, domain_atom in enumerate(stream.domain):
                if get_prefix(head) != get_prefix(domain_atom):
                    continue
                if len(head.args) != len(get_args(domain_atom)):
                    raise ValueError(head, domain_atom)
                if any(
                        isinstance(b, Object) and (a != b)
                        for (a, b) in zip(head.args, get_args(domain_atom))):
                    continue
                self.atoms_from_domain[(i, j)].append(head)
                values = [
                    self.atoms_from_domain[(i, k)] if j != k else [head]
                    for k in range(len(stream.domain))
                ]
                domain = list(map(head_from_fact, stream.domain))
                #domain = stream.domain
                for combo in product(*values):
                    mapping = get_mapping(domain, combo)
                    if mapping is None:
                        continue
                    input_objects = tuple(mapping[p] for p in stream.inputs)
                    self._add_instance(stream, input_objects)
        return True
예제 #2
0
 def add_atom(self, atom, complexity):
     if not is_atom(atom):
         return False
     head = atom.head
     if head in self.complexity_from_atom:
         assert self.complexity_from_atom[head] <= complexity
         return False
     self.complexity_from_atom[head] = complexity
     self._add_new_instances(head)
     return True
예제 #3
0
def fd_from_evaluation(evaluation):
    name = evaluation.head.function
    args = tuple(map(pddl_from_object, evaluation.head.args))
    if is_atom(evaluation):
        return pddl.Atom(name, args)
    elif is_negated_atom(evaluation):
        return pddl.NegatedAtom(name, args)
    fluent = pddl.f_expression.PrimitiveNumericExpression(symbol=name, args=args)
    expression = pddl.f_expression.NumericConstant(evaluation.value)
    return pddl.f_expression.Assign(fluent, expression)
예제 #4
0
def pddl_from_evaluation(evaluation):
    #if evaluation.head.function == TOTAL_COST:
    #    return None
    head = pddl_head(evaluation.head.function, evaluation.head.args)
    if is_atom(evaluation):
        return head
    elif is_negated_atom(evaluation):
        return '(not {})'.format(head)
    #value = int(evaluation.value)
    value = evaluation.value  # floats are fine for temporal planners
    #value = int(math.ceil(evaluation.value))
    return '(= {} {})'.format(head, value)
예제 #5
0
def get_init(init_evaluations, negated=False):
    # TODO: this doesn't include =
    init = []
    for evaluation in init_evaluations:
        name = evaluation.head.function
        args = tuple(map(pddl_from_object, evaluation.head.args))
        if is_atom(evaluation):
            init.append(pddl.Atom(name, args))
        elif negated and is_negated_atom(evaluation):
            init.append(pddl.NegatedAtom(name, args))
        else:
            fluent = pddl.f_expression.PrimitiveNumericExpression(symbol=name,
                                                                  args=args)
            expression = pddl.f_expression.NumericConstant(
                evaluation.value)  # Integer
            init.append(pddl.f_expression.Assign(fluent, expression))
    return init
예제 #6
0
def get_achieving_streams(evaluations,
                          stream_results,
                          unit_efforts=False):  #, max_effort=INF):
    # TODO: could do this with bound_stream_instances instead
    unprocessed_from_atom = defaultdict(list)
    node_from_atom = {NULL_COND: Node(0, None)}
    conditions_from_stream = {}
    remaining_from_stream = {}
    for result in stream_results:
        conditions_from_stream[result] = result.instance.get_domain() + (
            NULL_COND, )
        remaining_from_stream[result] = len(conditions_from_stream[result])
        for atom in conditions_from_stream[result]:
            unprocessed_from_atom[atom].append(result)
    for atom in evaluations:
        if is_atom(atom):
            node_from_atom[fact_from_evaluation(atom)] = Node(0, None)

    queue = [
        HeapElement(node.effort, atom)
        for atom, node in node_from_atom.items()
    ]
    while queue:
        atom = heappop(queue).value
        if atom not in unprocessed_from_atom:
            continue
        for result in unprocessed_from_atom[atom]:
            remaining_from_stream[result] -= 1
            if remaining_from_stream[result]:
                continue
            effort = get_instance_effort(result.instance, unit_efforts)
            total_effort = effort + COMBINE_OP(
                node_from_atom[cond].effort
                for cond in conditions_from_stream[result])
            #if max_effort <= total_effort:
            #    continue
            for new_atom in result.get_certified():
                if (new_atom not in node_from_atom) or (
                        total_effort < node_from_atom[new_atom].effort):
                    node_from_atom[new_atom] = Node(total_effort, result)
                    heappush(queue, HeapElement(total_effort, new_atom))
        del unprocessed_from_atom[atom]
    del node_from_atom[NULL_COND]
    return node_from_atom
예제 #7
0
def get_achieving_streams(evaluations,
                          stream_results,
                          max_effort=INF,
                          **effort_args):
    unprocessed_from_atom = defaultdict(list)
    node_from_atom = {NULL_COND: Node(0, None)}
    conditions_from_stream = {}
    remaining_from_stream = {}
    for result in stream_results:
        conditions_from_stream[result] = result.instance.get_domain() + (
            NULL_COND, )
        remaining_from_stream[result] = len(conditions_from_stream[result])
        for atom in conditions_from_stream[result]:
            unprocessed_from_atom[atom].append(result)
    for atom in evaluations:
        if is_atom(atom):
            node_from_atom[fact_from_evaluation(atom)] = Node(0, None)

    queue = [
        HeapElement(node.effort, atom)
        for atom, node in node_from_atom.items()
    ]
    while queue:
        atom = heappop(queue).value
        if atom not in unprocessed_from_atom:
            continue
        for result in unprocessed_from_atom[atom]:
            remaining_from_stream[result] -= 1
            if remaining_from_stream[result]:
                continue
            effort = compute_result_effort(result, **effort_args)
            total_effort = effort + EFFORT_OP(
                node_from_atom[cond].effort
                for cond in conditions_from_stream[result])
            if max_effort <= total_effort:
                continue
            for new_atom in result.get_certified():
                if (new_atom not in node_from_atom) or (
                        total_effort < node_from_atom[new_atom].effort):
                    node_from_atom[new_atom] = Node(total_effort, result)
                    heappush(queue, HeapElement(total_effort, new_atom))
        del unprocessed_from_atom[atom]
    del node_from_atom[NULL_COND]
    return node_from_atom
예제 #8
0
def get_achieving_streams(evaluations, stream_results, op=sum):
    # TODO: could do this with bound_stream_instances instead
    unprocessed_from_atom = defaultdict(list)
    none = (None, )  # None
    node_from_atom = {none: Node(0, None)}
    conditions_from_stream = {}
    remaining_from_stream = {}
    for stream_result in stream_results:
        conditions_from_stream[
            stream_result] = stream_result.instance.get_domain() + (none, )
        remaining_from_stream[stream_result] = len(
            conditions_from_stream[stream_result])
        for atom in conditions_from_stream[stream_result]:
            unprocessed_from_atom[atom].append(stream_result)
    for atom in evaluations:
        if is_atom(atom):
            node_from_atom[fact_from_evaluation(atom)] = Node(0, None)

    queue = [
        HeapElement(node.effort, atom)
        for atom, node in node_from_atom.items()
    ]
    while queue:
        atom = heappop(queue).value
        if atom not in unprocessed_from_atom:
            continue
        for stream_result in unprocessed_from_atom[atom]:
            remaining_from_stream[stream_result] -= 1
            if remaining_from_stream[stream_result]:
                continue
            effort = 1
            total_effort = op(
                node_from_atom[cond].effort
                for cond in conditions_from_stream[stream_result]) + effort
            for new_atom in stream_result.get_certified():
                if (new_atom not in node_from_atom) or (
                        total_effort < node_from_atom[new_atom].effort):
                    node_from_atom[new_atom] = Node(total_effort,
                                                    stream_result)
                    heappush(queue, HeapElement(total_effort, new_atom))
        del unprocessed_from_atom[atom]
    del node_from_atom[none]
    return node_from_atom