
piecewise_linear(?X, ++Points, ?Y)

   Relates X and Y according to a piecewise linear function.

Arguments
   X                   Parameter/domain of the piecewise function
   Points              Collection (a la collection_to_list/2) of points defining the piecewise function
   Y                   Result/interval of piecewise the function

Type
   library(ic)

Description

   This predicate imposes the constraint Y = f(X), where f is a piecewise
   linear function defined by Points.  Points must be (after processing by
   collection_to_list/2) a list of elements of the form (X, Y), sorted by
   increasing X values.  The function is constructed by performing linear
   interpolation between consecutive points, and extrapolating the first and
   last linear segments to infinity.

   Discontinuities are allowed, by specifying more than one point with the
   same X coordinate.  However, since the constraint is a function, one must
   specify which of the given Y values is the true value of the function at
   that point.  This is done by annotating which of the adjacent line
   segments is ``open'' at that end (i.e. does not include the end point).
   There are three allowed forms of discontinuity:

	(X1, Y1), (X2, Y2a), (>(X2), Y2b), (X3, Y3) 
	(X1, Y1), (<(X2), Y2a), (X2, Y2b), (X3, Y3) 
	(X1, Y1), (<(X2), Y2a), (X2, Y2b), (>(X2), Y2c), (X3, Y3)

   In the first form, the segment specified by the first two points is
   defined over the interval [X1 .. X2] while that specified by the last two
   is defined over the interval (X2 .. X3].  That is, the first interval is
   closed at X2, the second is open at X2 (i.e. only includes points
   strictly greater than X2), and thus the value of the function at X2 is
   Y2a.

   In the second form, the reverse is true.  The first segment is over the
   interval [X1 .. X2) (points less than X2), the second is over the
   interval [X2 .. X3], and the value of the function at X2 is Y2b.

   The final form is a double discontinuity.  Both adjacent segments are
   open - [X1 .. X2), (X2 .. X3] - and at X2 the value of the function is
   Y2b, taken from neither segment.

   Note that a segment can be open at both ends, if it has discontinuities
   at both ends.  For example, if the list of points is

	[(0, 0), (10, 0), (>(10), 1), (<(20), 1), (20, 2), (30, 2)]

   then the function has value 0 for all values of X up to and including 10,
   it has value 2 for all values of X from 20 onwards, and has value 1 in
   between.


   Other notes:

   A piecewise linear constraint is expected to have at least two points
   (though if it only has two, then a standard linear constraint would do,
   and likely be more efficient).  If there is only one point, then there is
   no way to determine the gradient to use to extend the function to other
   values of X.  As a result, the value of the function is not defined for
   all other values of X.  Similarly, if the first or last points in the
   specification of the piecewise constraint are involved in
   discontinuities, then the corresponding extensions to infinity are
   undefined; it is recommended that the user either provide a valid
   extension by supplying an extra point, or exclude those values of X by
   imposing an appropriate bound.  (In any event, the first and last points
   must be closed; an open discontinuity is not permitted at either end.)

   Whilst the piecewise constraint accepts bounded reals in its arguments,
   the current implementation does not fully support bounded reals of
   non-zero width (i.e. those which do not correspond to a single floating
   point value).  As a result, use of such bounded reals is not recommended
   at this time.


See Also
   eplex : piecewise_linear_hull / 3, lists : collection_to_list / 2
