type cursor = {
  arr: (Z.t) array;
  bound: Z.t;
  mutable rank: Z.t;
  mutable last: bool;
  }

let create_cursor (n: Z.t) : cursor =
  let a = Array.make (Z.to_int n) Z.zero in
  { arr = a; bound = n; rank = Z.zero; last = Z.leq n Z.one }

let has_next (c: cursor) : bool =
  let a = c.arr in
  let n = Z.of_int (Array.length a) in
  let b = c.bound in
  let r = ref (Z.sub n Z.one) in
  while Z.geq !r Z.zero && Z.geq a.(Z.to_int !r) (Z.sub b Z.one) do
    r := Z.sub !r Z.one
  done;
  c.last <- Z.lt !r Z.zero;
  not c.last

let next (c: cursor) : (Z.t) array =
  if Z.equal c.rank Z.zero
  then begin c.rank <- Z.one; c.arr end
  else
    begin
      let r = ref (Z.of_string "-1") in
      let t = ref (Z.sub (Z.of_int (Array.length c.arr)) Z.one) in
      while Z.geq !t Z.zero do
        if Z.lt (c.arr).(Z.to_int !t) (Z.sub c.bound Z.one)
        then begin r := !t; t := Z.of_string "-1" end
        else t := Z.sub !t Z.one
      done;
      if Z.lt !r Z.zero
      then c.last <- true
      else
        begin
          c.arr.(Z.to_int !r) <- Z.add (c.arr).(Z.to_int !r) Z.one;
          (let o = Z.sub (Z.of_int (Array.length c.arr)) Z.one in
           let o1 = Z.add !r Z.one in
           let rec for_loop_to2 i =
             if Z.leq i o
             then begin
               c.arr.(Z.to_int i) <- Z.zero;
               for_loop_to2 (Z.succ i)
             end
           in for_loop_to2 o1);
          c.rank <- Z.add c.rank Z.one;
          c.last <- false
        end;
      c.arr end

