Prove.hs revision 5c7228df8b5c735df42d849ffde9cbb96958a849
7abd0c58a5ce51db13f93de82407b2188d55d298Christian MaederModule : $Header$
81d182b21020b815887e9057959228546cf61b6bChristian MaederDescription : Interface for the SPASS theorem prover.
14a1af9d9909dc47dc7fee6b0170b7ac0aef85daChristian MaederCopyright : (c) Rene Wagner, Klaus Lttich, Uni Bremen 2005-2006
97018cf5fa25b494adffd7e9b4e87320dae6bf47Christian MaederLicense : similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt
3f69b6948966979163bdfe8331c38833d5d90ecdChristian MaederMaintainer : luettich@tzi.de
7abd0c58a5ce51db13f93de82407b2188d55d298Christian MaederStability : provisional
2ac1742771a267119f1d839054b5e45d0a468085Christian MaederPortability : needs POSIX
35597678f1c9da703de8d0b6b66ea63247ebe884Christian MaederInterface for the SPASS theorem prover.
c00adad2e9459b422dee09e3a2bddba66b433bb7Christian MaederSee <http://spass.mpi-sb.mpg.de/> for details on SPASS.
e8ffec0fa3d3061061bdc16e44247b9cf96b050fChristian Maeder - window opens too small on linux; why? ... maybe fixed
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder --> failure still there, opens sometimes too small (using KDE),
14a1af9d9909dc47dc7fee6b0170b7ac0aef85daChristian Maeder but not twice in a row
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder - keep focus of listboxes if updated (also relevant for
e8ffec0fa3d3061061bdc16e44247b9cf96b050fChristian Maeder - check if the theorem is used in the proof;
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder if not, the theory is inconsistent;
d42a01c4eb6892fe23ca9eff107bb29f4a229480Christian Maeder mark goal as proved and emmit a warning...
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder - Implement a consistency checker based on GUI
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian Maedermodule SPASS.Prove (spassProver,spassProveGUI,spassProveBatch) where
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian Maederimport SPASS.Print (genSPASSProblem)
35597678f1c9da703de8d0b6b66ea63247ebe884Christian Maederimport qualified Common.AS_Annotation as AS_Anno
81946e2b3f6dde6167f48769bd02c7a634736856Christian Maederimport ChildProcess
2ac1742771a267119f1d839054b5e45d0a468085Christian Maederimport ProcessClasses
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian Maederimport qualified Control.Exception as Exception
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian Maederimport qualified Control.Concurrent as Concurrent
ce7653c9c71e23bf04a5ec0ca5cb600c3738a909Christian Maederimport SpinButton
2ac1742771a267119f1d839054b5e45d0a468085Christian Maederimport Messages
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian Maederimport TextDisplay
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian Maederimport Separator
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maederimport XSelection
b1bd8688a1ce545444792a307412711c2c61df5fChristian Maederimport qualified Common.Lib.Map as Map
b1bd8688a1ce545444792a307412711c2c61df5fChristian Maeder-- * Prover implementation
b1bd8688a1ce545444792a307412711c2c61df5fChristian Maeder The Prover implementation. First runs the batch prover (with graphical
b1bd8688a1ce545444792a307412711c2c61df5fChristian Maeder feedback), then starts the GUI prover.
b1bd8688a1ce545444792a307412711c2c61df5fChristian MaederspassProver :: Prover Sign Sentence ()
b1bd8688a1ce545444792a307412711c2c61df5fChristian Maeder Prover { prover_name = "SPASS",
b1bd8688a1ce545444792a307412711c2c61df5fChristian Maeder prover_sublogic = "SPASS",
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder prove = spassProveGUI
5ba383b1607c20c57e14324e72cee2c789436d5fChristian Maeder-- * Shared data structures and assorted utility functions
14a1af9d9909dc47dc7fee6b0170b7ac0aef85daChristian Maeder Represents a prover configuration used when proving a goal.
2ac1742771a267119f1d839054b5e45d0a468085Christian Maederdata SPASSConfig = SPASSConfig {
0f0aa53f11a0d1ab08c76428b9de73db5b17c977Christian Maeder -- | time limit in seconds passed
7c35990c03276d1e675ea6f4ba38f47081620d77Christian Maeder -- to SPASS via -TimeLimit. Default will be used if Nothing.
7c35990c03276d1e675ea6f4ba38f47081620d77Christian Maeder timeLimit :: Maybe Int,
0f0aa53f11a0d1ab08c76428b9de73db5b17c977Christian Maeder -- | True if timelimit exceed during last prover run
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian Maeder timeLimitExceeded :: Bool,
14a1af9d9909dc47dc7fee6b0170b7ac0aef85daChristian Maeder -- | extra options passed verbatimely to SPASS.
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian Maeder -- -DocProof, -Stdin, and -TimeLimit will be overridden.
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian Maeder extraOpts :: [String]
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder } deriving (Eq, Ord, Show)
840b2a6f37ec58f3281da16fafbc4121462c856aChristian Maeder Creates an empty SPASSConfig. Default time limit and no extra options.
5ba383b1607c20c57e14324e72cee2c789436d5fChristian MaederemptyConfig :: SPASSConfig
0f0aa53f11a0d1ab08c76428b9de73db5b17c977Christian MaederemptyConfig = SPASSConfig {timeLimit = Nothing,
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian Maeder timeLimitExceeded = False,
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian Maeder extraOpts = []}
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder Utility function to set the time limit of a SPASSConfig.
72909c6c1cfe9702f5910d0a135c8b55729c7917Christian Maeder For values <= 0 a default value is used.
14a1af9d9909dc47dc7fee6b0170b7ac0aef85daChristian MaedersetTimeLimit :: Int -> SPASSConfig -> SPASSConfig
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian MaedersetTimeLimit n c = if n > 0 then c{timeLimit = Just n}
72909c6c1cfe9702f5910d0a135c8b55729c7917Christian Maeder else c{timeLimit = Nothing}
d5b008ac61f0f3d99f41ad3476f945e2b65bd3c0Christian Maeder Utility function to set the extra options of a SPASSConfig.
d5b008ac61f0f3d99f41ad3476f945e2b65bd3c0Christian MaedersetExtraOpts :: [String] -> SPASSConfig -> SPASSConfig
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian MaedersetExtraOpts opts c = c{extraOpts = opts}
35597678f1c9da703de8d0b6b66ea63247ebe884Christian Maeder Represents the general return value of a prover run.
d5b008ac61f0f3d99f41ad3476f945e2b65bd3c0Christian Maederdata SpassProverRetval
d5b008ac61f0f3d99f41ad3476f945e2b65bd3c0Christian Maeder -- | SPASS completed successfully
d5b008ac61f0f3d99f41ad3476f945e2b65bd3c0Christian Maeder = SpassSuccess
d5b008ac61f0f3d99f41ad3476f945e2b65bd3c0Christian Maeder -- | SPASS did not terminate before the time limit exceeded
35597678f1c9da703de8d0b6b66ea63247ebe884Christian Maeder | SpassTLimitExceeded
d5b008ac61f0f3d99f41ad3476f945e2b65bd3c0Christian Maeder -- | an error occured while running SPASS
d5b008ac61f0f3d99f41ad3476f945e2b65bd3c0Christian Maeder | SpassError String
d5b008ac61f0f3d99f41ad3476f945e2b65bd3c0Christian Maeder deriving (Eq, Show)
d5b008ac61f0f3d99f41ad3476f945e2b65bd3c0Christian Maeder Checks whether a SpassProverRetval indicates that the time limit was
35597678f1c9da703de8d0b6b66ea63247ebe884Christian MaederisTimeLimitExceeded :: SpassProverRetval -> Bool
2ac1742771a267119f1d839054b5e45d0a468085Christian MaederisTimeLimitExceeded SpassTLimitExceeded = True
89dc77946055c0e4cb4671c4a74c3dcd55ed41a1Christian MaederisTimeLimitExceeded _ = False
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder Represents the result of a prover run.
d93bbbec133697cc79d59f9d7cc8e97458976c15Christian Maeder (Proof_status, full output)
35597678f1c9da703de8d0b6b66ea63247ebe884Christian Maedertype SPASSResult = (Proof_status (), [String])
2ac1742771a267119f1d839054b5e45d0a468085Christian MaederopenResult :: String -> SPASSResult
35597678f1c9da703de8d0b6b66ea63247ebe884Christian MaederopenResult n = (openSPASSProof_status n,[])
81946e2b3f6dde6167f48769bd02c7a634736856Christian MaederopenSPASSProof_status :: String -> Proof_status ()
35597678f1c9da703de8d0b6b66ea63247ebe884Christian MaederopenSPASSProof_status n =
d93bbbec133697cc79d59f9d7cc8e97458976c15Christian Maeder ((openProof_status n (prover_name spassProver))::Proof_status ())
35597678f1c9da703de8d0b6b66ea63247ebe884Christian Maeder {proofTree = ()}
35597678f1c9da703de8d0b6b66ea63247ebe884Christian Maeder-- * GUI Prover
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder-- ** Constants
35597678f1c9da703de8d0b6b66ea63247ebe884Christian Maeder Default time limit for the GUI mode prover in seconds.
35597678f1c9da703de8d0b6b66ea63247ebe884Christian MaederguiDefaultTimeLimit :: Int
0f0aa53f11a0d1ab08c76428b9de73db5b17c977Christian MaederguiDefaultTimeLimit = 10
d48085f765fca838c1d972d2123601997174583dChristian Maeder-- ** Data Structures
0f0aa53f11a0d1ab08c76428b9de73db5b17c977Christian Maeder We need to store one SPASSConfig per goal.
d93bbbec133697cc79d59f9d7cc8e97458976c15Christian Maedertype SPASSConfigsMap = Map.Map SPIdentifier SPASSConfig
c2dead95fafd7ca36d06ddf07606a1292ead6d8aChristian Maeder Adjusts the configuration associated to a goal by applying the supplied
10397bcc134edbcfbe3ae2c7ea4c6080036aae22Christian Maeder function or inserts a new emptyConfig with the function applied if there's
c2dead95fafd7ca36d06ddf07606a1292ead6d8aChristian Maeder no configuration associated yet.
c2dead95fafd7ca36d06ddf07606a1292ead6d8aChristian Maeder Uses Map.member, Map.adjust, and Map.insert for the corresponding tasks
c2dead95fafd7ca36d06ddf07606a1292ead6d8aChristian MaederadjustOrSetConfig :: (SPASSConfig -> SPASSConfig)
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder -- ^ function to be applied against the current
c2dead95fafd7ca36d06ddf07606a1292ead6d8aChristian Maeder -- configuration or a new emptyConfig
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder -> SPIdentifier -- ^ name of the goal
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder -> SPASSConfigsMap -- ^ current SPASSConfigsMap
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder -> SPASSConfigsMap
c2dead95fafd7ca36d06ddf07606a1292ead6d8aChristian Maeder -- ^ resulting SPASSConfigsMap with the changes applied
2ac1742771a267119f1d839054b5e45d0a468085Christian MaederadjustOrSetConfig f k m = if (Map.member k m)
c2dead95fafd7ca36d06ddf07606a1292ead6d8aChristian Maeder else Map.insert k (f emptyConfig) m
10397bcc134edbcfbe3ae2c7ea4c6080036aae22Christian Maeder Performs a lookup on the ConfigsMap. Returns the config for the goal or an
d9953bc9d3d8aa7290bf6d3c2c86b84c984a0f09Christian Maeder empty config if none is set yet.
2ac1742771a267119f1d839054b5e45d0a468085Christian MaedergetConfig :: SPIdentifier -> SPASSConfigsMap -> SPASSConfig
10397bcc134edbcfbe3ae2c7ea4c6080036aae22Christian MaedergetConfig spid m = if (isJust lookupId)
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder then fromJust lookupId
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder else emptyConfig
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder lookupId = Map.lookup spid m
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder Store one result per goal.
2ac1742771a267119f1d839054b5e45d0a468085Christian Maedertype SPASSResultsMap = Map.Map SPIdentifier SPASSResult
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder Map to SPASS compliant identifiers
2ac1742771a267119f1d839054b5e45d0a468085Christian Maedertype SPASSGoalNameMap = Map.Map String String
0f0aa53f11a0d1ab08c76428b9de73db5b17c977Christian Maeder Represents the global state of the prover GUI.
e3deb984f8f0a06e1b5ed101fb42aa11b8673ffaChristian Maederdata State = State { -- | currently selected goal or Nothing
0f0aa53f11a0d1ab08c76428b9de73db5b17c977Christian Maeder currentGoal :: Maybe SPIdentifier,
0f0aa53f11a0d1ab08c76428b9de73db5b17c977Christian Maeder -- | theory to work on
d9953bc9d3d8aa7290bf6d3c2c86b84c984a0f09Christian Maeder theory :: Theory Sign Sentence (),
d9953bc9d3d8aa7290bf6d3c2c86b84c984a0f09Christian Maeder -- | stores the prover configurations for each goal
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder configsMap :: SPASSConfigsMap,
d9953bc9d3d8aa7290bf6d3c2c86b84c984a0f09Christian Maeder -- | stores the results retrieved by running
5ba383b1607c20c57e14324e72cee2c789436d5fChristian Maeder -- SPASS for each goal
5ba383b1607c20c57e14324e72cee2c789436d5fChristian Maeder resultsMap :: SPASSResultsMap,
d9953bc9d3d8aa7290bf6d3c2c86b84c984a0f09Christian Maeder -- | stores a mapping to SPASS compliant
35597678f1c9da703de8d0b6b66ea63247ebe884Christian Maeder -- identifiers for all goals
35597678f1c9da703de8d0b6b66ea63247ebe884Christian Maeder namesMap :: SPASSGoalNameMap,
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder -- | list of all goals
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian Maeder goalsList :: [AS_Anno.Named SPTerm],
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder -- | logical part without theorems
0a39036fa485579a7b7c81cdd44a412392571927Christian Maeder initialLogicalPart :: SPLogicalPart,
d9953bc9d3d8aa7290bf6d3c2c86b84c984a0f09Christian Maeder batchModeIsRunning :: Bool,
d48085f765fca838c1d972d2123601997174583dChristian Maeder mainDestroyed :: Bool
7c35990c03276d1e675ea6f4ba38f47081620d77Christian Maederdata ThreadState = TSt { batchId :: Maybe Concurrent.ThreadId
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder , batchStopped :: Bool
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian MaederinitialThreadState :: ThreadState
f26a1fc3851297e6483cf3fb56e9c0967b8f8b13Christian MaederinitialThreadState = TSt { batchId = Nothing
d9953bc9d3d8aa7290bf6d3c2c86b84c984a0f09Christian Maeder , batchStopped = False}
35597678f1c9da703de8d0b6b66ea63247ebe884Christian Maeder Creates an initial State around a Theory.
81946e2b3f6dde6167f48769bd02c7a634736856Christian MaederinitialState :: Theory Sign Sentence () -> SPASS.Prove.State
36c6cc568751e4235502cfee00ba7b597dae78dcChristian MaederinitialState th =
35597678f1c9da703de8d0b6b66ea63247ebe884Christian Maeder State {currentGoal = Nothing,
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder configsMap = Map.fromList (map (\ g -> (AS_Anno.senName g,
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder emptyConfig)) goals),
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder map (\ g -> let gName = AS_Anno.senName g
9fb0db7f56cbb44c3df49552c04afc881267b84eChristian Maeder in (gName,openResult gName)) goals,
840b2a6f37ec58f3281da16fafbc4121462c856aChristian Maeder namesMap = collectNameMapping nSens oSens',
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder goalsList = goals,
bb13d067514a3f474166f345e098b81f3de11dbeChristian Maeder initialLogicalPart = foldl insertSentence
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder (signToSPLogicalPart sign)
bb13d067514a3f474166f345e098b81f3de11dbeChristian Maeder (reverse axioms),
bb13d067514a3f474166f345e098b81f3de11dbeChristian Maeder batchModeIsRunning = False,
bb13d067514a3f474166f345e098b81f3de11dbeChristian Maeder mainDestroyed = False
2ac1742771a267119f1d839054b5e45d0a468085Christian Maeder where Theory sign oSens = th
bb13d067514a3f474166f345e098b81f3de11dbeChristian Maeder oSens' = toNamedList oSens
840b2a6f37ec58f3281da16fafbc4121462c856aChristian Maeder nSens = prepareSenNames transSenName oSens'
bb13d067514a3f474166f345e098b81f3de11dbeChristian Maeder (axioms, goals) = partition AS_Anno.isAxiom nSens
bb13d067514a3f474166f345e098b81f3de11dbeChristian Maeder-- ** Defining the view
9fb0db7f56cbb44c3df49552c04afc881267b84eChristian Maeder Colors used by the GUI to indicate the status of a goal.
9fb0db7f56cbb44c3df49552c04afc881267b84eChristian Maederdata ProofStatusColour
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder -- | Proved, but theory is inconsitent
filterOpenGoals = Map.filter isOpenGoal
Generates a list of 'GUI.HTkUtils.LBGoalView' representations of all goals
from a 'SPASS.Prove.State'.
goalsView :: SPASS.Prove.State -- ^ current global prover state
let res = Map.lookup g (resultsMap s)
(map AS_Anno.senName (goalsList s))
goalProcessed :: IORef SPASS.Prove.State
-> AS_Anno.Named SPTerm -- ^ goal that has just been processed
(AS_Anno.senName nGoal)
updateDisplay :: SPASS.Prove.State -- ^ current global prover state
let mprfst = Map.lookup go (resultsMap st)
cf = Map.findWithDefault
timeEntry # HTk.value t'
optionsEntry # HTk.value opts'
axiomsLb # HTk.value (usedAxs::[String])
HTk.value guiDefaultTimeLimit]
-> Theory Sign Sentence () -- ^ theory consisting of a SPASS.Sign.Sign and a list of Named SPASS.Sign.Sentence
-- HBox for the upper part (goals on the left, options/results on the right)
-- right frame (options/results)
timeEntry # HTk.value
axiomsLb <- newListBox axiomsFrame [HTk.value $ ([]::[String]),
tEntry # HTk.value t'
batchTimeEntry # HTk.value batchTLimit
-- bottom frame (help/save/exit buttons)
Just $ AS_Anno.senName
let s'' = s'{resultsMap = Map.insert goal (res, output)
let result = Map.lookup goal (resultsMap s)
batchTimeEntry # HTk.value tLimit
let numGoals = Map.size $ filterOpenGoals $ resultsMap s
batchProverId <- Concurrent.forkIO
let proof_stats = map (\g -> let res = Map.lookup g (resultsMap s)
g' = Map.findWithDefault
(map AS_Anno.senName $ goalsList s)
findIndex (\sen -> AS_Anno.senName sen == goal)
(AS_Anno.senName sen)) beforeThis
insertSentence lp (provedGoal{AS_Anno.isAxiom = True}))
else (maybe (error ("SPASS.Prove.prepareLP: Goal "++goal++
id (find ((==goal) . AS_Anno.senName) (goalsList s)),
(Map.toList mp)) "}"
where trN x' = Map.findWithDefault
axs) (:axs) (Map.lookup ax nm)
reads ENV-variable HETS_SPASS_BATCH_TIME_LIMIT and if it exists and has an Int-value this value is returned otherwise the value of 'batchTimeLimit' is returned.
is <- Exception.catch (getEnv "HETS_SPASS_BATCH_TIME_LIMIT")
Exception.IOException ie ->
else Exception.throwIO e
_ -> Exception.throwIO e)
g = Map.lookup goal resMap
-> AS_Anno.Named SPTerm
then insertSentence lp (g{AS_Anno.isAxiom = True})
let gName = AS_Anno.senName g
if Map.member gName openGoals
AS_Anno.senName) gs))
AS_Anno.senName) gs))
Map.findWithDefault (openResult gName)
runSpass :: SPLogicalPart -- ^ logical part containing the input Sign and axioms and possibly goals that have been proved earlier as additional axioms
-> AS_Anno.Named SPTerm -- ^ goal to prove
spass <- newChildProcess "SPASS" [ChildProcess.arguments allOptions]
Exception.catch (runSpassReal spass)
(openResult $ AS_Anno.senName nGoal))
(openResult $ AS_Anno.senName nGoal))))
(openResult $ AS_Anno.senName nGoal))
(openSPASSProof_status (AS_Anno.senName nGoal))
{ goalStatus = Proved $ if elem (AS_Anno.senName nGoal) usedAxs
, usedAxioms = filter (/=(AS_Anno.senName nGoal)) usedAxs })