ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
kitty_operations.hpp
Go to the documentation of this file.
1#ifndef _KITTY_OPERATIONS_TT_H_
2#define _KITTY_OPERATIONS_TT_H_
3#pragma once
4
5#include <algorithm>
6#include <cassert>
7#include <functional>
8#include <iterator>
9#include <iostream>
10
11#include "kitty_algorithm.hpp"
12#include "kitty_constants.hpp"
13#include "kitty_dynamic_tt.hpp"
14#include "kitty_static_tt.hpp"
15
17
18namespace kitty
19{
20
22template<typename TT>
23inline TT unary_not_if( const TT& tt, bool cond )
24{
25#ifdef _MSC_VER
26#pragma warning( push )
27#pragma warning( disable : 4146 )
28#endif
29 const auto mask = -static_cast<uint64_t>( cond );
30#ifdef _MSC_VER
31#pragma warning( pop )
32#endif
33 return unary_operation( tt, [mask]( uint64_t a )
34 { return a ^ mask; } );
35}
36
38template<typename TT>
39inline TT unary_not( const TT& tt )
40{
41 return unary_operation( tt, []( uint64_t a )
42 { return ~a; } );
43}
44
46template<typename TT>
47
48inline TT binary_and( const TT& first, const TT& second )
49{
50 return binary_operation( first, second, std::bit_and<uint64_t>() );
51}
52
54template<typename TT>
55inline TT binary_or( const TT& first, const TT& second )
56{
57 return binary_operation( first, second, std::bit_or<uint64_t>() );
58}
59
70template<typename TT>
71void swap_inplace( TT& tt, uint8_t var_index1, uint8_t var_index2 )
72{
73 if ( var_index1 == var_index2 )
74 {
75 return;
76 }
77
78 if ( var_index1 > var_index2 )
79 {
80 std::swap( var_index1, var_index2 );
81 }
82
83 if ( tt.num_vars() <= 6 )
84 {
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 );
88 }
89 else if ( var_index2 <= 5 )
90 {
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 )
95 {
96 return ( word & pmask[0] ) | ( ( word & pmask[1] ) << shift ) | ( ( word & pmask[2] ) >> shift );
97 } );
98 }
99 else if ( var_index1 <= 5 ) /* in this case, var_index2 > 5 */
100 {
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 ) )
105 {
106 for ( auto i = decltype( step ){ 0 }; i < step; ++i )
107 {
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;
112 }
113 it += 2 * step;
114 }
115 }
116 else
117 {
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 ) )
122 {
123 for ( auto i = 0; i < step2; i += 2 * step1 )
124 {
125 for ( auto j = 0; j < step1; ++j )
126 {
127 std::swap( *( it + i + j + step1 ), *( it + i + j + step2 ) );
128 }
129 }
130 it += 2 * step2;
131 }
132 }
133}
134
135template<uint32_t NumVars>
136inline void swap_inplace( static_truth_table<NumVars, true>& tt, uint8_t var_index1, uint8_t var_index2 )
137{
138 if ( var_index1 == var_index2 )
139 {
140 return;
141 }
142
143 if ( var_index1 > var_index2 )
144 {
145 std::swap( var_index1, var_index2 );
146 }
147
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 );
151}
152
162template<typename TT, typename TTFrom>
163void extend_to_inplace( TT& tt, const TTFrom& from )
164{
165 assert( tt.num_vars() >= from.num_vars() );
166
167 if ( from.num_vars() < 6 )
168 {
169 auto mask = *from.begin();
170
171 for ( auto i = from.num_vars(); i < std::min<uint8_t>( 6, tt.num_vars() ); ++i )
172 {
173 mask |= ( mask << ( 1 << i ) );
174 }
175
176 std::fill( tt.begin(), tt.end(), mask );
177 }
178 else
179 {
180 auto it = tt.begin();
181 while ( it != tt.end() )
182 {
183 it = std::copy( from.cbegin(), from.cend(), it );
184 }
185 }
186}
187
197template<uint32_t NumVars, typename TTFrom>
198inline static_truth_table<NumVars> extend_to( const TTFrom& from )
199{
201 extend_to_inplace( tt, from );
202 return tt;
203}
204
210template<typename TT>
211bool has_var( const TT& tt, uint8_t var_index )
212{
213 assert( var_index < tt.num_vars() );
214
215 if ( tt.num_vars() <= 6 || var_index < 6 )
216 {
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] ); } );
221 }
222
223 const auto step = 1 << ( var_index - 6 );
224 for ( auto i = 0u; i < static_cast<uint32_t>( tt.num_blocks() ); i += 2 * step )
225 {
226 for ( auto j = 0; j < step; ++j )
227 {
228 if ( tt._bits[i + j] != tt._bits[i + j + step] )
229 {
230 return true;
231 }
232 }
233 }
234 return false;
235}
236
243template<typename TT>
244bool has_var( const TT& tt, const TT& care, uint8_t var_index )
245{
246 assert( var_index < tt.num_vars() );
247 assert( tt.num_vars() == care.num_vars() );
248
249 if ( tt.num_vars() <= 6 || var_index < 6 )
250 {
251 auto it_tt = std::begin( tt._bits );
252 auto it_care = std::begin( care._bits );
253 while ( it_tt != std::end( tt._bits ) )
254 {
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 )
257 {
258 return true;
259 }
260 ++it_tt;
261 ++it_care;
262 }
263
264 return false;
265 }
266
267 const auto step = 1 << ( var_index - 6 );
268 for ( auto i = 0u; i < static_cast<uint32_t>( tt.num_blocks() ); i += 2 * step )
269 {
270 for ( auto j = 0; j < step; ++j )
271 {
272 if ( ( ( tt._bits[i + j] ^ tt._bits[i + j + step] ) & care._bits[i + j] & care._bits[i + j + step] ) != 0 )
273 {
274 return true;
275 }
276 }
277 }
278 return false;
279}
280
290template<typename TT, typename TTFrom>
291void shrink_to_inplace( TT& tt, const TTFrom& from )
292{
293 assert( tt.num_vars() <= from.num_vars() );
294
295 std::copy( from.begin(), from.begin() + tt.num_blocks(), tt.begin() );
296
297 if ( tt.num_vars() < 6 )
298 {
299 tt.mask_bits();
300 }
301}
302
311template<typename TTFrom>
312inline dynamic_truth_table shrink_to( const TTFrom& from, unsigned num_vars )
313{
314 auto tt = create<dynamic_truth_table>( num_vars );
315 shrink_to_inplace( tt, from );
316 return tt;
317}
318
326template<typename TT>
327void print_hex( const TT& tt, std::ostream& os = std::cout )
328{
329 auto const chunk_size =
330 std::min<uint64_t>( tt.num_vars() <= 1 ? 1 : ( tt.num_bits() >> 2 ), 16 );
331
332 for_each_block_reversed( tt, [&os, chunk_size]( uint64_t word )
333 {
334 std::string chunk( chunk_size, '0' );
335
336 auto it = chunk.rbegin();
337 while (word && it != chunk.rend()) {
338 auto hex = word & 0xf;
339 if (hex < 10) {
340 *it = '0' + static_cast<char>(hex);
341 } else {
342 *it = 'a' + static_cast<char>(hex - 10);
343 }
344 ++it;
345 word >>= 4;
346 }
347 os << chunk; } );
348}
349
350} //namespace kitty
351
353
354#endif // _KITTY_OPERATIONS_TT_H_
ABC_NAMESPACE_HEADER_START typedef unsigned char uint8_t
Definition Fxch.h:31
#define ABC_NAMESPACE_CXX_HEADER_START
#define ABC_NAMESPACE_CXX_HEADER_END
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
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.
#define assert(ex)
Definition util_old.h:213