The first and last points are stored explicitly, not least to ensure that there are two of them. The list of points in the middle is stored in reverse order for convenience when checking the path.
In a path, we might demand that we go from A -> B directly, or A -> B possibly via
some other points. This is represented as { first = Direct_point a; last = b; ... }
and { first = Point a; last = b; ... } respectively; that is, whether or not it must
go directly is stored on the source, not the destination.
A final example:
{ first = Point a; middle_rev = [Direct_point b]; last = c }
matches any sequence of points that starts at a, goes (possibly via some other
distinct points) to b, and then directly from b to c.
This and the Event_generator.t do not have the full power of regular expressions
Notably, the same point may not appear in a path twice, except for when its
second appearance is the last point in the path.
include sig ... endval point_of_sexp : (Sexplib.Sexp.t ‑> 'a) ‑> Sexplib.Sexp.t ‑> 'a pointval sexp_of_point : ('a ‑> Sexplib.Sexp.t) ‑> 'a point ‑> Sexplib.Sexp.tinclude sig ... endval t_of_sexp : (Sexplib.Sexp.t ‑> 'a) ‑> Sexplib.Sexp.t ‑> 'a tval sexp_of_t : ('a ‑> Sexplib.Sexp.t) ‑> 'a t ‑> Sexplib.Sexp.tmodule I : sig ... endval string_t_of_string : string ‑> string t optionval string_t_to_string : string t ‑> stringval examples : string t listval readme : string Core.Lazy.tval lookup_ids : string t ‑> Util.Name_map.group ‑> Core_profiler.Probe_id.t tval lookup_names : Core_profiler.Probe_id.t t ‑> Reader.Header.t ‑> string tval id_t_to_string : Core_profiler.Probe_id.t t ‑> ?with_group:string ‑> Reader.Header.t ‑> stringval last : 'a t ‑> 'a