-
Notifications
You must be signed in to change notification settings - Fork 0
Limits
Limits define one or more ranges of values that are legal for a particular numeric parameter. The range of a numeric parameter is relevant in two different situations: when generating values while creating a design, and when setting the value of a parameter in an existing design.
The many possible configurations have various exceptions, and a simple rule for how ranges are defined is currently beyond our grasp. Future versions of the specification are likely to be more accommodating.
Ranges are defined by specifying one or more of four possible limits.
- Inclusive minimum.
- Exclusive minimum.
- Inclusive maximum.
- Exclusive maximum.
Only one kind of minimum and maximum limit is allowed at one time. That is, a parameter cannot be defined with an inclusive and also an exclusive minimum.
There is no way to explicitly specify "no limit". If no limit is specified, then the parameter is assumed to be unbounded, and the (inclusive) minimum/maximum for the given type is used.
Limit definitions may consist of a simple numeric literal. They may also consist of mathematical expressions that reference other parameters and optionally use JavaScript Math functions. Note that using math functions is completely optional, but any mathematical expression must reference one or more other parameters. The converse also holds; any reference must occur within a mathematical expression. Whitespace in expressions is ignored.
Defining empty ranges is not strictly illegal. However, explicitly specifying literal limits such that the lower limit is greater than or equal to the upper limit is illegal. Hence empty ranges are only possible when defined relative to other parameters. In the event that a range turns out to be empty, the limits are swapped.
It is also legal to define multiple ranges by listing multiple comma-separated values when specifying limits. The usual rules for specifying values apply. That is, values may be simple numerals or mathematical expressions referencing other parameters. However, there is no combination of limits and values that could be considered valid.
The type of a limit may be different from the type of the parameter itself. When using floating point values to define the range of an integer parameter, the limits are simply truncated. Limits overflow by rolling around to min/max if set to a value that exceeds the range of the type.
For obvious reasons, circular dependencies are not allowed.
Once a range has been defined, it has mostly the obvious meaning. InPUT4j v0.5 does have a few quirks, though. When the range is {x}, x will be generated. This means that, when the set of legal values is a singleton set, all the members in the set are produced. However, this is not the case when the set is not a singleton. Let X be the set of legal values for a given range, and |X| > 1. Then there must exist some x such that x is the largest value in X. Then the set of values that will ever be generated is X \ {x}. Note that this is the case for each range. So when defining a multi-range, the largest legal value for each range is excluded from the set of values that will be generated.
For integer values, the notions of inclusive and exclusive limits work as expected, with the exception of the excluded maximum value mentioned above. However, for floating point values, limits are always inclusive. So a parameter that has been defined to be in the range ]0.1,0.2[ may be initialized to 0.1 or 0.2, which one might expect to be excluded from the set of legal values. This may not be a big problem, considering that there are, at least mathematically, an infinite number of values between two real numbers. So the chance that exactly an end point is generated is infinitesimal. Even though practice is different from theory, it may still be close enough. However, it is also possible to accidentally set the value to exactly the endpoint, and it will be accepted.
Specifying mixed limits when defining a multi-range (one limit is inclusive while the other is exclusive) is illegal. Exclusive limits do not yield a multi-range, because only the first range is registered. When using expressions, the situation is similar, but only the last range is used. Inclusive limits without expressions are interpreted differently by a design space and a design. So they are only valid from the perspective of generated values, not from the perspective of legal values. Values from all ranges will be generated, but only values from the intersection of the ranges will be considered legal by a design. This does not prevent it from being initialized with a value that is not in the intersection, but only values from the intersection can be set after the design has been initialized.
When defining a parameter with a multi-range in InPUT4j v0.5, the number of min limits must be at least as great as the number of max limits. Otherwise, the design space cannot even be instantiated by InPUT4j. A multi-range with a greater number of minimum limits is legal in a sense, but using the resulting design space will fail sooner or later. So calling such a configuration legal would really be stretching our definitions. In general then, InPUT does not allow multi-ranges with mismatching limits, which makes complete sense. There just is no way to unambiguously specify "no limit", even implicitly, the way single ranges work. This would of course be possible if "slots" could explicitly be left blank, or filled with a special "no limit" place holder symbol. For example, a string such as ',1,,2' or '*,1,*,2' could solve this problem. Unfortunately, this format is not currently supported by InPUT4j, and so it is not considered legal in InPUT v0.5.
Another limitation is that it is impossible to mix inclusive and exclusive limits so that one range has an inclusive lower limit while another range has an exclusive lower limit. This is a problem that is inherent in the approach of specifying inclusive/exclusive min/max limits in the way InPUT currently does, and empty "slots" would not eliminate this limitation. Mixing limits would mean specifying both inclusive and exclusive min and/or max limits. There is no way to make sense of such a configuration.
<NParam id='A' type='integer' />
<NParam id='B' inclMin='2' type='integer' />
<NParam id='C' inclMax='0.9' type='integer' />
<NParam id='E' exclMin='B* 2' type='integer' />
<NParam id='F' inclMin='Math.sqrt(B)/2' exclMax='B*Math.sin(C) - A' type='integer' />
<NParam id='A' exclMin='1,5' exclMax='2,10' type='integer' />
<NParam id='B' exclMin='0.1' exclMax='0.2' type='double' />
<NParam id='C' exclMin='A+1, A+10' exclMax='A+5, A+20' type='double' />
<NParam id='D' inclMin='1,5' inclMax='2,10' type='integer' />
<NParam id='A' inclMin='1' exclMin='3' type='integer' />
<NParam id='B' inclMin='1 + 2' type='integer' />
<NParam id='C' inclMin='1' inclMax='10,20' type='integer' />
<NParam id='D' inclMin='1' inclMax='0' type='integer' />
<NParam id='E' inclMax='Math.PI' type='double' />
While it would probably be a good idea to move away from the explicit limit model as the only way to define ranges, this is a suggestion for how they should work. Some other model based on [intervals] Terms_Interval and/or sets would be even better, and the advantages are discussed below. However, they would entail much greater changes to InPUT.
Limits are comma-separated lists of mathematical expressions. In the simplest case, a limit is just a single, literal, numeric value. When defining a single range, no comma is required, since there are no limits to separate. In addition to numeric literals, the expressions can utilize addition, subtraction, multiplication, and division, using the standard operators (+-*/). Expressions can also reference other parameters by ID. Lastly, more complex expressions can be formed by using any of the standard JavaScript Math functions. White space in expressions is ignored.
By allowing expressions that do not reference other parameters, magic values can be avoided. Defining a parameter relative to 'Math.sqrt(2)' or 'Math.PI' is preferable to '1.41421' and '3.14159' for exactly the same reasons that symbolic constants are preferred to literals in programming. Similarly, it makes sense to reference another parameter as-is, without any other mathematical operations.
There are some severe limitations to the way ranges are defined in v0.5. Specifying individual inclusive/exclusive limits is verbose. Furthermore, it is impossible to specify a mix of inclusive and exclusive limits when defining a multi-range. For example, the intervals ]1,4[ and [1,2] cannot be expressed in InPUT4j v0.5. Some combinations of infinite limits are also impossible. For example, the intervals [1,*[ and ]*,5] cannot be expressed in v0.5.
The multi-range ]*,5], ]*,10] cannot be expressed either, because the number of min and max limits is different. Maybe it looks like a silly example, because ]*,5] ∪ ]*,10] = ]*,10]. However, if both ranges exist, and values are picked randomly from either one, then values in ]*,5] would be twice as likely to occur compared to values in ]5,10]. So it could be a meaningful parameter definition.
These limitations would be eliminated by supporting the interval notation that is used within this document.
In fact, an interval could merely be syntactic sugar for a set of values. A set of possible discrete values could be specified using standard set notation.
<NParam id='X' values='{2, 3, 5, 7, 11}' type='integer' />
It should be investigated which combinations of interval and set notation are useful.
It is infeasible to verify that all ranges are non-empty when they are defined using references to other parameters. It is impossible to know what the actual range will be until values have been generated for the referenced parameters. However, InPUT4j v0.5 resorts to ignoring the problem and will generate illegal values if the range is empty. Exactly how empty ranges should be handled is unclear, but initializing parameters to illegal values should not be one of the options.
One possibility would be to immediately notify the user that the design space is illegal, because it has been defined in such a way that parameters may sometimes end up being defined with an empty range.
Another possibility would be to make some number of attempts to re-initialize the referenced parameters and only notify the user after repeated failure.
All other details aside, the user should be informed of the problem one way or another!
Perhaps the 'Math' prefix could be omitted for more concise expressions.