WeBWorK Main Forum

Is default tolerance set correctly in pg/lib/Value.pm?

Is default tolerance set correctly in pg/lib/Value.pm?

by Alex Jordan -
Number of replies: 2
If I run this problem:

DOCUMENT();
loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"PGinfo.pl",
);
TEXT(listContextFlags());
Context("Numeric");
TEXT(listContextFlags());

ENDDOCUMENT();


Then it reveals two differences between explicitly declaring the Numeric context and not declaring it. One difference is probably irrelevant: the useBaseTenLog flag is at first undefined, then it is 0.

But the other difference is significant. The tolerance is 0.0001, then it is 0.001. This table in the wiki:
http://webwork.maa.org/wiki/Context_flags#Flags_for_Reals

says the default tolerance is 0.001, but I think the above demonstrates that isn't quite true. 0.001 is the default if you explicitly declare Numeric context (or load a macro library that loads Numeric context) and 0.0001 is the default otherwise.

I can see in pg/lib/Value.pm, lines 60 and 113, where it sets tolerance => 1E-4. My question to developers is if I would be right to submit a pull request changing this to 1E-3. (And while I'm at it, set useBaseTenLog to 0). Doing so would affect the tolerance on every problem using MathObjects that did not declare a context, did not load a macro library that declared a context, and did not explicitly set tolerance on its own. But it would resolve a discrepancy where the standards seem to change from "four significant digits" to "five significant digits" between some OPL problems.
In reply to Alex Jordan

Re: Is default tolerance set correctly in pg/lib/Value.pm?

by Davide Cervone -
The situation is actually a bit more complicated. Prior to MathObjects, the tolerance levels, types, and such were controlled by global variables like $numRelPercentTolDefault, $numZeroLevelDefault, and $useBaseTenLog. These in turn were set by the PG environment variables $envir{numRelPercentTolDefault} and so on.

Some of these can be controlled by the Course Configuration instructor tool on line, and all could be set in the course configuration file by hand. It is important for these values to be used by the MathObject contexts, since they can be set in the course configuration.

This is complicated by the fact that the MathObject perl libraries are loaded in the persistent perl memory (via mod_perl) at the time an http child process is started, and those definitions re shared among all the problems that are handled by that child process. In order to allow problems to change the values in a context, the problems can't be allowed to change the original context definitions, since that would mean those changes would be persistent and would affect the next problem that used that same child process. To overcome this, MathObjects makes a copy of the original context (in the safe compartment that is the temporary local storage for a problem run by the child process) whenever a context is requested. It is during this copying process that the tolerance and other values are obtained from the PG environment and used to set the corresponding context values. This guarantees that the context has the values from the course configuration, but that those changes aren't shared from problem to problem within the child process.

Unfortunately, it appears there is a timing problem with setting up the original (default) context that is in place if no Context() call is made. It appears that the PG environment isn't available yet at that point, and the copying of the values isn't performed in that case. So even though the numeric context is copied as the default, it doesn't get the values of tolerance, useBaseTenLog, and the other values from the environment (i.e., the course configuration). That is why you are seeing the defaults from pg/lib/Value.pm rather than the course configuration values.

While changing the values in pg/lib/Value.pm to match the default settings for the environment, that would not cause the defaults to be properly set if the course configuration changes the defaults. I think the proper approach is to put off making the default context until after the PG environment is available. I suggest adding Context("Numeric") to pg/macros/Parser.pl. This will make sure that, for any problem that loads MathObjects.pl, the default context is actually the same as the Numeric context since it will occur after the PG environment is in place. This was supposed to be the effect of some of the code already in that file, but the timing issues I mentioned above prevented that. An explicit Context("Numeric") should do the trick. One can still used parserCustominzation.pl to make further changes to the default context (or change the default to a different context) if desired.

I will make a PR to that effect. Although you are right that this could affect problems that don't set the context themselves, the course configuration is not being properly applied to those problems, and so I think it does need to be changed for those.