コード例 #1
0
ファイル: parser.py プロジェクト: kingabohus/fondparser
    def _parse_domain(self, f_domain):
        """
        Extract information from the domain file.

        The following will be extracted:
            * types
            * predicates
            * actions
        """

        parse_tree = PDDL_Tree.create(f_domain)

        assert "domain" in parse_tree, "Domain must have a name"
        self.domain_name = parse_tree ["domain"].named_children ()[0]

        # must read types before constants
        if ":types" in parse_tree:
            if "-" in parse_tree[":types"].named_children():
                type_hierarchy = PDDL_Utils.read_type(parse_tree[":types"])
                self.parent_types = {subtype: parent for subtype, parent in type_hierarchy}
                self.types = set(parse_tree[":types"].named_children())
                self.types.discard("-")
            else:
                self.types = set(parse_tree[":types"].named_children())
                self.parent_types = {t: None for t in self.types}
        else:
            self.types = set([Predicate.OBJECT])
            self.parent_types = {Predicate.OBJECT: None}

        # must read in constants before actions or predicates
        if ":constants" in parse_tree:
            object_list = PDDL_Utils.read_type(parse_tree[":constants"])
            self._add_objects(object_list)

        #TODO this may not be correct, depending on the type hierchy
        const_map = {const: list(self.obj_to_type[const])[0] for const in self.objects}

        self.predicates = [self.to_predicate(c, map=const_map) for c in parse_tree[":predicates"].children]

        # some predicates have this property: they are untyped.
        for predicate in self.predicates:
            if Predicate.OBJECT not in self.types and any([arg[1] == Predicate.OBJECT for arg in predicate.args]):
                for t in self.types:
                    if self.parent_types[t] is None:
                        self.parent_types[t] = Predicate.OBJECT

                self.parent_types[Predicate.OBJECT] = None
                self.types.add(Predicate.OBJECT)
                self.type_to_obj[Predicate.OBJECT] = set([])
                for obj, type_list in self.obj_to_type.iteritems():
                    type_list.add(Predicate.OBJECT)
                    self.type_to_obj[Predicate.OBJECT].add(obj)

                # only need to do this once, obviously
                break

        self.actions = [self.to_action(c) for c in parse_tree.find_all(":action")]
コード例 #2
0
    def _parse_problem(self, f_problem):
        """
        Extract information from the problem file.

        The following will be extracted:
            * problem name
            * objects
            * initial state
            * goal state
            * type_to_obj
            * obj_to_type
        """

        parse_tree = PDDL_Tree.create(f_problem)

        assert "problem" in parse_tree, "Problem must have a name"
        self.problem_name = parse_tree["problem"].named_children()[0]

        # objects must be parsed first
        if ":objects" in parse_tree:
            object_list = PDDL_Utils.read_type(parse_tree[":objects"])
            self._add_objects(object_list)

        #TODO this may not be valid with a non-flat type hierchy
        obj_map = {obj: list(self.obj_to_type[obj])[0] for obj in self.objects}

        # the goal can be expressed in either a formula form, or a direct form
        if len(parse_tree[":goal"].children
               ) == 1 and parse_tree[":goal"].children[0].name == "and":
            self.goal = And([
                Primitive(self.to_fluents(c))
                for c in parse_tree[":goal"].children[0].children
            ])
        else:
            self.goal = And([
                Primitive(self.to_fluents(c))
                for c in parse_tree[":goal"].children
            ])

        # it is critical that the formula here be checked against the objects
        if len(parse_tree[":init"].children) == 1 and \
                parse_tree[":init"].children[0].name == "and":
            self.init = self.to_formula(parse_tree[":init"].children[0],
                                        obj_map)
        else:
            # initial condition is one big AND
            #            print "```", self.init
            self.init = And([
                self.to_formula(c, obj_map)
                for c in parse_tree[":init"].children
            ])
コード例 #3
0
    def to_action(self, node):
        """
            Create an action out of this PDDL_Tree node.
            For now, will assume this makes sense.
        """

        name = node.children[0].name
        parameter_map = {}

        if ":parameters" in node:
            params = PDDL_Utils.read_type(node[":parameters"])
            parameter_map = {p[0]: p[1]
                             for p in params}  # map of variable-names to types
        else:
            params = []

        assert ":derive-condition" in node, "Error: You must include the :derive-condition value for every action."

        dcond_ind = [n.name for n in node.children].index(':derive-condition')
        dcond = self.to_formula(node.children[dcond_ind + 1], parameter_map)

        if ":precondition" in node:
            assert len(node[":precondition"].children) == 1,\
                "precondition should have one top-level child"
            precond = self.to_formula(node[":precondition"].children[0],
                                      parameter_map)
        else:
            precond = None

        if ":observe" in node:
            assert len(node[":observe"].children) == 1,\
                "observe should have one top-level child"
            observe = self.to_predicate(node[":observe"].children[0],
                                        map=parameter_map)
        else:
            observe = None

        if ":effect" in node:
            assert len(node[":effect"].children) == 1,\
                "effect should have one top-level child"
            effect = self.to_formula(node[":effect"].children[0],
                                     parameter_map)
        else:
            effect = None

        return Action(name, params, precond, observe, effect, dcond)
コード例 #4
0
    def to_predicate(self, node, f='predicate', map=None):
        """
            Create a predicate out of this PDDL_Tree node.
            For now, will assume this makes sense.
        """

        if 'AK{}' == node.name:
            assert 1 == len(
                node.children), "Error: AK{} had more than one child"
            pred = self.to_predicate(node.children[0], f, map)
            pred.always_known = True
            return pred

        args = PDDL_Utils.read_type(node)

        # change the type if there is only 1 type
        if len(self.types) == 1:
            t_args = args
            t = list(self.types)[0]
            args = []
            for arg in t_args:
                if arg[1] != t:
                    args.append((arg[0], t))
                else:
                    args.append(arg)

        # here is where the map comes in...
        if map is None:
            if 'predicate' == f:
                return Predicate(node.name, args)
            elif 'fluent' == f:
                return Predicate(node.name, args=None, ground_args=args)
        else:
            new_args = []
            for v, t in args:
                if v in map:
                    new_args.append((v, map[v]))
                else:
                    new_args.append((v, t))

            if 'predicate' == f:
                return Predicate(node.name, new_args)
            elif 'fluent' == f:
                return Predicate(node.name, args=None, ground_args=new_args)
コード例 #5
0
    def to_action(self, node):
        """
            Create an action out of this PDDL_Tree node.
            For now, will assume this makes sense.
        """

        name = node.children[0].name
        parameter_map = {}

        if ":parameters" in node:
            params = PDDL_Utils.read_type(node[":parameters"])
            parameter_map = {p[0]: p[1]
                             for p in params}  # map of variable-names to types
        else:
            params = []

        if ":precondition" in node:
            assert len(node[":precondition"].children) == 1,\
                "precondition should have one top-level child"
            precond = self.to_formula(node[":precondition"].children[0],
                                      parameter_map)
        else:
            precond = None

        if ":observe" in node:
            assert len(node[":observe"].children) == 1,\
                "observe should have one top-level child"
            observe = self.to_predicate(node[":observe"].children[0],
                                        map=parameter_map)
        else:
            observe = None

        if ":effect" in node:
            assert len(node[":effect"].children) == 1,\
                "effect should have one top-level child"
            effect = self.to_formula(node[":effect"].children[0],
                                     parameter_map)
        else:
            effect = None

        return Action(name, params, precond, observe, effect)
コード例 #6
0
ファイル: parser.py プロジェクト: kingabohus/fondparser
    def _parse_problem(self, f_problem):
        """
        Extract information from the problem file.

        The following will be extracted:
            * problem name
            * objects
            * initial state
            * goal state
            * type_to_obj
            * obj_to_type
        """

        parse_tree = PDDL_Tree.create(f_problem)

        assert "problem" in parse_tree, "Problem must have a name"
        self.problem_name = parse_tree ["problem"].named_children ()[0]

        # objects must be parsed first
        if ":objects" in parse_tree:
            object_list = PDDL_Utils.read_type(parse_tree[":objects"])
            self._add_objects(object_list)

        #TODO this may not be valid with a non-flat type hierchy
        obj_map = {obj: list(self.obj_to_type[obj])[0] for obj in self.objects}

        # the goal can be expressed in either a formula form, or a direct form
        if len(parse_tree[":goal"].children) == 1 and parse_tree[":goal"].children[0].name == "and":
            self.goal = And([Primitive(self.to_fluents(c)) for c in parse_tree[":goal"].children[0].children])
        else:
            self.goal = And([Primitive(self.to_fluents(c)) for c in parse_tree[":goal"].children])

        # it is critical that the formula here be checked against the objects
        if len(parse_tree[":init"].children) == 1 and \
                parse_tree[":init"].children[0].name == "and":
            self.init = self.to_formula(parse_tree[":init"].children[0], obj_map)
        else:
            # initial condition is one big AND
            self.init = And([self.to_formula(c, obj_map) for c in parse_tree[":init"].children])
コード例 #7
0
    def to_predicate(self, node, f='predicate', map=None):
        """
            Create a predicate out of this PDDL_Tree node.
            For now, will assume this makes sense.
        """

        args = PDDL_Utils.read_type(node)

        # change the type if there is only 1 type
        if len(self.types) == 1:
            t_args = args
            t = list(self.types)[0]
            args = []
            for arg in t_args:
                if arg[1] != t:
                    args.append((arg[0], t))
                else:
                    args.append(arg)

        # here is where the map comes in...
        if map is None:
            if 'predicate' == f:
                return Predicate(node.name, args)
            elif 'fluent' == f:
                return Predicate(node.name, args=None, ground_args=args)
        else:
            new_args = []
            for v, t in args:
                if v in map:
                    new_args.append((v, map[v]))
                else:
                    new_args.append((v, t))

            if 'predicate' == f:
                return Predicate(node.name, new_args)
            elif 'fluent' == f:
                return Predicate(node.name, args=None, ground_args=new_args)
コード例 #8
0
ファイル: parser.py プロジェクト: kingabohus/fondparser
    def to_predicate(self, node, f='predicate', map=None):
        """
            Create a predicate out of this PDDL_Tree node.
            For now, will assume this makes sense.
        """

        args = PDDL_Utils.read_type(node)

        # change the type if there is only 1 type
        if len (self.types) == 1:
            t_args = args
            t = list (self.types) [0]
            args = []
            for arg in t_args:
                if arg[1] != t:
                    args.append ( (arg[0], t) )
                else:
                    args.append (arg)

        # here is where the map comes in...
        if map is None:
            if 'predicate' == f:
                return Predicate(node.name, args)
            elif 'fluent' == f:
                return Predicate(node.name, args=None, ground_args=args)
        else:
            new_args = []
            for v, t in args:
                if v in map:
                    new_args.append((v, map[v]))
                else:
                    new_args.append((v, t))

            if 'predicate' == f:
                return Predicate(node.name, new_args)
            elif 'fluent' == f:
                return Predicate(node.name, args=None, ground_args=new_args)
コード例 #9
0
ファイル: parser.py プロジェクト: kingabohus/fondparser
    def to_action(self, node):
        """
            Create an action out of this PDDL_Tree node.
            For now, will assume this makes sense.
        """

        name = node.children[0].name
        parameter_map = {}

        if ":parameters" in node:
            params = PDDL_Utils.read_type(node[":parameters"])
            parameter_map = {p[0]: p[1] for p in params}  # map of variable-names to types
        else:
            params = []

        if ":precondition" in node:
            assert len(node[":precondition"].children) == 1,\
                "precondition should have one top-level child"
            precond = self.to_formula(node[":precondition"].children[0], parameter_map)
        else:
            precond = None

        if ":observe" in node:
            assert len(node[":observe"].children) == 1,\
                "observe should have one top-level child"
            observe = self.to_predicate(node[":observe"].children[0], map=parameter_map)
        else:
            observe = None

        if ":effect" in node:
            assert len(node[":effect"].children) == 1,\
                "effect should have one top-level child"
            effect = self.to_formula(node[":effect"].children[0], parameter_map)
        else:
            effect = None

        return Action(name, params, precond, observe, effect)
コード例 #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)

            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))
コード例 #11
0
    def _parse_domain(self, f_domain):
        """
        Extract information from the domain file.

        The following will be extracted:
            * types
            * predicates
            * actions
        """

        parse_tree = PDDL_Tree.create(f_domain)

        assert "domain" in parse_tree, "Domain must have a name"
        self.domain_name = parse_tree["domain"].named_children()[0]

        # must read types before constants
        if ":types" in parse_tree:
            if "-" in parse_tree[":types"].named_children():
                type_hierarchy = PDDL_Utils.read_type(parse_tree[":types"])
                self.parent_types = {
                    subtype: parent
                    for subtype, parent in type_hierarchy
                }
                self.types = set(parse_tree[":types"].named_children())
                self.types.discard("-")
            else:
                self.types = set(parse_tree[":types"].named_children())
                self.parent_types = {t: None for t in self.types}
        else:
            self.types = set([Predicate.OBJECT])
            self.parent_types = {Predicate.OBJECT: None}

        # must read in constants before actions or predicates
        if ":constants" in parse_tree:
            object_list = PDDL_Utils.read_type(parse_tree[":constants"])
            self._add_objects(object_list)

        #TODO this may not be correct, depending on the type hierchy
        const_map = {
            const: list(self.obj_to_type[const])[0]
            for const in self.objects
        }

        self.predicates = [
            self.to_predicate(c, map=const_map)
            for c in parse_tree[":predicates"].children
        ]

        # some predicates have this property: they are untyped.
        for predicate in self.predicates:
            if Predicate.OBJECT not in self.types and any(
                [arg[1] == Predicate.OBJECT for arg in predicate.args]):
                for t in self.types:
                    if self.parent_types[t] is None:
                        self.parent_types[t] = Predicate.OBJECT
                self.parent_types[Predicate.OBJECT] = None
                self.types.add(Predicate.OBJECT)
                self.type_to_obj[Predicate.OBJECT] = set([])
                for obj, type_list in self.obj_to_type.iteritems():
                    type_list.add(Predicate.OBJECT)
                    self.type_to_obj[Predicate.OBJECT].add(obj)

                # only need to do this once, obviously
                break
        self.actions = [
            self.to_action(c) for c in parse_tree.find_all(":action")
        ]
コード例 #12
0
ファイル: parser.py プロジェクト: kingabohus/fondparser
    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))
コード例 #13
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))
コード例 #14
0
    def _parse_problem(self, f_problem):
        """
        Extract information from the problem file.

        The following will be extracted:
            * problem name
            * objects
            * initial state
            * goal state
            * type_to_obj
            * obj_to_type
        """

        parse_tree = PDDL_Tree.create(f_problem)

        assert "problem" in parse_tree, "Problem must have a name"
        self.problem_name = parse_tree["problem"].named_children()[0]

        # objects must be parsed first
        if ":objects" in parse_tree:
            object_list = PDDL_Utils.read_type(parse_tree[":objects"])
            self._add_objects(object_list)

        #TODO this may not be valid with a non-flat type hierchy
        obj_map = {obj: list(self.obj_to_type[obj])[0] for obj in self.objects}

        # the goal can be expressed in either a formula form, or a direct form
        if len(parse_tree[":goal"].children
               ) == 1 and parse_tree[":goal"].children[0].name == "and":
            self.goal = And([
                self.to_formula(c, obj_map)
                for c in parse_tree[":goal"].children[0].children
            ])
        else:
            self.goal = And([
                self.to_formula(c, obj_map)
                for c in parse_tree[":goal"].children
            ])

        # it is critical that the formula here be checked against the objects
        if len(parse_tree[":init"].children) == 1 and \
                parse_tree[":init"].children[0].name == "and":
            self.init = self.to_formula(parse_tree[":init"].children[0],
                                        obj_map)
        else:
            # initial condition is one big AND
            self.init = And([
                self.to_formula(c, obj_map)
                for c in parse_tree[":init"].children
            ])

        # Parse the multiagent stuff
        self.task = parse_tree[":task"].children[0].name
        self.depth = int(parse_tree[":depth"].children[0].name)
        self.projection = [a.name for a in parse_tree[":projection"].children]
        self.init_type = parse_tree[":init-type"].children[0].name
        self.plan = []
        if ':plan' in parse_tree:
            self.plan = map(
                lambda x: '_'.join(
                    map(str, [x.name] + [y.name for y in x.children])),
                parse_tree[":plan"].children)