{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LINE 1 "Quipper/Demos/QuantumIfTest.hs" #-} import Quipper import Quipper.Libraries.Simulation import Quipper.Libraries.QuantumIf -- ---------------------------------------------------------------------- -- * Testing quantum \"if then else\" -- | A dummy value of type Double, to feed the type in the simulator double :: Double double = undefined -- | A testing function that displays a circuit that tests the 'if_then_elseQ' -- statement, and the results of running the circuit on various inputs. if_test :: IO () if_test = do print_simple ASCII ifTest2 print_simple Preview ifTest2 res0 <- run_generic_io double ifTest2 (False,False,False) putStrLn (show res0) res1 <- run_generic_io double ifTest2 (False,False,True) putStrLn (show res1) res2 <- run_generic_io double ifTest2 (False,True,False) putStrLn (show res2) res3 <- run_generic_io double ifTest2 (False,True,True) putStrLn (show res3) res4 <- run_generic_io double ifTest2 (True,False,False) putStrLn (show res4) res5 <- run_generic_io double ifTest2 (True,False,True) putStrLn (show res5) res6 <- run_generic_io double ifTest2 (True,True,False) putStrLn (show res6) res7 <- run_generic_io double ifTest2 (True,True,True) putStrLn (show res7) -- | A test of the 'if_then_elseQ' function. ifTest :: Circ (Qubit,Qubit,Qubit) ifTest = do (q0,q1,q2,q3,q4,q5,q6) <- qinit (False,False,False,False,False,False,False) qnot_at q4 if_then_elseQ (Or (A q0) (And (A q1) (Not (A q2)))) ( --if q0 | (q1 & !q2) qnot_at q4 ) ( if_then_elseQ (And (A q2) (A q3)) ( --else if qnot_at q5 ) ( -- else qnot_at q6 ) ) return (q4,q5,q6) -- | Another test of the 'if_then_elseQ' function. ifTest2 :: (Qubit,Qubit,Qubit) -> Circ (Qubit,Qubit) ifTest2 (l,p,d) = do ctrl <- qinit True (x,y) <- qinit (False,False) with_controls ctrl ( do if_then_elseQ (Or (A l) (And (A p) (Not (A d)))) ( --if l | (p & !d) qnot_at x ) ( -- else qnot_at y ) ) qdiscard (l,p,d) qterm True ctrl return (x,y) -- | A simple test of the 'if_then_elseQ' function. ifTest3 :: Qubit -> Circ (Qubit,Qubit) ifTest3 q = do (q0,q1) <- qinit (False,False) if_then_elseQ (A q) ( qnot_at q0 ) ( qnot_at q1 ) qdiscard q return (q0,q1) -- | A small circuit for testing 'if_then_elseQinv' statements. small_circ :: [Qubit] -> Circ ([Qubit],Qubit,Qubit) small_circ qs = do (q1,q2) <- qinit (False,False) tempReg0 <- qinit (replicate (length qs) False) tempReg1 <- qinit (replicate (length qs) True) let boolean_statement = foldr1 (\x y -> And x y) (map A qs) let boolean_statement_out = Not boolean_statement if_then_elseQinv boolean_statement ( do qnot_at q1 swap (reverse tempReg0) (reverse qs) return () ) ( do swap tempReg1 qs qnot_at q2 ) boolean_statement_out return (qs,q1,q2) -- | Display the 'small_circ'. print_small_circ :: IO () print_small_circ = print_generic Preview small_circ (replicate 4 qubit) -- | Simulate the 'small_circ'. test_small_circ :: [Bool] -> IO () test_small_circ bs = do putStr (show bs ++ " -> ") res <- run_generic_io double small_circ bs putStrLn (show res) -- | A main function. main :: IO () main = test_small_circ [True,True,False]