1

I posed this as an issue with a specific planner, but it's a more general PDDL question so posing here.

I'm trying to create a plan that has durations and a limited number of things it can do in parallel. No matter what I try, SMTPlan either says it should all go in parallel, or it hangs and runs forever, or reports the plan is unsolveable. It's quite possible this is an error on my part in the PDDL, or maybe I'm tweaking some issue in the planner. To its credit, SMTPlan is the one thing I find that even comes close --- most in planutils simply dump core or complain! If anyone has pointers to other planners that should work, please post pointers....

The idea is to have a count of things that are OK to operate on, aggregated into pools (in this case I have a single "object-group" but there would be more). There's a check per object group that at all times, including after the start of the action with the start effect decrementing this count, the count should be > 0. So if I have 3 things, I expect it to operate on 2, wait 5 seconds, and operate on the 3rd. Instead the plan does all 3 at once.

Here is the simplified domain.

        (domain showbug)
        (:requirements :durative-actions :fluents :action-costs :negative-preconditions)
        (:functions
         (num-objects-unselected ?og)
         )
        (:predicates
                (object-group ?og)
                (object ?o)
                (object-in-group ?o ?og)
                (object-selected ?o)
        )
        (:durative-action select-object
                :parameters (?o ?og)
                :duration (= ?duration 5)
                :condition  (and
                             (at start (object ?o))
                             (at start (object-group ?og))
                             (at start (object-in-group ?o ?og))
                             (at start (not (object-selected ?o)))
                             (at start (> (num-objects-unselected ?og ) 0))
                             (over all (forall (?og2) (> (num-objects-unselected ?og2 ) 0)))
                           )
                :effect (and (at start (decrease  (num-objects-unselected ?og) 1))
                             (at end (object-selected ?o))
                             (at end (increase  (num-objects-unselected ?og) 1))
                             )
        )
)

And the problem instance:

        (problem showbug)
        (:domain showbug)
        (:objects
                o1 o2 o3 og1
        )
        (:init (object o1) (object o2) (object o3) (object-group og1)
               (object-in-group o1 og1) (object-in-group o2 og1) (object-in-group o3 og1)
               (= (num-objects-unselected og1) 3)
        )
        (:goal (and (object-selected o1) (object-selected o2) (object-selected o3)
               ))
)

Note that num-objects-unselected og1 goes from 3 to 2 at the start, and 5s later goes from 2 to 3. I expect that if it is selecting o1 o2 o3 at once, then it should decrement from 3 to 0. Since there is a requirement that it be above 0, it wouldn't allow all three to be selected simultaneously, exactly as I want.

If I run with debugging, I get this:

smtplan domain-bug.pddl problem-bug.pddl -d -v 
Grounded:   0.001963 seconds
Algebra:    0.003671 seconds
Encoded 1:  0.042437 seconds
Solved 1:   0.003274 seconds
Encoded 2:  0.000248 seconds
0.0:    (select-object o1 og1) [5.0]
0.0:    (select-object o2 og1) [5.0]
0.0:    (select-object o3 og1) [5.0]
0.0:    |(select-object o1 og1)0_run|   (running)
0.0:    |(select-object o2 og1)0_run|   (running)
0.0:    |(select-object o3 og1)0_run|   (running)
0.0:    |(num-objects-unselected og1)0_0| == 3.0
0.0:    |(num-objects-unselected og1)0_1| == 2.0
5.0:    |(select-object o1 og1)1_end|   (end)
5.0:    |(select-object o2 og1)1_end|   (end)
5.0:    |(select-object o3 og1)1_end|   (end)
5.0:    |(object-selected o1)1_1|
5.0:    |(object-selected o2)1_1|
5.0:    |(object-selected o3)1_1|
5.0:    |(num-objects-unselected og1)1_0| == 2.0
5.0:    |(num-objects-unselected og1)1_1| == 3.0
Goal at [5.0]
Solved 2:   0.007638 seconds
Total time: 0.117884 seconds

I expect that it would select two objects at time 0, decrementing num-objects-unselected og1 from 3 to 1, then at time 5 it would select the third object and change it from 1 to 2 (or 1 to 3 and then back down to 2), ending at time 10.

Fred Douglis
  • 141
  • 10
  • 2
    Ya, looks a bit odd. The lack of typing worries me a bit, since you're quantifying in the `over all` condition (the action parameters are fine untyped since you check things with the `object` and `object-group` fluents). I'd suggest trying optic/popf for this (maybe removing the quantification if you can), and otherwise give enhsp a go. All can be found in planutils. – haz Feb 22 '23 at 21:23
  • Thanks @haz for the comment. I originally had typing, and I removed it at some point when I worried that was confusing things. I did try those on my bigger problem and they wouldn't run, nor here: `'enhsp: line 3:43 mismatched input ':action' expecting ')'`... `optic` - avoid ADL... `popf` - core dump – Fred Douglis Feb 23 '23 at 19:44
  • BTW, assuming I didn't do it wrong, adding types back to it made no difference in any of the results. – Fred Douglis Feb 23 '23 at 19:54
  • More follow-up. It occurred to me that the sample code uses "Object" which is a keyword I gather; I changed to "obj" with no effect. Then I tried changing from a check on a count to `(over all (exists (?o1 -obj) (and (object-in-group ?o1 ?og) (not (object-being-selected ?o1)))))` with an appropriate `at start` and `at end` update to the new predicate. Still no effect, it selects all 3 at once. Sigh. – Fred Douglis Feb 23 '23 at 20:48
  • Here is a [gist](https://gist.github.com/fdouglis/dda2c3ee9bcb848b1b7379938d15942a) for the updated code (since comments are pretty limited in length), in case anyone wants to try it out. – Fred Douglis Feb 23 '23 at 22:14
  • Any way you can get rid of the ADL element? Replace the exists with an additional property that's appropriately set/unset. – haz Feb 24 '23 at 20:04
  • @haz, I'm not sure how to set such a property. In the simplified problem (gist) posted most recently, I've tried to assert that at all times, something is "not being selected" -- i.e. available for other uses. I've tried both a _count_ of how many are in that state and a _predicate_ that is set at the start of the action and unset at the end, and neither works. If there is a way to do this without the "exists" or "forall" condition, that's great, but I haven't come up with a way that works. – Fred Douglis Feb 24 '23 at 21:07
  • Note that before I had either of those, I tried simply saying that for any to take an action, there had to be a count of available ones that was > 0 at the start. But that failed as well. It really seemed like there wasn't an appropriate mutex around that value (which was the [issue](https://github.com/KCL-Planning/SMTPlan/issues/22) I raised with SMTPlan -- but no response.) – Fred Douglis Feb 24 '23 at 21:09

1 Answers1

1

So if the entire exploration was on SMTPlan, you may be facing bugs that are known and ignored at this point. I'm not sure the planner is being actively maintained, and not entirely sure how to dive into diagnosing it.

As for a rewrite to something POPF / Optic can handle, [this] is what I had in mind. Not that some spots may look a bit odd, but this is to remove the ADL aspects (no negative preconditions and existential). The plan it finds:

; Plan found with metric 10.002
; States evaluated so far: 10
; States pruned based on pre-heuristic cost lower bound: 0
; Time 0.09
0.000: (select-object o3 og1)  [5.000]
5.001: (select-object o2 og1)  [5.000]
5.002: (select-object o1 og1)  [5.000]

That look reasonable?

haz
  • 625
  • 4
  • 12
  • It absolutely does look reasonable, and I thank you so much for the rewrite! I thought I tried things along those lines, but I must have not hit the magic combination. – Fred Douglis Feb 27 '23 at 15:09
  • When I go back to my original problem, optic & popf simply dump core. I don't actually see a corefile, so I hardly know where to start. Are there debug flags or environmental settings to track this down? – Fred Douglis Feb 27 '23 at 15:36
  • 1
    Weird...didn't change the system architecture or anything, did you? The above example I created seems to work fine on both, and your original ones went through but complained about ADL (as expected). If you're using the planutils docker, are you running it with the `--privileged` option? – haz Feb 28 '23 at 16:38
  • Your example worked fine. It was when I tried to apply the techniques to my original problem that I hit issues. Simply dumping core (w/o a core file appearing) wasn't terribly informative. Just now I have successfully navigated whatever the issues were that I reintroduced, and got it to handle the more complicated problem. But I'd love to know how to track down these issues when they appear. And yes, I use `--privileged`. – Fred Douglis Feb 28 '23 at 18:51
  • I guess it depends entirely on what the issue is. I've noticed popf/optic becoming fairly informative when I messed up the PDDL in some way (syntax errors are getting helpful suggestions), but if there's something more fundamentally broken, not sure how to diagnose easily. – haz Mar 01 '23 at 19:34
  • Yes, I did sometimes see syntax errors referring to a line, and that was a big help. But core dumps don't help (when no core to examine) and sometimes the errors were less informative. – Fred Douglis Mar 01 '23 at 23:00