<commit_before>%  This file is a part of Uranium, a general-purpose functional
%  test platform.
%
%  Copyright (C) 2012, Kogorta OOO Ltd
%
%  This library is free software; you can redistribute it and/or
%  modify it under the terms of the GNU Lesser General Public
%  License as published by the Free Software Foundation; either
%  version 2.1 of the License, or (at your option) any later
%  version.
%
%  This library is distributed in the hope that it will be
%  useful, but WITHOUT ANY WARRANTY; without even the implied
%  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
%  PURPOSE.  See the GNU Lesser General Public License for more
%  details.
%
%  You should have received a copy of the GNU Lesser General
%  Public License along with this library; if not, write to the
%  Free Software Foundation, Inc., 51 Franklin Street, Fifth
%  Floor, Boston, MA 02110-1301 USA
%
%  e-mail: <EMAIL>
%  post:   49017 Ukraine, Dnepropetrovsk per. Kamenski, 6

% This module contain various predicaties
% for random strings generation.

:- module(gt_strings,
          [random_string/1,
	   random_string/2,
           randsel/4,       % +List, :Gen, +Seed0, -Seed
           randselchk/4,    % +List, :Gen, +Seed0, -Seed
	   range_pattern/2
           ]).

:- use_module(library(error)).
:- use_module(library(clpfd)).
:- use_module(library(random)). % TODO always use passed generators
:- use_module(u(regex/regex)).
:- use_module(u(rand/randgen)).
:- use_module(u(ur_option)).
:- use_module(u(v)).

random_string(Str) :-

   Ctx = context(random_string/1, _),
   random_string_cmn([], Str, Ctx).

:- meta_predicate random_string(:, -).

random_string(Options, Str) :-

   Ctx = context(random_string/2, _),
   random_string_cmn(Options, Str, Ctx).

random_string_cmn(Options, Str, _) :-

   options_to_object(random_string, Options, Opt),

   % check options (TODO: move to ur_options_v)
   obj_unify(Opt, weak,
             [length,
              generator,
              seed,
              pattern,
              det],
             [Lengths,
              generator(Generator),
              SeedOpt,
              Patterns,
              Det]
            ),
   must_be(callable, Generator),
   memberchk(SeedOpt, [seed(Seed0), seed(Seed0, Seed)]),
   must_be(integer, Seed0),
   (  var(Det) -> Det = semidet ; true ),

   (  Seed0 >= 0
   -> Seed1 = Seed0
   ;  Seed1 is random(4294967295) % TODO
   ),

   % NB Lengths and Patterns are always non-empty due to defaults
   (  Det == nondet 
   -> random_select(Pattern1, Patterns, _, Generator, Seed1, Seed2)
   ;  random_member(Pattern1, Patterns, Generator, Seed1, Seed2)
   ),

   (  Pattern1 = static(Str) 
   -> Seed = Seed2 % Just return a static value
   ;

     (  Det == nondet 
     -> random_select(Length, Lengths, _, Generator, Seed2, Seed3)
     ;  random_member(Length, Lengths, Generator, Seed2, Seed3)
     ),

     % regex/1, range/1 -> pattern/1
     context_module(That),
     (  Pattern1 = regex(Reg)
     -> regex_pattern(Reg, Pattern)
     ;  Pattern1 = range(Drep)
     -> Pattern = That:range_pattern(Drep)
     ;  pattern(Pattern) = Pattern1
     ),

     random_string_int(Pattern, Generator, Seed3, Seed, Length,
                       Codes),
     (  Det == semidet -> ! ; true  ),

     (   nonvar(Str), Str = atom(Atom)
     ->  atom_codes(Atom, Codes)
     ;   Str = Codes
     )
   ).

random_string_int(Pattern, Generator, Seed0, Seed, Length, Str) :-

   choose_length(Generator, Seed0, Seed1, Length, N),
   (  N =:= 0
   ->
      Str = [], 
      Seed = Seed1
   ;
      % Generate a string equation
      length(Str, N),
      call(Pattern, Str),

      % Make a selection
      randsel(Str, Generator, Seed1, Seed)
  ).

:- meta_predicate randsel(+, :, +, -).

%% randsel(+List, :Gen, +Seed0, -Seed) is nondet.<commit_msg>Cosmetic<commit_after>%  This file is a part of Uranium, a general-purpose functional
%  test platform.
%
%  Copyright (C) 2012, Kogorta OOO Ltd
%
%  This library is free software; you can redistribute it and/or
%  modify it under the terms of the GNU Lesser General Public
%  License as published by the Free Software Foundation; either
%  version 2.1 of the License, or (at your option) any later
%  version.
%
%  This library is distributed in the hope that it will be
%  useful, but WITHOUT ANY WARRANTY; without even the implied
%  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
%  PURPOSE.  See the GNU Lesser General Public License for more
%  details.
%
%  You should have received a copy of the GNU Lesser General
%  Public License along with this library; if not, write to the
%  Free Software Foundation, Inc., 51 Franklin Street, Fifth
%  Floor, Boston, MA 02110-1301 USA
%
%  e-mail: <EMAIL>
%  post:   49017 Ukraine, Dnepropetrovsk per. Kamenski, 6

% This module contain various predicaties
% for random strings generation.

:- module(gt_strings,
          [random_string/1,
	   random_string/2,
           randsel/4,       % +List, :Gen, +Seed0, -Seed
           randselchk/4,    % +List, :Gen, +Seed0, -Seed
	   range_pattern/2
           ]).

:- use_module(library(error)).
:- use_module(library(clpfd)).
:- use_module(library(random)). % TODO always use passed generators
:- use_module(u(regex/regex)).
:- use_module(u(rand/randgen)).
:- use_module(u(ur_option)).
:- use_module(u(v)).

random_string(Str) :-

   Ctx = context(random_string/1, _),
   random_string_cmn([], Str, Ctx).

:- meta_predicate random_string(:, -).

random_string(Options, Str) :-

   Ctx = context(random_string/2, _),
   random_string_cmn(Options, Str, Ctx).

random_string_cmn(Options, Str, _) :-

   options_to_object(random_string, Options, Opt),

   % check options (TODO: move to ur_options_v)
   obj_unify(Opt, weak,
             [length,
              generator,
              seed,
              pattern,
              det],
             [Lengths,
              generator(Generator),
              SeedOpt,
              Patterns,
              Det]
            ),
   must_be(callable, Generator),
   memberchk(SeedOpt, [seed(Seed0), seed(Seed0, Seed)]),
   must_be(integer, Seed0),
   (  var(Det) -> Det = semidet ; true ),

   (  Seed0 >= 0
   -> Seed1 = Seed0
   ;  Seed1 is random(4294967295) % TODO
   ),

   % NB Lengths and Patterns are always non-empty due to defaults
   (  Det == nondet 
   -> random_select(Pattern1, Patterns, _, Generator, Seed1, Seed2)
   ;  random_member(Pattern1, Patterns, Generator, Seed1, Seed2)
   ),

   (  Pattern1 = static(Str) 
   -> Seed = Seed2 % Just return a static value
   ;

     (  Det == nondet 
     -> random_select(Length, Lengths, _, Generator, Seed2, Seed3)
     ;  random_member(Length, Lengths, Generator, Seed2, Seed3)
     ),

     % regex/1, range/1 -> pattern/1
     context_module(That),
     (  Pattern1 = regex(Reg)
     -> regex_pattern(Reg, Pattern)
     ;  Pattern1 = range(Drep)
     -> Pattern = That:range_pattern(Drep)
     ;  pattern(Pattern) = Pattern1,
        must_be(callable, Pattern)
     ),

     random_string_int(Pattern, Generator, Seed3, Seed, Length,
                       Codes),
     (  Det == semidet -> ! ; true  ),

     (   nonvar(Str), Str = atom(Atom)
     ->  atom_codes(Atom, Codes)
     ;   Str = Codes
     )
   ).

random_string_int(Pattern, Generator, Seed0, Seed, Length, Str) :-

   choose_length(Generator, Seed0, Seed1, Length, N),
   (  N =:= 0
   ->
      Str = [], 
      Seed = Seed1
   ;
      % Generate a string equation
      length(Str, N),
      call(Pattern, Str),

      % Make a selection
      randsel(Str, Generator, Seed1, Seed)
  ).

:- meta_predicate randsel(+, :, +, -).

%% randsel(+List, :Gen, +Seed0, -Seed) is nondet.
{'fraction_non_alphanumeric': 0.11983847857235899, 'fraction_numerical': 0.01979940080760714, 'mean_word_length': 2.609779031499765, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3708658', 'n_tokens_mistral': 2674, 'n_tokens_neox': 2527, 'n_words': 699}