/*
* 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