unsigned add_line_to_circuit( circuit& circ, const std::string& input, const std::string& output, const constant& c, bool g ) { std::vector<std::string> ins = circ.inputs(); std::vector<std::string> outs = circ.outputs(); std::vector<constant> cs = circ.constants(); std::vector<bool> gar = circ.garbage(); circ.set_lines( circ.lines() + 1u ); ins += input; circ.set_inputs( ins ); outs += output; circ.set_outputs( outs ); cs += c; circ.set_constants( cs ); gar += g; circ.set_garbage( gar ); return circ.lines() - 1u; }
bool transposition_based_synthesis( circuit& circ, const binary_truth_table& spec, properties::ptr settings, properties::ptr statistics ) { // Settings parsing // Run-time measuring timer<properties_timer> t; if ( statistics ) { properties_timer rt( statistics ); t.start( rt ); } unsigned bw = spec.num_outputs(); circ.set_lines( bw ); copy_metadata( spec, circ ); std::map<unsigned, unsigned> values_map; for ( binary_truth_table::const_iterator it = spec.begin(); it != spec.end(); ++it ) { binary_truth_table::cube_type in( it->first.first, it->first.second ); binary_truth_table::cube_type out( it->second.first, it->second.second ); values_map.insert( std::make_pair( truth_table_cube_to_number( in ), truth_table_cube_to_number( out ) ) ); } // Set of cycles std::vector<std::vector<unsigned> > cycles; while ( !values_map.empty() ) { unsigned start_value = values_map.begin()->first; // first key in values_map std::vector<unsigned> cycle; unsigned target = start_value; do { cycle += target; unsigned old_target = target; target = values_map[target]; values_map.erase( old_target ); // erase this entry } while ( target != start_value ); cycles += cycle; } for ( auto& cycle : cycles ) { unsigned max_distance = 0u; unsigned max_index = 0u; for ( unsigned i = 0u; i < cycle.size(); ++i ) { unsigned first = cycle.at(i); unsigned second = cycle.at( (i + 1u) % cycle.size() ); unsigned distance = hamming_distance( first, second ); if ( distance > max_distance ) { max_distance = distance; max_index = i; } } std::vector<unsigned> tmp; std::copy( cycle.begin() + ( max_index + 1u ), cycle.end(), std::back_inserter( tmp ) ); std::copy( cycle.begin(), cycle.begin() + ( max_index + 1u ), std::back_inserter( tmp ) ); std::copy( tmp.begin(), tmp.end(), cycle.begin() ); std::reverse( cycle.begin(), cycle.end() ); } // TODO create transpositions function for ( auto& cycle : cycles ) { for ( unsigned i = 0u; i < cycle.size() - 1; ++i ) { circuit transposition_circ( spec.num_inputs() ); unsigned first = cycle.at(i); unsigned second = cycle.at( (i + 1) % cycle.size() ); boost::dynamic_bitset<> first_bits( spec.num_inputs(), first ); boost::dynamic_bitset<> second_bits( spec.num_inputs(), second ); transposition_to_circuit( transposition_circ, first_bits, second_bits ); append_circuit( circ, transposition_circ); } } return true; }