123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297(******************************************************************************)(* *)(* Mulnir *)(* *)(* Frédéric Bour, Tarides *)(* *)(* Menhir *)(* *)(* François Pottier, Inria Paris *)(* Yann Régis-Gianas, PPS, Université Paris Diderot *)(* *)(* Copyright Inria. All rights reserved. This file is distributed under the *)(* terms of the GNU General Public License version 2, as described in the *)(* file LICENSE. *)(* *)(******************************************************************************)moduletypeS1=sig(* Elements are assumed to have a natural total order. *)type'aelement(* Sets. *)type'at(* The empty set. *)valempty:'at(* [is_empty s] tells whether [s] is the empty set. *)valis_empty:'at->boolvalis_not_empty:'at->bool(* [singleton x] returns a singleton set containing [x] as its only
element. *)valsingleton:'aelement->'at(* [is_singleton s] tests whether [s] is a singleton set. *)valis_singleton:'at->bool(* [cardinal s] returns the cardinal of [s]. *)valcardinal:'at->int(* [choose s] returns an arbitrarily chosen element of [s], if [s]
is nonempty, and raises [Not_found] otherwise. *)valchoose:'at->'aelementvalminimum:'at->'aelementoptionvalmaximum:'at->'aelementoption(* [mem x s] returns [true] if and only if [x] appears in the set
[s]. *)valmem:'aelement->'at->bool(* [add x s] returns a set whose elements are all elements of [s],
plus [x]. *)valadd:'aelement->'at->'at(* [remove x s] returns a set whose elements are all elements of
[s], except [x]. *)valremove:'aelement->'at->'at(* [union s1 s2] returns the union of the sets [s1] and [s2]. *)valunion:'at->'at->'at(* [inter s t] returns the set intersection of [s] and [t], that is,
$s\cap t$. *)valinter:'at->'at->'at(* [disjoint s1 s2] returns [true] if and only if the sets [s1] and
[s2] are disjoint, i.e. iff their intersection is empty. *)valdisjoint:'at->'at->bool(* [iter f s] invokes [f x], in turn, for each element [x] of the
set [s]. Elements are presented to [f] in increasing order. *)valiter:('aelement->unit)->'at->unitvalrev_iter:('aelement->unit)->'at->unit(* [fold f s seed] invokes [f x accu], in turn, for each element [x]
of the set [s]. Elements are presented to [f] in increasing
order. The initial value of [accu] is [seed]; then, at each new
call, its value is the value returned by the previous invocation
of [f]. The value returned by [fold] is the final value of
[accu]. In other words, if $s = \{ x_1, x_2, \ldots, x_n \}$,
where $x_1 < x_2 < \ldots < x_n$, then [fold f s seed] computes
$([f]\,x_n\,\ldots\,([f]\,x_2\,([f]\,x_1\,[seed]))\ldots)$. *)valfold:('aelement->'b->'b)->'at->'b->'bvalfold_right:('a->'belement->'a)->'a->'bt->'avalmap:('aelement->'belement)->'at->'btvalexists:('aelement->bool)->'at->bool(* [elements s] is a list of all elements in the set [s]. *)valelements:'at->'aelementlist(* [compare] is an ordering over sets. *)valcompare:'at->'at->int(* [equal] implements equality over sets. *)valequal:'at->'at->bool(* [subset] implements the subset predicate over sets. *)valsubset:'at->'at->bool(* [quick_subset s1 s2] is a fast test for the set inclusion [s1 ⊆ s2].
The sets [s1] and [s2] must be nonempty.
It must be known ahead of time that either [s1] is a subset of [s2] or
these sets are disjoint: that is, [s1 ⊆ s2 ⋁ s1 ∩ s2 = ∅] must hold.
Under this hypothesis, [quick_subset s1 s2] can be implemented simply
by picking an arbitrary element of [s1] (if there is one) and testing
whether it is a member of [s2]. *)valquick_subset:'at->'at->boolvaldiff:'at->'at->'at(** {1 Decomposing sets}
These functions implements the [Refine.DECOMPOSABLE] interface.
We cannot reference it here as [Refine] is implemented using bitsets,
that would create a reference cycle.
*)(* [compare_minimum l r] order two sets by comparing their least element *)valcompare_minimum:'at->'at->int(* [extract_unique_prefix l r] split l in two sets (l_min, l_rest) such that:
- l_min contains elements strictly smaller than the all elements of [r]
- l_rest contains other elements
*)valextract_unique_prefix:'at->'at->'at*'at(* [extract_shared_prefix l r] decomposes l and r in (min, l', r') such that:
- [min] is the set of minimal elements that are part of both [l] and [r]
- [l = min U l'] and [r = min U r']
*)valextract_shared_prefix:'at->'at->'at*('at*'at)(* [sorted_union l] computes the union of an ordered list of intervals.
This is an optimized special case of union *)valsorted_union:'atlist->'atvalof_list:'aelementlist->'atvalinit_interval:'aelement->'aelement->'atvalinit_subset:'aelement->'aelement->('aelement->bool)->'atvalfilter:('aelement->bool)->'at->'atvalfilter_map:('aelement->'belementoption)->'at->'btvalsplit:'aelement->'at->'at*bool*'atvalfind:('aelement->bool)->'at->'aelementvalfind_map:('aelement->'boption)->'at->'boptionvalto_seq:'at->'aelementSeq.tvalbind:'at->('aelement->'bt)->'bt(** Split a set into consecutive “runs” of elements that share the same class.
{b Parameters}
- [cls : 'a element → 'b element] that assigns a class to each element.
- [xs : 'a t] – the input set to be split.
{b Returns}
A list of pairs. Each pair is made of a class (the result of [cls] for
the run) and the subset of the original elements that belong to that run
(preserving the original order). *)valsplit_by_run:('aelement->'belement)->'at->('belement*'at)list(* [fused_inter_union a b ~acc] is [union (inter a b) acc] *)valfused_inter_union:'at->'at->acc:'at->'atvalrev_map_elements:'at->('aelement->'b)->'blistendmoduletypeS0=sigtypeelementtypetincludeS1withtype'aelement:=elementandtype'at:=tendmoduletypeStdSetS1=sigtype'aelttype'atvalempty:'atvalis_empty:'at->boolvalmem:'aelt->'at->boolvaladd:'aelt->'at->'atvalsingleton:'aelt->'atvalremove:'aelt->'at->'atvalunion:'at->'at->'atvalinter:'at->'at->'atvaldisjoint:'at->'at->boolvaldiff:'at->'at->'atvalcompare:'at->'at->intvalequal:'at->'at->boolvalsubset:'at->'at->boolvaliter:('aelt->unit)->'at->unitvalmap:('aelt->'belt)->'at->'btvalfold:('aelt->'b->'b)->'at->'b->'bvalfor_all:('aelt->bool)->'at->boolvalexists:('aelt->bool)->'at->boolvalfilter:('aelt->bool)->'at->'atvalfilter_map:('aelt->'beltoption)->'at->'btvalpartition:('aelt->bool)->'at->'at*'atvalcardinal:'at->intvalelements:'at->'aeltlistvalmin_elt:'at->'aeltvalmin_elt_opt:'at->'aeltoptionvalmax_elt:'at->'aeltvalmax_elt_opt:'at->'aeltoptionvalchoose:'at->'aeltvalchoose_opt:'at->'aeltoptionvalsplit:'aelt->'at->'at*bool*'atvalfind:'aelt->'at->'aeltvalfind_opt:'aelt->'at->'aeltoptionvalfind_first:('aelt->bool)->'at->'aeltvalfind_first_opt:('aelt->bool)->'at->'aeltoptionvalfind_last:('aelt->bool)->'at->'aeltvalfind_last_opt:('aelt->bool)->'at->'aeltoptionvalof_list:'aeltlist->'atvalto_seq_from:'aelt->'at->'aeltSeq.tvalto_seq:'at->'aeltSeq.tvalto_rev_seq:'at->'aeltSeq.tvaladd_seq:'aeltSeq.t->'at->'atvalof_seq:'aeltSeq.t->'atendmoduletypeStdMapS1=sigtype'nkeytype('n,'a)tvalempty:('n,'a)tvalis_empty:('n,'a)t->boolvalmem:'nkey->('n,'a)t->boolvaladd:'nkey->'a->('n,'a)t->('n,'a)tvalupdate:'nkey->('aoption->'aoption)->('n,'a)t->('n,'a)tvalsingleton:'nkey->'a->('n,'a)tvalremove:'nkey->('n,'a)t->('n,'a)tvalmerge:('nkey->'aoption->'boption->'coption)->('n,'a)t->('n,'b)t->('n,'c)tvalunion:('nkey->'a->'a->'aoption)->('n,'a)t->('n,'a)t->('n,'a)tvalcompare:('a->'a->int)->('n,'a)t->('n,'a)t->intvalequal:('a->'a->bool)->('n,'a)t->('n,'a)t->boolvaliter:('nkey->'a->unit)->('n,'a)t->unitvalfold:('nkey->'a->'b->'b)->('n,'a)t->'b->'bvalfor_all:('nkey->'a->bool)->('n,'a)t->boolvalexists:('nkey->'a->bool)->('n,'a)t->boolvalfilter:('nkey->'a->bool)->('n,'a)t->('n,'a)tvalfilter_map:('nkey->'a->'boption)->('n,'a)t->('n,'b)tvalpartition:('nkey->'a->bool)->('n,'a)t->('n,'a)t*('n,'a)tvalcardinal:('n,'a)t->intvalbindings:('n,'a)t->('nkey*'a)listvalmin_binding:('n,'a)t->('nkey*'a)valmin_binding_opt:('n,'a)t->('nkey*'a)optionvalmax_binding:('n,'a)t->('nkey*'a)valmax_binding_opt:('n,'a)t->('nkey*'a)optionvalchoose:('n,'a)t->('nkey*'a)valchoose_opt:('n,'a)t->('nkey*'a)optionvalsplit:'nkey->('n,'a)t->('n,'a)t*'aoption*('n,'a)tvalfind:'nkey->('n,'a)t->'avalfind_opt:'nkey->('n,'a)t->'aoptionvalfind_first:('nkey->bool)->('n,'a)t->'nkey*'avalfind_first_opt:('nkey->bool)->('n,'a)t->('nkey*'a)optionvalfind_last:('nkey->bool)->('n,'a)t->'nkey*'avalfind_last_opt:('nkey->bool)->('n,'a)t->('nkey*'a)optionvalmap:('a->'b)->('n,'a)t->('n,'b)tvalmapi:('nkey->'a->'b)->('n,'a)t->('n,'b)tvalto_seq:('n,'a)t->('nkey*'a)Seq.tvalto_rev_seq:('n,'a)t->('nkey*'a)Seq.tvalto_seq_from:'nkey->('n,'a)t->('nkey*'a)Seq.tvaladd_seq:('nkey*'a)Seq.t->('n,'a)t->('n,'a)tvalof_seq:('nkey*'a)Seq.t->('n,'a)tend