category

# `arbitrary`

Adds predicates for generating and shrinking random values for selected types to the library `type` object. User extensible.

Availability:
`logtalk_load(arbitrary(loader))`
Author: Paulo Moura
Version: 2:35:1
Date: 2024-08-13
Compilation flags:
`static`
Complements:
type
Uses:
fast_random
integer
list
type
Remarks:

> - Logtalk specific types: `entity`, `object`, `protocol`, `category`, `entity_identifier`, `object_identifier`, `protocol_identifier`, `category_identifier`, `event`, `predicate`.

> - Prolog module related types (when the backend compiler supports modules): `module`, `module_identifier`, `qualified_callable`.

> - Prolog base types: `term`, `var`, `nonvar`, `atomic`, `atom`, `number`, `integer`, `float`, `compound`, `callable`, `ground`.

> - Atom derived types: `non_quoted_atom`, `non_empty_atom`, `non_empty_atom(CharSet)`, `boolean`, `character`, `in_character`, `char`, `operator_specifier`, `hex_char`.

> - Atom derived parametric types: `atom(CharSet)`, `atom(CharSet,Length)`, `non_empty_atom(CharSet)`, `character(CharSet)`, `in_character(CharSet)`, `char(CharSet)`.

> - Number derived types: `positive_number`, `negative_number`, `non_positive_number`, `non_negative_number`.

> - Float derived types: `positive_float`, `negative_float`, `non_positive_float`, `non_negative_float`, `probability`.

> - Integer derived types: `positive_integer`, `negative_integer`, `non_positive_integer`, `non_negative_integer`, `byte`, `in_byte`, `character_code`, `in_character_code`, `code`, `operator_priority`, `hex_code`.

> - Integer derived parametric types: `character_code(CharSet)`, `in_character_code(CharSet)`, `code(CharSet)`.

> - List types (compound derived types): `list`, `non_empty_list`, `partial_list`, `list_or_partial_list`, `list(Type)`, `list(Type,Length)`, `list(Type,Min,Max)`, `list(Type,Length,Min,Max)`, `non_empty_list(Type)`, `codes`, `chars`.

> - Difference list types (compound derived types): `difference_list`, `difference_list(Type)`.

> - List and difference list types length: The types that do not take a fixed length generate lists with a length in the `[0,MaxSize]` interval (`[1,MaxSize]` for non-empty list types).

> - Predicate and non-terminal indicator types arity: These types generate indicators with an arity in the `[0,MaxSize]` interval.

> - Other compound derived types: `compound(Name,Types)`, `predicate_indicator`, `non_terminal_indicator`, `predicate_or_non_terminal_indicator`, `clause`, `grammar_rule`, `pair`, `pair(KeyType,ValueType)`.

> - Other types: `Object::Closure`, `between(Type,Lower,Upper)`, `property(Type,LambdaExpression)`, `one_of(Type,Set)`, `var_or(Type)`, `ground(Type)`, `types(Types)`, `types_frequency(Pairs)`, `transform(Type,Closure)`, `constrain(Type,Closure)`.

> - Type `Object::Closure` notes: Allows calling public object predicates as generators and shrinkers. The `Closure` closure is extended with either a single argument, the generated arbitrary value, or with two arguments, when shrinking a value.

> - Type `compound(Name,Types)` notes: Generate a random compound term with the given name with a random argument for each type.

> - Type `types_frequency(Pairs)` notes: Generate a random term for one of the types in a list of `Type-Frequency` pairs. The type is randomly selected taking into account the types frequency.

> - Type `transform(Type,Closure)` notes: Generate a random term by transforming the term generated for the given type using the given closure.

> - Type `constrain(Type,Closure)` notes: Generate a random term for the given type that satisfy the given closure.

> - Registering new types: Add clauses for the `arbitrary/1-2` multifile predicates and optionally for the `shrinker/1` and `shrink/3` multifile predicates. The clauses must have a bound first argument to avoid introducing spurious choice-points.

> - Shrinking values: The `shrink/3` should either succeed or fail but never throw an exception.

> - Character sets: `ascii_identifier`, `ascii_printable`, `ascii_full`, `byte`, `unicode_bmp`, `unicode_full`.

> - Default character sets: The default character set when using a parameterizable type that takes a character set parameter depends on the type.

> - Default character sets: Entity, predicate, and non-terminal identifier types plus compound and callable types default to an `ascii_identifier` functor. Character and character code types default to `ascii_full`. Other types default to `ascii_printable`.

> - Caveats: The type argument (and any type parameterization) to the predicates is not type-checked (or checked for consistency) for performance reasons.

> - Unicode limitations: Currently, correct character/code generation is only ensured for SWI-Prolog and XVM as other backends do not provide support for querying a Unicode code point category.

Inherited public predicates:
(none)

## Public predicates

### `arbitrary/1`

Table of defined types for which an arbitrary value can be generated. A new type can be registered by defining a clause for this predicate and adding a clause for the `arbitrary/2` multifile predicate.

Compilation flags:
`static, multifile`
Template:
`arbitrary(Type)`
Mode and number of proofs:
`arbitrary(?callable)` - `zero_or_more`

### `arbitrary/2`

Generates an arbitrary term of the specified type. Fails if the type is not supported. A new generator can be defined by adding a clause for this predicate and registering it via the `arbitrary/1` predicate.

Compilation flags:
`static, multifile`
Template:
`arbitrary(Type,Term)`
Meta-predicate template:
`arbitrary(::,*)`
Mode and number of proofs:
`arbitrary(@callable,-term)` - `zero_or_one`

### `shrinker/1`

Table of defined types for which a shrinker is provided. A new shrinker can be registered by defining a clause for this predicate and adding a definition for the `shrink/3` multifile predicate.

Compilation flags:
`static, multifile`
Template:
`shrinker(Type)`
Mode and number of proofs:
`shrinker(?callable)` - `zero_or_more`

### `shrink/3`

Shrinks a value to a smaller value if possible. Must generate a finite number of solutions. Fails if the type is not supported. A new shrinker can be defined by adding a clause for this predicate and registering it via the `shrinker/1` predicate.

Compilation flags:
`static, multifile`
Template:
`shrink(Type,Large,Small)`
Mode and number of proofs:
`shrink(@callable,@term,-term)` - `zero_or_more`

### `shrink_sequence/3`

Shrinks a value repeatedly until shrinking is no longer possible returning the sequence of values (ordered from larger to smaller value). Fails if the type is not supported.

Compilation flags:
`static`
Template:
`shrink_sequence(Type,Value,Sequence)`
Mode and number of proofs:
`shrink_sequence(@callable,@term,-list(term))` - `zero_or_one`

### `edge_case/2`

Table of type edge cases. Fails if the given type have no defined edge cases. New edge cases for existing or new types can be added by defining a clause for this multifile predicate.

Compilation flags:
`static, multifile`
Template:
`edge_case(Type,Term)`
Mode and number of proofs:
`edge_case(?callable,?term)` - `zero_or_more`

### `get_seed/1`

Gets the current random generator seed. Seed should be regarded as an opaque ground term.

Compilation flags:
`static`
Template:
`get_seed(Seed)`
Mode and number of proofs:
`get_seed(-ground)` - `one`

### `set_seed/1`

Sets the random generator seed to a given value returned by calling the `get_seed/1` predicate.

Compilation flags:
`static`
Template:
`set_seed(Seed)`
Mode and number of proofs:
`set_seed(+ground)` - `one`

### `max_size/1`

User defined maximum size for types where its meaningful and implicit. When not defined, defaults to 42. When multiple definitions exist, the first valid one found is used.

Compilation flags:
`static, multifile`
Template:
`max_size(Size)`
Mode and number of proofs:
`max_size(?positive_integer)` - `zero_or_one`

## Protected predicates

(no local declarations; see entity ancestors if any)

## Private predicates

(no local declarations; see entity ancestors if any)

## Operators

(none)

See also

type