{-# LANGUAGE RecordWildCards #-}
module Language.Quil.Types (
Machine(..)
, machine
, Definitions(..)
, Gate
, Circuit
, Instruction(..)
, CircuitInstruction(..)
, CircuitQBit(..)
, Parameter(..)
, Name
, QBit
, QVariable
, Address
, Variable
, Label
, Expression(..)
, Number
, Parameters
, Arguments
, BitData(..)
, toBitVector
, boolFromBitVector
, finiteBitsFromBitVector
, integerFromBitVector
, doubleFromBitVector
, complexFromBitVector
) where
import Data.Binary.IEEE754 (doubleToWord, wordToDouble)
import Data.BitVector (BV, bitVec, extract, showHex, size, testBit)
import Data.Bits (FiniteBits(finiteBitSize))
import Data.Complex (Complex((:+)), imagPart, realPart)
import Data.Default (Default(def))
import Data.Int (Int8, Int16, Int32, Int64)
import Data.Monoid ((<>))
import Data.Qubit (Operator, Wavefunction, groundState)
import Data.Vector (Vector)
import Data.Word (Word8, Word16, Word32, Word64)
data Machine =
Machine
{
qstate :: Wavefunction
, cstate :: BV
, definitions :: Definitions
, counter :: Int
, halted :: Bool
}
instance Show Machine where
show Machine{..} =
unlines
[
"Quantum state: " ++ show qstate
, "Classical state: " ++ showHex cstate ++ " [" ++ show (size cstate) ++ "]"
, "Program counter: " ++ show counter
, "Halted? " ++ show halted
]
instance Default Machine where
def = machine 1 [BoolBit False]
machine :: Int
-> [BitData]
-> Machine
machine n cstate' =
let
qstate = groundState n
cstate = mconcat $ toBitVector <$> cstate'
definitions = def
counter = 0
halted = False
in
Machine{..}
data BitData =
BoolBit Bool
| IntBits8 Int8
| IntBits16 Int16
| IntBits32 Int32
| IntBits64 Int64
| WordBits8 Word8
| WordBits16 Word16
| WordBits32 Word32
| WordBits64 Word64
| IntegerBits Int Integer
| DoubleBits Double
| ComplexBits Number
deriving (Eq, Read, Show)
toBitVector :: BitData -> BV
toBitVector (BoolBit x) = bitVec 1 $ fromEnum x
toBitVector (IntBits8 x) = bitVec 8 $ toInteger x
toBitVector (IntBits16 x) = bitVec 16 $ toInteger x
toBitVector (IntBits32 x) = bitVec 32 $ toInteger x
toBitVector (IntBits64 x) = bitVec 64 $ toInteger x
toBitVector (WordBits8 x) = bitVec 8 $ toInteger x
toBitVector (WordBits16 x) = bitVec 16 $ toInteger x
toBitVector (WordBits32 x) = bitVec 32 $ toInteger x
toBitVector (WordBits64 x) = bitVec 64 $ toInteger x
toBitVector (IntegerBits n x) = bitVec n x
toBitVector (DoubleBits x) = bitVec 64 $ doubleToWord x
toBitVector (ComplexBits x) = bitVec 64 (doubleToWord $ realPart x) <> bitVec 64 (doubleToWord $ imagPart x)
boolFromBitVector :: Int
-> BV
-> Bool
boolFromBitVector = flip testBit
finiteBitsFromBitVector :: (Integral a, FiniteBits a)
=> Int
-> BV
-> a
finiteBitsFromBitVector k v =
let
y = fromIntegral . toInteger $ extract (k + finiteBitSize y - 1) k v
in
y
integerFromBitVector :: Int
-> Int
-> BV
-> Integer
integerFromBitVector k n = toInteger . extract (k + n - 1) k
doubleFromBitVector :: Int
-> BV
-> Double
doubleFromBitVector k = wordToDouble . fromIntegral . extract (k + 63) k
complexFromBitVector :: Int
-> BV
-> Number
complexFromBitVector k x = doubleFromBitVector (k + 64) x :+ doubleFromBitVector k x
data Definitions =
Definitions
{
gates :: [(Name, Gate)]
, circuits :: [(Name, Circuit)]
}
instance Default Definitions where
def = Definitions [] []
type Gate = [QBit] -> Arguments -> Operator
type Circuit = Definitions -> [QBit] -> Arguments -> Operator
data Instruction =
COMMENT String
| RESET
| I QBit
| X QBit
| Y QBit
| Z QBit
| H QBit
| PHASE Parameter QBit
| S QBit
| T QBit
| CPHASE00 Parameter QBit QBit
| CPHASE01 Parameter QBit QBit
| CPHASE10 Parameter QBit QBit
| CPHASE Parameter QBit QBit
| RX Parameter QBit
| RY Parameter QBit
| RZ Parameter QBit
| CNOT QBit QBit
| CCNOT QBit QBit QBit
| PSWAP Parameter QBit QBit
| SWAP QBit QBit
| ISWAP QBit QBit
| CSWAP QBit QBit QBit
| CZ QBit QBit
| DEFGATE Name [Variable] [Expression]
| USEGATE Name [Parameter] [QBit]
| DEFCIRCUIT Name [Variable] [QVariable] [CircuitInstruction]
| USECIRCUIT Name [Parameter] [QBit]
| MEASURE QBit (Maybe Address)
| HALT
| WAIT
| LABEL Label
| JUMP Label
| JUMP_WHEN Label Address
| JUMP_UNLESS Label Address
| FALSE Address
| TRUE Address
| NOT Address
| AND Address Address
| OR Address Address
| MOVE Address Address
| EXCHANGE Address Address
| NOP
| INCLUDE FilePath
| PRAGMA String
deriving (Eq, Read, Show)
data CircuitInstruction =
CircuitInstruction Instruction
| CircuitGate Name [Parameter] [CircuitQBit]
deriving (Eq, Read, Show)
data CircuitQBit =
CircuitQBit QBit
| CircuitQVariable QVariable
deriving (Eq, Read, Show)
data Parameter =
DynamicParameter Int (Maybe Int)
| Expression Expression
deriving (Eq, Read, Show)
type Name = String
type QBit = Int
type QVariable = String
type Address = Int
type Variable = String
type Label = String
data Expression =
Power Expression Expression
| Times Expression Expression
| Divide Expression Expression
| Plus Expression Expression
| Minus Expression Expression
| Negate Expression
| Sin Expression
| Cos Expression
| Sqrt Expression
| Exp Expression
| Cis Expression
| Number Number
| Variable Variable
deriving (Eq, Read, Show)
type Number = Complex Double
type Parameters = Vector Variable
type Arguments = Vector Number