LanQ – a quantum imperative programming language

Examples

Teleportation

The teleportation protocol described by Bennett et al. can be implemented in LanQ as shown below.

Brief description of the program

The program allocates a channel for sending integers and creates an EPR pair. Then it creates a new process which allocates a new qubit, performs some computation on it and finally teleports it to the original process. In the original process, usual correction is performed and the state of the teleported qubit is shown.

Detailed description of the program

We now describe the program line by line.

On line 1.1, we include a library which defines a Hermitian operator ProjTo0. This operator, given a qubit in a maximally mixed state, simulates projection to |0> basis vector. (We use this operator instead of measurement as this would create two probabilistic branches, one in |0> and the other in |1> basis state, what would double the number of required resources on the simulating computer.)

On line 2.1, we declare method computeSomething() which declares a qubit variable psi (line 2.2) and allocates a new qubit and assigns it to variable psi (line 2.3). Then the qubit is projected to |0> basis vector (line 2.4) and turned into |1> by σx operator (line 2.5). Finally, the state of the variable psi is displayed (line 2.6).

On line 3.1, we declare method createEPR() which creates two qubits in overall state 1/2(|00>+|11>) and returns this quantum system pair. First, it declares two qubit variables psi1 and psi2 (line 3.2). Then, a quantum compound system variable psiEPR, which is composed of quantum systems psi1 and psi2, is declared (line 3.3). On the next two lines (3.4 and 3.5), two qubits are allocated and assigned to variables psi1 and psi2. Both qubits are projected to |0> basis vector (lines 3.6 and 3.7). The following two lines 3.8 and 3.9 create the entanglement by application of Hadamard operator to first qubit and CNot operator to both qubits, psi1 being control and psi2 target qubit. On line 3.10, the created EPR pair is returned to the caller.

On line 4.1, method angela is declared. This method receives a channel end for transferring integers and a qubit as arguments. The qubit should be a particle from and EPR pair as it is used for teleportation. On lines 4.2 and 4.3, two variables i and phi are declared. The value of phi is obtained as return value of method computeSomething() call (line 4.4). On the next line 4.5, qubits phi and auxTeleportState are measured in Bell basis and the result of measurement is sent over a channel using its end c0.

Method bert is declared on line 5.1. This method also receives a channel end for transferring integers and a qubit as arguments. The qubit should be a particle from and EPR pair as it is used for teleportation. On line 5.2, an integer variable i is declared and a value is received from the given channel end (line 5.3). On the next lines (from 5.4 to 5.11), correction is done as required by the teleportation protocol. Finally the state of received qubit is displayed (line 5.12).

The main method from which the program is started is declared on line 6.1. It declares a channel c on line 6.2. The ends of the channel are idetified as c0 and c1. Next, two qubit variables psi1 and psi2 (line 6.3) and a compound quantum system variable psiEPR (line 6.4) are declared. An EPR pair is created by call to createEPR() method and assigned to psiEPR variable (line 6.5). This fills also variables psi1 and psi2 which the variable psiEPR is composed of. Then a channel capable of transmitting integers is allocated (line 6.6) and assigned to variable c (this also fills its ends c0 and c1). On the next line (6.7), a new process is started from method angela and one particle from the EPR pair and one channel end is passed to it. The other particle and the other channel end are passed to method bert on line 6.8.

The program

1.1#library "library.libq"
/****************************************************************************** In this method, we allocate a new quantum bit. This is allocated to maximally mixed state. We then use a nasty operation projTo0(psi) defined in library.libq to turn it into state |0> and then by σx transformation to (|1>). ******************************************************************************/
2.1qbit computeSomething() {
2.2 qbit psi;
2.3 psi = new qbit();
2.4 ProjTo0(psi);
2.5 Sigma_x(psi);
2.6 dump_q(psi);
2.7 return psi;
2.8}
/****************************************************************************** In this method, EPR pair is created. We use a nasty operation projTo0(psi1) defined in library.libq to turn psi1 into state |0>. Then by Had we get (|0>+|1>)/sqrt(2) and finally by CNot to 1/2(|00>+|11>) ******************************************************************************/
3.1qbit @ qbit createEPR() {
3.2 qbit psi1, psi2;
3.3 psiEPR aliasfor [psi1, psi2];
3.4 psi1 = new qbit();
3.5 psi2 = new qbit();
3.6 ProjTo0(psi1);
3.7 ProjTo0(psi2);
3.8 Had(psi1);
3.9 CNot(psi1, psi2);
3.10 return psiEPR;
3.11}
/****************************************************************************** This method defines behaviour of one process - it gets one channel end and one particle from EPR pair as arguments, then it creates its own particle phi which is finally measured together with the half of EPR pair and the result is sent over the given channel. ******************************************************************************/
4.1void angela(channelEnd[int] c0, qbit auxTeleportState) {
4.2 int i;
4.3 qbit phi;
4.4 phi = computeSomething();
4.5 i = measure(BellBasis, phi, auxTeleportState);
4.6 send(c0, i);
4.7}
/****************************************************************************** In this method, an integer is received from a channel and the qubit stateToTeleportOn passed as parameter is modified according to received integer. This qubit is the destination qubit onto which the teleported state gets teleported on. ******************************************************************************/
5.1void bert(channelEnd[int] c1, qbit stateToTeleportOn) {
5.2 int i;
5.3 i = recv(c1);
5.4 if (i == 1) {
5.5 Sigma_z(stateToTeleportOn);
5.6 } else if (i == 2) {
5.7 Sigma_x(stateToTeleportOn);
5.8 } else if (i == 3) {
5.9 Sigma_x(stateToTeleportOn);
5.10 Sigma_z(stateToTeleportOn);
5.11 }
5.12 dump_q(stateToTeleportOn);
5.13}
/****************************************************************************** Main method - from this method, the program is run. In its body, an EPR pair and a channel for sending integers is allocated. Then a new process is started from method angela(). One channel end and one EPR-pair particle is passed to it. Finally, method bert() is invoked. ******************************************************************************/
6.1void main() {
6.2 channel[int] c withends [c0,c1];
6.3 qbit psi1, psi2;
6.4 psiEPR aliasfor [psi1, psi2];
6.5 psiEPR = createEPR();
6.6 c = new channel[int]();
6.7 fork angela(c0, psi1);
6.8 bert(c1, psi2);
6.9}

Download source code