123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135(******************************************************************************)(* *)(* Kot *)(* *)(* Juliette Ponsonnet, ENS Lyon *)(* François Pottier, Inria Paris *)(* *)(* Copyright 2025--2025 Inria. All rights reserved. This file is *)(* distributed under the terms of the GNU Library General Public *)(* License, with an exception, as described in the file LICENSE. *)(* *)(******************************************************************************)moduletypeBUFFER=sigtype'abuffervalempty:'abuffervallength:'abuffer->intvalis_empty:'abuffer->boolvalpush:'a->'abuffer->'abuffervalpop:'abuffer->'a*'abuffer(**[first b] returns the first element of the buffer [b],
which must be nonempty. It is equivalent to [fst (pop b)]. *)valfirst:'abuffer->'avalinject:'abuffer->'a->'abuffervaleject:'abuffer->'abuffer*'a(**[last b] returns the last element of the buffer [b],
which must be nonempty. It is equivalent to [snd (eject b)]. *)vallast:'abuffer->'avalmap:('a->'b)->'abuffer->'bbuffervalfold_left:('b->'a->'b)->'b->'abuffer->'bvalfold_right:('a->'b->'b)->'abuffer->'b->'bend(**The signature [BUFFER8] extends the signature [BUFFER] with extra
operations. All of these operations are in principle redundant: that is,
they can be implemented in terms of the basic operations offered by
[BUFFER]. Nevertheless, it is useful to identify these operations, for two
reasons: first, their use makes client code more readable; second, a direct
implementation of these operations is more efficient than an indirect
implementation in terms of the basic operations. *)moduletypeBUFFER8=sigincludeBUFFER(**[doubleton x y] constructs a buffer whose length is 2 and whose elements
are [x] and [y]. *)valdoubleton:'a->'a->'abuffer(**[has_length_3 b] is equivalent to [length b = 3]. *)valhas_length_3:'abuffer->bool(**[has_length_6 b] is equivalent to [length b = 6]. *)valhas_length_6:'abuffer->bool(**[has_length_8 b] is equivalent to [length b = 8]. *)valhas_length_8:'abuffer->bool(**[move_left_1_33 b1 b2] requires the buffers [b1] and [b2] to have length 3.
One element is moved from [b2] to [b1]. The concatenation of the buffers
[b1] and [b2] is unchanged. *)valmove_left_1_33:'abuffer->'abuffer->'abuffer*'abuffer(**[move_right_1_33 b1 b2] requires the buffers [b1] and [b2] to have length 3.
One element is moved from [b1] to [b2]. The concatenation of the buffers
[b1] and [b2] is unchanged. *)valmove_right_1_33:'abuffer->'abuffer->'abuffer*'abuffer(**[double_move_left_323] expects three buffers whose lengths are 3, 2,
and 3. It moves one element from the middle buffer into the first
buffer and one element from the last buffer into the middle buffer. *)valdouble_move_left_323:'abuffer->'abuffer->'abuffer->'abuffer*'abuffer*'abuffer(**[double_move_right_323] expects three buffers whose lengths are 3, 2,
and 3. It moves one element from the first buffer into the middle
buffer and one element from the middle buffer into the last buffer. *)valdouble_move_right_323:'abuffer->'abuffer->'abuffer->'abuffer*'abuffer*'abuffer(**[double_move_left_32x] expects three buffers whose lengths are 3, 2,
and [X], where [X] is comprised between 4 and 6. It moves one element
from the middle buffer into the first buffer and one element from the
last buffer into the middle buffer. *)valdouble_move_left_32x:'abuffer->'abuffer->'abuffer->'abuffer*'abuffer*'abuffer(**[double_move_right_x23] expects three buffers whose lengths are
[X], 2, and 3, where [X] is comprised between 4 and 6. It moves
one element from the first buffer into the middle buffer and one
element from the middle buffer into the last buffer. *)valdouble_move_right_x23:'abuffer->'abuffer->'abuffer->'abuffer*'abuffer*'abuffer(**[concat23] concatenates two buffers whose lengths are 2 and 3. *)valconcat23:'abuffer->'abuffer->'abuffer(**[concat32] concatenates two buffers whose lengths are 3 and 2. *)valconcat32:'abuffer->'abuffer->'abuffer(**[concat323] concatenates three buffers whose lengths are 3, 2, and 3. *)valconcat323:'abuffer->'abuffer->'abuffer->'abuffer(**[split23l] expects a buffer whose length is comprised between 2 and 5.
This buffer is split into two buffers [b1] and [b2] such that [b1] has
length 2 or 3 and [b2] has length 0 or 2 or 3. *)valsplit23l:'abuffer->'abuffer*'abuffer(**[split23r] expects a buffer whose length is comprised between 2 and 5.
This buffer is split into two buffers [b1] and [b2] such that [b1] has
length 0 or 2 or 3 and [b2] has length 2 or 3. *)valsplit23r:'abuffer->'abuffer*'abuffer(**[split8] expects a buffer of length 8. This buffer is split into three
buffers whose lengths are 3, 2, and 3. *)valsplit8:'abuffer->'abuffer*'abuffer*'abuffer(***[split642] expects a buffer of length 6. This buffer is split into two
buffers whose lengths are 4 and 2. *)valsplit642:'abuffer->'abuffer*'abuffer(***[split624] expects a buffer of length 6. This buffer is split into two
buffers whose lengths are 2 and 4. *)valsplit624:'abuffer->'abuffer*'abufferend