Next: The Ria library algorithms
Up: RIA: ECLiPSe Real Number
Previous: Introduction
  Index
Subsections
- Vars :: Lo..Hi
-
Logically: Constrain a variable (or all variables in a list)
to take values between and including Lo and Hi.
The type of the bounds determines the type of the variable (real or integer).
It is possible to use the bounds -inf (or -1.0Inf) and
-inf (or 1.0Inf) to represent infinities. This is the default range
used for variables where no range has been declared.
Operationally: This information is immediately stored into the
variable's attribute. The bounds are also widened by one float
below and above to ensure the bounds are included in the range.
- reals(Vars)
-
Equivalent to Vars :: -inf..inf
- integers(Vars)
-
The given variables can only take integer values.
- ria:(ExprX =:= ExprY)
-
ExprX is equal to ExprY. ExprX and ExprY are general expressions.
- ria:(ExprX >= ExprY)
-
ExprX is greater or equal to ExprY. ExprX and ExprY are general expressions.
- ria:(ExprX =< ExprY)
-
ExprX is less or equal to ExprY. ExprX and ExprY are general expressions.
- ExprX #= ExprY
-
ExprX is equal to ExprY. ExprX and ExprY are general expressions, with the
variables constrained to be integers.
- ExprX #>= ExprY
-
ExprX is greater or equal to ExprY. ExprX and ExprY are general
expressions, with the variables constrained to be integers.
- ExprX #=< ExprY
-
ExprX is less or equal to ExprY. ExprX and ExprY are general
expressions, with the variables constrained to be integers.
- ExprX #> ExprY
-
ExprX is less than ExprY. ExprX and ExprY are general
expressions, with the variables constrained to be integers. ExprX is
considered equal to ExprY if their values differ by less than 1.
- ExprX #< ExprY
-
ExprX is greater than ExprY. ExprX and ExprY are general
expressions, with the variables constrained to be integers. ExprX is
considered equal to ExprY if their values differ by less than 1.
- Var iis SimpleExpr
-
This is the simple, uni-directional constraint that is used by the
solver to rewrite all other constraints.
It is not meant for use inside a program, but it shows up among
the delayed goals.
The comparison constraints >=/2
, =</2
, and =:=/2
have
the same syntax as their standard ECLiPSe built-in comparison operators. This ambiguity can be resolved if the user
explicitly qualify which is wanted:
ria:(A =:= B), % use ria's =:=/2
eclipse_language: (A =:= B), % use the ECLiPSe built-in
Alternatively, the user can explicitly import the version needed before the
first use:
:- import (>=) / 2, (=<) / 2, (=:=) / 2 from ria.
use(X, Y) :-
X >= Y. % this will use ria's >=/2
If none of the above are done and the user uses the operator unqualified,
ECLiPSe will resolve the ambiguity by importing the built-in version on
first use.
The following arithmetic expression can be used inside the constraints:
- X
- Variables. If X is not yet a ranged variable, it is turned into one
via an implicit declaration X :: -inf..inf.
- 123
- Integer constants. They are assumed to be exact and are used as is.
- 0.1
- Floating point constants. They are assumed to be inexact and are widened
into a narrow interval that is guaranteed to contain the true value.
- exact(0.5)
-
Sometimes the programmer knows that a floating point constant is exact
or meant to be taken literally. In that case, use this form.
- pi, e
-
Intervals enclosing the constants pi and e respectively.
- inf
-
Floating point infinity.
- +Expr
-
Identity.
- -Expr
-
Sign change.
- +-Expr
-
Expr or -Expr. The result is an interval enclosing both.
- abs(Expr)
-
The absolute value of Expr.
- E1+E2
-
Addition.
- E1-E2
-
Subtraction.
- E1*E2
-
Multiplication.
- E1/E2
-
Division.
- E1
^
E2
-
Exponentiation.
- min(E1,E2)
-
Minimum.
- max(E1,E2)
-
Maximum.
- sqr(Expr)
-
Square. Logically equivalent to Expr*Expr,
but with better operational behaviour.
- sqrt(Expr)
-
Square root (always positive).
- exp(Expr)
-
Same as e
^
Expr.
- ln(Expr)
-
Natural logarithm, the reverse of the exp function.
- sin(Expr)
-
Sine.
- cos(Expr)
-
Cosine.
- atan(Expr)
-
Arcus tangens.
- rsqr(Expr)
-
Reverse of the sqr function. The same as +-sqrt(Expr).
- rpow(Expr,N)
-
Reverse of Expr
^
N, where N is an integer constant.
- (E1;E2)
- E1 or E2. Operationally, this computes the union of two intervals.
- sub(Expr)
-
A subinterval of Expr.
Solving by Interval Propagation
Some problems can be solved just by interval propagation, for example:
[eclipse 9]: X :: 0.0..100.0, ria:(sqr(X) =:= 7-X).
X = X{2.1925824014821349 .. 2.1925824127108311}
Delayed goals:
...
yes.
There are two things to note here:
- The solver never instantiates real-variables. They only get
reduced to narrow ranges.
- In general, many delayed goals remain at the end of propagation.
This reflects the fact that the variable's ranges could possibly
be further reduced later on during the computation.
It also reflects he fact that
- the solver does not guarantee the existence of solutions in the
computed ranges. However, it guarantees that there are no solutions
outside these ranges.
Note that, since variables by default range from minus to plus infinity,
we could have written the above example as:
[eclipse 2]: ria:(sqr(X) =:= 7-X), ria:(X >= 0).
X = X{2.1925824014821349 .. 2.1925824127108311}
Delayed goals:
...
yes.
If too little information is given, the interval propagation may not
be able to infer any interesting bounds:
[eclipse 2]: ria:(sqr(X) =:= 7-X).
X = X{-1.0Inf .. 7.0000000000000009}
Delayed goals:
...
yes.
There are two methods for further domain reduction. They both rely on
search and splitting the domains. There are 2 parameters to specify how
domains are to be split.
The Precision parameter is used to specify the minimum required
precision, i.e. the maximum size of the resulting intervals.
Note that the
arc-propagation threshold
needs to be one or
several orders of magnitude smaller than precision, otherwise
the solver may not be able to achieve the required precision.
The lin/log parameter guides the way domains are split.
If it is set to lin then the split is in the arithmetic middle.
If it is set to log, the split is such as to have the
same number of floats to either side of the split. This is to take
the logarithmic distribution of the floats into account.
If the ranges of variables at the start of the squashing algorithm are
known not to span several orders of magnitude (
|max| < 10 * |min|) the
somewhat cheaper linear splitting may be used. In general, log splitting
is recommended.
- locate(+Vars, +Precision)
- locate(+Vars, +Precision, +lin/log)
-
Locate solution intervals for the given variables with the required
precision. This works well if the problem has a finite number of solutions.
locate/2,3 work by nondeterministically splitting the ranges of the variables
until they are narrower than Precision.
- squash(+Vars, +Precision, +lin/log)
-
Use the
squash algorithm
on these variables.
This is a deterministic reduction of the ranges of variables, done by
searching for domain restrictions which cause failure, and then reducing
the domain to the complement of that which caused the failure.
This algorithm is appropriate when the problem has continuous solution ranges
(where locate would return many adjacent solutions).
- locate(+LocateVars,+SquashVars,+Precision,+lin/log)
-
A variant of locate/2,3 with interleaved squashing:
The
squash algorithm
is applied once to the SquashVars initially,
and then again after each splitting step,
ie. each time one of the LocateVars has been split nondeterministically.
A variable may occur both in LocateVars and SquashVars.
Setting the Arc-Propagation Threshold
Limiting the amount of propagation is important for efficiency.
A higher threshold speeds up computations, but reduces precision and may
in the extreme case prevent the system from being able to locate
individual solutions.
- set_threshold(+Threshold)
-
Set the threshold to Threshold which is a small floating-point number.
This means any propagation which results in a domain reduction
smaller than Threshold will not be executed.
The default is 1e-8.
- get_threshold(-Threshold)
-
Read the current threshold.
Often it is difficult to know where the solver spends its time.
The library has built-in counters which keep track of
- Propagation steps (prop)
- Domain splits in locate/2,3,4 (split)
- Attempts to bound reduction in squash/3 or locate/4 (squash)
The counters are controlled using the primitive
- ria_stat(on)
- ria_stat(off)
- Enables/disable collection of statistics. Default is off.
- ria_stat(reset)
- Reset statistics counters.
- ria_stat(-Stat)
- Returns a list of CounterName=CounterValue pairs, summarising
the computation since the last reset.
- ria_stat(print)
- Print statistics counters.
Next: The Ria library algorithms
Up: RIA: ECLiPSe Real Number
Previous: Introduction
  Index
Warwick Harvey
2004-08-07