diff --git a/CMakeLists.txt b/CMakeLists.txt index f0f67ce..740d225 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,74 +1,97 @@ cmake_minimum_required(VERSION 3.31.6) -project(BBDD_Manipulation_Package) +project(BBDD_Manipulation_Package LANGUAGES CXX) + +# create compile_cpmmands.json for nvim +set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "") # 1) A header-only target that exposes include/ # Anything that links to this gets -I/include automatically. add_library(project_headers INTERFACE) target_include_directories(project_headers INTERFACE ${CMAKE_SOURCE_DIR}/include ) # Optional: set a default C++ standard for all targets made below set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 2) Discover all example source files (top-level .cpp files in examples/) # Use CONFIGURE_DEPENDS so 'cmake --build .' picks up new files after re-configure. file(GLOB EXAMPLE_SOURCES CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/examples/*.cpp) # 3) Create an executable per example file and link include paths via project_headers foreach(example_src IN LISTS EXAMPLE_SOURCES) get_filename_component(example_name "${example_src}" NAME_WE) add_executable(${example_name} "${example_src}") # Link the header-only interface to inherit include/ (and any future compile defs/opts) target_link_libraries(${example_name} PRIVATE project_headers) # Optional: place example binaries into build/examples/ set_target_properties(${example_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/examples" ) endforeach() ############################################# Generate Doxygen Documentation # Option to build docs option(BUILD_DOC "Build API documentation with Doxygen" ON) if(BUILD_DOC) find_package(Doxygen QUIET) if(NOT DOXYGEN_FOUND) message(WARNING "Doxygen not found. Set BUILD_DOC=OFF or install Doxygen.") else() # Graphviz (dot) for diagrams — optional find_program(DOT_EXE dot) set(DOXYGEN_HAVE_DOT "NO") if(DOT_EXE) set(DOXYGEN_HAVE_DOT "YES") endif() configure_file( "${CMAKE_SOURCE_DIR}/Doxyfile.in" "${CMAKE_BINARY_DIR}/Doxyfile" @ONLY ) # docs target add_custom_target(docs COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/Doxyfile" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" COMMENT "Generating API documentation with Doxygen" VERBATIM ) # Optional: convenience target to clean generated docs add_custom_target(docs-clean COMMAND "${CMAKE_COMMAND}" -E rm -rf "${DOXYGEN_OUTPUT_DIR}" COMMENT "Removing generated documentation in ${DOXYGEN_OUTPUT_DIR}" VERBATIM ) endif() endif() + +#------------------ Testing ------------------------ +include(CTest) +enable_testing() +add_subdirectory(tests) + +# Fetch GoogleTest automatically (no manual install needed) +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.15.2.zip +) +# For MSVC: avoid overriding parent compiler settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +# Ensure 'make test' builds the test exe before running ctest (nice-to-have safety) +if (TARGET test AND TARGET bbdd_tests) + add_dependencies(test bbdd_tests) +endif() diff --git a/examples/example_basic.cpp b/examples/example_basic.cpp deleted file mode 100644 index c9c0678..0000000 --- a/examples/example_basic.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "bbdd.hpp" -#include -#include - -int main() { - Unique_table table; - table.init_table(100, "bbdd_test"); - std::vector inputs = {2, 3, 4, 5}; - std::string expected_result; - uint32_t input_size = 4; - table.init_cvo(inputs, cvo_none); - bbdd_node_t *f, *g, *h, *i, *j; - bbdd_cases_t test_case = case_5f; - bool custom = true; - bool adder = true; - if (custom) { - if (!adder) { - f = add_ref(base_case_two_inputs(&table, 3, 2, bbdd_xor)); - g = add_ref(base_case_two_inputs(&table, 5, 4, bbdd_xnor)); - i = add_ref(base_case_two_inputs(&table, 2, 3, bbdd_and)); - h = add_ref(merge_bbdds(&table, f, g, bbdd_and)); - f = i; - h = add_ref(merge_bbdds(&table, h, i, bbdd_or)); - //h = table.swap_variables(h, 2, 3); - //h = table.swap_variables(h, 2, 4); - h = table.reduce_bbdd(sift_bbdd(&table, h)); - dump_ordering(table.cvo); - expected_result = "0000100110011111"; - table.add_output("f", f); - table.add_output("g", g); - table.add_output("h", h); - table.dump_table(); - std::string h_function = table.dump_tt(input_size, "h"); - //assert(expected_result == h_function); - std::cout << h_function << "\n"; - table.dump_dot("vis/f.dot", "f"); - table.dump_dot("vis/g.dot", "g"); - table.dump_dot("vis/h.dot", "h"); - } else { - f = add_ref(base_case_two_inputs(&table, 2, 3, bbdd_xor)); - g = add_ref(merge_bbdds(&table, f, 4, bbdd_xor)); - g = sift_bbdd(&table, g); - h = add_ref(base_case_two_inputs(&table, 2, 3, bbdd_and)); - i = add_ref(merge_bbdds(&table, base_case_two_inputs(&table, 2, 3, bbdd_xor), table.insert_node({{4, INT_MAX}, 0, 1}), bbdd_and)); - j = add_ref(merge_bbdds(&table, i, h, bbdd_or)); - j = table.reorder_bbdd(j, 3, 4); - j = table.reorder_bbdd(j, 3, 2); - j = table.reduce_bbdd(j); - table.add_output("j", j); - input_size = 3; - table.dump_tt(input_size, "j"); - table.dump_tt(input_size, "f"); - expected_result = "01101001"; - table.add_output("Sum", g); - table.add_output("Cout", j); - table.add_output("h", f); - table.dump_table(); - table.dump_dot("vis/f.dot", "Sum"); - table.dump_dot("vis/g.dot", "Cout"); - table.dump_dot("vis/h.dot", "h"); - } - } else { - if (test_case == case_0) { - } else if (test_case == case_1f) { - f = add_ref(base_case_two_inputs(&table, 2, 3, bbdd_xor)); - g = add_ref(base_case_two_inputs(&table, 4, 5, bbdd_xnor)); - h = merge_bbdds(&table, f, g, bbdd_and); - expected_result = "0000100110010000"; - } else if (test_case == case_1g) { - f = add_ref(base_case_two_inputs(&table, 4, 5, bbdd_xnor)); - g = add_ref(base_case_two_inputs(&table, 2, 3, bbdd_xor)); - h = merge_bbdds(&table, f, g, bbdd_and); - expected_result = "0000100110010000"; - } else if (test_case == case_2f) { - f = add_ref(base_case_two_inputs(&table, 2, 4, bbdd_xor)); - g = add_ref(base_case_two_inputs(&table, 3, 5, bbdd_xnor)); - h = add_ref(merge_bbdds(&table, f, g, bbdd_or)); - expected_result = "1011011111101101"; - } else if (test_case == case_2g) { - f = add_ref(base_case_two_inputs(&table, 3, 5, bbdd_xor)); - g = add_ref(base_case_two_inputs(&table, 2, 4, bbdd_xnor)); - h = add_ref(merge_bbdds(&table, f, g, bbdd_and)); - expected_result = "0100100000010010"; - } else if (test_case == case_3f) { - f = add_ref(base_case_two_inputs(&table, 2, 4, bbdd_xor)); - g = add_ref(base_case_two_inputs(&table, 3, 4, bbdd_xnor)); - h = add_ref(merge_bbdds(&table, f, g, bbdd_and)); - expected_result = "00011000"; - input_size = 3; - } else if (test_case == case_3g) { - f = add_ref(base_case_two_inputs(&table, 3, 4, bbdd_xnor)); - g = add_ref(base_case_two_inputs(&table, 2, 4, bbdd_xor)); - h = add_ref(merge_bbdds(&table, f, g, bbdd_and)); - expected_result = "00011000"; - input_size = 3; - } else if (test_case == case_4f) { - f = base_case_two_inputs(&table, 2, 3, bbdd_and); - g = base_case_two_inputs(&table, 4, 5, bbdd_xor); - h = merge_bbdds(&table, f, g, bbdd_and); - expected_result = "0000000000000110"; - } else if (test_case == case_4g) { - f = base_case_two_inputs(&table, 4, 5, bbdd_xor); - g = base_case_two_inputs(&table, 2, 3, bbdd_and); - h = merge_bbdds(&table, f, g, bbdd_and); - expected_result = "0000000000000110"; - } else if (test_case == case_5f) { - f = base_case_two_inputs(&table, 2, 4, bbdd_xor); - g = base_case_two_inputs(&table, 2, 3, bbdd_xnor); - h = merge_bbdds(&table, f, g, bbdd_or); - expected_result = "11011011"; - input_size = 3; - } else if (test_case == case_5g) { - f = base_case_two_inputs(&table, 2, 3, bbdd_xnor); - g = base_case_two_inputs(&table, 2, 4, bbdd_xor); - h = merge_bbdds(&table, f, g, bbdd_or); - expected_result = "11011011"; - input_size = 3; - } - table.add_output("f", f); - table.add_output("g", g); - table.add_output("h", h); - table.dump_table(); - g = sift_bbdd(&table, g); - std::string h_function = table.dump_tt(input_size, "h"); - //assert(expected_result == h_function); - std::cout << h_function << "\n"; - table.dump_dot("vis/f.dot", "f"); - table.dump_dot("vis/g.dot", "g"); - table.dump_dot("vis/h.dot", "h"); - } - table.free_table(); - return 0; -} diff --git a/examples/sifting_example.cpp b/examples/sifting_example.cpp new file mode 100644 index 0000000..9fbb091 --- /dev/null +++ b/examples/sifting_example.cpp @@ -0,0 +1,32 @@ +#include "bbdd.hpp" +#include +#include + +int main() { + Unique_table table; + table.init_table(1000, "bbdd_test"); + std::vector inputs = {2, 3, 4, 5}; + std::string expected_result; + table.init_cvo(inputs, cvo_none); + bbdd_node_t *f, *g, *h, *i, *j; + f = add_ref(base_case_two_inputs(&table, 3, 2, bbdd_xor)); + g = add_ref(base_case_two_inputs(&table, 5, 4, bbdd_xnor)); + i = add_ref(base_case_two_inputs(&table, 2, 3, bbdd_and)); + h = add_ref(merge_bbdds(&table, f, g, bbdd_and)); + h = add_ref(merge_bbdds(&table, h, i, bbdd_or)); + dump_ordering(table.cvo); + expected_result = "0000100110011111"; + table.add_output("f", f); + table.add_output("g", g); + table.add_output("h", h); + table.dump_table(); + std::string h_function = table.dump_tt("h"); + std::cout << h_function << "\n"; + table.dump_dot("f.dot", "f"); + table.dump_dot("g.dot", "g"); + table.dump_dot("h.dot", "h"); + //sift(&table, &Unique_table::get_total_number_nodes, &table); + //table.dump_dot("sift.dot"); + //table.free_table(); + return 0; +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..4e1ee21 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,12 @@ +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests") + +add_executable(bbdd_tests test.cpp) +target_link_libraries(bbdd_tests PRIVATE project_headers GTest::gtest_main) + +include(GoogleTest) +gtest_discover_tests(bbdd_tests + DISCOVERY_MODE PRE_TEST + WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + DISCOVERY_TIMEOUT 60 +) + diff --git a/tests/test.cpp b/tests/test.cpp new file mode 100644 index 0000000..c0bfb8a --- /dev/null +++ b/tests/test.cpp @@ -0,0 +1,184 @@ +#include + +#include "bbdd.hpp" +#include "bbdd_node.hpp" +#include "bbdd_types.hpp" + +TEST(BBDDTEST, CASE_1F) { + Unique_table table; + table.init_table(1000, "bbdd_test"); + std::vector inputs = {2, 3, 4, 5}; + table.init_cvo(inputs, cvo_none); + bbdd_node_t *f = add_ref(base_case_two_inputs(&table, 2, 3, bbdd_xor)); + bbdd_node_t *g = add_ref(base_case_two_inputs(&table, 4, 5, bbdd_xnor)); + bbdd_node_t *h = merge_bbdds(&table, f, g, bbdd_and); + std::string expected_result = "0000100110010000"; + sift(&table, &Unique_table::get_total_number_nodes, &table); + table.add_output("h", h); + std::string h_function = table.dump_tt("h"); + std::cout << h_function << "\n"; + EXPECT_EQ(expected_result, h_function); +} + +TEST(BBDDTEST, CASE_1G) { + Unique_table table; + table.init_table(1000, "bbdd_test"); + std::vector inputs = {2, 3, 4, 5}; + table.init_cvo(inputs, cvo_none); + std::string expected_result; + bbdd_node_t *f, *g, *h; + f = add_ref(base_case_two_inputs(&table, 4, 5, bbdd_xnor)); + g = add_ref(base_case_two_inputs(&table, 2, 3, bbdd_xor)); + h = merge_bbdds(&table, f, g, bbdd_and); + expected_result = "0000100110010000"; + sift(&table, &Unique_table::get_total_number_nodes, &table); + table.add_output("h", h); + std::string h_function = table.dump_tt("h"); + std::cout << h_function << "\n"; + EXPECT_EQ(expected_result, h_function); +} + +TEST(BBDDTEST, CASE_2F) { + Unique_table table; + table.init_table(1000, "bbdd_test"); + std::vector inputs = {2, 3, 4, 5}; + table.init_cvo(inputs, cvo_none); + std::string expected_result; + bbdd_node_t *f, *g, *h; + f = add_ref(base_case_two_inputs(&table, 2, 4, bbdd_and)); + g = add_ref(base_case_two_inputs(&table, 3, 5, bbdd_or)); + h = add_ref(merge_bbdds(&table, f, g, bbdd_or)); + expected_result = "0101111101111111";//"1111111011111010"; + sift(&table, &Unique_table::get_total_number_nodes, &table); + table.add_output("h", h); + std::string h_function = table.dump_tt("h"); + std::cout << h_function << "\n"; + EXPECT_EQ(expected_result, h_function); +} + +TEST(BBDDTEST, CASE_2G) { + Unique_table table; + table.init_table(1000, "bbdd_test"); + std::vector inputs = {2, 3, 4, 5}; + table.init_cvo(inputs, cvo_none); + std::string expected_result; + bbdd_node_t *f, *g, *h; + f = add_ref(base_case_two_inputs(&table, 3, 5, bbdd_xor)); + g = add_ref(base_case_two_inputs(&table, 2, 4, bbdd_xnor)); + h = add_ref(merge_bbdds(&table, f, g, bbdd_and)); + expected_result = "0100100000010010"; + sift(&table, &Unique_table::get_total_number_nodes, &table); + table.add_output("h", h); + std::string h_function = table.dump_tt("h"); + std::cout << h_function << "\n"; + EXPECT_EQ(expected_result, h_function); +} + +TEST(BBDDTEST, CASE_3F) { + Unique_table table; + table.init_table(1000, "bbdd_test"); + std::vector inputs = {2, 3, 4}; + table.init_cvo(inputs, cvo_none); + std::string expected_result; + bbdd_node_t *f, *g, *h; + f = add_ref(base_case_two_inputs(&table, 2, 4, bbdd_and)); + g = add_ref(base_case_two_inputs(&table, 3, 4, bbdd_or)); + h = add_ref(merge_bbdds(&table, f, g, bbdd_and)); + expected_result = "00000101"; + sift(&table, &Unique_table::get_total_number_nodes, &table); + table.add_output("h", h); + std::string h_function = table.dump_tt("h"); + std::cout << h_function << "\n"; + EXPECT_EQ(expected_result, h_function); +} + +TEST(BBDDTEST, CASE_3G) { + Unique_table table; + table.init_table(1000, "bbdd_test"); + std::vector inputs = {2, 3, 4}; + table.init_cvo(inputs, cvo_none); + std::string expected_result; + bbdd_node_t *f, *g, *h; + f = add_ref(base_case_two_inputs(&table, 3, 4, bbdd_nor)); + g = add_ref(base_case_two_inputs(&table, 2, 4, bbdd_nand)); + h = add_ref(merge_bbdds(&table, f, g, bbdd_and)); + expected_result = "10001000"; + sift(&table, &Unique_table::get_total_number_nodes, &table); + table.add_output("h", h); + std::string h_function = table.dump_tt("h"); + std::cout << h_function << "\n"; + EXPECT_EQ(expected_result, h_function); +} + +TEST(BBDDTEST, CASE_4F) { + Unique_table table; + table.init_table(1000, "bbdd_test"); + std::vector inputs = {2, 3, 4, 5}; + table.init_cvo(inputs, cvo_none); + std::string expected_result; + bbdd_node_t *f, *g, *h; + f = base_case_two_inputs(&table, 2, 3, bbdd_and); + g = base_case_two_inputs(&table, 4, 5, bbdd_xor); + h = merge_bbdds(&table, f, g, bbdd_and); + expected_result = "0000000000000110"; + sift(&table, &Unique_table::get_total_number_nodes, &table); + table.add_output("h", h); + std::string h_function = table.dump_tt("h"); + std::cout << h_function << "\n"; + EXPECT_EQ(expected_result, h_function); +} + +TEST(BBDDTEST, CASE_4G) { + Unique_table table; + table.init_table(1000, "bbdd_test"); + std::vector inputs = {2, 3, 4, 5}; + table.init_cvo(inputs, cvo_none); + std::string expected_result; + bbdd_node_t *f, *g, *h; + f = base_case_two_inputs(&table, 4, 5, bbdd_xor); + g = base_case_two_inputs(&table, 2, 3, bbdd_and); + h = merge_bbdds(&table, f, g, bbdd_and); + expected_result = "0000000000000110"; + sift(&table, &Unique_table::get_total_number_nodes, &table); + table.add_output("h", h); + std::string h_function = table.dump_tt("h"); + std::cout << h_function << "\n"; + EXPECT_EQ(expected_result, h_function); +} + +TEST(BBDDTEST, CASE_5F) { + Unique_table table; + table.init_table(1000, "bbdd_test"); + std::vector inputs = {2, 3, 4, 5}; + table.init_cvo(inputs, cvo_none); + std::string expected_result; + bbdd_node_t *f, *g, *h; + f = base_case_two_inputs(&table, 2, 4, bbdd_xor); + g = base_case_two_inputs(&table, 2, 3, bbdd_xnor); + h = merge_bbdds(&table, f, g, bbdd_or); + expected_result = "1111001111001111"; + sift(&table, &Unique_table::get_total_number_nodes, &table); + table.add_output("h", h); + std::string h_function = table.dump_tt("h"); + std::cout << h_function << "\n"; + EXPECT_EQ(expected_result, h_function); +} + +TEST(BBDDTEST, CASE_5G) { + Unique_table table; + table.init_table(1000, "bbdd_test"); + std::vector inputs = {2, 3, 4}; + table.init_cvo(inputs, cvo_none); + std::string expected_result; + bbdd_node_t *f, *g, *h; + f = base_case_two_inputs(&table, 2, 3, bbdd_nor); + g = base_case_two_inputs(&table, 2, 4, bbdd_nand); + h = merge_bbdds(&table, f, g, bbdd_or); + expected_result = "11111010"; + sift(&table, &Unique_table::get_total_number_nodes, &table); + table.add_output("h", h); + std::string h_function = table.dump_tt("h"); + std::cout << h_function << "\n"; + EXPECT_EQ(expected_result, h_function); +} +