everything broken but code broadly finished
parent
3c467f2b52
commit
b896d07109
|
@ -27,7 +27,7 @@ macro(compile_options target_name)
|
||||||
sanitizers(${target_name})
|
sanitizers(${target_name})
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
project(blt-gp VERSION 0.5.33)
|
project(blt-gp VERSION 0.5.34)
|
||||||
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ blt::gp::prog_config_t config = blt::gp::prog_config_t()
|
||||||
.set_reproduction_chance(0)
|
.set_reproduction_chance(0)
|
||||||
.set_max_generations(50)
|
.set_max_generations(50)
|
||||||
.set_pop_size(500)
|
.set_pop_size(500)
|
||||||
.set_thread_count(0);
|
.set_thread_count(1);
|
||||||
|
|
||||||
int main(int argc, const char** argv)
|
int main(int argc, const char** argv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace blt::gp
|
||||||
void print_args(std::integer_sequence<u64, indices...>)
|
void print_args(std::integer_sequence<u64, indices...>)
|
||||||
{
|
{
|
||||||
BLT_INFO("Arguments:");
|
BLT_INFO("Arguments:");
|
||||||
(BLT_INFO("%ld: %s", indices, blt::type_string<Args>().c_str()), ...);
|
(BLT_INFO("{}: {}", indices, blt::type_string<Args>().c_str()), ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Func, u64... indices, typename... ExtraArgs>
|
template <typename Func, u64... indices, typename... ExtraArgs>
|
||||||
|
|
|
@ -397,7 +397,7 @@ namespace blt::gp
|
||||||
|
|
||||||
void modify_operator(size_t point, operator_id new_id, std::optional<type_id> return_type = {}) const;
|
void modify_operator(size_t point, operator_id new_id, std::optional<type_id> return_type = {}) const;
|
||||||
|
|
||||||
void swap_operators(subtree_point_t point, ptrdiff_t extent, tree_t& other_tree, subtree_point_t other_point, ptrdiff_t other_extent) const;
|
void swap_operators(subtree_point_t point, tree_t& other_tree, subtree_point_t other_point) const;
|
||||||
|
|
||||||
void swap_operators(size_t point, tree_t& other_tree, size_t other_point) const;
|
void swap_operators(size_t point, tree_t& other_tree, size_t other_point) const;
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,8 @@ namespace blt::gp
|
||||||
// this is largely to not break the tests :3
|
// this is largely to not break the tests :3
|
||||||
// it's also to allow for quick setup of a gp program if you don't care how crossover or mutation is handled
|
// it's also to allow for quick setup of a gp program if you don't care how crossover or mutation is handled
|
||||||
static advanced_mutation_t s_mutator;
|
static advanced_mutation_t s_mutator;
|
||||||
static subtree_crossover_t s_crossover;
|
// static subtree_crossover_t s_crossover;
|
||||||
// static one_point_crossover_t s_crossover;
|
static one_point_crossover_t s_crossover;
|
||||||
static ramped_half_initializer_t s_init;
|
static ramped_half_initializer_t s_init;
|
||||||
|
|
||||||
prog_config_t::prog_config_t(): mutator(s_mutator), crossover(s_crossover), pop_initializer(s_init)
|
prog_config_t::prog_config_t(): mutator(s_mutator), crossover(s_crossover), pop_initializer(s_init)
|
||||||
|
|
|
@ -143,225 +143,7 @@ namespace blt::gp
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& p1_operator = p1.get_operator(point1.get_point());
|
c1.manipulate().easy_manipulator().swap_operators(point1, c2, point2);
|
||||||
const auto& p2_operator = p2.get_operator(point2.get_point());
|
|
||||||
|
|
||||||
const auto& p1_info = program.get_operator_info(p1_operator.id());
|
|
||||||
const auto& p2_info = program.get_operator_info(p2_operator.id());
|
|
||||||
|
|
||||||
struct reorder_index_t
|
|
||||||
{
|
|
||||||
size_t index1;
|
|
||||||
size_t index2;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct swap_index_t
|
|
||||||
{
|
|
||||||
size_t p1_index;
|
|
||||||
size_t p2_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
thread_local struct type_resolver_t
|
|
||||||
{
|
|
||||||
tracked_vector<child_t> children_data_p1;
|
|
||||||
tracked_vector<child_t> children_data_p2;
|
|
||||||
hashmap_t<type_id, std::vector<size_t>> missing_p1_types;
|
|
||||||
hashmap_t<type_id, std::vector<size_t>> missing_p2_types;
|
|
||||||
hashset_t<size_t> correct_types;
|
|
||||||
hashset_t<size_t> p1_correct_types;
|
|
||||||
hashset_t<size_t> p2_correct_types;
|
|
||||||
std::vector<reorder_index_t> p1_reorder_types;
|
|
||||||
std::vector<reorder_index_t> p2_reorder_types;
|
|
||||||
std::vector<swap_index_t> swap_types;
|
|
||||||
std::vector<tree_t> temp_trees;
|
|
||||||
|
|
||||||
void print_missing_types()
|
|
||||||
{
|
|
||||||
for (const auto& [id, v] : missing_p1_types)
|
|
||||||
{
|
|
||||||
if (!v.empty())
|
|
||||||
{
|
|
||||||
BLT_INFO("(P1) For type {} missing indexes:", id);
|
|
||||||
for (const auto idx : v)
|
|
||||||
BLT_INFO("\t{}", idx);
|
|
||||||
BLT_INFO("----");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto& [id, v] : missing_p2_types)
|
|
||||||
{
|
|
||||||
if (!v.empty())
|
|
||||||
{
|
|
||||||
BLT_INFO("(P2) For type {} missing indexes:", id);
|
|
||||||
for (const auto idx : v)
|
|
||||||
BLT_INFO("\t{}", idx);
|
|
||||||
BLT_INFO("----");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<size_t> get_p1_index(const type_id& id)
|
|
||||||
{
|
|
||||||
if (!missing_p1_types.contains(id))
|
|
||||||
return {};
|
|
||||||
if (missing_p1_types[id].empty())
|
|
||||||
return {};
|
|
||||||
auto idx = missing_p1_types[id].back();
|
|
||||||
missing_p1_types[id].pop_back();
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<size_t> get_p2_index(const type_id& id)
|
|
||||||
{
|
|
||||||
if (!missing_p2_types.contains(id))
|
|
||||||
return {};
|
|
||||||
if (missing_p2_types[id].empty())
|
|
||||||
return {};
|
|
||||||
auto idx = missing_p2_types[id].back();
|
|
||||||
missing_p2_types[id].pop_back();
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool handled_p1(const size_t index) const
|
|
||||||
{
|
|
||||||
return correct_types.contains(index) || p1_correct_types.contains(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool handled_p2(const size_t index) const
|
|
||||||
{
|
|
||||||
return correct_types.contains(index) || p2_correct_types.contains(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear(gp_program& program)
|
|
||||||
{
|
|
||||||
children_data_p1.clear();
|
|
||||||
children_data_p2.clear();
|
|
||||||
correct_types.clear();
|
|
||||||
p1_correct_types.clear();
|
|
||||||
p2_correct_types.clear();
|
|
||||||
p1_reorder_types.clear();
|
|
||||||
p2_reorder_types.clear();
|
|
||||||
swap_types.clear();
|
|
||||||
for (auto& tree : temp_trees)
|
|
||||||
tree.clear(program);
|
|
||||||
for (auto& [id, v] : missing_p1_types)
|
|
||||||
v.clear();
|
|
||||||
for (auto& [id, v] : missing_p2_types)
|
|
||||||
v.clear();
|
|
||||||
}
|
|
||||||
} resolver;
|
|
||||||
resolver.clear(program);
|
|
||||||
|
|
||||||
auto min_size = std::min(p1_info.argument_types.size(), p2_info.argument_types.size());
|
|
||||||
|
|
||||||
// resolve type information
|
|
||||||
for (size_t i = 0; i < min_size; i++)
|
|
||||||
{
|
|
||||||
if (p1_info.argument_types[i] != p2_info.argument_types[i])
|
|
||||||
{
|
|
||||||
resolver.missing_p1_types[p1_info.argument_types[i].id].push_back(i);
|
|
||||||
resolver.missing_p2_types[p2_info.argument_types[i].id].push_back(i);
|
|
||||||
} else
|
|
||||||
resolver.correct_types.insert(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = min_size; i < p1_info.argument_types.size(); i++)
|
|
||||||
resolver.missing_p1_types[p1_info.argument_types[i].id].push_back(i);
|
|
||||||
|
|
||||||
for (size_t i = min_size; i < p2_info.argument_types.size(); i++)
|
|
||||||
resolver.missing_p2_types[p2_info.argument_types[i].id].push_back(i);
|
|
||||||
|
|
||||||
// if swaping p1 -> p2 and p2 -> p1, we may already have the types we need just in a different order
|
|
||||||
|
|
||||||
// first, make a list of types which can simply be reordered
|
|
||||||
for (size_t i = 0; i < p1_info.argument_types.size(); i++)
|
|
||||||
{
|
|
||||||
if (resolver.correct_types.contains(i))
|
|
||||||
continue;
|
|
||||||
if (auto index = resolver.get_p2_index(p1_info.argument_types[i].id))
|
|
||||||
{
|
|
||||||
resolver.p2_reorder_types.push_back({i, *index});
|
|
||||||
resolver.p2_correct_types.insert(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BLT_DEBUG("Operator C1 {} expects types: ", p1_operator.id());
|
|
||||||
for (const auto [i, type] : enumerate(p1_info.argument_types))
|
|
||||||
BLT_TRACE("{} -> {}", i, type);
|
|
||||||
BLT_DEBUG("Operator C2 {} expects types: ", p2_operator.id());
|
|
||||||
for (const auto [i, type] : enumerate(p2_info.argument_types))
|
|
||||||
BLT_TRACE("{} -> {}", i, type);
|
|
||||||
resolver.print_missing_types();
|
|
||||||
|
|
||||||
for (size_t i = 0; i < p2_info.argument_types.size(); i++)
|
|
||||||
{
|
|
||||||
if (resolver.correct_types.contains(i))
|
|
||||||
continue;
|
|
||||||
if (auto index = resolver.get_p1_index(p2_info.argument_types[i].id))
|
|
||||||
{
|
|
||||||
resolver.p1_reorder_types.push_back({i, *index});
|
|
||||||
resolver.p1_correct_types.insert(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// next we need to figure out which types need to be swapped
|
|
||||||
for (size_t i = 0; i < p1_info.argument_types.size(); i++)
|
|
||||||
{
|
|
||||||
if (resolver.handled_p2(i))
|
|
||||||
continue;
|
|
||||||
if (auto index = resolver.get_p1_index(p1_info.argument_types[i].id))
|
|
||||||
resolver.swap_types.push_back({*index, i});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < p2_info.argument_types.size(); i++)
|
|
||||||
{
|
|
||||||
if (resolver.handled_p1(i))
|
|
||||||
continue;
|
|
||||||
if (auto index = resolver.get_p2_index(p2_info.argument_types[i].id))
|
|
||||||
resolver.swap_types.push_back({i, *index});
|
|
||||||
}
|
|
||||||
|
|
||||||
// now we do the swap
|
|
||||||
p1.find_child_extends(resolver.children_data_p1, point1.get_point(), p1_info.argument_types.size());
|
|
||||||
p2.find_child_extends(resolver.children_data_p2, point2.get_point(), p2_info.argument_types.size());
|
|
||||||
|
|
||||||
for (const auto& [index1, index2] : resolver.p1_reorder_types)
|
|
||||||
{
|
|
||||||
BLT_DEBUG("Reordering in C1: {} -> {}", index1, index2);
|
|
||||||
c1.manipulate().easy_manipulator().swap_subtrees(resolver.children_data_p1[index1], c1, resolver.children_data_p1[index2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& [index1, index2] : resolver.p2_reorder_types)
|
|
||||||
{
|
|
||||||
BLT_DEBUG("Reordering in C2: {} -> {}", index1, index2);
|
|
||||||
c2.manipulate().easy_manipulator().swap_subtrees(resolver.children_data_p2[index1], c2, resolver.children_data_p2[index2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto c1_insert = resolver.children_data_p1.back().end;
|
|
||||||
auto c2_insert = resolver.children_data_p2.back().end;
|
|
||||||
|
|
||||||
for (const auto& [p1_index, p2_index] : resolver.swap_types)
|
|
||||||
{
|
|
||||||
if (p1_index < p1_info.argument_types.size() && p2_index < p2_info.argument_types.size())
|
|
||||||
c1.manipulate().easy_manipulator().swap_subtrees(resolver.children_data_p1[p1_index], c2, resolver.children_data_p2[p2_index]);
|
|
||||||
else if (p1_index < p1_info.argument_types.size() && p2_index >= p2_info.argument_types.size())
|
|
||||||
{
|
|
||||||
BLT_TRACE("(P1 IS UNDER!) Trying to swap P1 {} for P2 {} (Sizes: P1: {} P2: {})", p1_index, p2_index, p1_info.argument_types.size(), p2_info.argument_types.size());
|
|
||||||
BLT_TRACE("Inserting into P2 from P1!");
|
|
||||||
c1.manipulate().easy_manipulator().copy_subtree(resolver.children_data_p1[p1_index], resolver.temp_trees[0]);
|
|
||||||
c1.manipulate().easy_manipulator().delete_subtree(resolver.children_data_p1[p1_index]);
|
|
||||||
c2_insert = c2.manipulate().easy_manipulator().insert_subtree(subtree_point_t{c1_insert}, resolver.temp_trees[0]);
|
|
||||||
} else if (p2_index < p2_info.argument_types.size() && p1_index >= p1_info.argument_types.size())
|
|
||||||
{
|
|
||||||
BLT_TRACE("(P2 IS UNDER!) Trying to swap P1 {} for P2 {} (Sizes: P1: {} P2: {})", p1_index, p2_index, p1_info.argument_types.size(), p2_info.argument_types.size());
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
BLT_WARN("This should be an impossible state!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
c1.manipulate().easy_manipulator().modify_operator(point1.get_point(), p2_operator.id(), p2_info.return_type);
|
|
||||||
c2.manipulate().easy_manipulator().modify_operator(point2.get_point(), p1_operator.id(), p1_info.return_type);
|
|
||||||
|
|
||||||
#if BLT_DEBUG_LEVEL >= 2
|
#if BLT_DEBUG_LEVEL >= 2
|
||||||
if (!c1.check(detail::debug::context_ptr) || !c2.check(detail::debug::context_ptr))
|
if (!c1.check(detail::debug::context_ptr) || !c2.check(detail::debug::context_ptr))
|
||||||
|
|
171
src/tree.cpp
171
src/tree.cpp
|
@ -21,6 +21,7 @@
|
||||||
#include <blt/logging/logging.h>
|
#include <blt/logging/logging.h>
|
||||||
#include <blt/gp/program.h>
|
#include <blt/gp/program.h>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace blt::gp
|
namespace blt::gp
|
||||||
{
|
{
|
||||||
|
@ -36,6 +37,18 @@ namespace blt::gp
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void print_child(child_t child)
|
||||||
|
{
|
||||||
|
BLT_TRACE("\tChild: {} -> {} ( {} )", child.start, child.end, child.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_child_vec(const std::vector<child_t>& children)
|
||||||
|
{
|
||||||
|
BLT_TRACE("Children: ");
|
||||||
|
for (const auto& c : children)
|
||||||
|
print_child(c);
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& create_indent(std::ostream& out, blt::size_t amount, bool pretty_print)
|
std::ostream& create_indent(std::ostream& out, blt::size_t amount, bool pretty_print)
|
||||||
{
|
{
|
||||||
if (!pretty_print)
|
if (!pretty_print)
|
||||||
|
@ -346,6 +359,8 @@ namespace blt::gp
|
||||||
tree->values.copy_to(ptr, size_total);
|
tree->values.copy_to(ptr, size_total);
|
||||||
tree->values.pop_bytes(size_total);
|
tree->values.pop_bytes(size_total);
|
||||||
|
|
||||||
|
BLT_TRACE("Removing Bytes! {} = First {} + Between {} + Last {} + After {}", size_total, size_first, size_between, size_last, size_after);
|
||||||
|
|
||||||
tree->values.copy_from(ptr + size_first + size_between, size_last);
|
tree->values.copy_from(ptr + size_first + size_between, size_last);
|
||||||
tree->values.copy_from(ptr + size_first, size_between);
|
tree->values.copy_from(ptr + size_first, size_between);
|
||||||
tree->values.copy_from(ptr, size_first);
|
tree->values.copy_from(ptr, size_first);
|
||||||
|
@ -597,8 +612,7 @@ namespace blt::gp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void slow_tree_manipulator_t::swap_operators(const subtree_point_t point, const ptrdiff_t extent, tree_t& other_tree, const subtree_point_t other_point,
|
void slow_tree_manipulator_t::swap_operators(const subtree_point_t point, tree_t& other_tree, const subtree_point_t other_point) const
|
||||||
const ptrdiff_t other_extent) const
|
|
||||||
{
|
{
|
||||||
const auto point_info = tree->m_program->get_operator_info(tree->operations[point.get_spoint()].id());
|
const auto point_info = tree->m_program->get_operator_info(tree->operations[point.get_spoint()].id());
|
||||||
const auto other_point_info = tree->m_program->get_operator_info(other_tree.operations[other_point.get_spoint()].id());
|
const auto other_point_info = tree->m_program->get_operator_info(other_tree.operations[other_point.get_spoint()].id());
|
||||||
|
@ -612,10 +626,12 @@ namespace blt::gp
|
||||||
// const auto our_bytes_after = calculate_ephemeral_size(our_end_point_iter, tree->operations.end());
|
// const auto our_bytes_after = calculate_ephemeral_size(our_end_point_iter, tree->operations.end());
|
||||||
// const auto other_bytes_after = calculate_ephemeral_size(other_end_point_iter, other_tree.operations.end());
|
// const auto other_bytes_after = calculate_ephemeral_size(other_end_point_iter, other_tree.operations.end());
|
||||||
|
|
||||||
thread_local struct
|
thread_local struct storage_t
|
||||||
{
|
{
|
||||||
buffer_wrapper_t our_after;
|
tree_t temp;
|
||||||
buffer_wrapper_t other_after;
|
|
||||||
|
buffer_wrapper_t our_after{};
|
||||||
|
buffer_wrapper_t other_after{};
|
||||||
// argument index -> type_id for missing types
|
// argument index -> type_id for missing types
|
||||||
std::vector<std::tuple<size_t, type_id, bool>> our_types;
|
std::vector<std::tuple<size_t, type_id, bool>> our_types;
|
||||||
std::vector<std::tuple<size_t, type_id, bool>> other_types;
|
std::vector<std::tuple<size_t, type_id, bool>> other_types;
|
||||||
|
@ -628,7 +644,12 @@ namespace blt::gp
|
||||||
|
|
||||||
std::vector<type_id> our_current_types;
|
std::vector<type_id> our_current_types;
|
||||||
std::vector<type_id> other_current_types;
|
std::vector<type_id> other_current_types;
|
||||||
} storage;
|
|
||||||
|
explicit storage_t(tree_t tree): temp(std::move(tree))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
} storage{tree_t{*tree->m_program}};
|
||||||
|
storage.temp.clear(*tree->m_program);
|
||||||
storage.our_types.clear();
|
storage.our_types.clear();
|
||||||
storage.other_types.clear();
|
storage.other_types.clear();
|
||||||
storage.our_swaps.clear();
|
storage.our_swaps.clear();
|
||||||
|
@ -657,11 +678,19 @@ namespace blt::gp
|
||||||
storage.our_types.emplace_back(i, point_info.argument_types[i], false);
|
storage.our_types.emplace_back(i, point_info.argument_types[i], false);
|
||||||
storage.other_types.emplace_back(i, other_point_info.argument_types[i], false);
|
storage.other_types.emplace_back(i, other_point_info.argument_types[i], false);
|
||||||
}
|
}
|
||||||
|
storage.our_current_types.emplace_back(point_info.argument_types[i]);
|
||||||
|
storage.other_current_types.emplace_back(other_point_info.argument_types[i]);
|
||||||
}
|
}
|
||||||
for (size_t i = common_size; i < point_info.argument_types.size(); ++i)
|
for (size_t i = common_size; i < point_info.argument_types.size(); ++i)
|
||||||
|
{
|
||||||
storage.our_types.emplace_back(i, point_info.argument_types[i], false);
|
storage.our_types.emplace_back(i, point_info.argument_types[i], false);
|
||||||
|
storage.our_current_types.emplace_back(point_info.argument_types[i]);
|
||||||
|
}
|
||||||
for (size_t i = common_size; i < other_point_info.argument_types.size(); ++i)
|
for (size_t i = common_size; i < other_point_info.argument_types.size(); ++i)
|
||||||
|
{
|
||||||
storage.other_types.emplace_back(i, other_point_info.argument_types[i], false);
|
storage.other_types.emplace_back(i, other_point_info.argument_types[i], false);
|
||||||
|
storage.other_current_types.emplace_back(other_point_info.argument_types[i]);
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto& [index, type, _] : storage.our_types)
|
for (const auto& [index, type, _] : storage.our_types)
|
||||||
{
|
{
|
||||||
|
@ -689,6 +718,8 @@ namespace blt::gp
|
||||||
}
|
}
|
||||||
|
|
||||||
tree->find_child_extends(storage.our_children, point.get_point(), point_info.argc.argc);
|
tree->find_child_extends(storage.our_children, point.get_point(), point_info.argc.argc);
|
||||||
|
BLT_DEBUG("Ours:");
|
||||||
|
print_child_vec(storage.our_children);
|
||||||
|
|
||||||
// apply the swaps
|
// apply the swaps
|
||||||
for (const auto& [i, j] : storage.our_swaps)
|
for (const auto& [i, j] : storage.our_swaps)
|
||||||
|
@ -698,9 +729,18 @@ namespace blt::gp
|
||||||
const auto s2 = storage.our_children[j].size();
|
const auto s2 = storage.our_children[j].size();
|
||||||
storage.our_children[i].end = storage.our_children[i].start + s1;
|
storage.our_children[i].end = storage.our_children[i].start + s1;
|
||||||
storage.our_children[j].end = storage.our_children[j].start + s2;
|
storage.our_children[j].end = storage.our_children[j].start + s2;
|
||||||
|
|
||||||
|
const auto tmp = storage.our_current_types[i];
|
||||||
|
storage.our_current_types[i] = storage.our_current_types[j];
|
||||||
|
storage.our_current_types[j] = tmp;
|
||||||
}
|
}
|
||||||
|
BLT_DEBUG("Ours (Swaps):");
|
||||||
|
print_child_vec(storage.our_children);
|
||||||
|
|
||||||
other_tree.find_child_extends(storage.other_children, other_point.get_point(), other_point_info.argc.argc);
|
other_tree.find_child_extends(storage.other_children, other_point.get_point(), other_point_info.argc.argc);
|
||||||
|
BLT_DEBUG("-----------");
|
||||||
|
BLT_DEBUG("Other:");
|
||||||
|
print_child_vec(storage.other_children);
|
||||||
|
|
||||||
for (const auto& [i, j] : storage.other_swaps)
|
for (const auto& [i, j] : storage.other_swaps)
|
||||||
{
|
{
|
||||||
|
@ -709,37 +749,128 @@ namespace blt::gp
|
||||||
const auto s2 = storage.other_children[j].size();
|
const auto s2 = storage.other_children[j].size();
|
||||||
storage.other_children[i].end = storage.other_children[i].start + s1;
|
storage.other_children[i].end = storage.other_children[i].start + s1;
|
||||||
storage.other_children[j].end = storage.other_children[j].start + s2;
|
storage.other_children[j].end = storage.other_children[j].start + s2;
|
||||||
|
|
||||||
|
const auto tmp = storage.other_current_types[i];
|
||||||
|
storage.other_current_types[i] = storage.other_current_types[j];
|
||||||
|
storage.other_current_types[j] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
BLT_DEBUG("Other (Swaps):");
|
||||||
|
print_child_vec(storage.other_children);
|
||||||
|
|
||||||
|
BLT_INFO("-----------");
|
||||||
|
|
||||||
|
for (size_t i = 0; i < common_size; i++)
|
||||||
|
{
|
||||||
|
if (storage.our_current_types[i] != other_point_info.argument_types[i])
|
||||||
|
{
|
||||||
|
for (auto& [index, type, consumed] : storage.other_types)
|
||||||
|
{
|
||||||
|
if (consumed)
|
||||||
|
continue;
|
||||||
|
if (type == other_point_info.argument_types[i])
|
||||||
|
{
|
||||||
|
consumed = true;
|
||||||
|
const auto s1 = storage.other_children[index].size();
|
||||||
|
const auto s2 = storage.our_children[i].size();
|
||||||
|
swap_subtrees(storage.our_children[i], other_tree, storage.other_children[index]);
|
||||||
|
storage.our_children[i].end = storage.our_children[i].start + s1;
|
||||||
|
storage.other_children[index].end = storage.other_children[index].start + s2;
|
||||||
|
goto b1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if BLT_DEBUG_LEVEL >= 1
|
||||||
|
BLT_ERROR("Unable to find type for position {}, expected type {} but found type {}. ", i, other_point_info.argument_types[i], storage.our_current_types[i]);
|
||||||
|
BLT_ABORT("Failure state in swap operators!");
|
||||||
|
#endif
|
||||||
|
b1:{}
|
||||||
|
}
|
||||||
|
if (storage.other_current_types[i] != point_info.argument_types[i])
|
||||||
|
{
|
||||||
|
for (auto& [index, type, consumed] : storage.our_types)
|
||||||
|
{
|
||||||
|
if (consumed)
|
||||||
|
continue;
|
||||||
|
if (type == point_info.argument_types[i])
|
||||||
|
{
|
||||||
|
consumed = true;
|
||||||
|
const auto s1 = storage.our_children[index].size();
|
||||||
|
const auto s2 = storage.other_children[i].size();
|
||||||
|
other_tree.manipulate().easy_manipulator().swap_subtrees(storage.other_children[i], *tree, storage.our_children[index]);
|
||||||
|
storage.other_children[i].end = storage.other_children[i].start + s1;
|
||||||
|
storage.our_children[index].end = storage.our_children[index].start + s2;
|
||||||
|
goto b2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if BLT_DEBUG_LEVEL >= 1
|
||||||
|
BLT_WARN("Unable to find type for position {}, expected type {} but found type {}. ", i, point_info.argument_types[i], storage.other_current_types[i]);
|
||||||
|
BLT_ABORT("Failure state in swap operators!");
|
||||||
|
#endif
|
||||||
|
b2:{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto insert_index = storage.other_children.back().end;
|
auto insert_index = storage.other_children.back().end;
|
||||||
for (auto& [index, type, consumed] : storage.our_types)
|
for (size_t i = common_size; i < point_info.argument_types.size(); i++)
|
||||||
{
|
{
|
||||||
if (consumed)
|
for (auto& [index, type, consumed] : storage.our_types)
|
||||||
continue;
|
|
||||||
if (index >= other_point_info.argument_types.size())
|
|
||||||
{
|
{
|
||||||
insert_index = other_tree.manipulate().easy_manipulator().insert_subtree(subtree_point_t{insert_index}, other_tree);
|
if (consumed)
|
||||||
consumed = true;
|
continue;
|
||||||
|
if (index != i)
|
||||||
|
continue;
|
||||||
|
if (type == point_info.argument_types[i])
|
||||||
|
{
|
||||||
|
storage.temp.clear(*tree->m_program);
|
||||||
|
copy_subtree(storage.our_children[i], storage.temp);
|
||||||
|
insert_index = other_tree.manipulate().easy_manipulator().insert_subtree(subtree_point_t{insert_index}, storage.temp);
|
||||||
|
consumed = true;
|
||||||
|
goto b3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#if BLT_DEBUG_LEVEL >= 1
|
||||||
|
BLT_WARN("Unable to find type for position {}, expected type {}", i, point_info.argument_types[i]);
|
||||||
|
BLT_ABORT("Failure state in swap operators!");
|
||||||
|
#endif
|
||||||
|
b3:{}
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_index = storage.our_children.back().end;
|
insert_index = storage.our_children.back().end;
|
||||||
for (auto& [index, type, consumed] : storage.other_types)
|
for (size_t i = common_size; i < other_point_info.argument_types.size(); i++)
|
||||||
{
|
{
|
||||||
if (consumed)
|
for (auto& [index, type, consumed] : storage.other_types)
|
||||||
continue;
|
|
||||||
if (index >= point_info.argument_types.size())
|
|
||||||
{
|
{
|
||||||
insert_index = tree->manipulate().easy_manipulator().insert_subtree(subtree_point_t{insert_index}, *tree);
|
if (consumed)
|
||||||
consumed = true;
|
continue;
|
||||||
|
if (index != i)
|
||||||
|
continue;
|
||||||
|
if (type == other_point_info.argument_types[i])
|
||||||
|
{
|
||||||
|
storage.temp.clear(*tree->m_program);
|
||||||
|
other_tree.manipulate().easy_manipulator().copy_subtree(storage.other_children[i], storage.temp);
|
||||||
|
insert_index = insert_subtree(subtree_point_t{insert_index}, storage.temp);
|
||||||
|
consumed = true;
|
||||||
|
goto b4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
b4:{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BLT_DEBUG_LEVEL >= 1
|
||||||
|
for (const auto& [index, type, consumed] : storage.our_types)
|
||||||
|
BLT_ASSERT_MSG(consumed, ("Expected type to be consumed, was not at index " + std::to_string(index)).c_str());
|
||||||
|
for (const auto& [index, type, consumed] : storage.other_types)
|
||||||
|
BLT_ASSERT_MSG(consumed, ("Expected type to be consumed, was not at index " + std::to_string(index)).c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto op = tree->operations[point.get_spoint()];
|
||||||
|
tree->operations[point.get_spoint()] = other_tree.operations[other_point.get_spoint()];
|
||||||
|
other_tree.operations[other_point.get_spoint()] = op;
|
||||||
}
|
}
|
||||||
|
|
||||||
void slow_tree_manipulator_t::swap_operators(const size_t point, tree_t& other_tree, const size_t other_point) const
|
void slow_tree_manipulator_t::swap_operators(const size_t point, tree_t& other_tree, const size_t other_point) const
|
||||||
{
|
{
|
||||||
swap_operators(subtree_point_t{point}, tree->find_endpoint(static_cast<ptrdiff_t>(point)), other_tree, subtree_point_t{other_point},
|
swap_operators(subtree_point_t{point}, other_tree, subtree_point_t{other_point});
|
||||||
other_tree.find_endpoint(static_cast<ptrdiff_t>(other_point)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue