packages feed

quipper-demos-0.9.0.0: Quipper/Demos/QEC.hs

import Quipper

-- import other stuff
import Control.Monad (zipWithM_)

-- ======================================================================
-- ALGORITHM SPECIFIC CODE

{- the test circuit from Alex V. and Benoit's email. It looks like
this:

In Alex's notation: 

  H(a)
  c = meas(a)
  if c then
    X(b)
  else Y(b)

In circuit notation:

 a -H--Meas===x==o==|
              |  |
 b -----------X--Y----

In QPL notation: 
-} 

testcircuit :: (Qubit, Qubit) -> Circ Qubit
testcircuit (a,b) = do
  hadamard a
  c <- measure a
  with_controls (c .==. 1) $ do {
    gate_X_at b
  }
  with_controls (c .==. 0) $ do {
    gate_Y_at b
  }
  cdiscard c
  return b

-- Let's see if we can implement some parts of the Steane
-- code. Working from Alex V.'s notes.


-- prepare the logical |+〉 state for the Steane code. This returns a list
-- of 7 qubits
plusState :: Circ [Qubit]
plusState = do
  -- prepare (a...g) in the state "00+0+++"
  [a,b,c,d,e,f,g] <- qinit_of_string "00+0+++"

  qnot_at a `controlled` c .==. 1
  qnot_at d `controlled` f .==. 1
  qnot_at b `controlled` g .==. 1
  qnot_at a `controlled` e .==. 1
  qnot_at d `controlled` g .==. 1
  qnot_at b `controlled` f .==. 1
  qnot_at a `controlled` g .==. 1
  qnot_at b `controlled` c .==. 1
  qnot_at d `controlled` e .==. 1
  
  return [a,b,c,d,e,f,g]

-- prepare the logical |0〉 state for the Steane code
zeroState :: Circ [Qubit]
zeroState = do
  -- prepare (a...g) in the state "00+0+++"
  [a,b,c,d,e,f,g] <- qinit_of_string "++0+000"

  qnot_at c `controlled` a .==. 1
  qnot_at f `controlled` d .==. 1
  qnot_at g `controlled` b .==. 1
  qnot_at e `controlled` a .==. 1
  qnot_at g `controlled` d .==. 1
  qnot_at f `controlled` b .==. 1
  qnot_at g `controlled` a .==. 1
  qnot_at c `controlled` b .==. 1
  qnot_at e `controlled` d .==. 1
  
  return [a,b,c,d,e,f,g]

preparePlus :: Circ ([Qubit], Bit)
preparePlus = do
  qs <- plusState
  vs <- plusState
  zipWithM_ (\q v -> qnot_at q `controlled` v .==. 1) qs vs
  measure <- mapM measure vs
  result <- cgate_and measure
  mapM_ cdiscard measure
  return (qs, result)

{-
-- this function operates on a 7-tuple of qubits, which are inputs and
-- outputs. The additional output Bit is 0 when the error correction
-- fails, else 1
preGateCorrection :: (Qubit,Qubit,Qubit,Qubit,Qubit,Qubit,Qubit) -> Bit
preGateCorrection q = do
  result = cinit_bit False
  (a, av, result_a) <- preparePlus []
  with_controls (result_a .==. 1) $ do {
    (b, bv, result_b) <- prepareZero
    with_controls (result_b .==. 1) $ do {
      zRecover(q, a),
      xRecover(q, b),
      cnot result
    }
    with_controls (result_b .==. 0) $ do {
      .....
-}

    
-- ======================================================================
-- main functions (ugly, don't follow an "idiom" yet)

-- this is just a main function to print the circuit
main_testcircuit :: IO()
main_testcircuit =
  print_generic Preview testcircuit (qubit,qubit)

-- this is just a main function to print the circuit
main_plusState :: IO()
main_plusState =
  print_generic Preview plusState

-- this is just a main function to print the circuit
main_zeroState :: IO()
main_zeroState =
  print_generic Preview zeroState
   
-- this is just a main function to print the circuit
main_preparePlus :: IO()
main_preparePlus =
  print_generic Preview preparePlus
   
main = main_preparePlus