metamon
Metamon top-level public API.
metamon exports the small surface that most tests interact with:
forall, forall_morph, assert_morph, forall_morphs, the
Mr smart constructors, and a handful of metamorphic-relation
templates (idempotency_of, round_trip_with,
invariant_under, equivariant_under).
Configuration lives in metamon/config; generators in
metamon/generator; transforms in metamon/transform; relations
in metamon/relation; per-property context in metamon/annotate
and metamon/coverage; structural diff in metamon/diff.
Types
Re-export of Config so callers can write metamon.Config.
pub type Config =
config.Config
A named metamorphic relation. Construct via mr (the Plain form,
f(T(x)) ≈ f(x)) or mr_equivariant (the Equivariant form,
f(T(x)) ≈ U(f(x))).
Opaque on purpose: future versions may add fields without breaking callers that always go through the smart constructors.
pub opaque type Mr(a, b)
Re-export of OutputFormat so callers can write
metamon.OutputFormat.
pub type OutputFormat =
config.OutputFormat
Values
pub fn assert_morph(input: a, m: Mr(a, b), f: fn(a) -> b) -> Nil
Run a metamorphic relation against a single input. Generator-free.
pub fn commutativity_of(
name name: String,
of op: fn(a, a) -> b,
) -> Mr(#(a, a), b)
op(a, b) == op(b, a) — op is commutative.
The MR is over the input pair #(a, a) and the output type b.
Use it as:
let mr = metamon.commutativity_of(name: "add_commutative", of: add)
metamon.forall_morph(
generator.tuple2(int_gen, int_gen),
mr,
fn(pair) { add(pair.0, pair.1) },
)
pub fn equivariant_under(
name name: String,
input input_transform: transform.Transform(a),
output output_transform: transform.Transform(b),
relation rel: relation.Relation(b),
) -> Mr(a, b)
R(U(f(x)), f(T(x))). Equivariance: the input transform T and
the output transform U commute with f modulo R.
pub fn forall(
g: generator.Generator(a),
property: fn(a) -> Bool,
) -> Nil
Run a property over many random inputs.
pub fn forall_morph(
g: generator.Generator(a),
m: Mr(a, b),
f: fn(a) -> b,
) -> Nil
Run a metamorphic relation over many random inputs.
pub fn forall_morph_n(
g: generator.Generator(a),
transforms: List(transform.Transform(a)),
rel: relation.RelationN(b),
f: fn(a) -> b,
) -> Nil
Run an N-ary metamorphic relation: apply each of transforms to
the source input to build follow-up inputs, then assert that the
resulting outputs [f(x), f(T0(x)), ..., f(Tn(x))] satisfy
relation. Useful when the property requires comparing more than
two outputs in one shot (e.g. (a, b, c) ↦ op(op(a,b), c) and its
re-associations all agree).
pub fn forall_morph_n_with(
cfg: config.Config,
g: generator.Generator(a),
transforms: List(transform.Transform(a)),
rel: relation.RelationN(b),
f: fn(a) -> b,
) -> Nil
forall_morph_n with an explicit configuration.
pub fn forall_morph_with(
cfg: config.Config,
g: generator.Generator(a),
m: Mr(a, b),
f: fn(a) -> b,
) -> Nil
Run a metamorphic relation with an explicit configuration.
pub fn forall_morphs(
g: generator.Generator(a),
ms: List(Mr(a, b)),
f: fn(a) -> b,
) -> Nil
Run multiple metamorphic relations against the same generator. Each MR is tried independently; failures are collected and reported together at the end.
pub fn forall_with(
cfg: config.Config,
g: generator.Generator(a),
property: fn(a) -> Bool,
) -> Nil
Run a property with an explicit configuration.
pub fn idempotency_of(
name name: String,
of f: fn(a) -> a,
) -> Mr(a, a)
f(f(x)) == f(x). Idempotency.
Encoded as a Plain MR whose transform is f itself and whose
relation is structural equality.
pub fn invariant_under(
name name: String,
under under: transform.Transform(a),
) -> Mr(a, b)
f(T(x)) == f(x) — f is invariant under the input transform.
pub fn mr(
name name: String,
transform transform: transform.Transform(a),
relation relation: relation.Relation(b),
) -> Mr(a, b)
Construct a Plain MR. The relation is checked between
f(source_input) and f(transform.apply(source_input)).
pub fn mr_equivariant(
name name: String,
input input_transform: transform.Transform(a),
output output_transform: transform.Transform(b),
relation relation: relation.Relation(b),
) -> Mr(a, b)
Construct an Equivariant MR. The relation is checked between
output_transform.apply(f(source_input)) and
f(input_transform.apply(source_input)).
pub fn with_diff_enabled(
c: config.Config,
enabled: Bool,
) -> config.Config
Re-export of with_diff_enabled.
pub fn with_max_edges(
c: config.Config,
n: Int,
) -> Result(config.Config, config.ConfigError)
Re-export of with_max_edges.
pub fn with_max_size(
c: config.Config,
n: Int,
) -> Result(config.Config, config.ConfigError)
Re-export of with_max_size.
pub fn with_output_format(
c: config.Config,
fmt: config.OutputFormat,
) -> config.Config
Choose the failure-report output format. Text (default) is
human-friendly; Json is single-line JSON for CI / LLM consumers.
pub fn with_regression_file(
c: config.Config,
path: String,
) -> Result(config.Config, config.ConfigError)
Re-export of with_regression_file.
pub fn with_runs(
c: config.Config,
n: Int,
) -> Result(config.Config, config.ConfigError)
Re-export of with_runs.
pub fn with_seed(c: config.Config, s: seed.Seed) -> config.Config
Re-export of with_seed.
pub fn with_shrink_limit(
c: config.Config,
n: Int,
) -> Result(config.Config, config.ConfigError)
Re-export of with_shrink_limit.