Created
April 1, 2026 08:05
-
-
Save stedolan/f4fabc43963afab5bc64d847d9cc6bb5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module CCEqual = struct | |
| let physical = Stdlib.( == ) | |
| end | |
| module CCHeap : sig | |
| (* | |
| Copyright (c) 2013, Simon Cruanes | |
| All rights reserved. | |
| Redistribution and use in source and binary forms, with or without | |
| modification, are permitted provided that the following conditions are met: | |
| Redistributions of source code must retain the above copyright notice, this | |
| list of conditions and the following disclaimer. Redistributions in binary | |
| form must reproduce the above copyright notice, this list of conditions and | |
| the following disclaimer in the documentation and/or other materials | |
| provided with the distribution. | |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
| FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
| OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| *) | |
| (** Leftist Heaps | |
| Implementation following Okasaki's book. *) | |
| type 'a gen = unit -> 'a option | |
| type 'a ktree = unit -> [ `Nil | `Node of 'a * 'a ktree list ] | |
| type 'a printer = Format.formatter -> 'a -> unit | |
| module type PARTIAL_ORD = sig | |
| type t | |
| val leq : t -> t -> bool | |
| (** [leq x y] shall return [true] iff [x] is lower or equal to [y]. *) | |
| end | |
| module type TOTAL_ORD = sig | |
| type t | |
| val compare : t -> t -> int | |
| (** [compare a b] shall return | |
| a negative value if [a] is smaller than [b], | |
| [0] if [a] and [b] are equal or | |
| a positive value if [a] is greater than [b] *) | |
| end | |
| module type S = sig | |
| type elt | |
| type t | |
| (** {2 Basic heap operations} *) | |
| val empty : t | |
| (** [empty] returns the empty heap. *) | |
| val is_empty : t -> bool | |
| (** [is_empty h] returns [true] iff the heap [h] is empty. *) | |
| val merge : t -> t -> t | |
| (** [merge h1 h2] merges the two heaps [h1] and [h2]. | |
| If one heap is empty, the result is physically equal to the other heap. | |
| Complexity: [O(log (m+n))] where [m] and [n] are the number of elements in each heap. | |
| *) | |
| val insert : elt -> t -> t | |
| (** [insert x h] inserts an element [x] into the heap [h]. | |
| Complexity: [O(log n)] where [n] is the number of elements in [h]. | |
| *) | |
| val add : t -> elt -> t | |
| (** [add h x] is [insert x h]. *) | |
| val find_min : t -> elt option | |
| (** [find_min h] returns the minimal element of [h], | |
| or [None] if [h] is empty. | |
| Complexity: [O(1)]. | |
| *) | |
| val take : t -> (t * elt) option | |
| (** [take h] returns the minimum element of [h] | |
| and the new heap without this element, | |
| or [None] if [h] is empty. | |
| Complexity: [O(log n)]. | |
| *) | |
| val size : t -> int | |
| (** [size h] is the number of elements in the heap [h]. | |
| Complexity: [O(n)]. | |
| *) | |
| end | |
| module Make (E : PARTIAL_ORD) : S with type elt = E.t | |
| (** A convenient version of [Make] that takes a [TOTAL_ORD] instead of | |
| a partially ordered module. | |
| It allows to directly pass modules that implement [compare] | |
| without implementing [leq] explicitly. *) | |
| module Make_from_compare (E : TOTAL_ORD) : S with type elt = E.t | |
| end = struct | |
| (* This file is free software, part of containers. See file "license" for more details. *) | |
| (** {1 Leftist Heaps} *) | |
| type 'a gen = unit -> 'a option | |
| type 'a printer = Format.formatter -> 'a -> unit | |
| type 'a ktree = unit -> [ `Nil | `Node of 'a * 'a ktree list ] | |
| module type PARTIAL_ORD = sig | |
| type t | |
| val leq : t -> t -> bool | |
| (** [leq x y] shall return [true] iff [x] is lower or equal to [y]. *) | |
| end | |
| module type TOTAL_ORD = sig | |
| type t | |
| val compare : t -> t -> int | |
| (** [compare a b] shall return | |
| a negative value if [a] is smaller than [b], | |
| [0] if [a] and [b] are equal or | |
| a positive value if [a] is greater than [b] *) | |
| end | |
| module type S = sig | |
| type elt | |
| type t | |
| (** {2 Basing heap operations} *) | |
| val empty : t | |
| (** Empty heap. *) | |
| val is_empty : t -> bool | |
| (** Is the heap empty? *) | |
| val merge : t -> t -> t | |
| (** [merge h1 h2] merges the two heaps [h1] and [h2]. | |
| If one heap is empty, the result is physically equal to the other heap. | |
| Complexity: [O(log (m+n))] where [m] and [n] are the number of elements in each heap. | |
| *) | |
| val insert : elt -> t -> t | |
| (** [insert x h] inserts an element [x] into the heap [h]. | |
| Complexity: [O(log n)] where [n] is the number of elements in [h]. | |
| *) | |
| val add : t -> elt -> t | |
| (** [add h x] is [insert x h]. *) | |
| val find_min : t -> elt option | |
| (** [find_min h] returns the minimal element of [h], | |
| or [None] if [h] is empty. | |
| Complexity: [O(1)]. | |
| *) | |
| val take : t -> (t * elt) option | |
| (** [take h] returns the minimum element of [h] | |
| and the new heap without this element, | |
| or [None] if [h] is empty. | |
| Complexity: [O(log n)]. | |
| *) | |
| val size : t -> int | |
| (** [size h] is the number of elements in the heap [h]. | |
| Complexity: [O(n)]. | |
| *) | |
| end | |
| module Make (E : PARTIAL_ORD) : S with type elt = E.t = struct | |
| type elt = E.t | |
| type t = | |
| | E | |
| | N of int * elt * t * t | |
| let empty = E | |
| let is_empty = function | |
| | E -> true | |
| | N _ -> false | |
| let singleton x = N (1, x, E, E) | |
| (* Rank of the tree *) | |
| let _rank = function | |
| | E -> 0 | |
| | N (r, _, _, _) -> r | |
| (* Make a balanced node labelled with [x], and subtrees [a] and [b]. | |
| We ensure that the right child's rank is ≤ to the rank of the | |
| left child (leftist property). The rank of the resulting node | |
| is the length of the rightmost path. *) | |
| let _make_node x a b = | |
| if _rank a >= _rank b then | |
| N (_rank b + 1, x, a, b) | |
| else | |
| N (_rank a + 1, x, b, a) | |
| let rec merge t1 t2 = | |
| match t1, t2 with | |
| | t, E -> t | |
| | E, t -> t | |
| | N (_, x, a1, b1), N (_, y, a2, b2) -> | |
| if E.leq x y then | |
| _make_node x a1 (merge b1 t2) | |
| else | |
| _make_node y a2 (merge t1 b2) | |
| let insert x h = merge (singleton x) h | |
| let add h x = insert x h | |
| let find_min = function | |
| | E -> None | |
| | N (_, x, _, _) -> Some x | |
| let take = function | |
| | E -> None | |
| | N (_, x, l, r) -> Some (merge l r, x) | |
| let rec fold f acc h = | |
| match h with | |
| | E -> acc | |
| | N (_, x, a, b) -> | |
| let acc = f acc x in | |
| let acc = fold f acc a in | |
| fold f acc b | |
| let rec size = function | |
| | E -> 0 | |
| | N (_, _, l, r) -> 1 + size l + size r | |
| end | |
| module Make_from_compare (E : TOTAL_ORD) = Make (struct | |
| type t = E.t | |
| let leq a b = E.compare a b <= 0 | |
| end) | |
| end | |
| type step = { curr: int; stride: int } | |
| module PQ = CCHeap.Make (struct | |
| type t = step | |
| let leq a b = a.curr <= b.curr | |
| end) | |
| (* min <= rest, all composite *) | |
| let rec sieve min rest x xmax = | |
| if x >= xmax then [] | |
| else if x mod 2 = 0 || x mod 3 = 0 || x mod 5 = 0 then | |
| sieve min rest (x+1) xmax | |
| else | |
| if x < min.curr then | |
| let table = PQ.add rest { curr = x*x; stride = x } in | |
| x :: sieve min table (x+1) xmax | |
| else | |
| let table = PQ.add rest { min with curr = min.curr + min.stride } in | |
| let x = if x = min.curr then x+1 else x in | |
| let rest, min = | |
| match PQ.take table with | |
| | Some x -> x | |
| | _ -> assert false | |
| in | |
| sieve min rest x xmax | |
| let main ~limit = | |
| 2 :: 3 :: 5 :: 7 :: sieve { curr = 7*7; stride = 7 } PQ.empty 8 limit |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef limit | |
| #error "Parameter limit missing" | |
| #include <stop_after_error> | |
| #endif | |
| template <typename...> struct Cons; | |
| template <int tag, typename...> struct Cons_; | |
| template <int n> | |
| struct I{ | |
| static constexpr int tag = 1000; | |
| static constexpr bool nonzero = ((n) != (0)); | |
| static constexpr int val = n; | |
| }; | |
| struct EXCEPTION{ | |
| }; | |
| template <typename f0_> | |
| struct Cons<f0_>{ | |
| static constexpr int tag = 0; | |
| static constexpr bool nonzero = true; | |
| static constexpr int val = -1; | |
| typedef f0_ f0; | |
| }; | |
| template <int tag_, typename f0_> | |
| struct Cons_<tag_, f0_>{ | |
| static constexpr int tag = tag_; | |
| static constexpr bool nonzero = true; | |
| static constexpr int val = -1; | |
| typedef f0_ f0; | |
| }; | |
| template <typename f0_, typename f1_> | |
| struct Cons<f0_, f1_>{ | |
| static constexpr int tag = 0; | |
| static constexpr bool nonzero = true; | |
| static constexpr int val = -1; | |
| typedef f0_ f0; | |
| typedef f1_ f1; | |
| }; | |
| template <int tag_, typename f0_, typename f1_> | |
| struct Cons_<tag_, f0_, f1_>{ | |
| static constexpr int tag = tag_; | |
| static constexpr bool nonzero = true; | |
| static constexpr int val = -1; | |
| typedef f0_ f0; | |
| typedef f1_ f1; | |
| }; | |
| template <typename f0_, typename f1_, typename f2_, typename f3_> | |
| struct Cons<f0_, f1_, f2_, f3_>{ | |
| static constexpr int tag = 0; | |
| static constexpr bool nonzero = true; | |
| static constexpr int val = -1; | |
| typedef f0_ f0; | |
| typedef f1_ f1; | |
| typedef f2_ f2; | |
| typedef f3_ f3; | |
| }; | |
| template <int tag_, typename f0_, typename f1_, typename f2_, typename f3_> | |
| struct Cons_<tag_, f0_, f1_, f2_, f3_>{ | |
| static constexpr int tag = tag_; | |
| static constexpr bool nonzero = true; | |
| static constexpr int val = -1; | |
| typedef f0_ f0; | |
| typedef f1_ f1; | |
| typedef f2_ f2; | |
| typedef f3_ f3; | |
| }; | |
| template <typename f0_, typename f1_, typename f2_, typename f3_, typename f4_> | |
| struct Cons<f0_, f1_, f2_, f3_, f4_>{ | |
| static constexpr int tag = 0; | |
| static constexpr bool nonzero = true; | |
| static constexpr int val = -1; | |
| typedef f0_ f0; | |
| typedef f1_ f1; | |
| typedef f2_ f2; | |
| typedef f3_ f3; | |
| typedef f4_ f4; | |
| }; | |
| template <int tag_, typename f0_, typename f1_, typename f2_, typename f3_, typename f4_> | |
| struct Cons_<tag_, f0_, f1_, f2_, f3_, f4_>{ | |
| static constexpr int tag = tag_; | |
| static constexpr bool nonzero = true; | |
| static constexpr int val = -1; | |
| typedef f0_ f0; | |
| typedef f1_ f1; | |
| typedef f2_ f2; | |
| typedef f3_ f3; | |
| typedef f4_ f4; | |
| }; | |
| template <typename f0_, typename f1_, typename f2_, typename f3_, typename f4_, typename f5_, typename f6_, typename f7_> | |
| struct Cons<f0_, f1_, f2_, f3_, f4_, f5_, f6_, f7_>{ | |
| static constexpr int tag = 0; | |
| static constexpr bool nonzero = true; | |
| static constexpr int val = -1; | |
| typedef f0_ f0; | |
| typedef f1_ f1; | |
| typedef f2_ f2; | |
| typedef f3_ f3; | |
| typedef f4_ f4; | |
| typedef f5_ f5; | |
| typedef f6_ f6; | |
| typedef f7_ f7; | |
| }; | |
| template <int tag_, typename f0_, typename f1_, typename f2_, typename f3_, typename f4_, typename f5_, typename f6_, typename f7_> | |
| struct Cons_<tag_, f0_, f1_, f2_, f3_, f4_, f5_, f6_, f7_>{ | |
| static constexpr int tag = tag_; | |
| static constexpr bool nonzero = true; | |
| static constexpr int val = -1; | |
| typedef f0_ f0; | |
| typedef f1_ f1; | |
| typedef f2_ f2; | |
| typedef f3_ f3; | |
| typedef f4_ f4; | |
| typedef f5_ f5; | |
| typedef f6_ f6; | |
| typedef f7_ f7; | |
| }; | |
| template <bool cond> | |
| struct ifthenelse; | |
| template <> | |
| struct ifthenelse<true>{ | |
| typedef I<0> res; | |
| }; | |
| template <> | |
| struct ifthenelse<false>{ | |
| typedef I<1> res; | |
| }; | |
| template <typename param, bool cond> | |
| struct ifthenelse_; | |
| template <typename param> | |
| struct ifthenelse_<param, true>{ | |
| typedef typename param::f0 res; | |
| }; | |
| template <typename param> | |
| struct ifthenelse_<param, false>{ | |
| typedef I<0> res; | |
| }; | |
| template <typename _rank, typename x, typename a, typename b, bool cond> | |
| struct ifthenelse_2; | |
| template <typename _rank, typename x, typename a, typename b> | |
| struct ifthenelse_2<_rank, x, a, b, true>{ | |
| typedef Cons<I<((_rank::template app<b>::res::val) + (I<1>::val))>, x, a, b> res; | |
| }; | |
| template <typename _rank, typename x, typename a, typename b> | |
| struct ifthenelse_2<_rank, x, a, b, false>{ | |
| typedef Cons<I<((_rank::template app<a>::res::val) + (I<1>::val))>, x, b, a> res; | |
| }; | |
| template <typename _make_node, typename merge, typename t1, typename t2, typename x, typename y, bool cond> | |
| struct ifthenelse_3; | |
| template <typename _make_node, typename merge, typename t1, typename t2, typename x, typename y> | |
| struct ifthenelse_3<_make_node, merge, t1, t2, x, y, true>{ | |
| typedef typename _make_node::template app<x>::res::template app<typename t1::f2>::res::template app<typename merge::template app<typename t1::f3>::res::template app<t2>::res>::res res; | |
| }; | |
| template <typename _make_node, typename merge, typename t1, typename t2, typename x, typename y> | |
| struct ifthenelse_3<_make_node, merge, t1, t2, x, y, false>{ | |
| typedef typename _make_node::template app<y>::res::template app<typename t2::f2>::res::template app<typename merge::template app<t1>::res::template app<typename t2::f3>::res>::res res; | |
| }; | |
| template <typename _make_node, typename merge, typename t1, typename t2, typename E, bool cond> | |
| struct ifthenelse_4; | |
| template <typename _make_node, typename merge, typename t1, typename t2, typename E> | |
| struct ifthenelse_4<_make_node, merge, t1, t2, E, true>{ | |
| typedef typename t2::f1 y; | |
| typedef typename t1::f1 x; | |
| typedef typename ifthenelse_3<_make_node, merge, t1, t2, x, y, | |
| E::f0::template app<x>::res::template app<y>::res::nonzero>::res res; | |
| }; | |
| template <typename _make_node, typename merge, typename t1, typename t2, typename E> | |
| struct ifthenelse_4<_make_node, merge, t1, t2, E, false>{ | |
| typedef t2 res; | |
| }; | |
| template <typename _make_node, typename merge, typename t1, typename t2, typename E, bool cond> | |
| struct ifthenelse_5; | |
| template <typename _make_node, typename merge, typename t1, typename t2, typename E> | |
| struct ifthenelse_5<_make_node, merge, t1, t2, E, true>{ | |
| typedef typename ifthenelse_4<_make_node, merge, t1, t2, E, t1::nonzero>::res res; | |
| }; | |
| template <typename _make_node, typename merge, typename t1, typename t2, typename E> | |
| struct ifthenelse_5<_make_node, merge, t1, t2, E, false>{ | |
| typedef t1 res; | |
| }; | |
| template <typename param, bool cond> | |
| struct ifthenelse_6; | |
| template <typename param> | |
| struct ifthenelse_6<param, true>{ | |
| typedef Cons<typename param::f1> res; | |
| }; | |
| template <typename param> | |
| struct ifthenelse_6<param, false>{ | |
| typedef I<0> res; | |
| }; | |
| template <typename merge, typename param, bool cond> | |
| struct ifthenelse_7; | |
| template <typename merge, typename param> | |
| struct ifthenelse_7<merge, param, true>{ | |
| typedef Cons<Cons<typename merge::template app<typename param::f2>::res::template app<typename param::f3>::res, | |
| typename param::f1>> res; | |
| }; | |
| template <typename merge, typename param> | |
| struct ifthenelse_7<merge, param, false>{ | |
| typedef I<0> res; | |
| }; | |
| template <typename fold, typename f, typename acc, typename h, bool cond> | |
| struct ifthenelse_8; | |
| template <typename fold, typename f, typename acc, typename h> | |
| struct ifthenelse_8<fold, f, acc, h, true>{ | |
| typedef typename f::template app<acc>::res::template app<typename h::f1>::res acc_; | |
| typedef typename fold::template app<f>::res::template app<acc_>::res::template app<typename h::f2>::res acc_2; | |
| typedef typename fold::template app<f>::res::template app<acc_2>::res::template app<typename h::f3>::res res; | |
| }; | |
| template <typename fold, typename f, typename acc, typename h> | |
| struct ifthenelse_8<fold, f, acc, h, false>{ | |
| typedef acc res; | |
| }; | |
| template <typename size, typename param, bool cond> | |
| struct ifthenelse_9; | |
| template <typename size, typename param> | |
| struct ifthenelse_9<size, param, true>{ | |
| typedef I<((I<((I<1>::val) + (size::template app<typename param::f2>::res::val))>::val) + (size::template app<typename param::f3>::res::val))> res; | |
| }; | |
| template <typename size, typename param> | |
| struct ifthenelse_9<size, param, false>{ | |
| typedef I<0> res; | |
| }; | |
| template <typename x, bool cond> | |
| struct ifthenelse_10; | |
| template <typename x> | |
| struct ifthenelse_10<x, true>{ | |
| typedef I<((x::val) + (I<1>::val))> res; | |
| }; | |
| template <typename x> | |
| struct ifthenelse_10<x, false>{ | |
| typedef x res; | |
| }; | |
| template <typename _match_, bool cond> | |
| struct ifthenelse_11; | |
| template <typename _match_> | |
| struct ifthenelse_11<_match_, true>{ | |
| typedef typename _match_::f0 res; | |
| }; | |
| template <typename _match_> | |
| struct ifthenelse_11<_match_, false>{ | |
| typedef EXCEPTION res; | |
| }; | |
| template <typename PQ, typename sieve, typename min, typename rest, typename x, typename xmax, bool cond> | |
| struct ifthenelse_12; | |
| template <typename PQ, typename sieve, typename min, typename rest, typename x, typename xmax> | |
| struct ifthenelse_12<PQ, sieve, min, rest, x, xmax, true>{ | |
| typedef typename PQ::f4::template app<rest>::res::template app<Cons<I<((x::val) * (x::val))>, | |
| x>>::res table; | |
| typedef Cons<x, | |
| typename sieve::template app<min>::res::template app<table>::res::template app<I<((x::val) + (I<1>::val))>>::res::template app<xmax>::res> res; | |
| }; | |
| template <typename PQ, typename sieve, typename min, typename rest, typename x, typename xmax> | |
| struct ifthenelse_12<PQ, sieve, min, rest, x, xmax, false>{ | |
| typedef typename PQ::f4::template app<rest>::res::template app<Cons<I<((min::f0::val) + (min::f1::val))>, | |
| typename min::f1>>::res table; | |
| typedef typename ifthenelse_10<x, | |
| I<((x::val) == (min::f0::val))>::nonzero>::res x_; | |
| typedef typename PQ::f6::template app<table>::res _match_; | |
| typedef typename ifthenelse_11<_match_, _match_::nonzero>::res _match__; | |
| typedef typename sieve::template app<typename _match__::f1>::res::template app<typename _match__::f0>::res::template app<x_>::res::template app<xmax>::res res; | |
| }; | |
| template <typename PQ, typename sieve, typename min, typename rest, typename x, typename xmax, bool cond> | |
| struct ifthenelse_13; | |
| template <typename PQ, typename sieve, typename min, typename rest, typename x, typename xmax> | |
| struct ifthenelse_13<PQ, sieve, min, rest, x, xmax, true>{ | |
| typedef typename sieve::template app<min>::res::template app<rest>::res::template app<I<((x::val) + (I<1>::val))>>::res::template app<xmax>::res res; | |
| }; | |
| template <typename PQ, typename sieve, typename min, typename rest, typename x, typename xmax> | |
| struct ifthenelse_13<PQ, sieve, min, rest, x, xmax, false>{ | |
| typedef typename ifthenelse_12<PQ, sieve, min, rest, x, xmax, | |
| I<((x::val) < (min::f0::val))>::nonzero>::res res; | |
| }; | |
| template <typename x, bool cond> | |
| struct ifthenelse_14; | |
| template <typename x> | |
| struct ifthenelse_14<x, true>{ | |
| typedef I<1> res; | |
| }; | |
| template <typename x> | |
| struct ifthenelse_14<x, false>{ | |
| typedef I<((I<((x::val) % (I<5>::val))>::val) == (I<0>::val))> res; | |
| }; | |
| template <typename x, bool cond> | |
| struct ifthenelse_15; | |
| template <typename x> | |
| struct ifthenelse_15<x, true>{ | |
| typedef I<1> res; | |
| }; | |
| template <typename x> | |
| struct ifthenelse_15<x, false>{ | |
| typedef typename ifthenelse_14<x, | |
| I<((I<((x::val) % (I<3>::val))>::val) == (I<0>::val))>::nonzero>::res res; | |
| }; | |
| template <typename PQ, typename sieve, typename min, typename rest, typename x, typename xmax, bool cond> | |
| struct ifthenelse_16; | |
| template <typename PQ, typename sieve, typename min, typename rest, typename x, typename xmax> | |
| struct ifthenelse_16<PQ, sieve, min, rest, x, xmax, true>{ | |
| typedef I<0> res; | |
| }; | |
| template <typename PQ, typename sieve, typename min, typename rest, typename x, typename xmax> | |
| struct ifthenelse_16<PQ, sieve, min, rest, x, xmax, false>{ | |
| typedef typename ifthenelse_13<PQ, sieve, min, rest, x, xmax, | |
| ifthenelse_15<x, | |
| I<((I<((x::val) % (I<2>::val))>::val) == (I<0>::val))>::nonzero>::res::nonzero>::res res; | |
| }; | |
| struct physical{ | |
| template <typename prim> | |
| struct app{ | |
| struct res{ | |
| template <typename prim_> | |
| struct app{ | |
| typedef I<((prim::val) == (prim_::val))> res; | |
| }; | |
| }; | |
| }; | |
| }; | |
| typedef Cons<physical> CCEqual; | |
| struct Make{ | |
| template <typename E> | |
| struct app{ | |
| typedef I<0> empty; | |
| struct is_empty{ | |
| template <typename param> | |
| struct app{ | |
| typedef typename ifthenelse<param::nonzero>::res res; | |
| }; | |
| }; | |
| struct singleton{ | |
| template <typename x> | |
| struct app{ | |
| typedef Cons<I<1>, x, I<0>, I<0>> res; | |
| }; | |
| }; | |
| struct _rank{ | |
| template <typename param> | |
| struct app{ | |
| typedef typename ifthenelse_<param, param::nonzero>::res res; | |
| }; | |
| }; | |
| struct _make_node{ | |
| template <typename x> | |
| struct app{ | |
| struct res{ | |
| template <typename a> | |
| struct app{ | |
| struct res{ | |
| template <typename b> | |
| struct app{ | |
| typedef typename ifthenelse_2<_rank, x, a, b, | |
| I<((_rank::template app<a>::res::val) >= (_rank::template app<b>::res::val))>::nonzero>::res res; | |
| }; | |
| }; | |
| }; | |
| }; | |
| }; | |
| }; | |
| struct merge; | |
| struct merge{ | |
| template <typename t1> | |
| struct app{ | |
| struct res{ | |
| template <typename t2> | |
| struct app{ | |
| typedef typename ifthenelse_5<_make_node, merge, t1, t2, E, t2::nonzero>::res res; | |
| }; | |
| }; | |
| }; | |
| }; | |
| struct insert{ | |
| template <typename x> | |
| struct app{ | |
| struct res{ | |
| template <typename h> | |
| struct app{ | |
| typedef typename merge::template app<typename singleton::template app<x>::res>::res::template app<h>::res res; | |
| }; | |
| }; | |
| }; | |
| }; | |
| struct add{ | |
| template <typename h> | |
| struct app{ | |
| struct res{ | |
| template <typename x> | |
| struct app{ | |
| typedef typename insert::template app<x>::res::template app<h>::res res; | |
| }; | |
| }; | |
| }; | |
| }; | |
| struct find_min{ | |
| template <typename param> | |
| struct app{ | |
| typedef typename ifthenelse_6<param, param::nonzero>::res res; | |
| }; | |
| }; | |
| struct take{ | |
| template <typename param> | |
| struct app{ | |
| typedef typename ifthenelse_7<merge, param, param::nonzero>::res res; | |
| }; | |
| }; | |
| struct fold; | |
| struct fold{ | |
| template <typename f> | |
| struct app{ | |
| struct res{ | |
| template <typename acc> | |
| struct app{ | |
| struct res{ | |
| template <typename h> | |
| struct app{ | |
| typedef typename ifthenelse_8<fold, f, acc, h, h::nonzero>::res res; | |
| }; | |
| }; | |
| }; | |
| }; | |
| }; | |
| }; | |
| struct size; | |
| struct size{ | |
| template <typename param> | |
| struct app{ | |
| typedef typename ifthenelse_9<size, param, param::nonzero>::res res; | |
| }; | |
| }; | |
| typedef Cons<empty, is_empty, merge, insert, add, find_min, take, size> res; | |
| }; | |
| }; | |
| struct Make_from_compare{ | |
| template <typename E> | |
| struct app{ | |
| struct leq{ | |
| template <typename a> | |
| struct app{ | |
| struct res{ | |
| template <typename b> | |
| struct app{ | |
| typedef I<((E::f0::template app<a>::res::template app<b>::res::val) <= (I<0>::val))> res; | |
| }; | |
| }; | |
| }; | |
| }; | |
| typedef typename Make::template app<Cons<leq>>::res res; | |
| }; | |
| }; | |
| typedef Cons<Make, Make_from_compare> CCHeap; | |
| struct leq{ | |
| template <typename a> | |
| struct app{ | |
| struct res{ | |
| template <typename b> | |
| struct app{ | |
| typedef I<((a::f0::val) <= (b::f0::val))> res; | |
| }; | |
| }; | |
| }; | |
| }; | |
| typedef typename CCHeap::f0::template app<Cons<leq>>::res PQ; | |
| struct sieve; | |
| struct sieve{ | |
| template <typename min> | |
| struct app{ | |
| struct res{ | |
| template <typename rest> | |
| struct app{ | |
| struct res{ | |
| template <typename x> | |
| struct app{ | |
| struct res{ | |
| template <typename xmax> | |
| struct app{ | |
| typedef typename ifthenelse_16<PQ, sieve, min, rest, x, xmax, | |
| I<((x::val) >= (xmax::val))>::nonzero>::res res; | |
| }; | |
| }; | |
| }; | |
| }; | |
| }; | |
| }; | |
| }; | |
| }; | |
| struct main{ | |
| template <typename limit_> | |
| struct app{ | |
| typedef Cons<I<2>, Cons<I<3>, Cons<I<5>, Cons<I<7>, | |
| typename sieve::template app<Cons<I<((I<7>::val) * (I<7>::val))>, | |
| I<7>>>::res::template app<typename PQ::f0>::res::template app<I<8>>::res::template app<limit_>::res>>>> res; | |
| }; | |
| }; | |
| typedef typename main::template app<I<limit>>::res output; | |
| typedef typename output::print print; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment