| {-# LANGUAGE ForeignFunctionInterface #-} |
| {-# LANGUAGE StrictData #-} |
|
|
| |
| |
| |
| |
| |
| |
|
|
| module LiquidLean.Jacobian.QuantumFortranBridge |
| ( haskell_theorem3_offload |
| ) where |
|
|
| import Foreign.C |
| import Foreign.Ptr |
| import System.IO.Unsafe (unsafePerformIO) |
| import Control.Monad.State.Strict (runState) |
| import Data.Ratio ((%)) |
|
|
| import LiquidLean.Jacobian.Theorem3Entry |
| ( theorem3EnforceGenusZero |
| , Theorem3Evidence(..) |
| , Theorem3Status(..) |
| ) |
| import LiquidLean.Jacobian.Theorem3Kernel |
| ( Polynomial |
| , Thermal(..) |
| , Energy(..) |
| , fromTerms |
| , zeroPoly |
| , onePoly |
| ) |
| import LiquidLean.Jacobian.QuantumChipInterface (ibm_verify_genus_zero) |
|
|
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| foreign export ccall haskell_theorem3_offload |
| :: CString -> CInt -> IO CInt |
|
|
| haskell_theorem3_offload :: CString -> CInt -> IO CInt |
| haskell_theorem3_offload polyStrPtr energyBudgetC = do |
| |
| polyStr <- peekCString polyStrPtr |
| let energyBudget = fromIntegral energyBudgetC :: Integer |
|
|
| |
| case parsePolynomialString polyStr of |
| Left _err -> return 3 |
| Right poly -> do |
| |
| let evidence = theorem3EnforceGenusZero poly energyBudget |
|
|
| case evidence of |
| Left _obstruction -> |
| |
| return 1 |
|
|
| Right ev -> do |
| |
| case evStatus ev of |
| GenusZeroProved _ -> do |
| |
| let genus = evGenusBound ev |
| quantumOk <- ibm_verify_genus_zero genus |
| if quantumOk |
| then return 0 |
| else return 4 |
|
|
| CounterexampleFound _ g -> do |
| |
| return 2 |
|
|
| AnalysisBlocked _ -> |
| |
| return 1 |
|
|
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| parsePolynomialString :: String -> Either String Polynomial |
| parsePolynomialString str |
| | all (\c -> c `elem` " \t\n") str = Right zeroPoly |
| | otherwise = do |
| terms <- parseTermsList (filter (/= ' ') str) |
| if null terms |
| then Right zeroPoly |
| else Right (fromTerms terms) |
|
|
| parseTermsList :: String -> Either String [(Int, Int, Rational)] |
| parseTermsList str = go str [] |
| where |
| go [] acc = Right (reverse acc) |
| go s acc = do |
| (term, rest) <- parseTerm s |
| case rest of |
| [] -> Right (reverse (term : acc)) |
| ('+':s') -> go s' (term : acc) |
| ('-':s') -> |
| |
| case parseTerm s' of |
| Right (u, x, c, s'') -> go s'' ((u, x, negate c) : (term : acc)) |
| Left e -> Left e |
| _ -> Left "Invalid polynomial format" |
|
|
| |
| parseTerm :: String -> Either String ((Int, Int, Rational), String) |
| parseTerm str = |
| case parseCoeff str of |
| Left e -> Left e |
| Right (c, rest) -> do |
| (u, rest') <- parseVarPower 'u' rest |
| (x, rest'') <- parseVarPower 'x' rest' |
| return ((u, x, c), rest'') |
|
|
| |
| parseCoeff :: String -> Either String (Rational, String) |
| parseCoeff str = go str "" False |
| where |
| go [] acc _ = if null acc |
| then Right (1, "") |
| else case reads acc of |
| [(n, "")] -> Right (fromInteger n, "") |
| _ -> Left ("Bad coefficient: " ++ acc) |
| go ('*':rest) acc _ = |
| case reads acc of |
| [(n, "")] -> Right (fromInteger n, rest) |
| _ -> if null acc then Right (1, rest) else Left ("Bad coefficient: " ++ acc) |
| go (c:rest) acc _ = go rest (acc ++ [c]) False |
|
|
| |
| parseVarPower :: Char -> String -> Either String (Int, String) |
| parseVarPower var str |
| | null str = Right (0, str) |
| | head str /= var = Right (0, str) |
| | otherwise = case drop 1 str of |
| ('^':rest) -> |
| case reads rest of |
| [(p, rest')] -> Right (p, rest') |
| _ -> Left ("Bad exponent for " ++ [var]) |
| rest -> Right (1, rest) |
|
|
| |
| |
| |
|
|
| |
| |
|
|