-- | Generates the XML packet that contains information about the interface
genHandShake :: CMDL_PgipState -> CMDL_PgipState
let msg = ( "<usespgip version = \"2.0\">"++
"<pgipelem>askpgip</pgipelem>"++
"<pgipelem>askpgml</pgipelem>"++
"<pgipelem>askprefs</pgipelem>"++
"<pgipelem>getpref</pgipelem>"++
"<pgipelem>setpref</pgipelem>"++
"<pgipelem>proverinit</pgipelem>"++
"<pgipelem>proverexit</pgipelem>"++
"<pgipelem>startquiet</pgipelem>"++
"<pgipelem>stopquiet</pgipelem>"++
"<pgipelem>pgmlsymbolson</pgipelem>"++
"<pgipelem>pgmlsymbolsoff</pgipelem>"++
"<pgipelem>dostep</pgipelem>"++
"<pgipelem>undostep</pgipelem>"++
"<pgipelem>redostep</pgipelem>"++
"<pgipelem>abortgoal</pgipelem>"++
"<pgipelem>forget</pgipelem>"++
"<pgipelem>restoregoal</pgipelem>"++
"<pgipelem>askids</pgipelem>"++
"<pgipelem>showid</pgipelem>"++
"<pgipelem>askguise</pgipelem>"++
"<pgipelem>parsescript</pgipelem>"++
"<pgipelem>showproofstate</pgipelem>"++
"<pgipelem>showctxt</pgipelem>"++
"<pgipelem>searchtheorems</pgipelem>"++
"<pgipelem>setlinewidth</pgipelem>"++
"<pgipelem>viewdoc</pgipelem>"++
"<pgipelem>doitem</pgipelem>"++
"<pgipelem>undoitem</pgipelem>"++
"<pgipelem>redoitem</pgipelem>"++
"<pgipelem>abortheory</pgipelem>"++
"<pgipelem>retracttheory</pgipelem>"++
"<pgipelem>loadfile</pgipelem>"++
"<pgipelem>openfile</pgipelem>"++
"<pgipelem>closefile</pgipelem>"++
"<pgipelem>abortfile</pgipelem>"++
"<pgipelem>changecwd</pgipelem>"++
"<pgipelem>systemcmd</pgipelem>"++
" </acceptedpgipelems>"++
in case useXML pgipData of
True -> addToMsg msg [] pgipData
-- | The function executes a communication step,
i.e. waits for input,
-- processes the message and outputs the answer
communicationStep:: CMDL_PgipState -> CMDL_State ->
IO (CMDL_PgipState, CMDL_State)
communicationStep pgD st =
tmp <- timeoutReadPacket (maxWaitTime pgD) pgD
Nothing -> case resendMsgIfTimeout pgD of
hPutStrLn (hout pgD) $ theMsg pgD
False -> communicationStep pgD st
cmds <- parseMsg pgD smtxt
let pgipSt = case useXML pgD of
addToMsg "<normalresponse></pgmltext>" []$
genPgipTag $ resetMsg [] pgD{
False -> resetMsg [] pgD{
(nwSt, nwPgipState) <- processCmds cmds st pgipSt
let nwPgipSt = case useXML pgD of
addToMsg "<ready/></pgip>" [] nwPgipState
hPutStrLn (hout pgD) $ theMsg nwPgipSt
-- | Comunicates over a port at which the prover should listen
cmdlListen2Port :: Bool -> Int -> IO CMDL_State
cmdlListen2Port swXML portNb
putStrLn("Starting hets. Listen to port "++(show portNb))
servSock <- listenOn $ PortNumber (fromIntegral portNb)
(servH,_,_) <- accept servSock
pgData <- genCMDL_PgipState swXML servH servH
True -> addToMsg "<ready/></pgip>" []
False -> resetMsg [] pgData
waitLoop pgD emptyCMDL_State
(nwpgD,nwSt) <- communicationStep pgipD st
False -> waitLoop nwpgD nwSt
-- | Comunicates over a port to which the prover has to connect
cmdlConnect2Port :: Bool -> String -> Int -> IO CMDL_State
cmdlConnect2Port swXML hostName portNb
putStrLn ("Starting hets. Connecting to port "++(show portNb))
sockH <- connectTo hostName $ PortNumber (fromIntegral portNb)
pgData <- genCMDL_PgipState swXML sockH sockH
True -> addToMsg "<ready/></pgip>" []
False -> resetMsg [] pgData
waitLoop pgD emptyCMDL_State
(nwpgD,nwSt) <- communicationStep pgipD st
False -> waitLoop nwpgD nwSt
-- | Reads from a handle, it waits only for a certain amount of time,
-- if no input comes it will return Nothing
timeoutReadPacket :: Int -> CMDL_PgipState -> IO (Maybe String)
timeoutReadPacket untilTimeout st
smtmp <- hWaitForInput (hin st) untilTimeout
True -> readPacket [] $ hin st
False -> hGetLine $ hin st
-- | Waits until it reads an entire XML packet
readPacket :: String -> Handle -> IO String
case isInfixOf "</pgip>" tmp of
True -> return (acc++tmp)
False -> readPacket (acc++tmp) hf
-- | Runs a shell in which the communication is expected to be
cmdlRunXMLShell :: IO CMDL_State
pgData <- genCMDL_PgipState True stdin stdout
let pgD = addToMsg "<ready/></pgip>" []
waitLoop pgD emptyCMDL_State
(nwpgD,nwSt) <- communicationStep pgipD st
False -> waitLoop nwpgD nwSt
-- | It inserts a given string into the XML packet as
genAnswer :: CMDL_PgipState -> CMDL_PgipState
True -> case nonFatalErrMsg st of
theMsg = (theMsg st) ++ "</pgmltext></normalresponse>"
theMsg = (theMsg st) ++ "</pgmltext></normalresponse>" ++
"<errorresponse fatality=\"nonfatal\">"++
"<pgmltext>"++ (nonFatalErrMsg st) ++
"</pgmltext></errorresponse>"
False -> case nonFatalErrMsg st of
theMsg = (theMsg st)++"\n"++stxt
-- | It inserts a given string into the XML packet as
genErrAnswer :: String -> CMDL_PgipState -> CMDL_PgipState
True ->addToMsg ("</pgmltext></normalresponse>"++
"<errorresponse fatality=\"fatal\"><pgmltext>"++
str++"</pgmltext></errorresponse>") [] st
False -> addToMsg str [] st
-- | Executes given commands and returns output message and the new state
processCmds :: [CMDL_XMLcommands] -> CMDL_State -> CMDL_PgipState ->
IO (CMDL_State, CMDL_PgipState)
processCmds cmds state pgipState
let pgipSt = pgipState {resendMsgIfTimeout = False,
[] -> case useXML pgipSt of
True -> return (state, genAnswer pgipSt )
False -> return (state, pgipSt)
(XML_Execute str):l -> do
hPutStrLn (hout pgipSt) $ theMsg pgipSt
let nPGIP = resetMsg [] pgipSt
nwSt <- cmdlProcessString str state
case errorMsg $ output nwSt of
[] -> processCmds l nwSt $
addToMsg (outputMsg $ output nwSt)
_ -> return (nwSt, genErrAnswer
(errorMsg $ output nwSt) nPGIP)
processCmds l state $ addToMsg "Exiting prover" []
True -> return (state, genHandShake
False -> return (state, resetMsg [] pgipSt)
processCmds l emptyCMDL_State $ addToMsg
"Prover state was reseted" [] pgipSt
-- Quiet not yet implemented !!
addToMsg "Quiet mode doesn't work properly" [] pgipSt {
-- Quiet not yet implemented !!
addToMsg "Quiet mode doesn't work properly" [] pgipSt {
(XML_OpenGoal str) :l -> do
hPutStrLn (hout pgipSt) $ theMsg pgipSt
let nPGIP = resetMsg [] pgipSt
nwSt <- cmdlProcessString ("add goals "++str++"\n") state
case errorMsg $ output nwSt of
[] -> processCmds l nwSt $
addToMsg (outputMsg $ output nwSt)
(errorMsg $ output nwSt) nPGIP
_ -> return (nwSt, genErrAnswer (errorMsg $ output nwSt)
(XML_CloseGoal str) :l -> do
hPutStrLn (hout pgipSt) $ theMsg pgipSt
let nPGIP = resetMsg [] pgipSt
nwSt <- cmdlProcessString ("add goals "++str++"\n prove \n")
case errorMsg $ output nwSt of
[] -> processCmds l nwSt $
addToMsg (outputMsg $ output nwSt)
(errorMsg $ output nwSt) nPGIP
_ -> return (nwSt, genErrAnswer (errorMsg $ output nwSt)
(XML_GiveUpGoal str) :l -> do
hPutStrLn (hout pgipSt) $ theMsg pgipSt
let nPGIP = resetMsg [] pgipSt
nwSt <- cmdlProcessString ("del goals "++str++"\n") state
case errorMsg $ output nwSt of
[] -> processCmds l nwSt $
addToMsg (outputMsg $ output nwSt)
(errorMsg $ output nwSt) nPGIP
_ -> return (nwSt, genErrAnswer (errorMsg $ output nwSt)
(XML_Unknown str) :_ -> do
return (state, addToMsg [] ("Unknown command : "++str)
hPutStrLn (hout pgipSt) $ theMsg pgipSt
let nPGIP = resetMsg [] pgipSt
nwSt <- cmdlProcessString ("undo \n") state
case errorMsg $ output nwSt of
[] -> processCmds l nwSt $
addToMsg (outputMsg $ output nwSt)
(errorMsg $ output nwSt) nPGIP
_ -> return (nwSt, genErrAnswer (errorMsg $ output nwSt)
hPutStrLn (hout pgipSt) $ theMsg pgipSt
let nPGIP = resetMsg [] pgipSt
nwSt <- cmdlProcessString ("redo \n") state
case errorMsg $ output nwSt of
[] -> processCmds l nwSt $
addToMsg (outputMsg $ output nwSt)
(errorMsg $ output nwSt) nPGIP
_ -> return (nwSt, genErrAnswer (errorMsg $ output nwSt)
(XML_Forget str) :l -> do
hPutStrLn (hout pgipSt) $ theMsg pgipSt
let nPGIP = resetMsg [] pgipSt
nwSt <- cmdlProcessString ("del axioms "++str++"\n") state
case errorMsg $ output nwSt of
[] -> processCmds l nwSt $
addToMsg (outputMsg $ output nwSt)
(errorMsg $ output nwSt) nPGIP
_ -> return (nwSt, genErrAnswer (errorMsg $ output nwSt)
(XML_OpenTheory str) :l -> do
hPutStrLn (hout pgipSt) $ theMsg pgipSt
let nPGIP = resetMsg [] pgipSt
nwSt <- cmdlProcessString ("select "++str ++ "\n") state
case errorMsg $ output nwSt of
[] -> processCmds l nwSt $
addToMsg (outputMsg $ output nwSt)
(errorMsg $ output nwSt) nPGIP
_ -> return (nwSt, genErrAnswer (errorMsg $ output nwSt)
(XML_CloseTheory _) :l -> do
case i_state $ intState state of
processCmds l state $ addToMsg "Theory closed" [] pgipSt
add2hist [IStateChange $ Just ist] $
intState = (intState state) {
i_state = Just $ emptyIntIState
(i_libEnv ist) (i_ln ist)
processCmds l nwSt $ addToMsg "Theory closed" [] pgipSt
(XML_CloseFile _) :l -> do
processCmds l emptyCMDL_State $ addToMsg "File closed" []
(XML_LoadFile str) : l -> do
hPutStrLn (hout pgipSt) $ theMsg pgipSt
let nPGIP = resetMsg [] pgipSt
nwSt <- cmdlProcessString ("use "++str++"\n") state
case errorMsg $ output nwSt of
[] -> processCmds l nwSt $
addToMsg (outputMsg $ output nwSt)
(errorMsg $ output nwSt) nPGIP
_ -> return (nwSt, genErrAnswer (errorMsg $ output nwSt)