PlanSys2 / ros2_planning_system

This repo contains a PDDL-based planning system for ROS2.
Apache License 2.0
390 stars 87 forks source link

Inefficient existential preconditions resolution #328

Open Rezenders opened 1 week ago

Rezenders commented 1 week ago

Hi @fmrico,

Unfortunately, the solution I proposed for existential predicates is inefficient. It is literally exploring the whole state space to check if the predicates are satisfied. This can easily explode. For example, if there are 75 instances and an existential precondition has 5 variables, this results in 75^5 possible combinations to check, which is unfeasible.

A concrete example (complete formulation can be found here):

    (:derived (inferred-Fg_status ?fg ?IN_ERROR_NFR_string)
        (and
            (= ?IN_ERROR_NFR_string IN_ERROR_NFR_string)
            (exists (?mqa ?eqa ?mqav ?fd ?eqav)
                (and
                    (inferred-FunctionGrounding ?fg)
                    (inferred-HasQAvalue ?fg ?mqa)
                    (inferred-IsQAtype ?eqa water_visibility)
                    (inferred-HasValue ?mqa ?mqav)
                    (inferred-TypeFD ?fg ?fd)
                    (inferred-HasValue ?eqa ?eqav)
                    (inferred-HasQAestimation ?fd ?eqa)
                    (inferred-IsQAtype ?mqa water_visibility)
                    (inferred-FunctionDesign ?fd)
                    (inferred-QAvalue ?mqa)
                    (inferred-QAvalue ?eqa)
                    (inferred-LessThan ?mqav ?eqav)
                )
            )
        )
    )

We need to come up with a mechanism to prune the possible variable combinations. I don't have any good ideas so far.

tobiaswjohn commented 1 week ago

The general procedure should be to start from the state, i.e. known facts and build the set of all derived facts from that. This applies to the existential quantification and the derived predicates.

I assume, that there is a set S that contains all atomic formulas of the form (p a_1 ... a_n) that are true in the current state

Algorithm for derived predicates

eval(P, S):
   case P = (p ?x_1 ... ?x_n) :
      return {{?x_1=a_1,...,?x_n=a_n} | (p a_1 ... a_n) in S}

   case P = (exists (?x_j) P') :
      E := eval(P', S)
      return {{?x_1=a_1,...,?x_n=a_n} | {?x_1=a_1,...,?x_n=a_n, ?x_j=a_j} in E}

   case P = (and (P' R')) :
      E_1 := eval(P', S)
      E_2 := eval(R', S)
      return join(E_1, E_2)   // join via shared variables

Algorithm to decide preconditions

Based on the before mentioned, we can decide, if the precondition of an action is satisfied.

Rezenders commented 1 week ago

@tobiaswjohn Thanks! I am working on improving the algorithm with your input. I will come back with some questions soon :)