示例#1
0
 def add_actions(self):
     self.check.write('ACTIONS \n')
     for o in self.op_lits:
         if self.precs[o] is not None:
             self.printtofile(When(o, self.precs[o]))
         if self.effects[o] is not None:
             self.printtofile(When(o, self.effects[o]))
示例#2
0
    def add_persistence(self):
        self.check.write('PERSISTENCE \n')
        for j in range(self.j):
            for t in range(self.horizon-1):
                for p in self.fluents:
                    pjt = self.lit_lookup[p,j,t+1]
                    pjt0 = self.lit_lookup[p,j,t]
                    adds = self.adds_fluent[pjt]

                    if len(adds) > 0:
                        iff = And([Not([pjt0])] + [Not([a]) for a in adds])
                        thenf = Not([pjt])
                        self.printtofile(When(iff, thenf))
                    else:
                        self.printtofile(When(Not([pjt0]), Not([pjt])))

                    dels = self.dels_fluent[pjt]
                    if len(dels) > 0:
                        iff = And([pjt0] + [Not([a]) for a in dels])
                        thenf = pjt
                        self.printtofile(When(iff, thenf))
                    else:
                        self.printtofile(When(pjt0, pjt))
示例#3
0
 def lit_formula(self, f,j,t):
     if f is None:
         return None
     if f.__class__ == Predicate:
         return self.lit_lookup[f, j, t]
     if f.name == 'Primitive':
         return self.lit_lookup[f.predicate, j, t]
     elif f.name == 'when':
         a = f.condition
         b = f.result
         a_lit = self.lit_formula(a, j, t - 1)
         b_lit = self.lit_formula(b, j, t)
         newf = When(a_lit, b_lit)
         return newf
     else:
         newargs = [self.lit_formula(a, j, t) for a in f.args]
         newf = f.__class__(newargs)
         return newf
示例#4
0
    def _partial_ground_formula(self, formula, assignment, fluent_dict):
        """
        Inputs:
            formula            The formula to be converted
            assignment        a dictionary mapping each possible variable name to an object

        Returns:
            A formula that has the particular valuation for the variables as given in input. The old formula is *untouched*
        """

        if formula is None:
            return None

        if isinstance(formula, Primitive):
            return Primitive(
                self._predicate_to_fluent(formula.predicate, assignment,
                                          fluent_dict))
        elif isinstance(formula, Forall):

            new_conjuncts = []
            var_names, val_generator = self._create_valuations(formula.params)
            for valuation in val_generator:
                new_assignment = {
                    var_name: val
                    for var_name, val in zip(var_names, valuation)
                }
                for k in assignment:
                    new_assignment[k] = assignment[k]
                new_conjuncts.append(
                    self._partial_ground_formula(formula.args[0],
                                                 new_assignment, fluent_dict))
            return And(new_conjuncts)

        elif isinstance(formula, When):
            return When(
                self._partial_ground_formula(formula.condition, assignment,
                                             fluent_dict),
                self._partial_ground_formula(formula.result, assignment,
                                             fluent_dict))
        else:
            return type(formula)([
                self._partial_ground_formula(arg, assignment, fluent_dict)
                for arg in formula.args
            ])
示例#5
0
    def lit(self, f, j, t):

        if f is None:
            return None
        if f.__class__ == Predicate:
            return Literal('fluent', f, (j, t))
        if f.name == 'Primitive':
            return Literal('fluent', f.predicate, (j, t))
        elif f.name == 'when':
            a = f.condition
            b = f.result
            a_lit = self.lit(a, j, t - 1)
            b_lit = self.lit(b, j, t)
            newf = When([a_lit, b_lit])
            return self.norm(newf)
        else:
            newargs = [self.lit(a, j, t) for a in f.args]
            newf = f.__class__(newargs)
            return self.norm(newf)
示例#6
0
    def add_restrictions(self):
        self.check.write('RESTRICTIONS \n')
        pos = list(self.possible_ops)
        for i in range(len(pos)-1):
            for l in range(i+1, len(pos)):
                a1 = pos[i]
                a2 = pos[l]
                for t in range(self.horizon-1):
                    for j in range(self.j):
                        a1jt = self.lit_lookup[a1, j, t]
                        a2jt = self.lit_lookup[a2, j, t]
                        self.printtofile(When(a1jt, Not([a2jt])))
                    for (j,k) in self.jk:
                        a1jt = self.lit_lookup[a1, j, t]
                        a2kt = self.lit_lookup[a2, k, t]
                        a1kt = self.lit_lookup[a1, k, t]
                        a2jt = self.lit_lookup[a2, j, t]
                        djkt = self.lit_lookup['D', (j,k), t]
                        self.printtofile(When(And([a1jt, a2kt]), djkt))
                        self.printtofile(When(And([a1kt, a2jt]), djkt))
        for o in pos:
            for t in range(self.horizon-1):
                for (j, k) in self.jk:
                    ajt = self.lit_lookup[o,j,t]
                    akt = self.lit_lookup[o,k,t]
                    djkt = self.lit_lookup['D', (j,k), t]
                    self.printtofile(When(And([ajt, Not([djkt])]),akt ))
                    self.printtofile(When(And([akt, Not([djkt])]), ajt))

        for j in range(self.j):
            for t in range(self.horizon-1):
                # alist = [self.lit_lookup[o,j,t] for o in pos]
                # dgjt = self.lit_lookup[self.dg_atom, j,t]
                # self.printtofile(Or([dgjt]+alist))
                goallist = [self.lit_lookup[g.predicate,j,t] for g in self.goal.args ]
                enda = self.lit_lookup[self.end_atom, j, t]
                self.printtofile(When(And(goallist), enda))
                dgjt = self.lit_lookup[self.dg_atom, j,t]
                alist = [self.lit_lookup[o, j, t] for o in pos]
                self.printtofile(When(dgjt, Not([Or(alist)])))
示例#7
0
    def to_formula(self, node, parameter_map=None):
        """
            Return a formula out of this PDDL_Tree node.
            For now, will assume this makes sense.
        """

        # forall is so weird that we can treat it as an entirely seperate entity
        if "forall" == node.name:
            # treat args differently in this case
            assert len(node.children) in[2, 4],\
                "Forall must have a variable(typed or untyped) and formula that it quantifies"
            i = len(node.children) - 1

            if len(node.children) == 2 and len(node.children[0].children) > 0:
                # adjust this node by changing the structure of the first child
                new_child = PDDL_Tree(PDDL_Tree.EMPTY)
                new_child.add_child(PDDL_Tree(node.children[0].name))

                for c in node.children[0].children:
                    new_child.add_child(c)
                node.children[0] = new_child
                l = PDDL_Utils.read_type(new_child)

            for v, t in l:
                parameter_map[v] = t
            args = [
                self.to_formula(c, parameter_map) for c in node.children[i:]
            ]
            for v, t in l:
                del (parameter_map[v])
            return Forall(l, args)

        i = 0
        args = [self.to_formula(c, parameter_map) for c in node.children[i:]]

        if "and" == node.name:
            return And(args)
        elif "or" == node.name:
            return Or(args)
        elif "oneof" == node.name:
            return Oneof(args)
        elif "not" == node.name:
            return Not(args)
        elif "xor" == node.name:
            return Xor(args)
        elif "nondet" == node.name:
            assert len(node.children) == 1,\
                                       "nondet must only have a single child as a predicate"
            # make p != p2, otherwise might run into issues with mutation in some later step
            return Oneof([args[0], Not(args)])
        elif "unknown" == node.name:
            assert len(node.children) == 1,\
                "unknown must only have a single child as a predicate"
            # make p != p2, otherwise might run into issues with mutation in some later step
            p = Primitive(
                self.to_predicate(node.children[0], map=parameter_map))
            p2 = Primitive(
                self.to_predicate(node.children[0], map=parameter_map))
            return Xor([p, Not([p2])])
        elif "when" == node.name:
            assert len(args) == 2,\
                "When clause must have exactly 2 children"
            return When(args[0], args[1])
        else:
            # it's a predicate
            return Primitive(self.to_predicate(node, map=parameter_map))
示例#8
0
    def add_observes(self):
        self.check.write('OBSERVES \n')
        for djk in self.jk:
            self.printtofile(Not([Literal('D', djk, 0)]))

        for (j,k) in self.jk:
            for t in range(self.horizon-1):
                djkt = self.lit_lookup['D', (j,k), t+1]
                djkt0 = self.lit_lookup['D', (j,k), t]
                self.printtofile(When(djkt0, djkt))
                for o in self.possible_ops:
                    if o.observe is None:
                        ajt = self.lit_lookup[o,j,t]
                        akt = self.lit_lookup[o,k,t]
                        (When(And([Not([djkt0]), ajt]), Not([djkt])))
                        (When(And([Not([djkt0]), akt]), Not([djkt])))
                    else:
                        obs = o.observe
                        ajt = self.lit_lookup[o, j, t]
                        akt = self.lit_lookup[o, k, t]
                        obsjt = self.lit_lookup[obs, j, t]
                        obskt = self.lit_lookup[obs, k, t]
                        iff = And([Not([djkt0]), ajt, obsjt, Not([obskt]) ])
                        thenf = djkt
                        self.printtofile(When(iff,thenf))
                        iff = And([Not([djkt0]), ajt, obskt, Not([obsjt]) ])
                        self.printtofile(When(iff,thenf))

                        iff = And([Not([djkt0]), akt, obsjt, Not([obskt])])
                        thenf = djkt
                        self.printtofile(When(iff, thenf))
                        iff = And([Not([djkt0]), akt, obskt, Not([obsjt])])
                        self.printtofile(When(iff, thenf))

                        iff = And([Not([djkt0]), ajt, obsjt, obskt])
                        thenf = Not([djkt])
                        self.printtofile(When(iff, thenf))
                        iff = And([Not([djkt0]), ajt, Not([obskt]), Not([obsjt])])
                        self.printtofile(When(iff, thenf))

                        iff = And([Not([djkt0]), akt, obsjt, obskt])
                        thenf = Not([djkt])
                        self.printtofile(When(iff, thenf))
                        iff = And([Not([djkt0]), akt, Not([obskt]), Not([obsjt])])
                        self.printtofile(When(iff, thenf))
示例#9
0
    def to_formula(self, node, parameter_map=None):
        """
            Return a formula out of this PDDL_Tree node.
            For now, will assume this makes sense.
        """

        # forall is so weird that we can treat it as an entirely seperate entity
        if "forall" == node.name:
            # treat args differently in this case
            assert len(node.children) in[2, 4],\
                "Forall must have a variable(typed or untyped) and formula that it quantifies"
            i = len(node.children) - 1

            if len(node.children) == 2 and len(node.children[0].children) > 0:
                # adjust this node by changing the structure of the first child
                new_child = PDDL_Tree(PDDL_Tree.EMPTY)
                new_child.add_child(PDDL_Tree(node.children[0].name))

                for c in node.children[0].children:
                    new_child.add_child(c)
                node.children[0] = new_child
                l = PDDL_Utils.read_type(new_child)
            else:
                l = [(node.children[0].name, node.children[2].name)]

            for v, t in l:
                parameter_map[v] = t
            args = [
                self.to_formula(c, parameter_map) for c in node.children[i:]
            ]
            for v, t in l:
                del (parameter_map[v])
            return Forall(l, args)

        i = 0
        args = [self.to_formula(c, parameter_map) for c in node.children[i:]]

        def handle_modality(node, pref_len, modality):

            assert 1 <= len(
                node.children) <= 2, "Error: Found %d children." % len(
                    node.children)

            #print "%s / %s / %s" % (str(node), str(pref_len), str(modality))

            ag = node.name[pref_len:-1]

            if len(node.children) == 1:
                pred = self.to_formula(node.children[0], parameter_map)
            else:
                pred = self.to_formula(node.children[1], parameter_map)
                pred.negated_rml = True

            assert not isinstance(
                pred, Not
            ), "Error: Cannot nest lack of belief with (not ...): %s" % pred.dump(
            )
            assert isinstance(
                pred, Primitive
            ), "Error: Type should have been Primitive, but was %s" % str(
                type(pred))

            pred.agent_list = "%s%s %s" % (modality, ag, pred.agent_list)

            return pred

        if "and" == node.name:
            return And(args)
        elif "or" == node.name:
            return Or(args)
        elif "oneof" == node.name:
            return Oneof(args)
        elif "not" == node.name:
            return Not(args)
        elif "xor" == node.name:
            return Xor(args)
        elif "nondet" == node.name:
            assert len(node.children) == 1,\
                                       "nondet must only have a single child as a predicate"
            # make p != p2, otherwise might run into issues with mutation in some later step
            return Oneof([args[0], Not(args)])
        elif "unknown" == node.name:
            assert len(node.children) == 1,\
                "unknown must only have a single child as a predicate"
            # make p != p2, otherwise might run into issues with mutation in some later step
            p = Primitive(
                self.to_predicate(node.children[0], map=parameter_map))
            p2 = Primitive(
                self.to_predicate(node.children[0], map=parameter_map))
            return Xor([p, Not([p2])])
        elif "when" == node.name:
            assert len(args) == 2,\
                "When clause must have exactly 2 children"
            return When(args[0], args[1])

        elif "P{" == node.name[:2]:
            return handle_modality(node, 2, 'P')

        elif "!P{" == node.name[:3]:
            return handle_modality(node, 3, '!P')

        elif "B{" == node.name[:2]:
            return handle_modality(node, 2, 'B')

        elif "!B{" == node.name[:3]:
            return handle_modality(node, 3, '!B')

        elif "!" == node.name[0]:
            node.name = node.name[1:]
            pred = Primitive(self.to_predicate(node, map=parameter_map))
            pred.negated_rml = True
            return pred
        else:
            # it's a predicate
            return Primitive(self.to_predicate(node, map=parameter_map))