himm
parent
2cc0814800
commit
6751127608
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
project(lilfbtf5 VERSION 0.1.27)
|
project(lilfbtf5 VERSION 0.1.28)
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -23,7 +23,12 @@
|
||||||
|
|
||||||
namespace fb
|
namespace fb
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class gp_system_t
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //LILFBTF5_SYSTEM_H
|
#endif //LILFBTF5_SYSTEM_H
|
||||||
|
|
|
@ -109,6 +109,13 @@ namespace fb
|
||||||
alloc.deallocate(children, type.argc());
|
alloc.deallocate(children, type.argc());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct node_helper_t
|
||||||
|
{
|
||||||
|
blt::bump_allocator<blt::BLT_2MB_SIZE, false>& alloc;
|
||||||
|
random& engine;
|
||||||
|
type_engine_t& types;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class tree_t
|
class tree_t
|
||||||
|
@ -120,10 +127,17 @@ namespace fb
|
||||||
|
|
||||||
inline blt::bump_allocator<blt::BLT_2MB_SIZE, false>& get_allocator()
|
inline blt::bump_allocator<blt::BLT_2MB_SIZE, false>& get_allocator()
|
||||||
{ return alloc; }
|
{ return alloc; }
|
||||||
|
|
||||||
|
static detail::node_t* allocate_non_terminal(detail::node_helper_t details, type_id type);
|
||||||
|
static detail::node_t* allocate_non_terminal_restricted(detail::node_helper_t details, type_id type);
|
||||||
|
|
||||||
|
static detail::node_t* allocate_terminal(detail::node_helper_t details, type_id type);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit tree_t(type_engine_t& types);
|
explicit tree_t(type_engine_t& types);
|
||||||
|
|
||||||
static tree_t make_tree(type_engine_t& types, random& engine, blt::size_t min_height, blt::size_t max_height, std::optional<type_id> starting_type = {});
|
static tree_t make_tree(type_engine_t& types, random& engine, blt::size_t min_height, blt::size_t max_height,
|
||||||
|
std::optional<type_id> starting_type = {});
|
||||||
|
|
||||||
std::pair<blt::unsafe::any_t, type_id> evaluate();
|
std::pair<blt::unsafe::any_t, type_id> evaluate();
|
||||||
};
|
};
|
||||||
|
|
66
src/tree.cpp
66
src/tree.cpp
|
@ -70,33 +70,26 @@ namespace fb
|
||||||
const auto& terminals = types.get_terminals(type_category);
|
const auto& terminals = types.get_terminals(type_category);
|
||||||
const auto& non_terminals = types.get_non_terminals(type_category);
|
const auto& non_terminals = types.get_non_terminals(type_category);
|
||||||
|
|
||||||
if (depth < max_height)
|
|
||||||
stack.emplace(node->children[i], depth + 1);
|
|
||||||
|
|
||||||
if (depth < min_height && !has_one_non_terminal)
|
if (depth < min_height && !has_one_non_terminal)
|
||||||
{
|
{
|
||||||
|
// make sure we have at least min height possible by using at least one non terminal
|
||||||
function_id selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)];
|
function_id selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)];
|
||||||
func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection);
|
func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection);
|
||||||
if (const auto& func_init = types.get_function_initializer(selection))
|
if (const auto& func_init = types.get_function_initializer(selection))
|
||||||
func_init.value()(func);
|
func_init.value()(func);
|
||||||
node->children[i] = tree.alloc.template emplace<node_t>(func, tree.alloc);
|
node->children[i] = tree.alloc.template emplace<node_t>(func, tree.alloc);
|
||||||
has_one_non_terminal = true;
|
has_one_non_terminal = true;
|
||||||
continue;
|
} else if (depth >= max_height)
|
||||||
}
|
|
||||||
|
|
||||||
if (depth >= max_height)
|
|
||||||
{
|
{
|
||||||
|
// if we are above the max_height select only terminals
|
||||||
function_id selection = terminals[engine.random_long(0, terminals.size() - 1)];
|
function_id selection = terminals[engine.random_long(0, terminals.size() - 1)];
|
||||||
func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection);
|
func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection);
|
||||||
if (const auto& func_init = types.get_function_initializer(selection))
|
if (const auto& func_init = types.get_function_initializer(selection))
|
||||||
func_init.value()(func);
|
func_init.value()(func);
|
||||||
node->children[i] = tree.alloc.template emplace<node_t>(func, tree.alloc);
|
node->children[i] = tree.alloc.template emplace<node_t>(func, tree.alloc);
|
||||||
continue;
|
} else if (engine.choice())
|
||||||
}
|
|
||||||
|
|
||||||
if (engine.choice())
|
|
||||||
{
|
{
|
||||||
// use full() method
|
// otherwise select between use full() method
|
||||||
function_id selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)];
|
function_id selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)];
|
||||||
func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection);
|
func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection);
|
||||||
if (const auto& func_init = types.get_function_initializer(selection))
|
if (const auto& func_init = types.get_function_initializer(selection))
|
||||||
|
@ -104,10 +97,10 @@ namespace fb
|
||||||
node->children[i] = tree.alloc.template emplace<node_t>(func, tree.alloc);
|
node->children[i] = tree.alloc.template emplace<node_t>(func, tree.alloc);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// use grow() method, meaning select choice again
|
// and use grow() method, meaning select choice again
|
||||||
if (engine.choice())
|
if (engine.choice())
|
||||||
{
|
{
|
||||||
// use non-terminals
|
// to use non-terminals
|
||||||
function_id selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)];
|
function_id selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)];
|
||||||
func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection);
|
func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection);
|
||||||
if (const auto& func_init = types.get_function_initializer(selection))
|
if (const auto& func_init = types.get_function_initializer(selection))
|
||||||
|
@ -115,7 +108,7 @@ namespace fb
|
||||||
node->children[i] = tree.alloc.template emplace<node_t>(func, tree.alloc);
|
node->children[i] = tree.alloc.template emplace<node_t>(func, tree.alloc);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// use terminals
|
// or use terminals
|
||||||
function_id selection = terminals[engine.random_long(0, terminals.size() - 1)];
|
function_id selection = terminals[engine.random_long(0, terminals.size() - 1)];
|
||||||
func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection);
|
func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection);
|
||||||
if (const auto& func_init = types.get_function_initializer(selection))
|
if (const auto& func_init = types.get_function_initializer(selection))
|
||||||
|
@ -123,6 +116,9 @@ namespace fb
|
||||||
node->children[i] = tree.alloc.template emplace<node_t>(func, tree.alloc);
|
node->children[i] = tree.alloc.template emplace<node_t>(func, tree.alloc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// node has children that need populated
|
||||||
|
if (node->children[i]->type.argc() != 0)
|
||||||
|
stack.emplace(node->children[i], depth + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,5 +151,45 @@ namespace fb
|
||||||
return {root->type.getValue(), root->type.getType()};
|
return {root->type.getValue(), root->type.getType()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detail::node_t* tree_t::allocate_non_terminal(detail::node_helper_t details, type_id type)
|
||||||
|
{
|
||||||
|
const auto& non_terminals = details.types.get_non_terminals(type);
|
||||||
|
function_id selection = non_terminals[details.engine.random_long(0, non_terminals.size() - 1)];
|
||||||
|
func_t func(details.types.get_function_argc(selection), details.types.get_function(selection), type, selection);
|
||||||
|
if (const auto& func_init = details.types.get_function_initializer(selection))
|
||||||
|
func_init.value()(func);
|
||||||
|
return details.alloc.template emplace<detail::node_t>(func, details.alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
detail::node_t* tree_t::allocate_terminal(detail::node_helper_t details, type_id type)
|
||||||
|
{
|
||||||
|
const auto& terminals = details.types.get_terminals(type);
|
||||||
|
|
||||||
|
// if we cannot allocate a terminal, we need to allocate a non-terminal in hopes of finding a closing path
|
||||||
|
// for example bools might not have an ending terminal, it doesn't make sense to.
|
||||||
|
if (terminals.empty())
|
||||||
|
return allocate_non_terminal_restricted(details, type);
|
||||||
|
|
||||||
|
function_id selection = terminals[details.engine.random_long(0, terminals.size() - 1)];
|
||||||
|
func_t func(details.types.get_function_argc(selection), details.types.get_function(selection), type, selection);
|
||||||
|
if (const auto& func_init = details.types.get_function_initializer(selection))
|
||||||
|
func_init.value()(func);
|
||||||
|
return details.alloc.template emplace<detail::node_t>(func, details.alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
detail::node_t* tree_t::allocate_non_terminal_restricted(detail::node_helper_t details, type_id type)
|
||||||
|
{
|
||||||
|
const auto& non_terminals = details.types.get_non_terminals(type);
|
||||||
|
function_id selection = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func_t func(details.types.get_function_argc(selection), details.types.get_function(selection), type, selection);
|
||||||
|
if (const auto& func_init = details.types.get_function_initializer(selection))
|
||||||
|
func_init.value()(func);
|
||||||
|
return details.alloc.template emplace<detail::node_t>(func, details.alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -39,7 +39,7 @@ namespace fb
|
||||||
all_non_terminals.emplace_back(tid, id);
|
all_non_terminals.emplace_back(tid, id);
|
||||||
function_argc.insert(id, argc);
|
function_argc.insert(id, argc);
|
||||||
if (auto& init = initializer)
|
if (auto& init = initializer)
|
||||||
function_initializer.insert(id, init.value());
|
function_initializer.insert({id, init.value()});
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ namespace fb
|
||||||
terminals.at(tid).push_back(id);
|
terminals.at(tid).push_back(id);
|
||||||
function_argc.insert(id, 0);
|
function_argc.insert(id, 0);
|
||||||
if (auto& init = initializer)
|
if (auto& init = initializer)
|
||||||
function_initializer.insert(id, init.value());
|
function_initializer.insert({id, init.value()});
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue