Ejemplo n.º 1
0
  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;
  }