Esempio n. 1
0
    def __init__(self, initial, goal, actions, axioms):
        self.index_from_var = {}
        self.var_order = []
        self.index_from_var_val = {}
        self.val_order_from_var = {}
        self.mutexes = []

        self.initial = apply(initial, defaultdict(lambda: self.default))
        self.fluent_heads = set()
        for op in (actions + axioms):
            for literal in op.effects:
                if isinstance(literal, Literal) and (
                        literal.value != self.initial[literal.head]):
                    self.fluent_heads.add(literal.head)
        self.condition_heads = set()
        for op in (actions + axioms + [Goal(goal)]):
            for literal in op.preconditions:
                assert isinstance(literal, Literal)
                if literal.head not in self.fluent_heads:
                    continue
                self.condition_heads.add(literal.head)

        self.goal = self._get_conditions(goal)
        self.actions = list(self._get_actions(actions))
        self.axioms = list(self._get_axioms(axioms))
        self.derived_vars = {axiom.effect.var for axiom in self.axioms}
Esempio n. 2
0
def is_solution(evals, plan, goal):

    state = defaultdict(bool)
    instances = [Initial(evals)
                 ] + [action.instantiate(args)
                      for action, args in plan] + [Goal(goal)]
    for instance in instances:
        if not instance.applicable(state):
            return False
        state = instance.apply(state)
    return True
Esempio n. 3
0
    def predicate_uses(self):
        predicate_to_signs = defaultdict(set)
        for op in (self.actions + [Goal(self.goal)]):
            for pre in op.preconditions:
                if isinstance(pre.head.function, Predicate):
                    predicate_to_signs[pre.head.function].add(pre.value)
        for ax in self.axioms:
            for sign in predicate_to_signs[ax.effect.head.function]:
                for pre in ax.preconditions:
                    if isinstance(pre.head.function, Predicate):
                        predicate_to_signs[pre.head.function].add(
                            sign == pre.value)

        return predicate_to_signs
Esempio n. 4
0
 def is_solution(self, plan):
     plan_instances = [action.instantiate(args) for action, args in plan
                       ] + [Goal(self.problem.goal)]
     axiom_instances = [
         axiom.instantiate(args) for axiom, args in self.axiom_instances()
     ]
     state = apply(self.evaluations, defaultdict(bool))
     for instance in plan_instances:
         reset_derived(self.axioms_from_derived, state)
         apply_axioms(axiom_instances, state)
         if not instance.applicable(state):
             return False
         state = instance.apply(state)
     return True
Esempio n. 5
0
def negative_axioms(universe, plan):
    negative_atoms = set()
    if plan is None:
        return negative_atoms

    action_instances = [action.instantiate(args) for action, args in plan
                        ] + [Goal(universe.problem.goal)]
    states = list(
        state_sequence(universe.evaluations, action_instances, default=bool))
    for state, action in zip(states, action_instances):
        atoms_from_predicate = defaultdict(list)
        for head, val in state.items():
            if (val is True) and (head.function in universe.fluents):
                atoms_from_predicate[head.function].append(Atom(head))
        for pre in action.preconditions:
            if not isinstance(pre,
                              NegatedAtom) or not universe.is_derived(pre):
                continue
            for axiom in universe.axioms_from_derived[pre.head.function]:
                assert not any(
                    universe.is_derived(a) for a in axiom.preconditions)
                external = filter(
                    lambda a: a.head.function.is_defined() and
                    (a.head.function.bound is False), axiom.preconditions)
                if not external:
                    continue
                fluents = filter(universe.is_fluent, axiom.preconditions)
                values = [
                    atoms_from_predicate.get(a.head.function, [])
                    for a in fluents
                ]
                initial_mapping = dict(
                    zip(axiom.effect.head.args, pre.head.args))
                for combo in product(*values):

                    mapping = get_mapping(fluents,
                                          combo,
                                          initial=initial_mapping)
                    if mapping is None:
                        continue
                    assert all(p in mapping for p in axiom.parameters)

                    if all(
                            pre.substitute(mapping).holds(state)
                            for pre in (set(axiom.preconditions) -
                                        set(external))):
                        negative_atoms.update(~pre.substitute(mapping)
                                              for pre in external)
    return filter(lambda a: not a.head.computed(), negative_atoms)
Esempio n. 6
0
def plan_preimage(universe, evaluations, plan):

    action_instances = [action.instantiate(args) for action, args in plan]
    lazy_states = list(literal_sequence(universe.evaluations,
                                        action_instances))
    real_states = list(literal_sequence(evaluations, action_instances))
    axiom_instances = [
        axiom.instantiate(args) for axiom, args in universe.axiom_instances()
    ]
    preimage = set()
    remapped_axioms = []
    for rs, ls, action in reversed(
            zip(real_states, lazy_states,
                action_instances + [Goal(universe.problem.goal)])):
        preimage -= set(action.effects)

        derived = filter(
            lambda a: isinstance(a, Atom) and
            (a.head.function in universe.axioms_from_derived),
            action.preconditions)
        preimage |= (set(action.preconditions) - set(derived))
        if derived:
            derived_map = {
                f: f.__class__(f.inputs)
                for f in universe.axioms_from_derived
            }
            remap_fn = lambda a: a.__class__(
                Head(derived_map[a.head.function], a.head.args))
            preimage.update(map(remap_fn, derived))
            for ax in axiom_instances:
                preconditions = []
                for atom in ax.preconditions:
                    if atom.head.function in derived_map:
                        preconditions.append(remap_fn(atom))
                    elif ls.get(atom.head, False) != atom.value:
                        break
                    elif (atom.head
                          not in rs) and (not atom.head.function.is_defined()):
                        preconditions.append(atom)

                else:
                    remapped_axioms.append(
                        Axiom([], preconditions, remap_fn(ax.effect)))
    return preimage, remapped_axioms
Esempio n. 7
0
 def functions(self):
     return {
         f
         for op in (self.actions + self.axioms + [Goal(self.goal)])
         for f in op.functions()
     }
Esempio n. 8
0
def plan_supporting_axioms(evaluations, plan_instances, axiom_instances, goal):
    states = state_sequence(evaluations, plan_instances, default=bool)
    for state, action in zip(states, plan_instances + [Goal(goal)]):
        yield supporting_axioms(state, action.preconditions, axiom_instances)