Randomization¶
The deterministic value generator and the constrained-transaction layer.
All in namespace cpptb. Random stimulus and the
randomization guides teach
usage; this page is the surface. Nothing here suspends a coroutine or
touches the DUT — randomization is pure computation.
The generator¶
Random¶
constexpr Random(); // seed 1 (kDefaultRandomSeed)
explicit constexpr Random(uint64_t seed);
uint64_t next_u64(); // raw xoshiro256** step
Value randint(Value minimum, Value maximum); // inclusive; unbiased;
// throws if min > max
Bits<W> randbits<W>(); // masked to W bits
range_value choice(range); // throws on an empty range
auto weighted_choice(range); // of Weighted{value, weight}
void shuffle(range); // Fisher-Yates in place
uint64_t seed() const; void reseed(uint64_t seed);
Integral and enum values through 64 bits; signed ranges are exact. The
algorithm identifier "xoshiro256ss-v1" is part of the replay contract —
recorded into every result, never silently changed.
In a test, test.random() returns the calling process’s stream,
derived from the master seed and the process’s creation-order ID; process
topology is therefore part of the replay input, and no process ever
consumes another’s draws. The master seed defaults to 1, set per run with
CPPTB_RANDOM_SEED. A standalone Random model_random{0x1234} is fine
for reference models and unit tests.
Constrained transactions¶
Randomized¶
class Randomized { // non-copyable, non-movable
ConstraintHandle constraint(Constraint expr, std::string_view label = {});
ConstraintHandle soft_constraint(Constraint expr, std::string_view label = {});
ConstraintHandle distribution(Distribution dist, std::string_view label = {});
virtual void pre_randomize() {} // before every solve attempt
virtual void post_randomize() {} // after a successful assignment
RandomizeResult randomize(Random& random,
ConstraintBackend& backend = default_constraint_backend());
RandomizeResult randomize_with(Random& random, Constraint expr,
ConstraintBackend& backend = default_constraint_backend());
};
The transaction base class. Declare fields as members, constraints in the
constructor. In a test, prefer test.randomize(item) /
test.randomize_with(item, expr) — same solve, but it uses the process
stream and configured backend, records solver metadata into the result,
and turns a failed solve into a fatal check.
Rand¶
RandC¶
RandArray¶
RandBits¶
Rand<Value> field{*this, "name", minimum, maximum}; // solvable scalar
RandC<Value> mode{*this, "mode"}; // nonrepeating: cycles its domain
RandArray<V, N> lanes{*this, "lanes"}; // N independent Rand<V>, operator[]
RandBits<W> payload{*this, "payload"}; // wide; constrain per 32-bit word
Rand<V>::get() (or implicit conversion) reads the last solved value.
Assigning to a Rand sets the stored value only — it does not constrain
the next solve.
Constraint expressions¶
Built from field references with ordinary operators — arithmetic
+ - * %, comparisons, and logical && || ! — plus:
inside(field, values_and_ranges...); // set membership; range(lo, hi)
dist(field, weighted(value, weight)...); // weighted distribution
Division, bitwise operators, implication syntax, and arbitrary C++ calls are not constraint operators.
ConstraintHandle¶
void enable() const; void disable() const;
void set_enabled(bool) const; bool enabled() const; bool soft() const;
Runtime control of a named constraint — the constraint_mode equivalent.
Results and backends¶
RandomizeResult¶
struct RandomizeResult {
RandomizeStatus status; // Solved, Unsatisfiable, CycleExhausted,
// SearchExhausted, BackendError
RandomizeEngine engine; // Sampling or Solver
std::string message;
explicit operator bool() const; // true iff Solved
};
ConstraintBackend¶
class RandomSearchBackend; // pure sampling, bounded attempts
class AdaptiveConstraintBackend; // sampling first, solver fallback — the default
class Z3RandomBackend; // Z3-backed, for hard constraint sets
ConstraintBackend& default_constraint_backend();
test.set_random_backend(backend); // per-test override
The result records which engine solved each transaction
(random_sampling_solves / random_solver_solves), so a constraint set
that quietly fell back to the solver is visible in CI.
See also¶
Constrained transactions, Value generation, Reproducibility — the guides.
Functional coverage — recording what the stimulus hit.