Dukales

partial derivative of function arguments pack

Nov 12th, 2014
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.27 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <string>
  4. #include <deque>
  5. #include <vector>
  6. #include <list>
  7. #include <iterator>
  8. #include <functional>
  9. #include <limits>
  10.  
  11. #include <cstdlib>
  12. #include <cassert>
  13.    
  14. template< typename type >
  15. struct reversed_container
  16. {
  17.  
  18.     reversed_container(type && _container)
  19.         : container_(std::forward< type >(_container))
  20.     { ; }
  21.  
  22.     decltype(auto)
  23.     begin() noexcept
  24.     {
  25.         return container_.rbegin();
  26.     }
  27.  
  28.     decltype(auto)
  29.     end() noexcept
  30.     {
  31.         return container_.rend();
  32.     }
  33.  
  34. private :
  35.  
  36.     type container_;
  37.  
  38. };
  39.  
  40. template< typename type >
  41. reversed_container< type >
  42. reverse(type && _container)
  43. {
  44.     return std::forward< type >(_container);
  45. }
  46.  
  47. using size_type = std::size_t;
  48. using boolean_type = bool;
  49. using symbol = std::string;
  50. using char_type = typename std::string::value_type;
  51. using symbols = std::list< symbol >;
  52.  
  53. struct derivator_of_arguments
  54. {
  55.  
  56.     using symbol_cref = symbol;//std::reference_wrapper< symbol const >;
  57.     using symbol_crefs = std::list< symbol_cref >;
  58.     using symbols_pack = std::list< symbol_crefs >;
  59.    
  60.     using result_type = std::deque< symbols_pack >;
  61.    
  62.     symbols_pack
  63.     tail(result_type const & _head, symbol const & _wrt) const
  64.     {
  65.         symbols_pack tail_;
  66.         for (symbols_pack const & symbols_pack_ : reverse(_head)) {
  67.             for (symbol_crefs const & symbol_crefs_ : reverse(symbols_pack_)) {
  68.                 tail_.push_front(symbol_crefs_);
  69.                 tail_.front().push_back(_wrt);
  70.             }
  71.             symbol const & wrt_ = symbols_pack_.back().back();
  72.             if (wrt_ == _wrt) {
  73.                 return tail_;
  74.             }
  75.         }
  76.         tail_.push_front({{_wrt}});
  77.         return tail_;
  78.     }
  79.  
  80.     result_type
  81.     head(symbols const & _wrts) const
  82.     {
  83.         result_type head_;
  84.         for (symbol const & wrt_ : _wrts) {
  85.             head_.push_back(tail(head_, wrt_));
  86.         }
  87.         return head_;
  88.     }
  89.  
  90. };
  91.  
  92. template< size_type n >
  93. struct test
  94. {
  95.    
  96.     static_assert(!(size_type('z' - 'a') + 1 < n)); // static_assert(n < 16); // x^x = 2^64 => x = 16
  97.    
  98.     using symbols_pack = typename derivator_of_arguments::symbols_pack;
  99.     using letters_type = std::vector< char_type >;
  100.    
  101.     boolean_type
  102.     operator () (letters_type const & _letters) const
  103.     {
  104.         symbols wrts_;
  105.         for (char_type const & letter_ : _letters) {
  106.             wrts_.emplace_back(letter_, 1);
  107.         }
  108.         derivator_of_arguments const derivator_of_arguments_{};
  109.         auto const derived_arguments_ = derivator_of_arguments_.head(wrts_);
  110.         {
  111.             std::list< std::reference_wrapper< symbols_pack const > > orderer_(std::cbegin(derived_arguments_), std::cend(derived_arguments_));
  112.             orderer_.sort(std::less< symbols_pack >{});
  113.             auto const oend = std::cend(orderer_);
  114.             if (std::adjacent_find(std::cbegin(orderer_), oend, std::equal_to< symbols_pack >{}) != oend) {
  115.                 return false;
  116.             }
  117.         }
  118.         return true;
  119.     }
  120.    
  121.     boolean_type
  122.     operator () () const
  123.     {
  124.         letters_type mishmash_(n);
  125.         size_type count_ = 1;
  126.         for (size_type i = 0; i < n; ++i) {
  127.             assert(!(std::numeric_limits< size_type >::max() / n < count_));
  128.             count_ *= n;
  129.         }
  130.         for (size_type i = 0; i < count_; ++i) {
  131.             size_type k = i;
  132.             for (size_type j = 0; j < n; ++j) {
  133.                 mishmash_[j] = char_type('a' + (k % n));
  134.                 k /= n;
  135.             }
  136.             if (!operator () (mishmash_)) {
  137.                 return false;
  138.             }
  139.         }
  140.         return true;
  141.     }
  142.    
  143. };
  144.  
  145. int
  146. main()
  147. {
  148.     test< 5 > const test_{};
  149.     if (test_()) {
  150.         std::cout << "Success!" << std::endl;
  151.         return EXIT_SUCCESS;
  152.     } else {
  153.         std::cerr << "Failure!" << std::endl;
  154.         return EXIT_FAILURE;
  155.     }
  156.    
  157.     /*
  158.     symbols wrts_;
  159.     wrts_.emplace_back("x");
  160.     wrts_.emplace_back("y");
  161.     wrts_.emplace_back("y");
  162.     wrts_.emplace_back("z");
  163.     wrts_.emplace_back("y");
  164.     derivator_of_arguments const derivator_of_arguments_{};
  165.     auto const derived_arguments_ = derivator_of_arguments_.head(wrts_);
  166.     std::cout << 1 << std::endl << std::endl; // argument pack itself
  167.     for (auto const & i : derived_arguments_) { // its derivatives
  168.         for (auto const & j : i) {
  169.             std::copy(std::cbegin(j), std::cend(j), std::ostream_iterator< symbol const & >(std::cout, ""));
  170.             std::cout << std::endl;
  171.         }
  172.         std::cout << std::endl;
  173.     }
  174. #if 1
  175.     { // check uniqueness
  176.         using symbols_pack = typename derivator_of_arguments::symbols_pack;
  177.         std::list< std::reference_wrapper< symbols_pack const > > orderer_(std::cbegin(derived_arguments_), std::cend(derived_arguments_));
  178.         orderer_.sort(std::less< symbols_pack >{});
  179.         auto const oend = std::cend(orderer_);
  180.         if (std::adjacent_find(std::cbegin(orderer_), oend, std::equal_to< symbols_pack >{}) != oend) {
  181.             std::cerr << "Failure!" << std::endl;
  182.             return EXIT_FAILURE;
  183.         }
  184.     }
  185. #endif
  186.     std::cout << "Success!" << std::endl;
  187.     return EXIT_SUCCESS;*/
  188. }
Advertisement
Add Comment
Please, Sign In to add comment