In this section, a couple of Hello World-like examples are provided to guide a start into the usage of RevKit. They give an idea of how to use the elementary data structures and functions of the framework. For further use and a detailed explanation of all classes, methods, and functions the reference documentation should be used.
The examples are structured as follows. First an abstract explanation is given, what the example is doing. Afterwards, the single steps are described in more detail before the code is displayed. Finally, related tasks and the respective reference is given.
In this example, how to create a circuit composed of multiple control Toffoli gates (MCT gates) is described. Therefore
revkit
namespace is explicitly used,#include <iostream> #include <core/circuit.hpp> #include <core/functions/add_gates.hpp> #include <core/io/print_circuit.hpp> using namespace revkit; int main( int argc, char ** argv ) { circuit circ( 3 ); append_toffoli( circ )( 2 )( 1 ); append_toffoli( circ )( 0, 1 )( 2 ); append_toffoli( circ )( 1, 2 )( 0 ); append_toffoli( circ )( 0, 1 )( 2 ); append_toffoli( circ )( 2 )( 1 ); std::cout << circ << std::endl; return 0; }
Further reading on this example:
The following example demonstrates how to read a realization from a file, how to modify the realization, and how to write it back to another file. Therefore,
#include <iostream> #include <core/circuit.hpp> #include <core/functions/reverse_circuit.hpp> #include <core/io/read_realization.hpp> #include <core/io/write_realization.hpp> using namespace revkit; int main( int argc, char ** argv ) { circuit circ; read_realization( circ, "circuit.real" ); reverse_circuit( circ ); write_realization( circ, "circuit-copy.real" ); return 0; }
Further reading on this example:
This example shows how to iterate through the gates of circuit using the foreach statement from the Boost library. For each gate the number of its control lines is printed to the standard output. Therefore,
std::distance
is used to calculate the distance between the iterators, i. e. the number of elements).#include <iostream> #include <iterator> // for std::distance #include <core/circuit.hpp> #include <core/gate.hpp> #include <core/io/read_realization.hpp> using namespace revkit; int main( int argc, char ** argv ) { circuit circ; read_realization( circ, "circuit.real" ); foreach ( const gate& g, circ ) { unsigned num_controls = std::distance( g.begin_controls(), g.end_controls() ); std::cout << "Gate has " << num_controls << " controls." << std::endl; } return 0; }
Further reading on this example:
Although there are methods in the circuit class for adding gates (circuit::append_gate, circuit::prepend_gate, and circuit::insert_gate), they should only used when adding user defined gates (Target Tags). When adding standard gates (as Toffoli, Fredin, Peres, V, or V+) there are pre-defined helper functions available to use (see also Creating a Circuit).
In the following example, a circuit is creating with different methods (using different gate types and positions where to insert the corresponding gate). Further, different techniques are used when adding gates with multiple control lines. Therefore,
#include <boost/assign/std/set.hpp> // for using += operator with gate::line_container #include <core/circuit.hpp> #include <core/functions/add_gates.hpp> using namespace boost::assign; int main( int argc, char ** argv ) { circuit circ( 5 ); append_cnot( circ, 2, 3 ); prepend_v( circ, 0, 1 ); append_fredkin( circ )( 0, 1 )( 2, 4 ); insert_vplus( circ, 2, 1, 2 ); prepend_not( circ, 2 ); gate::line_container controls; controls += 0,1,2,3; append_toffoli( circ, controls, 4 ); }
This leads to the following circuit: