From 295160980525cbf335e63b8f05a98c03dfe02f61 Mon Sep 17 00:00:00 2001 From: Thomas 'elfprince13' Dickerson Date: Tue, 26 Nov 2024 13:16:32 -0500 Subject: [PATCH] Refactored into separate source files --- CMakeLists.txt | 20 +- example/CMakeLists.txt | 10 + example/array-concat.cc | 28 + example/broken-do-not-use.cc | 28 + example/depend.cc | 1025 +---------------------------- example/log2.cc | 62 ++ include/dependent-cxx/algebra.hpp | 622 +++++++++++++++++ include/dependent-cxx/array.hpp | 103 +++ include/dependent-cxx/core-io.hpp | 38 ++ include/dependent-cxx/core.hpp | 189 ++++++ 10 files changed, 1101 insertions(+), 1024 deletions(-) create mode 100644 example/CMakeLists.txt create mode 100644 example/array-concat.cc create mode 100644 example/broken-do-not-use.cc create mode 100644 example/log2.cc create mode 100644 include/dependent-cxx/algebra.hpp create mode 100644 include/dependent-cxx/array.hpp create mode 100644 include/dependent-cxx/core-io.hpp create mode 100644 include/dependent-cxx/core.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 743d4ff..a983449 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,10 +3,18 @@ cmake_minimum_required(VERSION 3.13.5) set(CMAKE_CXX_STANDARD 17) project(Dependent-Cxx) -set(DEPND_INCLUDE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include) -set(DEPND_LIBRARY_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) -find_package(Boost 1.73) +set(dependent_cxx_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(base_path ${dependent_cxx_INCLUDE_DIR}/dependent-cxx) -add_executable(test-depend example/depend.cc) -target_compile_options(test-depend PUBLIC -Wall -Wextra) -target_link_libraries(test-depend LINK_PUBLIC Boost::boost) #static-hmap) +add_library(dependent-cxx INTERFACE) +target_sources(dependent-cxx INTERFACE + ${base_path}/algebra.hpp + ${base_path}/array.hpp + ${base_path}/core.hpp + ${base_path}/core-io.hpp + ) +target_include_directories(dependent-cxx INTERFACE ${dependent_cxx_INCLUDE_DIR}) +target_compile_options(dependent-cxx INTERFACE -Wall -Wextra) + + +add_subdirectory(example) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 0000000..5dffe03 --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,10 @@ +project(Examples) + +add_executable(test-depend depend.cc) +target_link_libraries(test-depend LINK_PUBLIC dependent-cxx) + +add_executable(test-log2 log2.cc) +target_link_libraries(test-log2 LINK_PUBLIC dependent-cxx) + +add_executable(test-array-concat array-concat.cc) +target_link_libraries(test-array-concat LINK_PUBLIC dependent-cxx) \ No newline at end of file diff --git a/example/array-concat.cc b/example/array-concat.cc new file mode 100644 index 0000000..550b98b --- /dev/null +++ b/example/array-concat.cc @@ -0,0 +1,28 @@ +#include +#include +#include + +using namespace dependent_cxx; + +// WIP demo of concatenating a dynamic length array with a static length array +int main(int argc, const char* argv[]) { + RootFrame(); + constexpr auto v32 = FreshType(32); + if constexpr (constexpr auto proofNonneg = algebra::less_than_or_equal_to::apply(Zero{}, v32, Context{}); + std::nullopt == proofNonneg) { + std::cerr << "Can't make negative-length array" << std::endl; + } else { + constexpr algebra::less_than_or_equal_to lte_ev = *proofNonneg; + collections::Array a32(v32, lte_ev); + + constexpr Constant<64> SixtyFour; + constexpr algebra::less_than_or_equal_to sixty_four_nn{Zero{}, SixtyFour}; + collections::Array a64(SixtyFour, sixty_four_nn); + + //auto a96{collections::concatenate(a64, a32)}; + // TODO: finish implementing concatenate + + } + + return 0; +} \ No newline at end of file diff --git a/example/broken-do-not-use.cc b/example/broken-do-not-use.cc new file mode 100644 index 0000000..0b395b1 --- /dev/null +++ b/example/broken-do-not-use.cc @@ -0,0 +1,28 @@ +// WIP: proof that a variant is one of a only a subset of possible values +/* +template +class SubsetVariant {}; + +template +class SubsetVariant,std::variant> { + template + inline static std::variant applyHelper(std::variant input) { + if(std::holds_alternative(input)) { + return std::get(input); + } else { + return applyHelper(input); + } + } + + template = true> + inline static std::variant applyHelper(std::variant ) { + static_assert(sizeof...(N) == 0); + return std::variant(([]() -> OldVarH { throw std::logic_error("These don't overlap"); })()); + } +public: + + constexpr static std::variant apply(std::variant input) { + return applyHelper(input); + }; +}; + */ \ No newline at end of file diff --git a/example/depend.cc b/example/depend.cc index 412f663..57ec71b 100644 --- a/example/depend.cc +++ b/example/depend.cc @@ -1,839 +1,7 @@ -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include +#include +#include -#include - -namespace detail { - template - struct Unique {}; - - template - std::ostream& operator<<(std::ostream& out, Unique) { - out <<"Unique<"; - (..., (out << Nums << ",")); - return out << ">"; - } -} - -#define TYPEOF(X) std::decay_t - -template struct ContextTag {}; -template -constexpr auto makeContext(Root, Trail...) { - return ContextTag{}; -} - -namespace detail { - template - struct is_context_tag { constexpr static const bool value = false; }; - template - struct is_context_tag> { constexpr static const bool value = true; }; - - template - struct fixed_point {}; - - template - struct is_fixed_point { constexpr static const bool value = false; }; - template - struct is_fixed_point> { - constexpr static const bool value = true; - }; -} - -template -std::ostream& operator<<(std::ostream& out, ContextTag) { - out << "Context<" << Root{}; - (... , (out << ", " << Trail{})); - return out << ">"; -} - -template struct Fresh : Tag { - const V v; -}; - -template Fresh(Tag, V) -> Fresh; - -template -struct is_fresh { constexpr static const bool value = false; }; -template -struct is_fresh> { constexpr static const bool value = true; }; - -template struct Constant { - const TYPEOF(V) v; - constexpr Constant() : v(V) {} -}; - -template -struct is_constant { constexpr static const bool value = false; }; -template -struct is_constant> { constexpr static const bool value = true; }; - -using Zero = Constant<0>; -using One = Constant<1>; -using Two = Constant<2>; - -template -std::ostream& operator<<(std::ostream& out, const Fresh& fresh) { - return out << "Fresh{" << (Tag)fresh << ", " << fresh.v << "}"; -} - -template -std::ostream& operator<<(std::ostream& out, const Constant) { - return out << "Constant{" << V << "}"; -} - -template -class CanValidate { - static_assert(detail::is_context_tag>::value, "Validator must be a context tag"); - static_assert(is_fresh>::value || is_constant>::value, "Term must be a context tag"); -public: - constexpr static const bool value = CanValidate, std::decay_t>::value; -}; - -template -class CanValidate> { -public: - constexpr static const bool value = true; -}; - - -template -class CanValidate, Fresh, TV>> { -protected: - constexpr static const bool SameRoot = std::is_same_v; - constexpr static const bool AnyRecursion = (... || detail::is_fixed_point::value); -public: - constexpr static const bool value = SameRoot && !AnyRecursion; -}; - -template -struct Equivalent { - static_assert(detail::is_context_tag::value, "CompareContext must be a context tag"); - static_assert(detail::is_context_tag::value, "Left must be a context tag"); - static_assert(detail::is_context_tag::value, "Right must be a context tag"); -}; - -template -class Equivalent, ContextTag, ContextTag> { - constexpr static const bool SameRoot = std::is_same_v && std::is_same_v; - constexpr static const bool SameComps = std::is_same_v, ContextTag>; - constexpr static const bool AnyRecursion = ((... || detail::is_fixed_point::value) || - (... || detail::is_fixed_point::value)); -public: - constexpr static const bool value = SameRoot && SameComps; - static_assert(SameRoot, "Cannot compare contexts which do not share a root and/or which are being inspected outside their root context. Consider calling RefreshType on Left and Right within the CompareContext"); - static_assert(!AnyRecursion || !SameComps, "Left and Right tags are equivalent but contain recursive fixed points and thus cannot be guaranteed unique. Consider re-rooting in a fresh context"); -}; - -namespace detail { - - template - std::ostream& operator<<(std::ostream& out, fixed_point) { - return out << "fixed_point{" << CT{} << "}"; - } - - template - struct CutFixedPoint {}; - - template - struct CutFixedPoint, std::tuple, FP> { - using type = ContextTag; // no fixed-point encountered; - }; - - template - struct CutFixedPoint, Ins...>, std::tuple, FP> { - using type = ContextTag>; - }; - - template - struct CutFixedPoint, std::tuple, FP> { - using type = typename CutFixedPoint, std::tuple, FP>::type; - }; - - template - struct PushContext { - static_assert(is_context_tag::value, "CT must be a context tag"); - }; - - template - struct PushContext, P> { - constexpr static const bool AnyRecursion = (std::is_same_v || ... || std::is_same_v); - constexpr static const bool KnownRecursion = (std::is_same_v> || ... || std::is_same_v>); - //using type = ContextTag; - //* - using type = std::conditional_t,std::tuple<>,P>::type, - ContextTag>>, - ContextTag>; - //*/ - }; -} -template -constexpr auto pushContext(ContextTag, Push) { - return typename detail::PushContext ::type{}; -} - -namespace detail { - template - constexpr bool dependEquiv(Fresh, Fresh) { - return Equivalent::value; - } -} - -#define DEPEND_EQUIV(Left, Right) (detail::dependEquiv(Left, Right)) - -#define UNIQUE detail::Unique<__LINE__, __COUNTER__> -#define FreshType(X) Fresh{pushContext(Context{},UNIQUE{}), X} -#define RootFrame() using Context = ContextTag -#define FreshTag() typename detail::PushContext::type -#define FreshFrame() using Context = typename detail::PushContext::type - -#define RefreshType(X) Fresh{pushContext(Context{},UNIQUE{}), X.v} - -template -class Return { - template - friend constexpr auto makeReturn(ParentContext); - Return() = default; -public: - constexpr Fresh operator()(V v) && { - return Fresh{UniqueContext{}, v}; - } -}; - -template -constexpr auto makeReturn(ParentContext) { - FreshFrame(); - return Return{}; -} - -#define MakeReturn(V) makeReturn(pushContext(Context{},UNIQUE{})) - -template