diff --git a/include/functions.h b/include/functions.h index 37a918a..0095899 100644 --- a/include/functions.h +++ b/include/functions.h @@ -119,6 +119,16 @@ void f_xor(ARGS); void f_if(ARGS); +void f_equ(ARGS); + +void f_lt(ARGS); + +void f_gt(ARGS); + +void f_lte(ARGS); + +void f_gte(ARGS); + /* * Define function enums / lists */ @@ -145,6 +155,12 @@ void f_if(ARGS); FUNC_DEFINE(AND, 2, 2, f_and, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \ FUNC_DEFINE(XOR, 2, 2, f_xor, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \ FUNC_DEFINE(IF, 3, 3, f_if, FUNC_ALLOW_BOOL, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \ + FUNC_DEFINE(EQU, 2, 2, f_equ, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \ + FUNC_DEFINE(LT, 2, 2, f_lt, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \ + FUNC_DEFINE(GT, 2, 2, f_gt, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \ + FUNC_DEFINE(LTE, 2, 2, f_lte, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \ + FUNC_DEFINE(GTE, 2, 2, f_gte, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) + #undef FUNC_ALLOW_ANY #undef FUNC_ALLOW_NONE @@ -185,7 +201,8 @@ static inline constexpr blt::i32 MAX_ARGS = std::max({FUNC_FUNCTIONS}); static inline const allowed_funcs NAME{__VA_ARGS__}; DEF_FUNC_LIST(FUNC_ALLOW_ANY, FUNC_FUNCTIONS); DEF_FUNC_LIST(FUNC_ALLOW_NONE,); -DEF_FUNC_LIST(FUNC_ALLOW_BOOL, function_t::OR, function_t::AND, function_t::XOR); +DEF_FUNC_LIST(FUNC_ALLOW_BOOL, function_t::OR, function_t::AND, function_t::XOR, function_t::EQU, function_t::GT, function_t::LT, function_t::GTE, + function_t::LTE); DEF_FUNC_LIST(FUNC_ALLOW_COORD, function_t::X, function_t::Y); DEF_FUNC_LIST(FUNC_ALLOW_SCALAR, function_t::SCALAR); DEF_FUNC_LIST(FUNC_ALLOW_SCALAR_COORD, function_t::SCALAR, function_t::X, function_t::Y); @@ -244,6 +261,7 @@ inline static allowed_funcs intersection_comp(const allowed_funcs diff --git a/include/gp.h b/include/gp.h index f5276e7..fbeb29e 100644 --- a/include/gp.h +++ b/include/gp.h @@ -50,7 +50,15 @@ struct node void populate_node(size_t i, std::mt19937_64& engine, const allowed_funcs& allowed_args, bool use_terminal); + std::string get_type_name(); + void print_tree(); + + void reset_children() + { + for (size_t i = 0; i < argc; i++) + sub_nodes[i]->img.reset(); + } public: explicit node(function_t type): type(type) diff --git a/src/functions.cpp b/src/functions.cpp index d0474cd..7c74cb0 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -22,6 +22,11 @@ #include #include +bool f_comp(float a, float b) +{ + return std::fabs(a - b) < std::numeric_limits::epsilon(); +} + #define FUNCTION_COORD() \ int xi = static_cast(x); \ int yi = static_cast(y); @@ -225,14 +230,72 @@ void f_if(image& img, float x, float y, blt::size_t argc, const image** argv, co GET_IMAGE(i2, 1); GET_IMAGE(i3, 2); - constexpr float SCALE = 0.1; - - if (i1.x() > SCALE || i1.x() < -SCALE) + if (!f_comp(i1.x(), 0)) img.set(i2, xi, yi); else img.set(i3, xi, yi); } +void f_equ(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data) +{ + FUNCTION_COORD(); + GET_IMAGE(i1, 0); + GET_IMAGE(i2, 1); + + if (f_comp(i1.x(), i2.x()) && f_comp(i1.y(), i2.y()) && f_comp(i1.z(), i2.z())) + img.set({1,1,1}, xi, yi); + else + img.set({0,0,0}, xi, yi); +} + +void f_lt(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data) +{ + FUNCTION_COORD(); + GET_IMAGE(i1, 0); + GET_IMAGE(i2, 1); + + if (i1.x() < i2.x() && i1.y() < i2.y() && i1.z() < i2.z()) + img.set({1,1,1}, xi, yi); + else + img.set({0,0,0}, xi, yi); +} + +void f_gt(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data) +{ + FUNCTION_COORD(); + GET_IMAGE(i1, 0); + GET_IMAGE(i2, 1); + + if (i1.x() > i2.x() && i1.y() > i2.y() && i1.z() > i2.z()) + img.set({1,1,1}, xi, yi); + else + img.set({0,0,0}, xi, yi); +} + +void f_lte(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data) +{ + FUNCTION_COORD(); + GET_IMAGE(i1, 0); + GET_IMAGE(i2, 1); + + if (i1.x() <= i2.x() && i1.y() <= i2.y() && i1.z() <= i2.z()) + img.set({1,1,1}, xi, yi); + else + img.set({0,0,0}, xi, yi); +} + +void f_gte(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data) +{ + FUNCTION_COORD(); + GET_IMAGE(i1, 0); + GET_IMAGE(i2, 1); + + if (i1.x() >= i2.x() && i1.y() >= i2.y() && i1.z() >= i2.z()) + img.set({1,1,1}, xi, yi); + else + img.set({0,0,0}, xi, yi); +} + double on_data(const double* data, blt::size_t len) { const static float NEGATION = 0; diff --git a/src/gp.cpp b/src/gp.cpp index c14bdeb..49e16e2 100644 --- a/src/gp.cpp +++ b/src/gp.cpp @@ -105,29 +105,89 @@ void node::populate_node(size_t i, std::mt19937_64& engine, const allowed_funcs< } } -void node::print_tree() +std::string node::get_type_name() { if (argc > 0) - std::cout << "("; - if (argc > 0) - std::cout << function_name_map[to_underlying(type)] << " "; + return function_name_map[to_underlying(type)]; else { if (type == function_t::SCALAR) { evaluate(); - std::cout << img->get().x() << " "; + return std::to_string(img->get().x()); } else if (type == function_t::COLOR) { evaluate(); - std::cout << '{' << img->get().x() << ", " << img->get().y() << ", " << img->get().z() << "} "; + return '{' + std::to_string(img->get().x()) + ", " + std::to_string(img->get().y()) + ", " + std::to_string(img->get().z()) + "}"; } else - std::cout << function_name_map[to_underlying(type)] << " "; + return function_name_map[to_underlying(type)]; } - for (size_t i = 0; i < argc; i++) - sub_nodes[i]->print_tree(); - if (argc > 0) - std::cout << ") "; +} + +void node::print_tree() +{ + struct stack_info + { + node* n; + blt::i64 layer = 0; + }; + std::stack> nodes; + std::vector stack_nodes; + nodes.emplace(0, this); + + while (!nodes.empty()) + { + auto top = nodes.top(); + stack_nodes.push_back({top.second, top.first}); + nodes.pop(); + for (size_t i = 0; i < top.second->argc; i++) + nodes.emplace(top.first + 1, top.second->sub_nodes[i]); + } + + for (auto e : blt::enumerate(stack_nodes)) + { + auto i = e.first; + auto& v = e.second; + std::cout << std::endl; + for (blt::i64 j = 0; j < v.layer; j++) + std::cout << "| "; + if (v.n->argc != 0) + { + std::cout << "("; + } + std::cout << v.n->get_type_name(); + if (i + 1 < stack_nodes.size()) + { + auto& n = stack_nodes[i + 1]; + if (n.layer < v.layer) + { + //std::cout << " "; +// if (v.layer - n.layer > 2) +// { + for (auto j = v.layer - 1; j >= n.layer; j--) + { + std::cout << std::endl; + for (blt::i64 k = 0; k < j; k++) + { + std::cout << "| "; + } + std::cout << ")"; + } +// } + } else + std::cout << " "; + } else + { + for (auto j = v.layer - 1; j >= 0; j--) + { + std::cout << std::endl; + for (blt::i64 k = 0; k < j; k++) + std::cout << "| "; + std::cout << ")"; + } + } + } + std::cout << std::endl; } node* node::construct_random_tree(blt::size_t max_depth) @@ -170,10 +230,15 @@ void node::evaluate() std::array sub_node_images{nullptr}; for (size_t i = 0; i < argc; i++) { - BLT_ASSERT(sub_nodes[i] != nullptr && sub_nodes[i]->img.has_value() && "Node must have evaluated children!"); + BLT_ASSERT_MSG(sub_nodes[i] != nullptr && sub_nodes[i]->img.has_value() && "Node must have evaluated children!", + ("Failed at arg: " + std::to_string(i) + " with type: " + function_name_map[to_underlying(type)] + " child type: " + + function_name_map[to_underlying(sub_nodes[i]->type)]).c_str()); sub_node_images[i] = &sub_nodes[i]->img.value(); } -#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) case function_t::NAME: { \ +#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) case function_t::NAME: { \ + if (function_t::NAME == function_t::IF) { \ + std::cout << "__:" << function_name_map[to_underlying(this->sub_nodes[0]->type)] << std::endl; \ + }\ if (FUNC_ALLOW_TERMINALS_SET.contains(function_t::NAME)){ \ FUNC(img.value(), 0, 0, argc, const_cast(sub_node_images.data()), data); \ } else { \ @@ -194,6 +259,7 @@ void node::evaluate() break; } #undef FUNC_DEFINE + reset_children(); } node::node(const node& copy) @@ -216,8 +282,23 @@ node* node::clone() void node::evaluate_tree() { - //std::stack> silly; - for (size_t i = 0; i < argc; i++) - sub_nodes[i]->evaluate_tree(); - evaluate(); + std::stack nodes; + std::stack node_stack; + + nodes.push(this); + + while (!nodes.empty()) + { + auto* top = nodes.top(); + node_stack.push(top); + nodes.pop(); + for (size_t i = 0; i < top->argc; i++) + nodes.push(top->sub_nodes[i]); + } + + while (!node_stack.empty()) + { + node_stack.top()->evaluate(); + node_stack.pop(); + } } diff --git a/src/main.cpp b/src/main.cpp index 9750d94..7809aac 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,6 +11,7 @@ #include "imgui.h" #include "extern.h" #include "blt/std/format.h" +#include "blt/profiling/profiler_v2.h" #include #include #include @@ -459,6 +460,10 @@ void update(std::int32_t w, std::int32_t h) int main() { +// auto& funcs = function_arg_allowed_map[to_underlying(function_t::IF)]; +// for (auto v : blt::enumerate(funcs)) +// for (auto f : v.second) +// std::cout << "arg " << v.first << ": " << function_name_map[to_underlying(f)] << std::endl; //shapiro_test_run(); blt::gfx::init(blt::gfx::window_data{"Window of GP test", init, update}.setSyncInterval(1)); global_matrices.cleanup();