Subversion

Galculator

?curdirlinks? -

Blame information for rev 7

Line No. Rev Author Line
1 1 paulosilva  
2 {-# LANGUAGE MultiParamTypeClasses, PatternSignatures, FlexibleContexts #-}
3 {-# OPTIONS_GHC -Wall #-}
4  
5 -------------------------------------------------------------------------------
6  
7 {- |
8 Module      :  Galculator.State
9 Description :  Global state of Galculator.
10 Copyright   :  (c) Paulo Silva
11 License     :  LGPL
12  
13 Maintainer  :  paufil@di.uminho.pt
14 Stability   :  experimental
15 Portability :  portable
16  
17 This module needs some improvements.
18  
19 -}
20  
21 -------------------------------------------------------------------------------
22  
23 module Galculator.State (
24   GalcState(..),
25   GalcStateT,
26   GalcSt,
27   emptyState,
28  
29   OpMode(..),
30   getOpMode,
31 7 paulosilva   inMode,
32 1 paulosilva  
33 7 paulosilva   updateProof,
34   enterProofMode,
35   enterFinalProofMode,
36   enterIndirectProofMode,
37  
38 1 paulosilva   setProof,
39   resetProof,
40  
41   getEnvironment,
42   addAssumption,
43   getLoadedModules,
44   getLaws,
45   getLaw,
46   getDefinitions,
47   addDefinition,
48   addModule,
49  
50   getCurExpr,
51   saveProof,
52   restartProof,
53  
54   undo,
55   removeModule,
56   getGC,
57   getGCs,
58   getAssumptions,
59  
60   getCurrentProof,
61   getExpression,
62  
63   getInitialExpr
64  ) where
65  
66 import Control.GalcError
67 import Control.Monad.Error
68 import Control.Monad.Fresh
69 import Control.Monad.State
70 import Control.Monad.Trans
71 import Data.Env
72 import Data.Existential
73 import Data.Maybe
74 import Data.IORef
75 7 paulosilva import Galculator.Proof
76 1 paulosilva import Language.Law.Syntax
77 import Language.Module.Syntax
78 import Language.R.Syntax
79  
80  
81 -------------------------------------------------------------------------------
82  
83 type GalcStateT t = ErrorT GalcError (FreshT [String] GalcState) t
84  
85 -------------------------------------------------------------------------------
86  
87 data GalcState a = GalcState {
88   unGalcState :: IORef GalcSt -> IO a }
89  
90 -------------------------------------------------------------------------------
91  
92 data GalcSt = GalcSt {
93   opMode           :: OpMode,
94  
95   modules          :: Env Module,
96   rtAssumpt        :: Env Law,
97   rtDefinitions    :: Env RType,
98  
99   proof            :: Maybe ProofSt
100  }
101  
102 -------------------------------------------------------------------------------
103  
104 data OpMode =
105     GlobalMode
106   | SetProofMode
107   | ProofMode
108   | IndirectProofMode
109   | FinalProofMode
110   deriving Eq
111  
112 -------------------------------------------------------------------------------
113  
114 getOpMode :: GalcStateT OpMode
115 getOpMode = ggets opMode
116  
117 -------------------------------------------------------------------------------
118  
119 enterGlobalMode :: GalcStateT ()
120 enterGlobalMode = updateGalcState $ \st -> st {opMode = GlobalMode}
121  
122 -------------------------------------------------------------------------------
123  
124 enterSetProofMode :: GalcStateT ()
125 enterSetProofMode = updateGalcState $ \st -> st {opMode = SetProofMode}
126  
127 -------------------------------------------------------------------------------
128  
129 enterProofMode :: GalcStateT ()
130 enterProofMode = updateGalcState $ \st -> st {opMode = ProofMode}
131  
132 -------------------------------------------------------------------------------
133  
134 enterIndirectProofMode :: GalcStateT ()
135 enterIndirectProofMode =
136   updateGalcState $ \st -> st {opMode = IndirectProofMode}
137  
138 -------------------------------------------------------------------------------
139  
140 enterFinalProofMode :: GalcStateT ()
141 enterFinalProofMode = updateGalcState $ \st -> st {opMode = FinalProofMode}
142  
143 -------------------------------------------------------------------------------
144 7 paulosilva inMode :: [OpMode] -> GalcStateT () -> GalcStateT ()
145 inMode lmod a = do
146   cmod <- getOpMode
147   if cmod `elem` lmod then a else throwError ModeError
148 1 paulosilva  
149 7 paulosilva -------------------------------------------------------------------------------
150  
151 1 paulosilva instance Monad GalcState where
152   (GalcState m) >>= k = GalcState $ \r -> m r >>= \a -> unGalcState (k a) r
153   return a = GalcState $ \_ -> return a
154  
155 -------------------------------------------------------------------------------
156  
157 instance MonadIO GalcState where
158   liftIO m = GalcState $ \_ -> m >>= return -- !??
159  
160 -------------------------------------------------------------------------------
161  
162 instance MonadState GalcSt GalcState where
163   get   = GalcState $ \r -> readIORef r
164   put s = GalcState $ \r -> writeIORef r s
165  
166 -------------------------------------------------------------------------------
167  
168 glift :: GalcState a -> GalcStateT a
169 glift = lift . lift
170  
171 -------------------------------------------------------------------------------
172 gget :: GalcStateT GalcSt
173 gget = glift get
174 -------------------------------------------------------------------------------
175 gput :: GalcSt -> GalcStateT ()
176 gput = glift . put
177 -------------------------------------------------------------------------------
178 ggets :: (GalcSt -> a) -> GalcStateT a
179 ggets = glift . gets
180 -------------------------------------------------------------------------------
181  
182 emptyState :: GalcSt
183 emptyState =
184   GalcSt {
185     opMode           = GlobalMode,
186     modules          = emptyEnv,
187     rtAssumpt        = emptyEnv,
188     rtDefinitions    = emptyEnv,
189  
190     proof            = Nothing
191   }
192  
193 -------------------------------------------------------------------------------
194  
195 updateGalcState :: (GalcSt -> GalcSt) ->  GalcStateT ()
196 updateGalcState f = glift . GalcState $ \r -> modifyIORef r f
197  
198 -------------------------------------------------------------------------------
199 -- | Updates the proof information.
200 updateProof :: (ProofSt -> GalcStateT ProofSt) -> GalcStateT ()
201 updateProof f = do
202   st   <- gget
203   prf  <- maybe2error NoProofError . proof $ st
204   prf' <- f prf
205   gput $ st {proof = Just prf'}
206  
207 -------------------------------------------------------------------------------
208 -- | Sets the law to prove and enters the set proof mode.
209 setProof :: Law -> GalcStateT ()
210 setProof e = (updateGalcState $
211   \st -> st { proof = Just $ ProofSt (getName e) e (Left (getLeft e)) [] })
212   >> enterSetProofMode
213  
214 -------------------------------------------------------------------------------
215 -- | Removes all the proof information and entes the global mode.
216 resetProof :: GalcStateT ()
217 resetProof =
218   (updateGalcState $ \st -> st { proof = Nothing }) >> enterGlobalMode
219  
220 -------------------------------------------------------------------------------
221 -- | Returns the environment where expressions can be evaluated.
222 --   The environment is composed of definitions, galois connections and
223 --   run-definitions.
224 getEnvironment :: GalcStateT (Env RType)
225 getEnvironment = do
226   mds <- ggets modules
227   let defs = map definitions . values $ mds
228       gcl =  map gcs . values $ mds
229   rtd <- ggets rtDefinitions
230   return $ foldr joinEnv rtd (defs ++ gcl)
231  
232 -------------------------------------------------------------------------------
233 -- | Adds an assumption (law) into the run-time assumption environment.
234 addAssumption :: Law -> GalcStateT ()
235 addAssumption l = do
236   let nm = getName l
237   st <- gget
238   lookupGuard ExistingRefError nm (rtAssumpt st)
239   gput $ st {rtAssumpt = addEnv nm l (rtAssumpt st)}
240  
241 -------------------------------------------------------------------------------
242 -- | Returns the name of the loaded modules.
243 getLoadedModules :: GalcStateT [String]
244 getLoadedModules = return . indexes =<< ggets modules
245  
246 -------------------------------------------------------------------------------
247 -- | Returns the list of laws of a given module.
248 getLaws :: String -> GalcStateT [Law]
249 getLaws mdl =
250   return . values . laws =<< lookupE ModuleRefError mdl =<< ggets modules
251  
252 -------------------------------------------------------------------------------
253 -- | Given a name, returns the law definitions.
254 getLaw :: String -> GalcStateT Law
255 getLaw nm =
256   maybe2error (ReferenceError nm) . msum . map (lookupEnv nm . laws) . values
257   =<< ggets modules
258  
259 -------------------------------------------------------------------------------
260 -- | Returns the list of definitions of a given module.
261 getDefinitions :: String -> GalcStateT [RType]
262 getDefinitions mdl =
263   return . values . definitions =<< lookupE ModuleRefError mdl =<< ggets modules
264  
265 -------------------------------------------------------------------------------
266 -- | Adds a definitions into the run-time definition environment.
267 addDefinition :: RType -> GalcStateT ()
268 addDefinition def = do
269   let nm = defName def
270   st <- gget
271   lookupGuard ExistingRefError nm (rtDefinitions st)
272   gput $ st { rtDefinitions = addEnv nm def (rtDefinitions st) }
273  
274 -------------------------------------------------------------------------------
275 -- Repeated:
276 -- Language.Module.TypeInference
277 defName :: RType -> String
278 defName (Exists _ (DEF n _)) = n
279 defName _ = ""
280  
281 -------------------------------------------------------------------------------
282 -- | Returns the current expression in the proof.
283 getCurExpr :: GalcStateT RType
284 getCurExpr =
285   return . eitherId . curExpr =<< maybe2error NoProofError =<< ggets proof
286  
287 eitherId :: Either a a -> a
288 eitherId = either id id
289  
290 -------------------------------------------------------------------------------
291 -- | Adds a new module into the module environement
292 addModule :: String -> Module -> GalcStateT ()
293 addModule nm m = do
294   st <- gget
295   lookupGuard ExistingRefError nm (modules st)
296   gput $ st { modules = addEnv nm m (modules st) }
297  
298 -------------------------------------------------------------------------------
299  
300 saveProof :: GalcStateT ()
301 saveProof = (updateGalcState $
302   \st -> st ) >> enterGlobalMode
303  
304 -------------------------------------------------------------------------------
305  
306 undo :: Int -> GalcStateT ()
307 undo n = updateProof $ return
308  
309 -------------------------------------------------------------------------------
310 -- | Restarts a proof, assuming a left expression.
311 restartProof :: GalcStateT ()
312 restartProof = (updateProof $ \prf ->
313     return prf {curExpr = Left . getLeft . expression $ prf, curProof = []}) >>
314   enterSetProofMode
315  
316 -------------------------------------------------------------------------------
317 -- | Removes a module from the module environment.
318 removeModule :: String -> GalcStateT ()
319 removeModule nm = do
320   st <- gget
321   lookupE ModuleRefError nm (modules st)
322   gput $ st { modules = delete nm (modules st) }
323  
324 -------------------------------------------------------------------------------
325  
326 7 paulosilva -- TODO: MonadOr?
327 1 paulosilva getGC :: MonadPlus m => String -> GalcStateT (m RType)
328 getGC nm = return . msum . map (lookupEnv nm . gcs) . values =<< ggets modules
329  
330 getGCs :: String -> GalcStateT [RType]
331 getGCs nm = return . msum . map (lookupEnv nm . gcs) . values =<< ggets modules
332  
333 getAssumptions :: GalcStateT [Law]
334 getAssumptions = return . values =<< ggets rtAssumpt
335  
336 getAssumption :: String -> GalcStateT Law
337 getAssumption nm = lookupE ReferenceError nm =<< ggets rtAssumpt
338  
339 ---  ======================
340 getExpression :: GalcStateT Law
341 getExpression = return . expression =<< maybe2error NoProofError =<< ggets proof
342  
343 7 paulosilva getInitialExpr :: GalcStateT RType
344 getInitialExpr =
345   return . getLeft . expression =<< maybe2error NoProofError =<< ggets proof
346 1 paulosilva  
347 getCurrentProof :: GalcStateT Proof
348 7 paulosilva getCurrentProof =
349   return . curProof =<< maybe2error NoProofError =<< ggets proof
350 1 paulosilva -------------------------------------------------------------------------------
351  
352 lookupGuard :: MonadError GalcError m
353         => (String -> GalcError) -> String -> Env a -> m ()
354 lookupGuard err nm =
355   maybe (return ()) (const $ throwError (err nm)) . lookupEnv nm
356  
357 -------------------------------------------------------------------------------
358  
359 lookupE :: MonadError GalcError m
360         => (String -> GalcError) -> String -> Env a -> m a
361 lookupE err nm = maybe2error (err nm) . lookupEnv nm
362  
363 -------------------------------------------------------------------------------
364  
365  

Theme by Vikram Singh | Powered by WebSVN v2.3.3