First Steps

First Steps

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.


Creating an Executable

In order to create an executable, call

helpers/testcase my_example

The script is interactive and will ask for parameter that should given to the program, a circuit that should be read. Futher information about creating executables is given in Creating an Executable.


Creating a Circuit

In this example, how to create a circuit composed of multiple control Toffoli gates (MCT gates) is described. Therefore

  1. The necessary header files are included (all files have the file extension .hpp and are separated into single header files categorized into directories),
  2. the revkit namespace is explicitly used,
  3. a circuit with 3 lines is initialized,
  4. Toffoli gates are added to the circuit, whereby the indices in the second brackets are determining the control lines (0 is the top line) and the index in the last bracket is the Toffoli line, and
  5. the circuit is printed out in ASCII format to the standard output.
#include <iostream>
#include <core/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:


Reading and Writing a Circuit from a File

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,

  1. an empty circuit is created (no argument as in the previous example),
  2. the RevLib realization file with file-name "circuit.real" is parsed,
  3. the circuit is reversed,
  4. the circuit is written to another file with file-name "circuit-copy.real".
#include <iostream>
#include <core/circuit.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:


Iterating through the Gates of a Circuit

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,

  1. an empty circuit is created and a RevLib file is parsed,
  2. every gate is traversed from left to right using foreach, and
  3. for each gate the number of its control lines is printed using the begin and end iterators of the controls in the gate (the STL function 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>
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:


Adding Gates

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,

  1. An empty circuit with 5 lines is created,
  2. a CNOT Gate with control at line 2 (counted from 0) and target at line 3 is added,
  3. a V Gate (control on 0, target on 1) is prepended (added in the front of the circuit),
  4. a Fredkin Gate with controls on 0 and 1 as well as targets on 2 and 4 is appended at the end of the circuit,
  5. a V+ Gate is inserted before the second gate (second parameter) with control on 1 and target on 2,
  6. a NOT Gate is prepended at the beginning of the circuit, and
  7. a Toffoli gate with controls on 0, 1, 2, and 3 and target on 4 is added dynamically.
#include <boost/assign/std/set.hpp> // for using += operator with gate::line_container
#include <core/circuit.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:


Generated on Tue Apr 16 2013 08:12:02 for RevKit by doxygen 1.8.3.1