# Commits

committed 4013e9b

Newline issues.

• Participants
• Parent commits e4cff8d

# File src/PaplConstraint.mli

Copyright (c) 2012 Anders Lau Olsen.
See LICENSE file for terms and conditions.
*)
-(** Constraints on values
-
-    A constraint is effectively a boolean function that either {i accepts} or {i
-    rejects} a value.
-
-    If [c] is a constraint and [x] is a value, then [x] is accepted if [accept c
-    x] is true and rejected if [reject c x] is true. The call [accept c x] is
-    equivalent to [not (reject c x)].
-*)
-
-(** {2 Types} *)
-
-type 'a t
-(** The type of a constraint on values of type ['a]. *)
-
-(** {2 Operations} *)
-
-val accept : 'a t -> 'a -> bool
-(** [accept c x] is true if and only if [c] accepts [x]. *)
-
-val reject : 'a t -> 'a -> bool
-(** [reject c x] is true if and only if [c] rejects [x]. *)
-
-(** {2 Constructors} *)
-
-val make_accept : ('a -> bool) -> 'a t
-(** The constraint [c = make_accept f] accepts [x] if and only if [f x] is
-    true. *)
-
-val make_reject : ('a -> bool) -> 'a t
-(** The constraint [c = make_reject f] rejects [x] if and only if [f x] is
-    true. *)
-
-val fixed_reject : bool -> 'a t
-(** A fixed constraint.
-
-    [reject (fixed_reject b) x] returns [b] for all [x].
-*)
-
-val fixed_accept : bool -> 'a t
-(** A fixed constraint.
-
-    [accept (fixed_accept b) [x]] returns [b] for all [x].
-*)
-
-val (<&>) : 'a t -> 'a t -> 'a t
-(** Composition of constraints.
-
-    The constraint [ca <&> cb] accepts a value [x] if [ca] and [cb] both accept
-    [x].
-*)
-
-val merge : ('a t) BatEnum.t -> 'a t
-(** The constraint [c = merge cs] rejects [x] if and only if any of the
-    constraints of [cs] rejects [x]. A logical equivalent is that [c] accepts
-    [x] if and only if all of the constraints of [cs] accept [x].
-*)
-
-val invert : 'a t -> 'a t
-(** Logical inversion of a constraint.
-
-    The constraint [c' = invert c] returns [not b] for [x] where [b] is the
-    value returned by [accept c x] or [reject c x].
-*)
-
-val bind : ('b -> 'a) -> 'a t -> 'b t
-(** The constraint [c' = bind f c] applied to [x] is equivalent to [c] applied
-    to [f x].
-*)
-
-val constrain_path : 'a t -> 'a list t
-(** A constraint for a path.
-
-    The constraint [c' = constrain_path c] rejects a list [xs] if any of the
-    elements [x] of [xs] is rejected by [c].
-*)
+(** Constraints on values
+
+    A constraint is effectively a boolean function that either {i accepts} or {i
+    rejects} a value.
+
+    If [c] is a constraint and [x] is a value, then [x] is accepted if [accept c
+    x] is true and rejected if [reject c x] is true. The call [accept c x] is
+    equivalent to [not (reject c x)].
+*)
+
+(** {2 Types} *)
+
+type 'a t
+(** The type of a constraint on values of type ['a]. *)
+
+(** {2 Operations} *)
+
+val accept : 'a t -> 'a -> bool
+(** [accept c x] is true if and only if [c] accepts [x]. *)
+
+val reject : 'a t -> 'a -> bool
+(** [reject c x] is true if and only if [c] rejects [x]. *)
+
+(** {2 Constructors} *)
+
+val make_accept : ('a -> bool) -> 'a t
+(** The constraint [c = make_accept f] accepts [x] if and only if [f x] is
+    true. *)
+
+val make_reject : ('a -> bool) -> 'a t
+(** The constraint [c = make_reject f] rejects [x] if and only if [f x] is
+    true. *)
+
+val fixed_reject : bool -> 'a t
+(** A fixed constraint.
+
+    [reject (fixed_reject b) x] returns [b] for all [x].
+*)
+
+val fixed_accept : bool -> 'a t
+(** A fixed constraint.
+
+    [accept (fixed_accept b) [x]] returns [b] for all [x].
+*)
+
+val (<&>) : 'a t -> 'a t -> 'a t
+(** Composition of constraints.
+
+    The constraint [ca <&> cb] accepts a value [x] if [ca] and [cb] both accept
+    [x].
+*)
+
+val merge : ('a t) BatEnum.t -> 'a t
+(** The constraint [c = merge cs] rejects [x] if and only if any of the
+    constraints of [cs] rejects [x]. A logical equivalent is that [c] accepts
+    [x] if and only if all of the constraints of [cs] accept [x].
+*)
+
+val invert : 'a t -> 'a t
+(** Logical inversion of a constraint.
+
+    The constraint [c' = invert c] returns [not b] for [x] where [b] is the
+    value returned by [accept c x] or [reject c x].
+*)
+
+val bind : ('b -> 'a) -> 'a t -> 'b t
+(** The constraint [c' = bind f c] applied to [x] is equivalent to [c] applied
+    to [f x].
+*)
+
+val constrain_path : 'a t -> 'a list t
+(** A constraint for a path.
+
+    The constraint [c' = constrain_path c] rejects a list [xs] if any of the
+    elements [x] of [xs] is rejected by [c].
+*)

# File src/PaplInterpolate.mli

Copyright (c) 2012 Anders Lau Olsen.
See LICENSE file for terms and conditions.
*)
-(**
-   Planning spaces
-
-   A motion planner searches for a path in a planning space. The type of the
-   planning space is generally user defined and depends on the robot and the
-   planning problem. This library does not distinguish between configuration
-   space and state space planning. A member of a planning space is called a {b
-   configuration} regardless of the nature of the planning.
-
-   Planning spaces may support a number of operations discussed in modules such
-   as {! PaplMetric}, {! PaplSampler}, {! PaplConstraint}, and more. The {!
-   PaplInterpolate} module is concerned with the property of being able to move
-   between a pair of discrete configurations. This is called {b interpolation}
-   and is accomplished by a function of type {! t}.
-*)
-
-(** {2 Types} *)
-
-type 'a t = 'a -> 'a -> float -> 'a
-(** Interpolation function for a planning space.
-
-    An interpolation function [interpolate] returns a configuration [x =
-    interpolate s a b] on the path connecting [a] to [b]. The interpolation
-    parameter [s] must be in the range [\[0, 1\]].
-*)
-
-type 'a intermediary_t = 'a -> 'a -> 'a BatEnum.t
-
-val intermediary_steps :
-  'a t -> 'a PaplMetric.threshold_t -> 'a intermediary_t
-(**
-   [intermediary_steps ip (metric, eps) a b] are the intermediary steps of
-   length [eps] connecting [a] to [b].
-
-   [a] and [b] are not explicitly included in the stream (but they can be if the
-   interpolation function [ip] happens to return them).
-*)
-
-(** {2 Float planning space} *)
-
-(** Planning space for floats.
-
-    Configurations are floats.
-
-    Floats are interpolated linearly.
-*)
-module Float : sig
-  val interpolate : float t
-  val flip_interpolate : float -> float -> float -> float
-end
-
-module Int : sig
-  val interpolate : int t
-end
-
-(** {2 Tuple planning space} *)
-
-(** Planning space for tuples.
-
-    Tuples can contain values of seperate types. Each coordinate is interpolated
-    using a seperate interpolation function.
-*)
-
-module Tuple2 : sig
-  val interpolate : 'a t -> 'b t -> ('a * 'b) t
-end
-
-module Tuple3 : sig
-  val interpolate : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t
-end
-
-(** {2 List planning space} *)
-
-(** Planning space for lists.
-
-    Configurations are lists.
-
-    Each coordinate is interpolated independently.
-
-    The lists must be of the same length when interpolated.
-*)
-
-module List : sig
-  val interpolate : 'a t -> 'a list t
-end
-
-(** {2 Array planning space} *)
-
-(** Planning space for arrays.
-
-    Configurations are arrays.
-
-    Each coordinate is interpolated independently.
-
-    Arrays being interpolated must be of the same length.
-*)
-
-module Array : sig
-  val interpolate : 'a t -> 'a array t
-end
+(**
+   Planning spaces
+
+   A motion planner searches for a path in a planning space. The type of the
+   planning space is generally user defined and depends on the robot and the
+   planning problem. This library does not distinguish between configuration
+   space and state space planning. A member of a planning space is called a {b
+   configuration} regardless of the nature of the planning.
+
+   Planning spaces may support a number of operations discussed in modules such
+   as {! PaplMetric}, {! PaplSampler}, {! PaplConstraint}, and more. The {!
+   PaplInterpolate} module is concerned with the property of being able to move
+   between a pair of discrete configurations. This is called {b interpolation}
+   and is accomplished by a function of type {! t}.
+*)
+
+(** {2 Types} *)
+
+type 'a t = 'a -> 'a -> float -> 'a
+(** Interpolation function for a planning space.
+
+    An interpolation function [interpolate] returns a configuration [x =
+    interpolate s a b] on the path connecting [a] to [b]. The interpolation
+    parameter [s] must be in the range [\[0, 1\]].
+*)
+
+type 'a intermediary_t = 'a -> 'a -> 'a BatEnum.t
+
+val intermediary_steps :
+  'a t -> 'a PaplMetric.threshold_t -> 'a intermediary_t
+(**
+   [intermediary_steps ip (metric, eps) a b] are the intermediary steps of
+   length [eps] connecting [a] to [b].
+
+   [a] and [b] are not explicitly included in the stream (but they can be if the
+   interpolation function [ip] happens to return them).
+*)
+
+(** {2 Float planning space} *)
+
+(** Planning space for floats.
+
+    Configurations are floats.
+
+    Floats are interpolated linearly.
+*)
+module Float : sig
+  val interpolate : float t
+  val flip_interpolate : float -> float -> float -> float
+end
+
+module Int : sig
+  val interpolate : int t
+end
+
+(** {2 Tuple planning space} *)
+
+(** Planning space for tuples.
+
+    Tuples can contain values of seperate types. Each coordinate is interpolated
+    using a seperate interpolation function.
+*)
+
+module Tuple2 : sig
+  val interpolate : 'a t -> 'b t -> ('a * 'b) t
+end
+
+module Tuple3 : sig
+  val interpolate : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t
+end
+
+(** {2 List planning space} *)
+
+(** Planning space for lists.
+
+    Configurations are lists.
+
+    Each coordinate is interpolated independently.
+
+    The lists must be of the same length when interpolated.
+*)
+
+module List : sig
+  val interpolate : 'a t -> 'a list t
+end
+
+(** {2 Array planning space} *)
+
+(** Planning space for arrays.
+
+    Configurations are arrays.
+
+    Each coordinate is interpolated independently.
+
+    Arrays being interpolated must be of the same length.
+*)
+
+module Array : sig
+  val interpolate : 'a t -> 'a array t
+end

# File src/PaplMetric.mli

Copyright (c) 2012 Anders Lau Olsen.
See LICENSE file for terms and conditions.
*)
-(** Distance measures
-
-   A metric is a function that measures the distance between a pair of values.
-   Mathematically speaking, a metric must satisfy properties of
-
-   - non-negativity
-   - symmetry
-   - reflexivity
-   - triangle inequality
-
-   but metric implementations aren't required to satisfy these laws. It is the
-   responsibility of each algorithm that uses a metric to specify the laws that
-   the metric must satisfy.
-*)
-
-(** {2 Types} *)
-
-type 'a pair_t = 'a * 'a
-
-type 'a t = 'a -> 'a -> float
-(** The type of a metric.
-
-    A metric measures the distance between a pair of values.
-*)
-
-type 'a norm_t = 'a -> float
-(** The type of a norm.
-
-    A norm measures the magnitude of a value.
-*)
-
-type 'a option_t = 'a -> 'a -> float option
-
-type 'a norm_option_t = 'a -> float option
-
-type 'a threshold_t = 'a t * float
-(** A threshold is a tuple [(metric, eps)] containing a metric [metric] for
-    measuring the distance between points and a threshold value [eps] for the
-    distance.
-
-    Whether [eps] is a lower, upper, or equality boundary for values returned by
-    [metric] depends on the user of the threshold.
-*)
-
-(** {2 Constructors} *)
-
-val to_option : 'a t -> 'a option_t
-
-val to_option_less_than : 'a t -> float -> 'a option_t
-
-val bind : (float -> float) -> 'a t -> 'a t
-(**
-   If [m' = bind f m] then [m' a b] is equivalent to [f (m a b)].
-*)
-
-val scale : float -> 'a t -> 'a t
-(**
-   [scale s] is equivalent to [bind (( *. ) s)].
-*)
-
-val add : 'a t -> 'a t -> 'a t
-(**
-   If [m = add m1 m2] then [m a b] is equivalent to [m1 a b +. m2 a b].
-*)
-
-val pow : 'a t -> float -> 'a t
-(**
-   [pow m p] is equivalent to [bind (fun v -> v**p) m].
-*)
-
-val path_length : 'a t -> 'a list -> float
-(**
-   The length of a path.
-
-   The length of an empty path or a one-element path is undefined and raises an
-   exception.
-*)
-
-module Float : sig
-  val dist : float t
-    (** [Float.dist a b] returns the absolute value of [b -. a].
-    *)
-end
-
-module Int : sig
-  val dist : int t
-    (** [Int.dist a b] returns the absolute value of [b - a] converted to a
-        [float].
-    *)
-end
-
-module Tuple2 : sig
-  val dist1 : 'a t -> 'b t -> ('a * 'b) t
-
-  val dist2 : 'a t -> 'b t -> ('a * 'b) t
-
-  val dist2_sqr : 'a t -> 'b t -> ('a * 'b) t
-
-  val dist_inf : 'a t -> 'b t -> ('a * 'b) t
-end
-
-module type OPTION = sig
-  type t
-  val dist : t option_t
-end
+(** Distance measures
+
+   A metric is a function that measures the distance between a pair of values.
+   Mathematically speaking, a metric must satisfy properties of
+
+   - non-negativity
+   - symmetry
+   - reflexivity
+   - triangle inequality
+
+   but metric implementations aren't required to satisfy these laws. It is the
+   responsibility of each algorithm that uses a metric to specify the laws that
+   the metric must satisfy.
+*)
+
+(** {2 Types} *)
+
+type 'a pair_t = 'a * 'a
+
+type 'a t = 'a -> 'a -> float
+(** The type of a metric.
+
+    A metric measures the distance between a pair of values.
+*)
+
+type 'a norm_t = 'a -> float
+(** The type of a norm.
+
+    A norm measures the magnitude of a value.
+*)
+
+type 'a option_t = 'a -> 'a -> float option
+
+type 'a norm_option_t = 'a -> float option
+
+type 'a threshold_t = 'a t * float
+(** A threshold is a tuple [(metric, eps)] containing a metric [metric] for
+    measuring the distance between points and a threshold value [eps] for the
+    distance.
+
+    Whether [eps] is a lower, upper, or equality boundary for values returned by
+    [metric] depends on the user of the threshold.
+*)
+
+(** {2 Constructors} *)
+
+val to_option : 'a t -> 'a option_t
+
+val to_option_less_than : 'a t -> float -> 'a option_t
+
+val bind : (float -> float) -> 'a t -> 'a t
+(**
+   If [m' = bind f m] then [m' a b] is equivalent to [f (m a b)].
+*)
+
+val scale : float -> 'a t -> 'a t
+(**
+   [scale s] is equivalent to [bind (( *. ) s)].
+*)
+
+val add : 'a t -> 'a t -> 'a t
+(**
+   If [m = add m1 m2] then [m a b] is equivalent to [m1 a b +. m2 a b].
+*)
+
+val pow : 'a t -> float -> 'a t
+(**
+   [pow m p] is equivalent to [bind (fun v -> v**p) m].
+*)
+
+val path_length : 'a t -> 'a list -> float
+(**
+   The length of a path.
+
+   The length of an empty path or a one-element path is undefined and raises an
+   exception.
+*)
+
+module Float : sig
+  val dist : float t
+    (** [Float.dist a b] returns the absolute value of [b -. a].
+    *)
+end
+
+module Int : sig
+  val dist : int t
+    (** [Int.dist a b] returns the absolute value of [b - a] converted to a
+        [float].
+    *)
+end
+
+module Tuple2 : sig
+  val dist1 : 'a t -> 'b t -> ('a * 'b) t
+
+  val dist2 : 'a t -> 'b t -> ('a * 'b) t
+
+  val dist2_sqr : 'a t -> 'b t -> ('a * 'b) t
+
+  val dist_inf : 'a t -> 'b t -> ('a * 'b) t
+end
+
+module type OPTION = sig
+  type t
+  val dist : t option_t
+end

# File src/PaplPlanner.mli

Copyright (c) 2012 Anders Lau Olsen.
See LICENSE file for terms and conditions.
*)
-
-(** Motion planners *)
-
-(** {2 Types} *)
-
-(*
-    A call [planner stop (from, to)] of a planner [planner] searches for a path
-    connecting a start region [from] to a goal region [end]. The planner
-    regularly calls [stop] to decide if the search should continue. The planner
-    returns [None] either if [stop] says stop or the planner has decided or
-    determined that it can't find a solution path.
-*)
-
-type 'a pair_t = 'a * 'a
-
-type 'a region_t = 'a list PaplSampler.t
-
-type 'a region_pair_t = 'a region_t pair_t
-
-exception Path_not_found of string
-
-(** {3 General planner types} *)
-
-type ('target, 'result) t = PaplStopCriteria.t -> 'target -> 'result
-
-type ('target, 'result) option_t = ('target, 'result option) t
-
-(** {3 Path planner types} *)
-
-type ('target, 'q) path_t = ('target, 'q list) t
-
-type 'a point_t = ('a * 'a, 'a) path_t
-
-type 'a sampler_t = ('a region_pair_t, 'a) path_t
-
-(** {3 Trajectory planner types} *)
-
-type ('target, 'q) trajectory_t = ('target, 'q PaplTrajectory.t) t
-
-type 'q point_trajectory_t = ('q * 'q, 'q) trajectory_t
-
-type 'a sampler_trajectory_t = ('a region_pair_t, 'a) trajectory_t
-
-(** {2 General planner operations} *)
-
-val fail : string -> 'a
-(** [fail msg] raises [Path_not_found msg]. *)
-
-val to_option : ('target, 'result) t -> ('target, 'result) option_t
-(** [to_option planner] calls [planner] and returns [Some result] if the planner
-    succesfully returns [result] and [None] if the planner throws a
-    [Path_not_found] exception.
-*)
-
-val bind_target :
-  ('target2 -> 'target1) ->
-  ('target1, 'result) t ->
-  ('target2, 'result) t
-
-val map_result :
-  ('result1 -> 'result2) ->
-  ('target, 'result1) t ->
-  ('target, 'result2) t
-
-val sampler_to_point_planner :
-  ('a region_t pair_t, 'result) t ->
-  ('a pair_t, 'result) t
-
-val point_to_sampler_planner :
-  ('a pair_t, 'result) t ->
-  ('a region_t pair_t, 'result) t
-
-(** {3 Trajectory planner operations} *)
-
-module Trajectory : sig
-  val of_metric :
-    ?t0:float ->
-    'a PaplInterpolate.t ->
-    'a PaplMetric.t ->
-    ('target, 'a) path_t ->
-    ('target, 'a) trajectory_t
-  (** Path planner to trajectory planner conversion.
-  *)
-end
-
-(** {3 Path planner module types} *)
-
-module type BIDIR = sig
-  type q_t
-  type a_t
-  type b_t
-
-  val planner : (a_t * b_t, q_t) path_t
-end
-
-module type POINT_BIDIR = sig
-  type q_t
-  include BIDIR with type q_t := q_t
-                and type a_t = q_t
-                and type b_t = q_t
-end
-
-module type SAMPLER_BIDIR = sig
-  type q_t
-  include BIDIR with type q_t := q_t
-                and type a_t = q_t region_t
-                and type b_t = q_t region_t
-end
+
+(** Motion planners *)
+
+(** {2 Types} *)
+
+(*
+    A call [planner stop (from, to)] of a planner [planner] searches for a path
+    connecting a start region [from] to a goal region [end]. The planner
+    regularly calls [stop] to decide if the search should continue. The planner
+    returns [None] either if [stop] says stop or the planner has decided or
+    determined that it can't find a solution path.
+*)
+
+type 'a pair_t = 'a * 'a
+
+type 'a region_t = 'a list PaplSampler.t
+
+type 'a region_pair_t = 'a region_t pair_t
+
+exception Path_not_found of string
+
+(** {3 General planner types} *)
+
+type ('target, 'result) t = PaplStopCriteria.t -> 'target -> 'result
+
+type ('target, 'result) option_t = ('target, 'result option) t
+
+(** {3 Path planner types} *)
+
+type ('target, 'q) path_t = ('target, 'q list) t
+
+type 'a point_t = ('a * 'a, 'a) path_t
+
+type 'a sampler_t = ('a region_pair_t, 'a) path_t
+
+(** {3 Trajectory planner types} *)
+
+type ('target, 'q) trajectory_t = ('target, 'q PaplTrajectory.t) t
+
+type 'q point_trajectory_t = ('q * 'q, 'q) trajectory_t
+
+type 'a sampler_trajectory_t = ('a region_pair_t, 'a) trajectory_t
+
+(** {2 General planner operations} *)
+
+val fail : string -> 'a
+(** [fail msg] raises [Path_not_found msg]. *)
+
+val to_option : ('target, 'result) t -> ('target, 'result) option_t
+(** [to_option planner] calls [planner] and returns [Some result] if the planner
+    succesfully returns [result] and [None] if the planner throws a
+    [Path_not_found] exception.
+*)
+
+val bind_target :
+  ('target2 -> 'target1) ->
+  ('target1, 'result) t ->
+  ('target2, 'result) t
+
+val map_result :
+  ('result1 -> 'result2) ->
+  ('target, 'result1) t ->
+  ('target, 'result2) t
+
+val sampler_to_point_planner :
+  ('a region_t pair_t, 'result) t ->
+  ('a pair_t, 'result) t
+
+val point_to_sampler_planner :
+  ('a pair_t, 'result) t ->
+  ('a region_t pair_t, 'result) t
+
+(** {3 Trajectory planner operations} *)
+
+module Trajectory : sig
+  val of_metric :
+    ?t0:float ->
+    'a PaplInterpolate.t ->
+    'a PaplMetric.t ->
+    ('target, 'a) path_t ->
+    ('target, 'a) trajectory_t
+  (** Path planner to trajectory planner conversion.
+  *)
+end
+
+(** {3 Path planner module types} *)
+
+module type BIDIR = sig
+  type q_t
+  type a_t
+  type b_t
+
+  val planner : (a_t * b_t, q_t) path_t
+end
+
+module type POINT_BIDIR = sig
+  type q_t
+  include BIDIR with type q_t := q_t
+                and type a_t = q_t
+                and type b_t = q_t
+end
+
+module type SAMPLER_BIDIR = sig
+  type q_t
+  include BIDIR with type q_t := q_t
+                and type a_t = q_t region_t
+                and type b_t = q_t region_t
+end

# File src/PaplSampler.mli

Copyright (c) 2012 Anders Lau Olsen.
See LICENSE file for terms and conditions.
*)
-(** Sampling of values
-
-    A sampler is a stream of values of some type. Samplers are imperative data
-    structures. Samplers are used throughout the library in the implementation
-    of sampling based planning algorithms.
-
-    A sampler ['a t] is a type synonym for the enumeration type ['a BatEnum.t]
-    of the Batteries Included library. The library defines a number of useful
-    functions for manipulating enumerations, such as maps and folds, and
-    functions for constructing enumerations for different types of sequence
-    data (see for example [BatList]).
-*)
-
-type 'a pair_t = 'a * 'a
-type rng_t = PaplRandom.rng_t
-
-(** {2 Types} *)
-
-type 'a t = 'a BatEnum.t
-(** A sampler is an enumeration. *)
-
-type range_t = float * float
-(** Real value ranges.
-
-    A pair [(a, b)] represents the values [x] for which [a <= x <= b].
-*)
-
-type int_range_t = int * int
-(** Integer ranges.
-
-    The pair [(i, j)] represents the integer values [x] for which [i <= x < j].
-*)
-
-(** {2 Combinators} *)
-
-val pair : 'a t -> 'a pair_t t
-(** Pairs of values extracted from a single-element sampler.
-
-    [pair s] is equivalent to [product2 s s].
-*)
-
-val product2 : 'a t -> 'b t -> ('a * 'b) t
-(** The cartesian product of 2 samplers.
-
-    The sampler [s = product2 sa sb] returns tuples [(a, b)] where [a] is
-    sampled from [sa] and [b] is sampled from [sb].
-
-    If either [sa] or [sb] becomes empty, then [s] is empty too.
-*)
-
-val product3 : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t
-(** The cartesian product of 3 samplers.
-
-    The sampler [s = product3 sa sb sb] returns tuples [(a, b, c)] where [a] is
-    sampled from [sa], [b] is sampled from [sb], and [c] is sampled from [sc].
-
-    If either [sa], [sb] or [sc] becomes empty, then [s] is empty too.
-*)
-
-val intersperse : 'a t -> int -> 'a t -> 'a t
-(** An interspersed sampler.
-
-    The sampler [sxy = intersperse sx n sy] repeatedly retrieves one value [x1]
-    from [sx] followed by [n] values [y1, ..., yn] retrieved from [sy]. If [x1]
-    could not be retrieved from [sx], then [sxy] is empty too.
-
-    - If [sx] is empty, then so is [sxy].
-
-    - If [n == 0], then [sxy] and [sx] are equivalent.
-
-    - If [sy] becomes empty, then sampling proceeds as if [n == 0].
-*)
-
-val constrain : 'a t -> 'a PaplConstraint.t -> 'a t
-(** Constraining the elements of a sampler.
-
-    The sampler [constrain s c] is the stream of elements of [s] that are
-    accepted by [c].
-
-    [constrain s c] is equivalent to [BatEnum.filter (PaplConstraint.accept c) s].
-*)
-
-val constrain_with_default : 'a t -> 'a PaplConstraint.t -> 'a t -> 'a t
-(** Replace elements that are constrained with elements from another sampler.
-
-    The sampler [s' = constrain_with_default s c sd] replaces each element of
-    [s] that does not satisfy [c] with an element from [sd].
-
-    - If [s] becomes empty then [s'] is empty.
-
-    - If [sd] becomes empty then [s'] becomes equivalent to [constrain s c].
-
-    - [s'] does not check if the default elements [sd] satisfy [c].
-*)
-
-val round_robin : 'a t t -> 'a t
-(** Round-robin sampling of samplers.
-
-    The sampler [s' = round_robin samplers] cyclically retrieves samplers [s]
-    from [samplers] and returns an element from that sampler. If [s] is empty,
-    the sampler is skipped, and the next samplers are tried instead. [s'] is
-    empty when all of the samplers of [samplers] are empty.
-*)
-
-(** {2 Random sampling} *)
-
-val distribute_by_weight :
-  ?rng:rng_t ->
-  (float * 'a) BatEnum.t ->
-  'a t
-(** Sampling of elements distributed by weight.
-
-    The sampler [s = distribute_by_weight pairs] returns values [x] from an
-    enumeration of pairs [(w, x)]. A value [x] is sampled with a probability
-    proportional to its weight relative to the total weight of all pairs.
-    Weights must be non-negative.
-*)
-
-val uniform : ?rng:rng_t -> range_t -> float t
-(** Random uniform sampling of a range.
-
-    The sampler [random_uniform range] uniformly samples the range [range].
-
-    If the range is empty then the sampler is empty.
-*)
-
-val get_uniform : ?rng:rng_t -> range_t -> float
-(** A single value sampled uniformly at random from a range.
-
-    If the range is empty then an exception is raised.
-*)
-
-val uniform_int : ?rng:rng_t -> int_range_t -> int t
-(** Random sampling of ranges.
-
-    The sampler [s = uniform_int range] returns integers sampled uniformly at
-    random from [range].
-
-    If the range is empty then [s] is empty.
-*)
-
-val gaussian : ?rng:rng_t -> unit -> float t
-(** Normal distributed numbers with mean 0 and variance 1.
-*)
-
-(** {2 Utilities} *)
-
-val mean_and_variance : float t -> float * float
-(**
-   [(mean, variance) = mean_and_variance stream] is the sample mean and sample
-   variance of the elements of [stream].
-
-   If [stream] has fewer than [2] elements, an exception is raised.
-*)
+(** Sampling of values
+
+    A sampler is a stream of values of some type. Samplers are imperative data
+    structures. Samplers are used throughout the library in the implementation
+    of sampling based planning algorithms.
+
+    A sampler ['a t] is a type synonym for the enumeration type ['a BatEnum.t]
+    of the Batteries Included library. The library defines a number of useful
+    functions for manipulating enumerations, such as maps and folds, and
+    functions for constructing enumerations for different types of sequence
+    data (see for example [BatList]).
+*)
+
+type 'a pair_t = 'a * 'a
+type rng_t = PaplRandom.rng_t
+
+(** {2 Types} *)
+
+type 'a t = 'a BatEnum.t
+(** A sampler is an enumeration. *)
+
+type range_t = float * float
+(** Real value ranges.
+
+    A pair [(a, b)] represents the values [x] for which [a <= x <= b].
+*)
+
+type int_range_t = int * int
+(** Integer ranges.
+
+    The pair [(i, j)] represents the integer values [x] for which [i <= x < j].
+*)
+
+(** {2 Combinators} *)
+
+val pair : 'a t -> 'a pair_t t
+(** Pairs of values extracted from a single-element sampler.
+
+    [pair s] is equivalent to [product2 s s].
+*)
+
+val product2 : 'a t -> 'b t -> ('a * 'b) t
+(** The cartesian product of 2 samplers.
+
+    The sampler [s = product2 sa sb] returns tuples [(a, b)] where [a] is
+    sampled from [sa] and [b] is sampled from [sb].
+
+    If either [sa] or [sb] becomes empty, then [s] is empty too.
+*)
+
+val product3 : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t
+(** The cartesian product of 3 samplers.
+
+    The sampler [s = product3 sa sb sb] returns tuples [(a, b, c)] where [a] is
+    sampled from [sa], [b] is sampled from [sb], and [c] is sampled from [sc].
+
+    If either [sa], [sb] or [sc] becomes empty, then [s] is empty too.
+*)
+
+val intersperse : 'a t -> int -> 'a t -> 'a t
+(** An interspersed sampler.
+
+    The sampler [sxy = intersperse sx n sy] repeatedly retrieves one value [x1]
+    from [sx] followed by [n] values [y1, ..., yn] retrieved from [sy]. If [x1]
+    could not be retrieved from [sx], then [sxy] is empty too.
+
+    - If [sx] is empty, then so is [sxy].
+
+    - If [n == 0], then [sxy] and [sx] are equivalent.
+
+    - If [sy] becomes empty, then sampling proceeds as if [n == 0].
+*)
+
+val constrain : 'a t -> 'a PaplConstraint.t -> 'a t
+(** Constraining the elements of a sampler.
+
+    The sampler [constrain s c] is the stream of elements of [s] that are
+    accepted by [c].
+
+    [constrain s c] is equivalent to [BatEnum.filter (PaplConstraint.accept c) s].
+*)
+
+val constrain_with_default : 'a t -> 'a PaplConstraint.t -> 'a t -> 'a t
+(** Replace elements that are constrained with elements from another sampler.
+
+    The sampler [s' = constrain_with_default s c sd] replaces each element of
+    [s] that does not satisfy [c] with an element from [sd].
+
+    - If [s] becomes empty then [s'] is empty.
+
+    - If [sd] becomes empty then [s'] becomes equivalent to [constrain s c].
+
+    - [s'] does not check if the default elements [sd] satisfy [c].
+*)
+
+val round_robin : 'a t t -> 'a t
+(** Round-robin sampling of samplers.
+
+    The sampler [s' = round_robin samplers] cyclically retrieves samplers [s]
+    from [samplers] and returns an element from that sampler. If [s] is empty,
+    the sampler is skipped, and the next samplers are tried instead. [s'] is
+    empty when all of the samplers of [samplers] are empty.
+*)
+
+(** {2 Random sampling} *)
+
+val distribute_by_weight :
+  ?rng:rng_t ->
+  (float * 'a) BatEnum.t ->
+  'a t
+(** Sampling of elements distributed by weight.
+
+    The sampler [s = distribute_by_weight pairs] returns values [x] from an
+    enumeration of pairs [(w, x)]. A value [x] is sampled with a probability
+    proportional to its weight relative to the total weight of all pairs.
+    Weights must be non-negative.
+*)
+
+val uniform : ?rng:rng_t -> range_t -> float t
+(** Random uniform sampling of a range.
+
+    The sampler [random_uniform range] uniformly samples the range [range].
+
+    If the range is empty then the sampler is empty.
+*)
+
+val get_uniform : ?rng:rng_t -> range_t -> float
+(** A single value sampled uniformly at random from a range.
+
+    If the range is empty then an exception is raised.
+*)
+
+val uniform_int : ?rng:rng_t -> int_range_t -> int t
+(** Random sampling of ranges.
+
+    The sampler [s = uniform_int range] returns integers sampled uniformly at
+    random from [range].
+
+    If the range is empty then [s] is empty.
+*)
+
+val gaussian : ?rng:rng_t -> unit -> float t
+(** Normal distributed numbers with mean 0 and variance 1.
+*)
+
+(** {2 Utilities} *)
+
+val mean_and_variance : float t -> float * float
+(**
+   [(mean, variance) = mean_and_variance stream] is the sample mean and sample
+   variance of the elements of [stream].
+
+   If [stream] has fewer than [2] elements, an exception is raised.
+*)