jacob thinks porn makes you gay

main
Brett 2024-03-19 13:00:25 -04:00
parent ef8b03ae66
commit 33352171e3
3 changed files with 60 additions and 12 deletions

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(lilfbtf5 VERSION 0.1.31) project(lilfbtf5 VERSION 0.1.32)
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)

View File

@ -74,14 +74,12 @@ namespace fb
enum class tree_init_t enum class tree_init_t
{ {
// standard grow method // standard koza grow method
GROW, GROW,
BRETT_GROW,
// standard full method // standard full method
FULL, FULL
// standard ramped half-and-half method
RAMPED_HALF_HALF,
// variant of grow/full method where at each level a choice is made between using only non-terminals or terminals
BRETT_HALF_HALF
}; };
namespace detail namespace detail
@ -160,6 +158,7 @@ namespace fb
static detail::node_t* allocate_terminal(detail::node_construction_info_t info, type_id type); static detail::node_t* allocate_terminal(detail::node_construction_info_t info, type_id type);
static void grow(detail::node_construction_info_t info, blt::size_t min_depth, blt::size_t max_depth); static void grow(detail::node_construction_info_t info, blt::size_t min_depth, blt::size_t max_depth);
static void brett_grow(detail::node_construction_info_t info, blt::size_t min_depth, blt::size_t max_depth);
static void full(detail::node_construction_info_t info, blt::size_t depth); static void full(detail::node_construction_info_t info, blt::size_t depth);

View File

@ -52,13 +52,12 @@ namespace fb
case tree_init_t::GROW: case tree_init_t::GROW:
grow({tree, tree_info}, min_depth, max_depth); grow({tree, tree_info}, min_depth, max_depth);
break; break;
case tree_init_t::BRETT_GROW:
brett_grow({tree, tree_info}, min_depth, max_depth);
break;
case tree_init_t::FULL: case tree_init_t::FULL:
full({tree, tree_info}, tree_info.engine.random_long(min_depth, max_depth)); full({tree, tree_info}, tree_info.engine.random_long(min_depth, max_depth));
break; break;
case tree_init_t::RAMPED_HALF_HALF:
break;
case tree_init_t::BRETT_HALF_HALF:
break;
} }
return tree; return tree;
@ -136,7 +135,7 @@ namespace fb
return info.tree.alloc.template emplace<detail::node_t>(func, info.tree.alloc); return info.tree.alloc.template emplace<detail::node_t>(func, info.tree.alloc);
} }
void tree_t::grow(detail::node_construction_info_t info, blt::size_t min_depth, blt::size_t max_depth) void tree_t::brett_grow(detail::node_construction_info_t info, blt::size_t min_depth, blt::size_t max_depth)
{ {
using namespace detail; using namespace detail;
std::stack<std::pair<node_t*, blt::size_t>> stack; std::stack<std::pair<node_t*, blt::size_t>> stack;
@ -209,5 +208,55 @@ namespace fb
} }
} }
void tree_t::grow(detail::node_construction_info_t info, blt::size_t min_depth, blt::size_t max_depth)
{
using namespace detail;
std::stack<std::pair<node_t*, blt::size_t>> stack;
stack.emplace(info.tree.root, 0);
while (!stack.empty())
{
auto top = stack.top();
auto* node = top.first;
auto depth = top.second;
stack.pop();
const auto& allowed_types = info.types.get_function_allowed_arguments(node->type.getFunction());
// we need to make sure there is at least one non-terminal generation, until we hit the min height
bool has_one_non_terminal = false;
for (blt::size_t i = 0; i < node->type.argc(); i++)
{
type_id type_category = allowed_types[i];
if (depth < min_depth && !has_one_non_terminal)
{
// make sure we have at least min depth possible by using at least one non terminal
node->children[i] = allocate_non_terminal(info, type_category);
has_one_non_terminal = true;
} else if (depth >= max_depth)
{
// if we are above the max_height select only terminals
node->children[i] = allocate_terminal(info, type_category);
} else
{
const auto& non_terminals = info.types.get_non_terminals(type_category);
const auto& terminals = info.types.get_terminals(type_category);
auto index = info.engine.random_long(0, terminals.size() + non_terminals.size());
function_id selection;
if (index >= non_terminals.size())
selection = terminals[index - non_terminals.size()];
else
selection = non_terminals[index];
func_t func(info.types.get_function_argc(selection), info.types.get_function(selection), type_category, selection);
if (const auto& func_init = info.types.get_function_initializer(selection))
func_init.value()(func);
node->children[i] = info.tree.alloc.template emplace<detail::node_t>(func, info.tree.alloc);
}
// node has children that need populated
if (node->children[i]->type.argc() != 0)
stack.emplace(node->children[i], depth + 1);
}
}
}
} }