Closed GMMDMDIDEMS closed 9 months ago
I think you may be dividing by zero, hence the error. I will try to take a closer look this week. If you fill in PREREQ such that sum_{?c2} PREREQ(?c2,?c) is no longer zero for all values of ?c, it should no longer complain. In any case, your rewrite is more numerically safe.
I ran your example, and it is consistent with how we wanted to handle divide-by-zero errors in pyrddlgym. You will find this error if you run the scripts from GymExample.py as well.
I am closing this issue, but I will likely revisit the error message handling in the near future to make it more informative. If you identify another error that misfires or is misleading, please feel free to reopen the issue.
I see the problem with division-by-zero errors, but should they be possible at all considering the mentioned domain.rddl
. If I am not mistaken, these should be intercepted via the following if-statement:
if (~exists_{?c2 : course} PREREQ(?c2,?c))
then Bernoulli( PRIOR_PROB_PASS_NO_PREREQ(?c) )
The full annotated formula:
passed'(?c) =
if (takeCourse(?c) ^ ~passed(?c)) // If take a course and not already passed
then [ if (~exists_{?c2 : course} PREREQ(?c2,?c)) // if there are no prereqs
then Bernoulli( PRIOR_PROB_PASS_NO_PREREQ(?c) )
else if (([(sum_{?c2 : course}[PREREQ(?c2,?c) ^ passed(?c2)]) // if all prereqs already passed
/ (sum_{?c2 : course}[PREREQ(?c2,?c)])]) == 1.0)
then Bernoulli( 0.95 )
else // not all prereqs passed yet
Bernoulli( 0.05 )
]
else
passed(?c); // Value persists if course not taken or already passed
Indeed, short-circuiting does not work as intuition suggests in the vectorized environments. Unfortunately, I do not see a natural way to fix this, since the vectorized computation in numpy is incompatible with short-circuiting.
There are currently two ways to fix this. If you ground the domain, then there is no vectorization and the branching will work as intended. A better alternative currently is to add the following lines before you call evaluate(), or anywhere after you initialize the environment:
import numpy as np
np.seterr('ignore')
This will override the default setting of catching numerical errors, but will ignore any valid errors that arise. You can do this if you are sure your environment does not have other numerical errors besides the divide-by-zero.
If you have any suggestions how to handle branching in general domains while short circuiting, please feel free to submit a PR.
I have opened up a more general issue #238 . We need to think about how to handle the problem more elegantly in general... not sure yet how it can be done.
When running PROST via the provided Docker, I get the following ArithmeticError from the RDDLSimAgent (domain.rddl and instance.rddl are appended):
The domain is a slightly modified version of the Academic Advising domain. Considering the error message, there must be an error in the
cpfs
part for the definition ofpassed'(?c)
:The error message and the lists provided confuse me a little, because they lead me to believe that the summation does not work (e.g. missing brackets). I changed the part above to the following, which I think should lead to the same result and it works:
domain.rddl
instance.rddl
Edit: I have corrected the error message to the above specified instance.