/* * Copyright (C) 2020,2023 Weber Yann * * This file is part of pyrpn. * * pyrpn is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * pyrpn 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with pyrpn. If not, see . */ #ifndef __rpn_mutate__h__ #define __rpn_mutate__h__ #include "config.h" #include #include #include #include #include "rpn_parse.h" /**@file rpn_mutate.h * @brief Expression mutation headers */ /**@brief RPN expression mutation parameters */ typedef struct rpn_mutation_params_s rpn_mutation_params_t; /**@brief Type of random values used by mutations */ typedef uint16_t rnd_t; /**@brief maximum value for rnd_t */ extern const rnd_t rnd_t_max; /**@brief Default values for mutations parameters */ extern rpn_mutation_params_t rpn_mutation_params_default; /**@brief RPN expression mutation parameters */ struct rpn_mutation_params_s { /**@brief Minimum expression length */ size_t min_len; /**@brief Weight of adding a token*/ float w_add; /**@brief Weight of deleting a token*/ float w_del; /**@brief Weight of mutating a token*/ float w_mut; /**@brief Weight of mutating a token without type change*/ float w_mut_soft; /**@brief Weight for each token types (op, const, var) when * adding a token*/ float w_add_elt[3]; /**@brief Weight for each token types (op, const, var) when * mutating a token*/ float w_mut_elt[3]; /**@brief For internal use, set by rpn_mutation_init_params * * weight reported by groups on rnd_t integers * - [0..3] -> weights mutation * - [4..6] -> w_add_elt * - [7..9] -> w_mut_elt * * @note Weights are stored a way allowing fast random choice. * They are kind of ascending threshold until @ref rnd_t max value. */ rnd_t _weights[10]; }; /**@brief Initialize mutation parameters * * pre-process integers threshold by group * @param params * @return 0 if no error else -1 and set ERRNO (EINVAL) */ int rpn_mutation_init_params(rpn_mutation_params_t *params); /**@brief Mutate a tokenized rpn expression * @param toks The tokenized expression * @param params The mutation parameters * @return 0 or -1 on error */ int rpn_mutation(rpn_tokenized_t *toks, rpn_mutation_params_t *params); /**@brief Mutate an expression by adding a token * @param toks The tokenized expression * @param params The mutation parameters * @return 0 or -1 on error */ int rpn_mutation_add(rpn_tokenized_t *toks, rpn_mutation_params_t *params); /**@brief Mutate an expression by removing a token * @param toks The tokenized expression * @param params The mutation parameters * @return 0 or -1 on error */ int rpn_mutation_del(rpn_tokenized_t *toks, rpn_mutation_params_t *params); /**@brief Mutate an expression by changing a token * @param toks The tokenized expression * @param params The mutation parameters * @return 0 or -1 on error */ int rpn_mutation_mut(rpn_tokenized_t *toks, rpn_mutation_params_t *params); /**@brief Mutate an expression by changing a token value (not type) * @param toks The tokenized expression * @param params The mutation parameters * @return 0 or -1 on error */ int rpn_mutation_mut_soft(rpn_tokenized_t *toks, rpn_mutation_params_t *params); /**@brief Change the "value" of a token randomly not it's type * @param tok Point on the token to mutate * @param toks The tokenized expression the token tok belongs to * @param params The mutation parameters * @return 0 or -1 on error */ int rpn_mutation_random_token(rpn_token_t *tok, rpn_tokenized_t *toks, rpn_mutation_params_t *params); /**@brief Choose a random token type * @param type Point on result * @param weights The weight of each types for the choice * @note Weights comes from @ref rpn_mutation_params_s._weights and are * processed in a form allowing a fast random choice. * @return 0 or -1 on error */ int rpn_random_token_type(rpn_token_type_t *type, rnd_t *weights); /**@brief Generate a random value * @param rand Point on result * @return -1 on error else 0 */ int rpn_getrandom(rnd_t *rand); /**@brief Generate a random number between 0 and max (max excluded) * @param max Maximum value * @param res Will be set to a value between [..max[ * @return -1 on error else 0 */ int rpn_rand_limit(size_t max, size_t *res); /**@brief Conver an array of float weights to an array for fast random * choices (see @ref _rpn_random_choices() ) * @param sz The number of items in to choose from * @param weights Array of size sz with items weights (positive values) * @param fast_weights Array of size sz pointing on result * @return -1 on error else 0 */ int rpnifs_fast_rnd_weights(size_t sz, const float *weights, rnd_t *fast_weights); /** * @return A float between [-range[1] .. -range[0]] or [range[0] .. range[1]] */ int rpnifs_rnd_float(float range[2], float *res); /**@brief Given a size return an random element with regards to given weights * @param sz The given size * @param weights Weights coming from @ref rpn_mutation_params_s._weights * @param res Points on result * @return 0 or -1 on error * @todo refactor rename without rpn prefix */ int _rpn_random_choice(size_t sz, rnd_t *weights, size_t *res); /**@brief Given a size and a (random) value, returns an element with regards * to given weights * @param sz The given size * @param weights Weights coming from @ref rpn_mutation_params_s._weights * @param rand A (random) value * @param res Points on result */ void __rpn_random_choice(size_t sz, rnd_t *weights, rnd_t rand, size_t *res); /**@brief Debugging function that dump mutation params in a human readable format * @param fd The file descriptor on wich we should print parameters * @param params The mutation parameters to dump */ void _print_params(int fd, rpn_mutation_params_t *params); #endif