pellierd / pddl4j

PDDL4J is an open source library under LGPL license whose purpose of PDDL4J is to facilitate the development of JAVA tools for Automated Planning based on PDDL language (Planning Domain Description Language).
https://lig-membres.imag.fr/pellier/
GNU Lesser General Public License v3.0
147 stars 68 forks source link

java.lang.NullPointerException while extracting relevant fluent #108

Closed eyess-glitch closed 1 year ago

eyess-glitch commented 1 year ago

I have the following domain and problem files

(define 
  (domain emergency-logistics)
  (:requirements :strips :typing :negative-preconditions :conditional-effects :disjunctive-preconditions)

  (:types 
    person box content location carrier agent value - object
  )

  (:constants
    zero one two three four - value
  )

  (:predicates
    (person-at-loc ?p - person ?l - location)
    (box-at-loc ?b - box ?l - location)
    (content-at-loc ?c - content ?l - location)
    (carrier-at-loc ?c - carrier ?l - location)
    (agent-at-loc ?a - agent ?l - location)   
    (is-box-empty ?b - box)
    (has-box-content ?c - content ?b - box)
    (has-person-content ?p - person ?c - content)
    (box-on-carrier ?b - box ?ca - carrier)
    (is-carrier-full ?c - carrier)
    (carrier-capacity ?c - carrier ?v - value)
    (total-boxes ?c - carrier ?v - value)
  )

  (:action FILL-BOX
    :parameters (?b - box ?c - content ?a - agent ?l - location)
    :precondition (and
      (box-at-loc ?b ?l)
      (agent-at-loc ?a ?l)
      (content-at-loc ?c ?l)
      (is-box-empty ?b)
    )
    :effect (and
      (not (is-box-empty ?b))
      (has-box-content ?c ?b)
    )
  )

  (:action EMPTY-BOX
    :parameters (?b - box ?c - content ?p - person ?l - location ?a - agent)
    :precondition (and
      (not (is-box-empty ?b))
      (not (has-person-content ?p ?c))
      (box-at-loc ?b ?l)
      (agent-at-loc ?a ?l)
      (has-box-content ?c ?b)
      (person-at-loc ?p ?l)
    )
    :effect (and
      (not (has-box-content ?c ?b))
      (has-person-content ?p ?c)
      (is-box-empty ?b)
      (content-at-loc ?c ?l)
    )
  )

  (:action PICK-AND-LOAD-BOX-ON-CARRIER
    :parameters (?b - box ?l - location ?a - agent ?c - carrier)
    :precondition (and
      (box-at-loc ?b ?l)
      (agent-at-loc ?a ?l)
      (carrier-at-loc ?c ?l)
      (not (box-on-carrier ?b ?c))
      (not (is-carrier-full ?c))
    )
    :effect (and
      (box-on-carrier ?b ?c)
      (not (box-at-loc ?b ?l))
      (when (total-boxes ?c zero) (and (not (total-boxes ?c zero)) (total-boxes ?c one)))
      (when (and (total-boxes ?c one) (carrier-capacity ?c two)) (and (not (total-boxes ?c one)) (total-boxes ?c two) (is-carrier-full ?c))) 
      (when (total-boxes ?c one) (and (not (total-boxes ?c one)) (total-boxes ?c two)))
      (when (and (total-boxes ?c two) (not (is-carrier-full ?c))) (and (not (total-boxes ?c two)) (total-boxes ?c three)))
      (when (and (total-boxes ?c three) (carrier-capacity ?c four)) (and (not (total-boxes ?c three)) (total-boxes ?c four) (is-carrier-full ?c))
      )
    )
  )

  (:action UNLOAD-CARRIER
    :parameters (?b - box ?c - carrier ?l - location ?a - agent)
    :precondition (and
      (agent-at-loc ?a ?l)
      (carrier-at-loc ?c ?l)
      (box-on-carrier ?b ?c)
    )
    :effect (and
      (when (total-boxes ?c one) (and (not (total-boxes ?c one)) (total-boxes ?c zero)))
      (when (total-boxes ?c two) (and (not (total-boxes ?c two)) (total-boxes ?c one)))
      (when (total-boxes ?c three) (and (not (total-boxes ?c three)) (total-boxes ?c two)))
      (when (total-boxes ?c four) (and (not (total-boxes ?c four)) (total-boxes ?c three)))
      ; modifico qua la capacità
      (when (and (carrier-capacity ?c four) (total-boxes ?c three)) (not (is-carrier-full ?c)))
      (when (and (carrier-capacity ?c two) (total-boxes ?c one)) (not (is-carrier-full ?c)))
      (not (box-on-carrier ?b ?c))
      (box-at-loc ?b ?l)
    )
  )

  (:action MOVE-CARRIER
    :parameters (?c - carrier ?l - location)
    :precondition (and
      (not (carrier-at-loc ?c ?l))
    )
    :effect (and
      (carrier-at-loc ?c ?l)
    )
  )

  (:action MOVE-AGENT
    :parameters (?a - agent ?c - carrier ?l - location)
    :precondition (and
      (not (agent-at-loc ?a ?l))
      (not (carrier-at-loc ?c ?l))
      ;(or (is-carrier-full ?c))
    )
    :effect (and
      (when (is-carrier-full ?c) (carrier-at-loc ?c ?l))
      (agent-at-loc ?a ?l)
    )
  )
)
(define 
  (problem emergency-logistics-instance)
  (:domain emergency-logistics)
  (:objects
    box1 box2 box3 box4 box5 - box
    food1 food2 medicine1 medicine2 - content
    depot location1 location2 - location
    carrier1 - carrier
    agent1 - agent
    person1 person2 person3 - person
  )

  (:init
    ; Box locations
    ; un box è ridondante
    (box-at-loc box1 depot)
    (box-at-loc box2 depot)
    (box-at-loc box3 depot)
    (box-at-loc box4 depot)
    (box-at-loc box5 depot)

    ; Content locations
    (content-at-loc food1 depot)
    (content-at-loc food2 depot)
    (content-at-loc medicine1 depot)
    (content-at-loc medicine2 depot)

    (person-at-loc person1 location1)
    (person-at-loc person2 location1)
    (person-at-loc person3 location2)

    (not (has-person-content person1 food1))
    (not (has-person-content person1 medicine1))
    (not (has-person-content person2 medicine2))
    (not (has-person-content person3 food2))

    ; Carrier location
    (carrier-at-loc carrier1 depot)

    ; Agent location
    (agent-at-loc agent1 depot)

    ; Empty box initial conditions
    (is-box-empty box1)
    (is-box-empty box2)
    (is-box-empty box3)
    (is-box-empty box4)
    (is-box-empty box5)

    (carrier-capacity carrier1 four)

    ; Initial carrier state
    (not (is-carrier-full carrier1))

    (total-boxes carrier1 zero)
    (not (total-boxes carrier1 one))
    (not (total-boxes carrier1 two))
    (not (total-boxes carrier1 three))
    (not (total-boxes carrier1 four))
  )

  (:goal
    (and
      (has-person-content person1 food1)
      (has-person-content person1 medicine1)
      (has-person-content person2 medicine2)
      (has-person-content person3 food2)
    )
  )
)

Both files are written in PDDL 1.2 (I cannot use the newer version of the language for several purpose). Based on the guide available on the site for pddl4j, I first tried instantiating the planning problem with the code

package fr.uga.pddl4j.examples;

import fr.uga.pddl4j.parser.DefaultParsedProblem;
import fr.uga.pddl4j.parser.ErrorManager;
import fr.uga.pddl4j.parser.Message;
import fr.uga.pddl4j.parser.Parser;
import fr.uga.pddl4j.problem.DefaultProblem;
import fr.uga.pddl4j.problem.Problem;
import fr.uga.pddl4j.problem.operator.Action;

import java.io.FileNotFoundException;

/**
 * The class is an example class. It shows how to use the library to create to ground planning problem.
 *
 * @author D. Pellier
 * @version 4.0 - 06.12.2021
 */
public class ProblemInstantiationExample {

    /**
     * The main method the class. The first argument must be the path to the PDDL domain description and the second
     * argument the path to the PDDL problem description.
     *
     * @param args the command line arguments.
     */
    public static void main(final String[] args) {

        // Checks the number of arguments from the command line
        if (args.length != 2) {
            System.out.println("Invalid command line");
            return;
        }

        try {
            // Creates an instance of the PDDL parser
            final Parser parser = new Parser();
            // Parses the domain and the problem files.
            final DefaultParsedProblem parsedProblem = parser.parse(args[0], args[1]);
            // Gets the error manager of the parser
            final ErrorManager errorManager = parser.getErrorManager();
            // Checks if the error manager contains errors
            if (!errorManager.isEmpty()) {
                // Prints the errors
                for (Message m : errorManager.getMessages()) {
                    System.out.println(m.toString());
                }
            } else {
                // Prints that the domain and the problem were successfully parsed
                System.out.print("\nparsing domain file \"" + args[0] + "\" done successfully");
                System.out.print("\nparsing problem file \"" + args[1] + "\" done successfully\n\n");
                // Create a problem
                final Problem problem = new DefaultProblem(parsedProblem);
                // Instantiate the planning problem
                problem.instantiate();
                // Print the list of actions of the instantiated problem
                for (Action a : problem.getActions()) {
                    //System.out.println(problem.toString(a));
                }
            }
            // This exception could happen if the domain or the problem does not exist
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

though it gives the following error

Exception in thread "main" java.lang.NullPointerException at fr.uga.pddl4j.problem.FinalizedProblem.extractRelevantFluents(FinalizedProblem.java:373) at fr.uga.pddl4j.problem.DefaultProblem.finalization(DefaultProblem.java:299) at fr.uga.pddl4j.problem.AbstractProblem.instantiate(AbstractProblem.java:444) at fr.uga.pddl4j.examples.ProblemInstantiationExample.main(ProblemInstantiationExample.java:56)

I'm pretty sure the problem is related to the domain file or problem file since I tried executing the same code on different problems and domains and it worked