{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LINE 1 "Quipper/Algorithms/USV/Main.hs" #-}
module Quipper.Algorithms.USV.Main where
import Quipper
import Quipper.Libraries.Arith
import Quipper.Libraries.Decompose
import Quipper.Algorithms.USV.Definitions
import Quipper.Algorithms.USV.USV
import Quipper.Algorithms.USV.Simulate
import Quipper.Utils.CommandLine
import Quipper.Utils.Sampling
import System.Console.GetOpt
import System.Environment
import System.Exit
import System.IO
import System.Random
import Control.Monad
import Data.List
import Data.Char
data WhatToShow =
F
| G
| H
| USVP
| Q
| R
| TPP
| Sieve
| DCP
| Test
deriving Show
data Options = Options {
s :: Int,
n :: Int,
b :: [[Integer]],
what :: WhatToShow,
format :: Format,
gatebase :: GateBase
} deriving Show
defaultOptions :: Options
defaultOptions = Options
{ s = 1,
n = 5,
b = (replicate 5 (replicate 5 1)),
what = Sieve,
format = ASCII,
gatebase = Logical
}
options :: [OptDescr (Options -> IO Options)]
options =
[
Option ['h'] ["help"] (NoArg help) "print usage info and exit",
Option ['f'] ["format"] (ReqArg format "<format>") "output format for circuits (default: eps)",
Option ['g'] ["gatebase"] (ReqArg gatebase "<gatebase>") "type of gates to decompose into (default: logical)",
Option ['n'] ["n"] (ReqArg nnn "<n>") "parameter n (default: 5)",
Option ['b'] ["b"] (ReqArg bbb "<b>") "parameter b (default: 5X5 with entries = 1)",
Option ['s'] ["s"] (ReqArg sss "<s>") "Random number generator seed s (default: 1)",
Option ['F'] [] (NoArg (what F)) "output subroutine f (depends on b).",
Option ['G'] [] (NoArg (what G)) "output subroutine g (depends on b).",
Option ['H'] [] (NoArg (what H)) "output subroutine h (depends on n).",
Option ['U'] [] (NoArg (what USVP)) "output algorithm 1 (depends on b).",
Option ['Q'] [] (NoArg (what Q)) "output algorithm 2 (depends on b).",
Option ['R'] [] (NoArg (what R)) "output algorithm 3 (depends on b).",
Option ['T'] [] (NoArg (what TPP)) "output algorithm 4 (depends on n).",
Option ['S'] [] (NoArg (what Sieve)) "output sieving subroutine (depends on n).",
Option ['D'] [] (NoArg (what DCP)) "output algorithm 5 (depends on n).",
Option ['t'] [] (NoArg (what Test)) "test subroutine h (depends on n)."
]
where
help :: Options -> IO Options
help o = do
usage
exitSuccess
format :: String -> Options -> IO Options
format str o = do
case match_enum format_enum str of
[(_, f)] -> return o { format = f }
[] -> optfail ("Unknown format -- " ++ str ++ "\n")
_ -> optfail ("Ambiguous format -- " ++ str ++ "\n")
gatebase :: String -> Options -> IO Options
gatebase str o = do
case match_enum gatebase_enum str of
[(_, f)] -> return o { gatebase = f }
[] -> optfail ("Unknown gate base -- " ++ str ++ "\n")
_ -> optfail ("Ambiguous gate base -- " ++ str ++ "\n")
nnn :: String -> Options -> IO Options
nnn string o =
case parse_int string of
Just n | n >= 1 -> return o { n = n }
_ -> optfail ("Invalid value for parameter n -- " ++ string ++ "\n")
bbb :: String -> Options -> IO Options
bbb string o =
case parse_list_basis string of
Just b -> if (all is_zero_vector b)
then optfail ("0 is an invalid value for parameter b " ++ "\n")
else return o { b = b }
_ -> optfail ("Invalid value for parameter b -- " ++ string ++ "\n")
sss :: String -> Options -> IO Options
sss string o =
case parse_int string of
Just s -> return o { s = s }
_ -> optfail ("Invalid value for parameter s -- " ++ string ++ "\n")
what :: WhatToShow -> Options -> IO Options
what w o = return o { what = w }
dopts :: [String] -> IO Options
dopts argv =
case getOpt Permute options argv of
(o, [], []) -> (foldM (flip id) defaultOptions o)
(_, _, []) -> optfail "Too many non-option arguments\n"
(_, _, errs) -> optfail (concat errs)
usage :: IO ()
usage = do
putStr (usageInfo header options)
putStr (show_enum "format" format_enum)
putStr (show_enum "gatebase" gatebase_enum)
where header = "Usage: usv [OPTION...]"
parse_list_basis :: String -> Maybe [[Integer]]
parse_list_basis s = case reads s of
[(ns, "")] -> Just ns
_ -> Nothing
main :: IO()
main = do
argv <- getArgs
options <- dopts argv
case options of
Options { what = what, format = format, gatebase = gatebase, n = n, b = b, s = s} ->
case what of
F -> print_generic format (decompose_generic gatebase (f_quantum b p m i0)) twopoint_from_b
G -> print_generic format (decompose_generic gatebase (g_quantum (toInteger n) ws)) vector_from_b
H -> print_generic format (decompose_generic gatebase h_quantum) vector_from_n
USVP -> print_generic format (decompose_generic gatebase (uSVP b))
Q -> print_generic format (decompose_generic gatebase (algorithm_Q b (l, m, i0, p) randomgen))
R -> print_generic format (decompose_generic gatebase (algorithm_R b l m i0 p randomgen))
TPP -> print_generic format (decompose_generic gatebase (tPP n)) (replicate (4*n^2+n) twopoint_from_n)
Sieve -> print_generic format (decompose_generic gatebase (\l -> sieving n 2 (zip l [0..]))) (replicate (2^n-1) qubit)
DCP -> print_generic format (decompose_generic gatebase (dCP n 0 0)) (replicate (8^n) cosetstate)
Test -> h_test n
where
randomgen = mkStdGen s
n_from_b = length b
l = ceiling $ norm $ head b
p = find_prime ((n_from_b)^3)
m = p-1
i0 = 0
max_b = maximum (map maximum b)
s = ceiling (logBase 2 (fromIntegral max_b)) + 5*n
twopoint_from_b = (qubit, (replicate n_from_b (qdint_shape (4*n_from_b))))
vector_from_b = (replicate n_from_b (qdint_shape s))
vector_from_n = (replicate n (qdint_shape (4*n)))
twopoint_from_n = (qubit, vector_from_n)
cosetstate = (qubit, (qdint_shape n))
ws = take n $ sample_random0 randomgen 1