aig-upf / tarski

Tarski - An AI Planning Modeling Framework
Apache License 2.0
59 stars 18 forks source link

Support for existential preconditions #140

Closed TheAeryan closed 1 year ago

TheAeryan commented 1 year ago

Hi, I am trying to parse a PDDL domain with existential preconditions (the exists keyword). However, I get the error tarski.errors.UndefinedVariable: Undefined element "?from" (error msg: None). Here is the PDDL domain:

(define (domain logistics)
(:requirements :strips :typing :existential-preconditions) 
(:types  city location thing - object
         package vehicle - thing
         truck airplane - vehicle  
         airport - location)
(:predicates  (in-city ?l - location ?c - city)
              (at ?obj - thing ?l - location)
              (in ?p - package ?veh - vehicle))
(:action drive
         :parameters    (?t - truck ?to - location)
         :precondition  (and 
                             (exists (?c - city ?from - location)
                                (and (at ?t ?from) (in-city ?from ?c) (in-city ?to ?c))
                              ))
         :effect        (and (not (at ?t ?from))
                             (at ?t ?to)))
;; Domain continues...

I have tested this PDDL domain (with the rest of the actions) with the FastDownward planner and it works. Therefore, my question is: does Tarski support ADL requirements such as existential preconditions?

In case it doesn't, do you know of some workaround to parse PDDL domains with existential preconditions on Tarski? The reason why I am using existential preconditions is because I want to reduce the number of action parameters as much as possible (this is needed for my current application), so I can't simply add extra variables to the action parameters.

miquelramirez commented 1 year ago

Thank you for the potential bug report.

I have added two test cases to cover the example given in the post above, see commit 3a7b2c899a1926a899c9fdb14f771eb99ecc6f6c

The FStripsReader parser does not report any errors (as I expected), and the (incomplete) PDDL 2.1 parser does report an error also as expected:

  def check_requirements_support(self):
        """
        Checks if requirements are supported
        :return:
        """
        unsupported = self.required_features - supported_features
        if len(unsupported) > 0:
            msg = "The following UNSUPPORTED features are required: {}".format(" ".join([f.name for f in unsupported]))
>           raise UnsupportedFeature(self.lexer.lineno(), msg)
E           tarski.io.pddl.errors.UnsupportedFeature: Unsupported PDDL feature: Line 3: The following UNSUPPORTED features are required: EXISTENTIAL_PRECONDITIONS

as can be seen from the test output, the PDDL 2.1 parser detects the :existential-preconditions requirement and raises an exception accordingly to notify that this feature of PDDL 2.1 is not implemented.

I can't reproduce the issue with the input provided (checkout the branch [140-support-for-existential-preconditions](https://github.com/aig-upf/tarski/tree/140-support-for-existential-preconditions) and test it yourself).

Following the following steps may help to identify the issue:

TheAeryan commented 1 year ago

I have executed the FstripsReader test (see test_tarski.py.txt, although I don't know if I have executed it correctly) and I get line 1:1 mismatched input 'define' expecting 'domain' [None].

Here I attach a full reproducible example (the full PDDL domain is logistics-domain-exists.pddl.txt):

from tarski.io.fstrips import FstripsReader

r = FstripsReader()

r.parse_domain('logistics-domain-exists.pddl')

I still get the same error tarski.errors.UndefinedVariable: Undefined element "?from" (error msg: None) in tarski\syntax\formulas.py", line 371, in get raise err.UndefinedVariable(name).

Could it be my tarski version? I am using 0.8.2 (the one which comes with pip install).

haz commented 1 year ago

I think the PDDL may be off. ?from in the effect without it being a parameter.

TheAeryan commented 1 year ago

Ah, you're absolutely right. Existential preconditions may introduce new variables (not present on the action parameters) but those variables can't be referenced in the action effects, right?

I tested this domain with the FastDownward planner and it worked. Maybe it is because FastDownward substitutes the variable ?from for the first valid instantiation and, since only one instantiation is valid (i.e., ?from can only be grounded on one object so that the existential precondition is met), that variable can be referenced in the effects without issue.

I have updated the domain file (by removing variables in effects which did not appear in the action preconditions) and now it works perfectly. Here is the new domain: logistics-domain-exists.pddl.txt

miquelramirez commented 1 year ago

chinstroke then I wonder why I didn't get an error in my test.

@TheAeryan when I have chance I will review the test case and see if I can get it to complain as it did for you. You can find usage examples for the FStripsReader here but it is not entirely complete.

If you can share an instance file I am happy to add a self-contained and commented usage example to examples.

Could it be my tarski version? I am using 0.8.2 (the one which comes with pip install).

Definitely not, we haven't touched these basic functionalities since early 2020 (by my reckoning).

Miquel.

TheAeryan commented 1 year ago

If by instance file you mean a PDDL problem, here is a very simple one: logistics-problem.pddl.txt

miquelramirez commented 1 year ago

Okay, all good I figured out why the test wasn't triggering with your original PDDL fragment.

I have added a new example with your PDDL formulation (which points out to your github repo?) so in the future there is a single-stop, very simple example of how to deal with "advanced" constructs. See PR details here: https://github.com/aig-upf/tarski/pull/141

Thank you very much for your report, and all the best with you research @TheAeryan.

If you have further questions please find the Discussions section, or create an issue to report technical issues.

Miquel.