.. index:: single: arbitrary .. _arbitrary/0: .. rst-class:: right **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:** | :ref:`type ` | **Uses:** | :ref:`fast_random ` | :ref:`integer ` | :ref:`list ` | :ref:`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 XVM and SWI-Prolog as other backends do not provide support for querying a Unicode code point category. | **Inherited public predicates:** | (none) .. contents:: :local: :backlinks: top Public predicates ----------------- .. index:: arbitrary/1 .. _arbitrary/0::arbitrary/1: ``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`` ------------ .. index:: arbitrary/2 .. _arbitrary/0::arbitrary/2: ``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`` ------------ .. index:: shrinker/1 .. _arbitrary/0::shrinker/1: ``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`` ------------ .. index:: shrink/3 .. _arbitrary/0::shrink/3: ``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`` ------------ .. index:: shrink_sequence/3 .. _arbitrary/0::shrink_sequence/3: ``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`` ------------ .. index:: edge_case/2 .. _arbitrary/0::edge_case/2: ``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`` ------------ .. index:: get_seed/1 .. _arbitrary/0::get_seed/1: ``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`` ------------ .. index:: set_seed/1 .. _arbitrary/0::set_seed/1: ``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`` ------------ .. index:: max_size/1 .. _arbitrary/0::max_size/1: ``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) .. seealso:: :ref:`type `