Пример #1
0
 def add_initial(self):
     self.check.write('INITIALS \n')
     for i in self.initial_lits:
         self.printtofile(i)
     for si in self.subinit_lits:
         self.printtofile(si)
     for ni in self.initnot_lits:
         self.printtofile(ni)
     for dg in [self.lit_lookup[self.dg_atom, j, 0] for j in range(self.j)]:
         self.printtofile(Not([dg]))
Пример #2
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)])))
Пример #3
0
 def norm_init(self, formula):
     oneofs = []
     ooset = set([])
     new_args = formula.args[:]
     for f in formula.args:
         if f.name == 'oneof':
             oneofs.append(f)
             new_args.remove(f)
     oneargs = [[]]
     for o in oneofs:
         newnew = []
         for oo in o.args:
             nots = o.args[:]
             nots.remove(oo)
             newnew.extend([[oo] + [Not([n]) for n in nots] + a
                            for a in oneargs])
         oneargs = newnew
     return oneargs, self.norm(And(new_args))
Пример #4
0
    def create_literals(self):

        self.all_atoms = list(self.fluents) + list(self.possible_ops) + self.jk
        for t in range(self.horizon):
            for j in range(self.j):
                for f in self.fluents:
                    lit = Literal('fluent', f, (j,t))
                    self.fluent_lits.append(lit)
                    self.lit_lookup[f, j, t] = lit
        for t in range(self.horizon-1):
            for j in range(self.j):
                for o in self.possible_ops:
                    lit = Literal('action', o, (j,t))
                    self.op_lits.append(lit)
                    self.lit_lookup[o, j, t] = lit
                    self.precs[lit] = self.lit_formula(o.precondition, j,t)
                    self.effects[lit] = self.lit_formula(o.effect, j, t+1)
                    self.observes[lit] = self.lit_formula(o.observe,j,t+1)
                    if o.name == 'End':
                        self.effects[lit] = And([ self.effects[lit], self.lit_formula(Primitive(self.dg_atom), j, self.horizon-1)])

        for t in range(self.horizon):
            for djk in self.jk:
                lit = Literal('D', djk, t)
                self.djk_lits.append(Literal('D', djk, t))
                self.lit_lookup['D',djk, t] = lit

        self.all_literals = self.fluent_lits + self.op_lits + self.djk_lits
        self.goal_lits = [self.lit_lookup[self.dg_atom, j, self.horizon-1] for j in range(self.j)]
        self.initial_lits = [self.lit_formula(self.init_known, j, 0) for j in range(self.j)]
        self.subinit_lits = [self.lit_formula(And(self.subproblems[j]),j, 0) for j in range(self.j)]
        self.initnot_lits = [self.lit_formula(And([Not([Primitive(i)])   for i in self.initnot]),j,0) for j in range(self.j)]

        d = 1
        for l in self.all_literals:
            self.lit_dict[l] = d
            d += 1
Пример #5
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))
Пример #6
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))
Пример #7
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))
Пример #8
0
    def norm(self, formula):
        name = formula.name
        if (name == 'Literal') | (name == 'Primitive'):
            return formula

        elif name == 'not':
            if len(formula.args) != 1:
                raise MyError('not with more args')
            if (formula.args[0].name == 'Literal') | (formula.args[0].name
                                                      == 'Primitive'):
                return formula
            elif formula.args[0].name == 'and':
                new_formula = Or([Not([a]) for a in formula.args[0].args])
                return self.norm(new_formula)
            elif formula.args[0].name == 'or':
                new_formula = And([Not([a]) for a in formula.args[0].args])
                return self.norm(new_formula)
            elif formula.args[0].name == 'not':
                new_formula = formula.args[0].args[0]
                return self.norm(new_formula)
            else:
                raise MyError('Formula in NOT:{}'.format(formula.args[0].name))
        elif name == 'and':
            for f in formula.args:
                if (f.name == 'Literal') or (f.name == 'Primitive'):
                    pass
                elif f.name == 'and':
                    rest = formula.args[:]
                    rest.remove(f)
                    rest.extend(f.args)
                    new_formula = And(rest)
                    return self.norm(new_formula)
                elif f.name == 'when':
                    f1 = self.norm(f)
                    rest = formula.args[:]
                    rest.remove(f)
                    rest.append(f1)
                    new_formula = And(rest)
                    return self.norm(new_formula)
                elif f.name == 'or' or f.name == 'not':
                    f1 = self.norm(f)
                    if f1 != f:
                        rest = formula.args[:]
                        rest.remove(f)
                        rest.append(f1)
                        new_formula = And(rest)
                        return self.norm(new_formula)
                else:
                    raise MyError('j')
            return formula

        elif name == 'or':
            if len(formula.args) == 1:
                return self.norm(formula.args[0])
            for arg in formula.args:
                if arg.name == 'and':
                    rest = formula.args[:]
                    rest.remove(arg)
                    new_list = []
                    for f in arg.args:
                        new_new_list = rest[:]
                        new_new_list.append(f)
                        new_list.append(Or(new_new_list))
                    new_formula = And(new_list)
                    return self.norm(new_formula)
                elif arg.name == 'or':
                    rest = formula.args[:]
                    rest.remove(arg)
                    new_list = arg.args[:]
                    new_list.extend(rest)
                    new_formula = Or(new_list)
                    return self.norm(new_formula)
                elif arg.name == 'not':
                    arg2 = self.norm(arg)
                    if arg2 != arg:
                        rest = formula.args[:]
                        rest.remove(arg)
                        rest.append(arg2)
                        new_formula = Or(rest)
                        return self.norm(new_formula)
                elif arg.name == 'when':
                    rest = formula.args[:]
                    rest.remove(arg)
                    arg2 = self.norm(arg)
                    return self.norm(Or(rest + [arg2]))

            return formula
        elif name == 'when':
            # when(a,b) <=> or(not-a, b)
            a = formula.condition
            b = formula.result
            new_a = Not([a])
            new_formula = Or([new_a, b])
            return self.norm(new_formula)
        else:
            raise MyError('not enough')
Пример #9
0
 def if_then(self, condition, result):
     iff = Not([condition])
     thenf = result
     return Or([Not([iff]), thenf])
Пример #10
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))