#ifndef _random_h_INCLUDED
#define _random_h_INCLUDED

#include <assert.h>
#include <stdbool.h>
#include <stdint.h>

typedef uint64_t generator;

static inline uint64_t kissat_next_random64 (generator *rng) {
  *rng *= 6364136223846793005ul;
  *rng += 1442695040888963407ul;
  return *rng;
}

static inline unsigned kissat_next_random32 (generator *rng) {
  return kissat_next_random64 (rng) >> 32;
}

static inline unsigned kissat_pick_random (generator *rng, unsigned l,
                                           unsigned r) {
  assert (l <= r);
  if (l == r)
    return l;
  const unsigned delta = r - l;
  const unsigned tmp = kissat_next_random32 (rng);
  const double fraction = tmp / 4294967296.0;
  assert (0 <= fraction), assert (fraction < 1);
  const unsigned scaled = delta * fraction;
  assert (scaled < delta);
  const unsigned res = l + scaled;
  assert (l <= res), assert (res < r);
  return res;
}

static inline bool kissat_pick_bool (generator *rng) {
  return kissat_pick_random (rng, 0, 2);
}

static inline double kissat_pick_double (generator *rng) {
  return kissat_next_random32 (rng) / 4294967296.0;
}

#endif
