Пример #1
0
    def minimal_covering_renamings(self, action, add_effect, inv_vars):
        """computes the minimal renamings of the action parameters such
           that the add effect is covered by the action.
           Each renaming is an constraint system"""

        # add_effect must be covered
        assigs = self.get_covering_assignments(inv_vars, add_effect.literal)

        # renaming of operator parameters must be minimal
        minimal_renamings = []
        params = [p.name for p in action.parameters]
        for assignment in assigs:
            system = constraints.ConstraintSystem()
            system.add_assignment(assignment)
            mapping = assignment.get_mapping()
            if params:
                if len(params) == 2:
                    n1 = params[0]
                    n2 = params[1]
                    if mapping.get(n1, n1) != mapping.get(n2, n2):
                        negative_clause = constraints.NegativeClause([(n1, n2)
                                                                      ])
                        system.add_negative_clause(negative_clause)
                else:
                    for (n1, n2) in itertools.combinations(params, 2):
                        if mapping.get(n1, n1) != mapping.get(n2, n2):
                            negative_clause = constraints.NegativeClause([
                                (n1, n2)
                            ])
                            system.add_negative_clause(negative_clause)
            minimal_renamings.append(system)
        return minimal_renamings
Пример #2
0
    def operator_too_heavy(self, h_action):
        # FOND
        for nondet_choice in h_action.effects:
            add_effects = [
                eff for eff in nondet_choice if not eff.literal.negated
                and self.predicate_to_part.get(eff.literal.predicate)
            ]
            inv_vars = find_unique_variables(h_action, self)

            #if len(add_effects) <= 1:
            #    return False

            for eff1, eff2 in itertools.combinations(add_effects, 2):
                system = constraints.ConstraintSystem()
                ensure_inequality(system, eff1.literal, eff2.literal)
                ensure_cover(system, eff1.literal, self, inv_vars)
                ensure_cover(system, eff2.literal, self, inv_vars)
                ensure_conjunction_sat(system,
                                       get_literals(h_action.precondition),
                                       get_literals(eff1.condition),
                                       get_literals(eff2.condition),
                                       [eff1.literal.negate()],
                                       [eff2.literal.negate()])
                if system.is_solvable():
                    return True
        return False
Пример #3
0
 def operator_too_heavy(self, h_action):
     inv_vars = find_unique_variables(h_action, self)
     for time in xrange(2):
         cond_time = 2 * time
         add_effects = [eff for eff in h_action.effects[time] 
                        if isinstance(eff.peffect, pddl.Literal) and 
                           not eff.peffect.negated and
                           self.predicate_to_part.get(eff.peffect.predicate)]
       
         if len(add_effects) <= 1:
             continue
             
         for eff1, eff2 in itertools.combinations(add_effects, 2):
             system = constraints.ConstraintSystem()
             ensure_inequality(system, eff1.peffect, eff2.peffect)
             ensure_cover(system, eff1.peffect, self, inv_vars)
             ensure_cover(system, eff2.peffect, self, inv_vars)
             ensure_conjunction_sat(system, 
                                    get_literals(h_action.condition[cond_time]),
                                    get_literals(eff1.condition[cond_time]),
                                    get_literals(eff2.condition[cond_time]),
                                    [eff1.peffect.negate()],
                                    [eff2.peffect.negate()])
             if system.is_solvable():
                 return True
     return False
Пример #4
0
    def unbalanced_renamings(self, del_effect, add_effect, inv_vars,
                             lhs_by_pred, unbalanced_renamings):
        """returns the renamings from unbalanced renamings for which
           the del_effect does not balance the add_effect."""

        system = constraints.ConstraintSystem()
        ensure_cover(system, del_effect.literal, self, inv_vars)

        # Since we may only rename the quantified variables of the delete effect
        # we need to check that "renamings" of constants are already implied by
        # the unbalanced_renaming (of the of the operator parameters). The
        # following system is used as a helper for this. It builds a conjunction
        # that formulates that the constants are NOT renamed accordingly. We
        # below check that this is impossible with each unbalanced renaming.
        check_constants = False
        constant_test_system = constraints.ConstraintSystem()
        for a, b in system.combinatorial_assignments[0][0].equalities:
            # first 0 because the system was empty before we called ensure_cover
            # second 0 because ensure_cover only adds assignments with one entry
            if b[0] != "?":
                check_constants = True
                neg_clause = constraints.NegativeClause([(a, b)])
                constant_test_system.add_negative_clause(neg_clause)

        ensure_inequality(system, add_effect.literal, del_effect.literal)

        still_unbalanced = []
        for renaming in unbalanced_renamings:
            if check_constants:
                new_sys = constant_test_system.combine(renaming)
                if new_sys.is_solvable():
                    # it is possible that the operator arguments are not
                    # mapped to constants as required for covering the delete
                    # effect
                    still_unbalanced.append(renaming)
                    continue

            new_sys = system.combine(renaming)
            if self.lhs_satisfiable(renaming, lhs_by_pred):
                implies_system = self.imply_del_effect(del_effect, lhs_by_pred)
                if not implies_system:
                    still_unbalanced.append(renaming)
                    continue
                new_sys = new_sys.combine(implies_system)
            if not new_sys.is_solvable():
                still_unbalanced.append(renaming)
        return still_unbalanced
Пример #5
0
 def imply_del_effect(self, del_effect, lhs_by_pred):
     """returns a constraint system that is solvable if lhs implies
        the del effect (only if lhs is satisfiable). If a solvable
        lhs never implies the del effect, return None."""
     # del_effect.cond and del_effect.atom must be implied by lhs
     implies_system = constraints.ConstraintSystem()
     for literal in itertools.chain(get_literals(del_effect.condition),
                                    [del_effect.literal.negate()]):
         poss_assignments = []
         for match in lhs_by_pred[literal.predicate]:
             if match.negated != literal.negated:
                 continue
             else:
                 a = constraints.Assignment(list(zip(literal.args, match.args)))
                 poss_assignments.append(a)
         if not poss_assignments:
             return None
         implies_system.add_assignment_disjunction(poss_assignments)
     return implies_system
Пример #6
0
    def unbalanced_renamings(self, del_effect, add_effect, inv_vars,
                             lhs_by_pred, unbalanced_renamings):
        """returns the renamings from unbalanced renamings for which
           the del_effect does not balance the add_effect."""
        system = constraints.ConstraintSystem()
        ensure_inequality(system, add_effect.literal, del_effect.literal)
        ensure_cover(system, del_effect.literal, self, inv_vars)

        still_unbalanced = []
        for renaming in unbalanced_renamings:
            new_sys = system.combine(renaming)
            if self.lhs_satisfiable(renaming, lhs_by_pred):
                implies_system = self.imply_del_effect(del_effect, lhs_by_pred)
                if not implies_system:
                    still_unbalanced.append(renaming)
                    continue
                new_sys = new_sys.combine(implies_system)
            if not new_sys.is_solvable():
                still_unbalanced.append(renaming)
        return still_unbalanced