1#ifndef _KITTY_OPERATIONS_TT_H_
2#define _KITTY_OPERATIONS_TT_H_
26#pragma warning( push )
27#pragma warning( disable : 4146 )
29 const auto mask = -
static_cast<uint64_t
>( cond );
34 {
return a ^ mask; } );
55inline TT
binary_or(
const TT& first,
const TT& second )
73 if ( var_index1 == var_index2 )
78 if ( var_index1 > var_index2 )
80 std::swap( var_index1, var_index2 );
83 if ( tt.num_vars() <= 6 )
85 const auto& pmask = detail::ppermutation_masks[var_index1][var_index2];
86 const auto shift = ( 1 << var_index2 ) - ( 1 << var_index1 );
87 tt._bits[0] = ( tt._bits[0] & pmask[0] ) | ( ( tt._bits[0] & pmask[1] ) << shift ) | ( ( tt._bits[0] & pmask[2] ) >> shift );
89 else if ( var_index2 <= 5 )
91 const auto& pmask = detail::ppermutation_masks[var_index1][var_index2];
92 const auto shift = ( 1 << var_index2 ) - ( 1 << var_index1 );
93 std::transform( std::begin( tt._bits ), std::end( tt._bits ), std::begin( tt._bits ),
94 [shift, &pmask]( uint64_t
word )
96 return ( word & pmask[0] ) | ( ( word & pmask[1] ) << shift ) | ( ( word & pmask[2] ) >> shift );
99 else if ( var_index1 <= 5 )
101 const auto step = 1 << ( var_index2 - 6 );
102 const auto shift = 1 << var_index1;
103 auto it = std::begin( tt._bits );
104 while ( it != std::end( tt._bits ) )
106 for (
auto i =
decltype( step ){ 0 }; i < step; ++i )
108 const auto low_to_high = ( *( it + i ) & detail::projections[var_index1] ) >> shift;
109 const auto high_to_low = ( *( it + i + step ) << shift ) & detail::projections[var_index1];
110 *( it + i ) = ( *( it + i ) & ~detail::projections[var_index1] ) | high_to_low;
111 *( it + i + step ) = ( *( it + i + step ) & detail::projections[var_index1] ) | low_to_high;
118 const auto step1 = 1 << ( var_index1 - 6 );
119 const auto step2 = 1 << ( var_index2 - 6 );
120 auto it = std::begin( tt._bits );
121 while ( it != std::end( tt._bits ) )
123 for (
auto i = 0; i < step2; i += 2 * step1 )
125 for (
auto j = 0; j < step1; ++j )
127 std::swap( *( it + i + j + step1 ), *( it + i + j + step2 ) );
135template<u
int32_t NumVars>
138 if ( var_index1 == var_index2 )
143 if ( var_index1 > var_index2 )
145 std::swap( var_index1, var_index2 );
148 const auto& pmask = detail::ppermutation_masks[var_index1][var_index2];
149 const auto shift = ( 1 << var_index2 ) - ( 1 << var_index1 );
150 tt._bits = ( tt._bits & pmask[0] ) | ( ( tt._bits & pmask[1] ) << shift ) | ( ( tt._bits & pmask[2] ) >> shift );
162template<
typename TT,
typename TTFrom>
165 assert( tt.num_vars() >= from.num_vars() );
167 if ( from.num_vars() < 6 )
169 auto mask = *from.begin();
171 for (
auto i = from.num_vars(); i < std::min<uint8_t>( 6, tt.num_vars() ); ++i )
173 mask |= ( mask << ( 1 << i ) );
176 std::fill( tt.begin(), tt.end(), mask );
180 auto it = tt.begin();
181 while ( it != tt.end() )
183 it = std::copy( from.cbegin(), from.cend(), it );
197template<u
int32_t NumVars,
typename TTFrom>
213 assert( var_index < tt.num_vars() );
215 if ( tt.num_vars() <= 6 || var_index < 6 )
217 return std::any_of( std::begin( tt._bits ), std::end( tt._bits ),
218 [var_index]( uint64_t
word )
219 { return ( ( word >> ( uint64_t( 1 ) << var_index ) ) & detail::projections_neg[var_index] ) !=
220 ( word & detail::projections_neg[var_index] ); } );
223 const auto step = 1 << ( var_index - 6 );
224 for (
auto i = 0u; i < static_cast<uint32_t>( tt.num_blocks() ); i += 2 * step )
226 for (
auto j = 0; j < step; ++j )
228 if ( tt._bits[i + j] != tt._bits[i + j + step] )
246 assert( var_index < tt.num_vars() );
247 assert( tt.num_vars() == care.num_vars() );
249 if ( tt.num_vars() <= 6 || var_index < 6 )
251 auto it_tt = std::begin( tt._bits );
252 auto it_care = std::begin( care._bits );
253 while ( it_tt != std::end( tt._bits ) )
255 if ( ( ( ( *it_tt >> ( uint64_t( 1 ) << var_index ) ) ^ *it_tt ) & detail::projections_neg[var_index]
256 & ( *it_care >> ( uint64_t( 1 ) << var_index ) ) & *it_care ) != 0 )
267 const auto step = 1 << ( var_index - 6 );
268 for (
auto i = 0u; i < static_cast<uint32_t>( tt.num_blocks() ); i += 2 * step )
270 for (
auto j = 0; j < step; ++j )
272 if ( ( ( tt._bits[i + j] ^ tt._bits[i + j + step] ) & care._bits[i + j] & care._bits[i + j + step] ) != 0 )
290template<
typename TT,
typename TTFrom>
293 assert( tt.num_vars() <= from.num_vars() );
295 std::copy( from.begin(), from.begin() + tt.num_blocks(), tt.begin() );
297 if ( tt.num_vars() < 6 )
311template<
typename TTFrom>
327void print_hex(
const TT& tt, std::ostream& os = std::cout )
329 auto const chunk_size =
330 std::min<uint64_t>( tt.num_vars() <= 1 ? 1 : ( tt.num_bits() >> 2 ), 16 );
334 std::string chunk( chunk_size,
'0' );
336 auto it = chunk.rbegin();
337 while (
word && it != chunk.rend()) {
338 auto hex =
word & 0xf;
340 *it =
'0' +
static_cast<char>(hex);
342 *it =
'a' +
static_cast<char>(hex - 10);
ABC_NAMESPACE_HEADER_START typedef unsigned char uint8_t
#define ABC_NAMESPACE_CXX_HEADER_START
#define ABC_NAMESPACE_CXX_HEADER_END
unsigned __int64 word
DECLARATIONS ///.
TT binary_operation(const TT &first, const TT &second, Fn &&op)
Perform bitwise binary operation on two truth tables.
TT binary_or(const TT &first, const TT &second)
Bitwise OR of two truth tables.
bool has_var(const TT &tt, uint8_t var_index)
Checks whether truth table depends on given variable index.
TT binary_and(const TT &first, const TT &second)
Bitwise AND of two truth tables.
TT create(unsigned num_vars)
Creates truth table with number of variables.
void swap_inplace(TT &tt, uint8_t var_index1, uint8_t var_index2)
Swaps two variables in a truth table.
void shrink_to_inplace(TT &tt, const TTFrom &from)
Shrinks larger truth table to smaller one.
TT unary_not_if(const TT &tt, bool cond)
void extend_to_inplace(TT &tt, const TTFrom &from)
Extends smaller truth table to larger one.
void print_hex(const TT &tt, std::ostream &os=std::cout)
Prints truth table in hexadecimal representation.
static_truth_table< NumVars > extend_to(const TTFrom &from)
Extends smaller truth table to larger static one.
dynamic_truth_table shrink_to(const TTFrom &from, unsigned num_vars)
Shrinks larger truth table to smaller dynamic one.
void for_each_block_reversed(const TT &tt, Fn &&op)
Iterates through each block of a truth table in reverse order.
TT unary_operation(const TT &tt, Fn &&op)
Perform bitwise unary operation on truth table.
TT unary_not(const TT &tt)
Inverts all bits in a truth table.