packages feed

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

import Quipper

-- | 'example1': do a basis change, then perform some operation, then
-- uncompute the basis change. Drawback: if this is later controlled,
-- then the controls are applied to the basis change too, which is
-- unnecessary.

example1 :: Qubit -> Qubit -> Circ ()
example1 a b = do
  -- basis change
  gate_W_at a b
  qnot_at b `controlled` a
  
  -- some operation
  hadamard_at b `controlled` a
  
  -- undo basis change
  qnot_at b `controlled` a
  gate_W_at a b  

-- | 'example2': low-level solution. The 'without_controls' operator
-- can be used to inhibit the addition of further controls to blocks
-- of code.  (However, this is not very safe. A better way to do this
-- is shown in 'example3').

example2 :: Qubit -> Qubit -> Circ ()
example2 a b = do
  -- basis change
  without_controls $ do
    gate_W_at a b
    qnot_at b `controlled` a
  -- some operation
  hadamard_at b `controlled` a
  -- undo basis change
  without_controls $ do
    qnot_at b `controlled` a
    gate_W_at a b

-- | 'example3': a better way to achieve the effect of 'example2' is
-- to use the operator 'with_basis_change'. This will take care of the
-- uncomputation automatically, and also ensure that controls will not
-- be added to the basis change.
example3 :: Qubit -> Qubit -> Circ ()    
example3 a b = do
  with_basis_change basischange $ do
    hadamard_at b `controlled` a

    where
      basischange = do
        gate_W_at a b
        qnot_at b `controlled` a

-- | 'example4': a similar effect is introduced by the operator
-- 'with_ancilla'. Normally, the gates that initialize and terminate
-- ancillas cannot be controlled. However, when using the
-- 'with_ancilla' operator, the resulting circuit can be controlled as
-- a whole, provided that the body is controllable.

example4 :: Qubit -> Qubit -> Circ ()
example4 a b = do
  with_ancilla $ \d -> do
    with_basis_change (qnot_at d `controlled` b .==. False) $ do
      hadamard_at a `controlled` d

my_circuit :: Qubit -> Qubit -> Qubit -> Circ ()
my_circuit ctrl a b = do
  example1 a b `controlled` ctrl
  example2 a b `controlled` ctrl
  example3 a b `controlled` ctrl
  example4 a b `controlled` ctrl

main =
  print_simple Preview my_circuit