70 static constexpr uint32_t max_num_vars = 11;
76 : num_vars( num_vars ), ps( ps )
78 std::iota( permutations.begin(), permutations.end(), 0 );
87 if ( num_vars > max_num_vars || num_vars >= 2 * ps.lut_size )
93 ps.max_shared_vars = std::min( ps.max_shared_vars, ps.lut_size - 2 );
96 init_truth_table( ptt );
99 return find_decomposition();
108 if ( num_vars > max_num_vars || num_vars >= 2 * ps.lut_size )
113 uint32_t late_arriving = __builtin_popcount( delay_profile );
116 if ( late_arriving >= ps.lut_size )
120 ps.max_shared_vars = std::min( ps.max_shared_vars, ps.lut_size - 2 );
123 init_truth_table( ptt );
127 reposition_late_arriving_variables( delay_profile, late_arriving );
130 return find_decomposition_offset( late_arriving ) ? ( delay_profile == 0 ? 2 : 1 ) : 0;
138 compute_decomposition_impl();
140 if ( ps.verify && !verify_impl() )
152 return num_vars + 1 + num_shared_vars;
156 return bs_support_size + best_free_set + 1 + num_shared_vars;
162 unsigned profile = 0;
169 for (
uint32_t i = 0; i < best_free_set; ++i )
171 profile |= 1 << permutations[i];
176 for (
uint32_t i = 0; i < bs_support_size; ++i )
178 profile |= 1 << permutations[bs_support[i] + best_free_set];
180 profile = ~profile & ( ( 1u << num_vars ) - 1 );
191 get_decomposition_abc( decompArray );
195 bool find_decomposition()
203 return find_decomposition_bs_multi_ss( num_vars - ps.
lut_size );
206 uint32_t max_free_set = num_vars == ( 2 * ps.
lut_size - 1 ) ? ps.
lut_size - 1 : ps.lut_size - 1 - ps.max_shared_vars;
211 if ( find_decomposition_bs( i ) )
219 bool find_decomposition_offset(
uint32_t offset )
225 if ( ps.max_shared_vars > 1 )
227 return find_decomposition_bs_offset_multi_ss( std::max( num_vars - ps.lut_size, offset ), offset );
230 uint32_t max_free_set = ( num_vars == ( 2 * ps.lut_size - 1 ) || ( offset == ps.lut_size - 1 ) ) ? ps.
lut_size - 1 : ps.lut_size - 1 - ps.max_shared_vars;
233 for (
uint32_t i = std::max( num_vars - 6, offset ); i <= max_free_set; ++i )
235 if ( find_decomposition_bs_offset( i, offset ) )
243 void init_truth_table(
word* ptt )
245 uint32_t const num_blocks = ( num_vars <= 6 ) ? 1 : ( 1 << ( num_vars - 6 ) );
247 for (
uint32_t i = 0; i < num_blocks; ++i )
249 start_tt._bits[i] = ptt[i];
252 local_extend_to( start_tt, num_vars );
257 assert( free_set_size <= 5 );
259 uint32_t const num_blocks = ( num_vars > 6 ) ? ( 1u << ( num_vars - 6 ) ) : 1;
260 uint64_t
const shift = UINT64_C( 1 ) << free_set_size;
261 uint64_t
const mask = ( UINT64_C( 1 ) << shift ) - 1;
262 uint32_t const limit = ( ps.max_shared_vars == 0 || free_set_size == ( ps.lut_size - 1 ) ) ? 2 : 4;
263 uint32_t const inner_loop_max = ( num_vars < 6 ? ( 1 << num_vars ) : 64 ) >> free_set_size;
268 for (
auto i = 0u; i < num_blocks; ++i )
270 uint64_t sub = tt._bits[i];
271 for (
auto j = 0; j < inner_loop_max; ++j )
275 for ( k = 0; k <
size; ++k )
277 if ( fs_fn == cofactors[k] )
283 cofactors[
size++] = fs_fn;
293 assert( free_set_size <= 5 );
295 uint32_t const num_blocks = ( num_vars > 6 ) ? ( 1u << ( num_vars - 6 ) ) : 1;
296 uint64_t
const shift = UINT64_C( 1 ) << free_set_size;
297 uint64_t
const mask = ( UINT64_C( 1 ) << shift ) - 1;
298 uint32_t const inner_loop_max = ( num_vars < 6 ? ( 1 << num_vars ) : 64 ) >> free_set_size;
303 for (
auto i = 0u; i < num_blocks; ++i )
305 uint64_t sub = tt._bits[i];
306 for (
auto j = 0; j < inner_loop_max; ++j )
310 for ( k = 0; k <
size; ++k )
312 if ( fs_fn == cofactors[k] )
318 cofactors[
size++] = fs_fn;
330 for ( i = k - 1; pComb[i] == num_vars - k + i; --i )
338 uint32_t pos_new = pInvPerm[var_old + 1];
339 std::swap( pInvPerm[var_old + 1], pInvPerm[var_old] );
340 std::swap( pComb[i], pComb[pos_new] );
341 swap_inplace_local( tt, i, pos_new );
343 for (
uint32_t j = i + 1; j < k; j++ )
346 pos_new = pInvPerm[pComb[j - 1] + 1];
347 std::swap( pInvPerm[pComb[j - 1] + 1], pInvPerm[var_old] );
348 std::swap( pComb[j], pComb[pos_new] );
349 swap_inplace_local( tt, j, pos_new );
359 for ( i = k - 1; pComb[i] ==
size - k + i; --i )
367 uint32_t pos_new = pInvPerm[var_old + 1];
368 std::swap( pInvPerm[var_old + 1], pInvPerm[var_old] );
369 std::swap( pComb[i], pComb[pos_new] );
371 for (
uint32_t j = i + 1; j < k; j++ )
374 pos_new = pInvPerm[pComb[j - 1] + 1];
375 std::swap( pInvPerm[pComb[j - 1] + 1], pInvPerm[var_old] );
376 std::swap( pComb[j], pComb[pos_new] );
382 bool find_decomposition_bs(
uint32_t free_set_size )
391 for (
uint32_t i = 0; i < num_vars; ++i )
393 pComb[i] = pInvPerm[i] = i;
397 best_free_set = free_set_size;
400 uint32_t cost = column_multiplicity( tt, free_set_size );
404 best_multiplicity = cost;
405 for (
uint32_t i = 0; i < num_vars; ++i )
407 permutations[i] = pComb[i];
411 else if ( ps.max_shared_vars > 0 && cost <= 4 && free_set_size < 5 )
414 best_multiplicity = cost;
415 int res = check_shared_set( tt );
420 for (
uint32_t i = 0; i < num_vars; ++i )
422 permutations[i] = pComb[i];
425 swap_inplace_local( best_tt, res, num_vars - 1 );
426 std::swap( permutations[res], permutations[num_vars - 1] );
431 }
while ( combinations_next( free_set_size, 0, pComb, pInvPerm, tt ) );
436 bool find_decomposition_bs_offset(
uint32_t free_set_size,
uint32_t offset )
439 best_free_set = free_set_size;
442 if ( free_set_size == offset )
444 uint32_t cost = column_multiplicity( tt, free_set_size );
448 best_multiplicity = cost;
451 else if ( ps.max_shared_vars > 0 && cost <= 4 && free_set_size < 5 )
454 best_multiplicity = cost;
455 int res = check_shared_set( tt );
461 swap_inplace_local( best_tt, res, num_vars - 1 );
462 std::swap( permutations[res], permutations[num_vars - 1] );
472 for (
uint32_t i = 0; i < num_vars; ++i )
474 pComb[i] = pInvPerm[i] = i;
480 uint32_t cost = column_multiplicity( tt, free_set_size );
484 best_multiplicity = cost;
485 for (
uint32_t i = 0; i < num_vars; ++i )
487 pInvPerm[i] = permutations[pComb[i]];
489 for (
uint32_t i = 0; i < num_vars; ++i )
491 permutations[i] = pInvPerm[i];
495 else if ( ps.max_shared_vars > 0 && cost <= 4 && free_set_size < 5 )
498 best_multiplicity = cost;
499 int res = check_shared_set( tt );
504 for (
uint32_t i = 0; i < num_vars; ++i )
506 pInvPerm[i] = permutations[pComb[i]];
508 for (
uint32_t i = 0; i < num_vars; ++i )
510 permutations[i] = pInvPerm[i];
513 swap_inplace_local( best_tt, res, num_vars - 1 );
514 std::swap( permutations[res], permutations[num_vars - 1] );
519 }
while ( combinations_next( free_set_size, offset, pComb, pInvPerm, tt ) );
524 bool find_decomposition_bs_multi_ss(
uint32_t free_set_size )
529 uint32_t pComb[11], pInvPerm[11], shared_set[4];
530 for (
uint32_t i = 0; i < num_vars; ++i )
532 pComb[i] = pInvPerm[i] = i;
535 uint32_t limit = std::min( 1 << ( ps.lut_size - free_set_size ), 1 << ( ps.max_shared_vars + 1 ) );
538 best_free_set = free_set_size;
541 uint32_t cost = column_multiplicity2( tt, free_set_size, limit );
545 best_multiplicity = cost;
546 for (
uint32_t i = 0; i < num_vars; ++i )
548 permutations[i] = pComb[i];
553 uint32_t ss_vars_needed = cost <= 4 ? 1 : cost <= 8 ? 2
557 if ( ss_vars_needed + free_set_size < ps.lut_size )
560 best_multiplicity = cost;
561 int res = check_shared_set_multi( tt, ss_vars_needed, shared_set );
566 for (
uint32_t i = 0; i < num_vars; ++i )
568 permutations[i] = pComb[i];
571 for ( int32_t i = res - 1; i >= 0; --i )
573 swap_inplace_local( best_tt, shared_set[i] + best_free_set, num_vars - res + i );
574 std::swap( permutations[shared_set[i] + best_free_set], permutations[num_vars - res + i] );
576 num_shared_vars = res;
580 }
while ( combinations_next( free_set_size, 0, pComb, pInvPerm, tt ) );
586 bool find_decomposition_bs_offset_multi_ss(
uint32_t free_set_size,
uint32_t offset )
592 best_free_set = free_set_size;
595 uint32_t limit = std::min( 1 << ( ps.lut_size - free_set_size ), 1 << ( ps.max_shared_vars + 1 ) );
598 if ( free_set_size == offset )
600 uint32_t cost = column_multiplicity2( tt, free_set_size, limit );
604 best_multiplicity = cost;
608 uint32_t ss_vars_needed = cost <= 4 ? 1 : cost <= 8 ? 2
613 if ( ss_vars_needed + free_set_size < ps.lut_size )
616 best_multiplicity = cost;
617 int res = check_shared_set_multi( tt, ss_vars_needed, shared_set );
623 for ( int32_t i = res - 1; i >= 0; --i )
625 swap_inplace_local( best_tt, shared_set[i] + best_free_set, num_vars - res + i );
626 std::swap( permutations[shared_set[i] + best_free_set], permutations[num_vars - res + i] );
628 num_shared_vars = res;
639 for (
uint32_t i = 0; i < num_vars; ++i )
641 pComb[i] = pInvPerm[i] = i;
647 uint32_t cost = column_multiplicity2( tt, free_set_size, limit );
651 best_multiplicity = cost;
652 for (
uint32_t i = 0; i < num_vars; ++i )
654 pInvPerm[i] = permutations[pComb[i]];
656 for (
uint32_t i = 0; i < num_vars; ++i )
658 permutations[i] = pInvPerm[i];
663 uint32_t ss_vars_needed = cost <= 4 ? 1 : cost <= 8 ? 2
668 if ( ss_vars_needed + free_set_size < ps.lut_size )
671 best_multiplicity = cost;
672 int res = check_shared_set_multi( tt, ss_vars_needed, shared_set );
677 for (
uint32_t i = 0; i < num_vars; ++i )
679 pInvPerm[i] = permutations[pComb[i]];
681 for (
uint32_t i = 0; i < num_vars; ++i )
683 permutations[i] = pInvPerm[i];
686 for ( int32_t i = res - 1; i >= 0; --i )
688 swap_inplace_local( best_tt, shared_set[i] + best_free_set, num_vars - res + i );
689 std::swap( permutations[shared_set[i] + best_free_set], permutations[num_vars - res + i] );
691 num_shared_vars = res;
695 }
while ( combinations_next( free_set_size, offset, pComb, pInvPerm, tt ) );
701 bool check_shared_var( STT
const& tt,
uint32_t free_set_size,
uint32_t shared_var )
703 assert( free_set_size <= 5 );
705 uint32_t const num_blocks = ( num_vars > 6 ) ? ( 1u << ( num_vars - 6 ) ) : 1;
706 uint64_t
const shift = UINT64_C( 1 ) << free_set_size;
707 uint64_t
const mask = ( UINT64_C( 1 ) << shift ) - 1;
708 uint32_t const inner_loop_max = ( num_vars < 6 ? ( 1 << num_vars ) : 64 ) >> free_set_size;
711 uint32_t shared_var_shift = shared_var - free_set_size;
715 for (
auto i = 0u; i < num_blocks; ++i )
717 uint64_t sub = tt._bits[i];
718 for (
auto j = 0; j < inner_loop_max; ++j )
721 uint32_t p = ( iteration_counter >> shared_var_shift ) & 1;
723 for ( k = 0; k <
size[
p]; ++k )
725 if ( fs_fn == cofactors[
p][k] )
731 cofactors[
p][
size[
p]++] = fs_fn;
740 inline int check_shared_set( STT
const& tt )
743 for (
uint32_t i = best_free_set; i < num_vars; ++i )
746 if ( check_shared_var( tt, best_free_set, i ) )
755 bool check_shared_var_combined( STT
const& tt,
uint32_t free_set_size,
uint32_t shared_vars[6],
uint32_t num_shared_vars )
757 assert( free_set_size <= 5 );
758 assert( num_shared_vars <= 4 );
760 uint32_t const num_blocks = ( num_vars > 6 ) ? ( 1u << ( num_vars - 6 ) ) : 1;
761 uint64_t
const shift = UINT64_C( 1 ) << free_set_size;
762 uint64_t
const mask = ( UINT64_C( 1 ) << shift ) - 1;
763 uint32_t const inner_loop_max = ( num_vars < 6 ? ( 1 << num_vars ) : 64 ) >> free_set_size;
769 for (
auto i = 0u; i < num_blocks; ++i )
771 uint64_t sub = tt._bits[i];
772 for (
auto j = 0; j < inner_loop_max; ++j )
776 for (
uint32_t k = 0; k < num_shared_vars; ++k )
778 p |= ( ( iteration_counter >> shared_vars[k] ) & 1 ) << k;
782 for ( k = 0; k <
size[
p]; ++k )
784 if ( fs_fn == cofactors[
p][k] )
790 cofactors[
p][
size[
p]++] = fs_fn;
799 inline int check_shared_set_multi( STT
const& tt,
uint32_t target_num_ss,
uint32_t* res_shared )
803 uint32_t max_shared_vars = std::min( ps.lut_size - best_free_set - 1, ps.max_shared_vars );
806 for (
uint32_t i = std::max( target_num_ss, ps.min_shared_vars ); i <= max_shared_vars; ++i )
810 pComb[i] = pInvPerm[i] = i;
816 if ( check_shared_var_combined( tt, best_free_set, pComb, i ) )
820 res_shared[j] = pComb[j];
823 std::sort( res_shared, res_shared + i );
826 }
while ( combinations_next_simple( i, pComb, pInvPerm, num_vars - best_free_set ) );
832 void compute_decomposition_impl(
bool verbose =
false )
841 uint32_t num_blocks = ( num_vars > 6 ) ? ( 1u << ( num_vars - 6 ) ) : 1;
842 uint64_t
const shift = UINT64_C( 1 ) << best_free_set;
843 uint64_t
const mask = ( UINT64_C( 1 ) << shift ) - 1;
844 uint32_t const num_groups = 1 << num_shared_vars;
845 uint32_t const next_group = 1 << ( num_vars - best_free_set - num_shared_vars );
846 uint32_t const inner_loop_max = ( num_vars < 6 ? ( 1 << num_vars ) : 64 ) >> best_free_set;
848 uint64_t fs_fun[32] = { 0 };
849 uint64_t dc_mask = ( ( UINT64_C( 1 ) << next_group ) - 1 );
853 fs_fun[0] = best_tt._bits[0] & mask;
855 for (
auto i = 0u; i < num_blocks; ++i )
857 uint64_t cof = best_tt._bits[i];
858 for (
auto j = 0; j < inner_loop_max; ++j )
860 uint64_t val = cof & mask;
862 if ( set_index == next_group )
867 fs_fun[group_index + 1] = fs_fun[group_index];
868 bs_dc._bits |= dc_mask;
874 fs_fun[group_index] = val;
875 dc_mask <<= next_group;
878 if ( val != fs_fun[group_index] )
880 bs._bits |= UINT64_C( 1 ) << ( j + offset );
881 fs_fun[group_index + 1] = val;
887 offset = ( offset + inner_loop_max ) & 0x3F;
893 fs_fun[group_index + 1] = fs_fun[group_index];
894 bs_dc._bits |= dc_mask;
898 for (
uint32_t i = 0; i < 2 * num_groups; ++i )
900 composition._bits |= fs_fun[i] << ( i * shift );
906 uint64_t
constexpr masks[] = { 0x0, 0x3, 0xF, 0xFF, 0xFFFF, 0xFFFFFFFF, UINT64_MAX };
907 care._bits = masks[num_vars - best_free_set] & ~bs_dc._bits;
908 for (
uint32_t i = 0; i < num_vars - best_free_set; ++i )
910 if ( !has_var6( bs, care, i ) )
912 adjust_truth_table_on_dc( bs, care, i );
916 if ( bs_support_size < i )
921 bs_support[bs_support_size] = i;
926 dec_funcs[0] = bs._bits;
927 dec_funcs[1] = composition._bits;
933 f._bits = dec_funcs[0];
934 std::cout <<
"BS function : ";
937 f._bits = dec_funcs[1];
938 std::cout <<
"Composition function: ";
944 template<
typename TT_type>
945 void local_extend_to( TT_type& tt,
uint32_t real_num_vars )
947 if ( real_num_vars < 6 )
949 auto mask = *tt.begin();
951 for (
auto i = real_num_vars; i < num_vars; ++i )
953 mask |= ( mask << ( 1 << i ) );
956 std::fill( tt.begin(), tt.end(), mask );
960 uint32_t num_blocks = ( 1u << ( real_num_vars - 6 ) );
961 auto it = tt.begin();
962 while ( it != tt.end() )
964 it = std::copy( tt.cbegin(), tt.cbegin() + num_blocks, it );
969 inline void reposition_late_arriving_variables(
unsigned delay_profile,
uint32_t late_arriving )
972 for (
uint32_t i = 0; i < late_arriving; ++i )
974 while ( ( ( delay_profile >> k ) & 1 ) == 0 )
977 if ( permutations[i] == k )
983 std::swap( permutations[i], permutations[k] );
984 swap_inplace_local( best_tt, i, k );
989 void swap_inplace_local( STT& tt,
uint8_t var_index1,
uint8_t var_index2 )
991 if ( var_index1 == var_index2 )
996 if ( var_index1 > var_index2 )
998 std::swap( var_index1, var_index2 );
1001 const uint32_t num_blocks = num_vars <= 6 ? 1 : 1 << ( num_vars - 6 );
1003 if ( num_vars <= 6 )
1005 const auto& pmask = kitty::detail::ppermutation_masks[var_index1][var_index2];
1006 const auto shift = ( 1 << var_index2 ) - ( 1 << var_index1 );
1007 tt._bits[0] = ( tt._bits[0] & pmask[0] ) | ( ( tt._bits[0] & pmask[1] ) << shift ) | ( ( tt._bits[0] & pmask[2] ) >> shift );
1009 else if ( var_index2 <= 5 )
1011 const auto& pmask = kitty::detail::ppermutation_masks[var_index1][var_index2];
1012 const auto shift = ( 1 << var_index2 ) - ( 1 << var_index1 );
1013 std::transform( std::begin( tt._bits ), std::begin( tt._bits ) + num_blocks, std::begin( tt._bits ),
1014 [shift, &pmask]( uint64_t
word ) {
1015 return ( word & pmask[0] ) | ( ( word & pmask[1] ) << shift ) | ( ( word & pmask[2] ) >> shift );
1018 else if ( var_index1 <= 5 )
1020 const auto step = 1 << ( var_index2 - 6 );
1021 const auto shift = 1 << var_index1;
1022 auto it = std::begin( tt._bits );
1023 while ( it != std::begin( tt._bits ) + num_blocks )
1025 for (
auto i =
decltype( step ){ 0 }; i < step; ++i )
1027 const auto low_to_high = ( *( it + i ) & kitty::detail::projections[var_index1] ) >> shift;
1028 const auto high_to_low = ( *( it + i + step ) << shift ) & kitty::detail::projections[var_index1];
1029 *( it + i ) = ( *( it + i ) & ~kitty::detail::projections[var_index1] ) | high_to_low;
1030 *( it + i + step ) = ( *( it + i + step ) & kitty::detail::projections[var_index1] ) | low_to_high;
1037 const auto step1 = 1 << ( var_index1 - 6 );
1038 const auto step2 = 1 << ( var_index2 - 6 );
1039 auto it = std::begin( tt._bits );
1040 while ( it != std::begin( tt._bits ) + num_blocks )
1042 for (
auto i = 0; i < step2; i += 2 * step1 )
1044 for (
auto j = 0; j < step1; ++j )
1046 std::swap( *( it + i + j + step1 ), *( it + i + j + step2 ) );
1054 inline bool has_var6(
const LTT& tt,
const LTT& care,
uint8_t var_index )
1056 if ( ( ( ( tt._bits >> ( uint64_t( 1 ) << var_index ) ) ^ tt._bits ) & kitty::detail::projections_neg[var_index] & ( care._bits >> ( uint64_t( 1 ) << var_index ) ) & care._bits ) != 0 )
1064 void adjust_truth_table_on_dc( LTT& tt, LTT& care,
uint32_t var_index )
1066 uint64_t new_bits = tt._bits & care._bits;
1067 tt._bits = ( ( new_bits | ( new_bits >> ( uint64_t( 1 ) << var_index ) ) ) & kitty::detail::projections_neg[var_index] ) |
1068 ( ( new_bits | ( new_bits << ( uint64_t( 1 ) << var_index ) ) ) & kitty::detail::projections[var_index] );
1069 care._bits = ( care._bits | ( care._bits >> ( uint64_t( 1 ) << var_index ) ) ) & kitty::detail::projections_neg[var_index];
1070 care._bits = care._bits | ( care._bits << ( uint64_t( 1 ) << var_index ) );
1086 void get_decomposition_abc(
unsigned char* decompArray )
1088 unsigned char* pArray = decompArray;
1089 unsigned char bytes = 2;
1098 *pArray = bs_support_size;
1103 for (
uint32_t i = 0; i < bs_support_size; ++i )
1105 *pArray = (
unsigned char)permutations[bs_support[i] + best_free_set];
1111 uint32_t tt_num_bytes = ( bs_support_size <= 3 ) ? 1 : ( 1 << ( bs_support_size - 3 ) );
1112 for (
uint32_t i = 0; i < tt_num_bytes; ++i )
1114 *pArray = (
unsigned char)( ( dec_funcs[0] >> ( 8 * i ) ) & 0xFF );
1121 uint32_t support_size = best_free_set + 1 + num_shared_vars;
1122 *pArray = support_size;
1127 for (
uint32_t i = 0; i < best_free_set; ++i )
1129 *pArray = (
unsigned char)permutations[i];
1134 *pArray = (
unsigned char)num_vars;
1138 for (
uint32_t i = 0; i < num_shared_vars; ++i )
1140 *pArray = (
unsigned char)permutations[num_vars - num_shared_vars + i];
1146 tt_num_bytes = ( support_size <= 3 ) ? 1 : ( 1 << ( support_size - 3 ) );
1147 for (
uint32_t i = 0; i < tt_num_bytes; ++i )
1149 *pArray = (
unsigned char)( ( dec_funcs[1] >> ( 8 * i ) ) & 0xFF );
1155 *decompArray = bytes;
1161 STT pis[max_num_vars];
1162 for (
uint32_t i = 0; i < num_vars; ++i )
1169 for (
uint32_t i = 0; i < bs_support_size; ++i )
1171 bsi[i] = pis[best_free_set + bs_support[i]];
1176 for (
uint32_t i = 0u; i < ( 1 << num_vars ); ++i )
1179 for (
auto j = 0; j < bs_support_size; ++j )
1181 pattern |= get_bit( bsi[j], i ) << j;
1183 if ( ( dec_funcs[0] >> pattern ) & 1 )
1185 set_bit( bsf_sim, i );
1191 for (
uint32_t i = 0u; i < ( 1 << num_vars ); ++i )
1194 for (
auto j = 0; j < best_free_set; ++j )
1196 pattern |= get_bit( pis[j], i ) << j;
1198 pattern |= get_bit( bsf_sim, i ) << best_free_set;
1201 for (
auto j = 0u; j < num_shared_vars; ++j )
1203 pattern |= get_bit( pis[num_vars - num_shared_vars + j], i ) << ( best_free_set + 1 + j );
1206 if ( ( dec_funcs[1] >> pattern ) & 1 )
1208 set_bit( top_sim, i );
1213 for (
uint32_t i = 0; i < ( 1 << ( num_vars > 6 ? num_vars - 6 : 1 ) ); ++i )
1215 if ( top_sim._bits[i] != start_tt._bits[i] )
1217 std::cout <<
"Found incorrect decomposition\n";
1218 report_tt( top_sim );
1219 std::cout <<
" instead_of\n";
1220 report_tt( start_tt );
1228 uint32_t get_bit(
const STT& tt, uint64_t index )
1230 return ( tt._bits[index >> 6] >> ( index & 0x3f ) ) & 0x1;
1233 void set_bit( STT& tt, uint64_t index )
1235 tt._bits[index >> 6] |= uint64_t( 1 ) << ( index & 0x3f );
1238 void report_tt( STT
const& stt )
1240 kitty::dynamic_truth_table tt( num_vars );
1242 std::copy( std::begin( stt._bits ), std::begin( stt._bits ) + ( 1 << ( num_vars > 6 ? num_vars - 6 : 0 ) ), std::begin( tt ) );
1254 uint64_t dec_funcs[2];
1259 std::array<uint32_t, max_num_vars> permutations;