From 0ecfa3750cc823691f075dc3bcbab7c1692535a0 Mon Sep 17 00:00:00 2001 From: Brett Date: Fri, 21 Jun 2024 22:04:57 -0400 Subject: [PATCH] cleanup and structure --- CMakeLists.txt | 2 +- examples/main.cpp | 30 ++--- include/blt/gp/fwdecl.h | 11 +- include/blt/gp/generators.h | 49 ++++++++ include/blt/gp/operations.h | 122 ++++++++++++++++++++ include/blt/gp/program.h | 205 +++++---------------------------- include/blt/gp/tree.h | 47 ++++++++ include/blt/gp/typesystem.h | 96 +++++++++++++++ lib/blt | 2 +- src/generators.cpp | 34 ++++++ src/{gp.cpp => typesystem.cpp} | 8 +- 11 files changed, 405 insertions(+), 201 deletions(-) create mode 100644 include/blt/gp/generators.h create mode 100644 include/blt/gp/operations.h create mode 100644 include/blt/gp/tree.h create mode 100644 include/blt/gp/typesystem.h create mode 100644 src/generators.cpp rename src/{gp.cpp => typesystem.cpp} (92%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ac47d6..17b1998 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.0.24) +project(blt-gp VERSION 0.0.25) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) diff --git a/examples/main.cpp b/examples/main.cpp index 858aa16..c01a72b 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -107,6 +107,7 @@ void test() tree_generator.push(op::LIT); } + // print out the tree / operators for (const auto& v : operations) std::cout << to_string(v) << " "; std::cout << std::endl; @@ -270,37 +271,20 @@ void test() std::cout << process.top() << std::endl; } -// -//struct silly -//{ -// long nyah = 50; -// int bruh = 10; -// -// friend std::ostream& operator<<(std::ostream& stream, const silly& silly) -// { -// stream << "[" << silly.nyah << " " << silly.bruh << "]"; -// return stream; -// } -//}; -// -//struct large -//{ -// unsigned char data[2048]; -//}; -// -//struct super_large -//{ -// unsigned char data[9582]; -//}; blt::gp::type_system type_system; blt::gp::gp_program program(type_system); +std::random_device dev; +std::mt19937_64 engine{dev()}; blt::gp::operation_t add([](float a, float b) { return a + b; }); blt::gp::operation_t sub([](float a, float b) { return a - b; }); blt::gp::operation_t mul([](float a, float b) { return a * b; }); blt::gp::operation_t pro_div([](float a, float b) { return b == 0 ? 0.0f : a / b; }); -blt::gp::operation_t lit([]() { return 0.0f; }); +blt::gp::operation_t lit([]() { + static std::uniform_real_distribution dist(-32000, 32000); + return dist(engine); +}); int main() diff --git a/include/blt/gp/fwdecl.h b/include/blt/gp/fwdecl.h index e452ac8..81b6b33 100644 --- a/include/blt/gp/fwdecl.h +++ b/include/blt/gp/fwdecl.h @@ -19,9 +19,18 @@ #ifndef BLT_GP_FWDECL_H #define BLT_GP_FWDECL_H + namespace blt::gp { - + + class gp_program; + class type; + class type_system; + + class tree_generator_t; + class grow_generator_t; + class full_generator_t; + } #endif //BLT_GP_FWDECL_H diff --git a/include/blt/gp/generators.h b/include/blt/gp/generators.h new file mode 100644 index 0000000..f20dbf2 --- /dev/null +++ b/include/blt/gp/generators.h @@ -0,0 +1,49 @@ +#pragma once +/* + * Copyright (C) 2024 Brett Terpstra + * + * This program 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 + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifndef BLT_GP_GENERATORS_H +#define BLT_GP_GENERATORS_H + +#include +#include + +namespace blt::gp +{ + + // base class for any kind of tree generator + class tree_generator_t + { + public: + virtual tree_t generate(gp_program& program, blt::size_t min_depth, blt::size_t max_depth) = 0; + }; + + class grow_generator_t : public tree_generator_t + { + public: + tree_t generate(gp_program& program, blt::size_t min_depth, blt::size_t max_depth) final; + }; + + class full_generator_t : public tree_generator_t + { + public: + tree_t generate(gp_program& program, blt::size_t min_depth, blt::size_t max_depth) final; + }; + +} + +#endif //BLT_GP_GENERATORS_H diff --git a/include/blt/gp/operations.h b/include/blt/gp/operations.h new file mode 100644 index 0000000..c2a9556 --- /dev/null +++ b/include/blt/gp/operations.h @@ -0,0 +1,122 @@ +#pragma once +/* + * Copyright (C) 2024 Brett Terpstra + * + * This program 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 + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifndef BLT_GP_OPERATIONS_H +#define BLT_GP_OPERATIONS_H + +#include +#include +#include +#include + +namespace blt::gp +{ + template + class operation_t; + + template + class operation_t + { + public: + using function_t = std::function; + + constexpr operation_t(const operation_t& copy) = default; + + constexpr operation_t(operation_t&& move) = default; + + template + constexpr explicit operation_t(const Functor& functor): func(functor) + {} + + template + [[nodiscard]] inline constexpr static blt::size_t getByteOffset() + { + blt::size_t offset = 0; + blt::size_t current_index = 0; + ((offset += (current_index++ > index ? stack_allocator::aligned_size() : 0)), ...); + return offset; + } + + template + inline constexpr Return exec_sequence_to_indices(stack_allocator& allocator, std::integer_sequence) const + { + // expands Args and indices, providing each argument with its index calculating the current argument byte offset + return func(allocator.from(getByteOffset())...); + } + + [[nodiscard]] constexpr inline Return operator()(stack_allocator& allocator) const + { + if constexpr (sizeof...(Args) == 0) + { + return func(); + } else + { + constexpr auto seq = std::make_integer_sequence(); + Return ret = exec_sequence_to_indices(allocator, seq); + allocator.call_destructors(); + allocator.pop_bytes((stack_allocator::aligned_size() + ...)); + return ret; + } + } + + [[nodiscard]] std::function make_callable() const + { + return [this](stack_allocator& values) { + values.push(this->operator()(values)); + }; + } + + [[nodiscard]] inline constexpr blt::size_t get_argc() const + { + return sizeof...(Args); + } + + private: + function_t func; + }; + + template + class operation_t : public operation_t + { + public: + using operation_t::operation_t; + }; + + template + operation_t(Lambda) -> operation_t; + + template + operation_t(Return (*)(Args...)) -> operation_t; + +// templat\e +// operation_t make_operator(Return (Class::*)(Args...) const lambda) +// { +// // https://ventspace.wordpress.com/2022/04/11/quick-snippet-c-type-trait-templates-for-lambda-details/ +// } +// +// template +// operation_t make_operator(Lambda&& lambda) +// { +// return operation_t(std::forward(lambda)); +// } +// +// template +// operation(std::function) -> operation; +} + +#endif //BLT_GP_OPERATIONS_H diff --git a/include/blt/gp/program.h b/include/blt/gp/program.h index 87a4722..285d47e 100644 --- a/include/blt/gp/program.h +++ b/include/blt/gp/program.h @@ -28,187 +28,20 @@ #include #include #include + #include #include #include #include #include #include +#include +#include +#include #include namespace blt::gp { - template - struct integer_type - { - T id; - - integer_type() = default; - - integer_type(T id): id(id) // NOLINT - {} - - inline operator T() const // NOLINT - { - return id; - } - }; - - struct operator_id : integer_type - { - using integer_type::integer_type; - }; - - struct type_id : integer_type - { - using integer_type::integer_type; - }; - - class type - { - public: - type() = default; - - template - static type make_type(type_id id) - { - return type(sizeof(T), id, blt::type_string()); - } - - [[nodiscard]] blt::size_t size() const - { - return size_; - } - - [[nodiscard]] type_id id() const - { - return id_; - } - - [[nodiscard]] std::string_view name() const - { - return name_; - } - - private: - type(size_t size, type_id id, std::string_view name): size_(size), id_(id), name_(name) - {} - - blt::size_t size_{}; - type_id id_{}; - std::string name_{}; - }; - - class type_system - { - public: - type_system() = default; - - template - inline type register_type() - { - types.insert({blt::type_string_raw(), type::make_type(types.size())}); - return types[blt::type_string_raw()]; - } - - template - inline type get_type() - { - return types[blt::type_string_raw()]; - } - - private: - blt::hashmap_t types; - }; - - template - class operation_t; - - template - class operation_t - { - public: - using function_t = std::function; - - constexpr operation_t(const operation_t& copy) = default; - - constexpr operation_t(operation_t&& move) = default; - - template - constexpr explicit operation_t(const Functor& functor): func(functor) - {} - - template - [[nodiscard]] inline constexpr static blt::size_t getByteOffset() - { - blt::size_t offset = 0; - blt::size_t current_index = 0; - ((offset += (current_index++ > index ? stack_allocator::aligned_size() : 0)), ...); - return offset; - } - - template - inline constexpr Return exec_sequence_to_indices(stack_allocator& allocator, std::integer_sequence) const - { - // expands Args and indices, providing each argument with its index calculating the current argument byte offset - return func(allocator.from(getByteOffset())...); - } - - [[nodiscard]] constexpr inline Return operator()(stack_allocator& allocator) const - { - if constexpr (sizeof...(Args) == 0) - return func(); - constexpr auto seq = std::make_integer_sequence(); - Return ret = exec_sequence_to_indices(allocator, seq); - allocator.call_destructors(); - allocator.pop_bytes((stack_allocator::aligned_size() + ...)); - return ret; - } - - [[nodiscard]] std::function make_callable() const - { - return [this](stack_allocator& values) { - values.push(this->operator()(values)); - }; - } - - [[nodiscard]] blt::size_t get_argc() const - { - return sizeof...(Args); - } - - private: - function_t func; - }; - - template - class operation_t : public operation_t - { - public: - using operation_t::operation_t; - }; - - template - operation_t(Lambda) -> operation_t; - - template - operation_t(Return (*)(Args...)) -> operation_t; - -// templat\e -// operation_t make_operator(Return (Class::*)(Args...) const lambda) -// { -// // https://ventspace.wordpress.com/2022/04/11/quick-snippet-c-type-trait-templates-for-lambda-details/ -// } -// -// template -// operation_t make_operator(Lambda&& lambda) -// { -// return operation_t(std::forward(lambda)); -// } -// -// template -// operation(std::function) -> operation; - class gp_program { public: @@ -226,14 +59,38 @@ namespace blt::gp (argument_types[operator_index].push_back(system.get_type()), ...); operators.push_back(op.make_callable()); } + + [[nodiscard]] inline type_system& get_typesystem() + { + return system; + } + + void generate_tree(); + + inline operator_id select_terminal(type_id id, std::mt19937_64& engine) + { + std::uniform_int_distribution dist(0, terminals[id].size() - 1); + return terminals[id][dist(engine)]; + } + + inline operator_id select_non_terminal(type_id id, std::mt19937_64& engine) + { + std::uniform_int_distribution dist(0, non_terminals[id].size() - 1); + return non_terminals[id][dist(engine)]; + } + + inline std::vector& get_argument_types(operator_id id) + { + return argument_types[id]; + } private: type_system system; blt::gp::stack_allocator alloc; // indexed from return TYPE ID, returns index of operator - blt::expanding_buffer> terminals; - blt::expanding_buffer> non_terminals; - // indexed from OPERATOR NUMBER + blt::expanding_buffer> terminals; + blt::expanding_buffer> non_terminals; + // indexed from OPERATOR ID (operator number) blt::expanding_buffer> argument_types; std::vector> operators; }; diff --git a/include/blt/gp/tree.h b/include/blt/gp/tree.h new file mode 100644 index 0000000..6859f19 --- /dev/null +++ b/include/blt/gp/tree.h @@ -0,0 +1,47 @@ +#pragma once +/* + * Copyright (C) 2024 Brett Terpstra + * + * This program 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 + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifndef BLT_GP_TREE_H +#define BLT_GP_TREE_H + +#include +#include +#include + +namespace blt::gp +{ + class tree_t + { + public: + [[nodiscard]] inline std::vector& get_operations() + { + return operations; + } + + [[nodiscard]] inline blt::gp::stack_allocator& get_values() + { + return values; + } + + private: + std::vector operations; + blt::gp::stack_allocator values; + }; +} + +#endif //BLT_GP_TREE_H diff --git a/include/blt/gp/typesystem.h b/include/blt/gp/typesystem.h new file mode 100644 index 0000000..6c3f0d4 --- /dev/null +++ b/include/blt/gp/typesystem.h @@ -0,0 +1,96 @@ +#pragma once +/* + * Copyright (C) 2024 Brett Terpstra + * + * This program 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 + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifndef BLT_GP_TYPESYSTEM_H +#define BLT_GP_TYPESYSTEM_H + +#include +#include +#include + +namespace blt::gp +{ + struct operator_id : integer_type + { + using integer_type::integer_type; + }; + + struct type_id : integer_type + { + using integer_type::integer_type; + }; + + class type + { + public: + type() = default; + + template + static type make_type(type_id id) + { + return type(sizeof(T), id, blt::type_string()); + } + + [[nodiscard]] inline blt::size_t size() const + { + return size_; + } + + [[nodiscard]] inline type_id id() const + { + return id_; + } + + [[nodiscard]] inline std::string_view name() const + { + return name_; + } + + private: + type(size_t size, type_id id, std::string_view name): size_(size), id_(id), name_(name) + {} + + blt::size_t size_{}; + type_id id_{}; + std::string name_{}; + }; + + class type_system + { + public: + type_system() = default; + + template + inline type register_type() + { + types.insert({blt::type_string_raw(), type::make_type(types.size())}); + return types[blt::type_string_raw()]; + } + + template + inline type get_type() + { + return types[blt::type_string_raw()]; + } + + private: + blt::hashmap_t types; + }; +} + +#endif //BLT_GP_TYPESYSTEM_H diff --git a/lib/blt b/lib/blt index 9ad9619..1ca46b9 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit 9ad96191ff91ec7efa6aa142e377201fe81b4c40 +Subproject commit 1ca46b9d7bb9621a2f7d02a9ca1eff99e91e3f1a diff --git a/src/generators.cpp b/src/generators.cpp new file mode 100644 index 0000000..406e039 --- /dev/null +++ b/src/generators.cpp @@ -0,0 +1,34 @@ +/* + * + * Copyright (C) 2024 Brett Terpstra + * + * This program 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 + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ +#include + +namespace blt::gp +{ + + tree_t grow_generator_t::generate(gp_program& program, blt::size_t min_depth, blt::size_t max_depth) + { + tree_t tree; + return tree; + } + + tree_t full_generator_t::generate(gp_program& program, blt::size_t min_depth, blt::size_t max_depth) + { + tree_t tree; + return tree; + } +} \ No newline at end of file diff --git a/src/gp.cpp b/src/typesystem.cpp similarity index 92% rename from src/gp.cpp rename to src/typesystem.cpp index 2a53a88..0190181 100644 --- a/src/gp.cpp +++ b/src/typesystem.cpp @@ -14,4 +14,10 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - */ \ No newline at end of file + */ +#include + +namespace blt::gp +{ + +} \ No newline at end of file