packages feed

ideas-0.5.8: src/Service/ServiceList.hs

-----------------------------------------------------------------------------
-- Copyright 2009, Open Universiteit Nederland. This file is distributed 
-- under the terms of the GNU General Public License. For more information, 
-- see the file "LICENSE.txt", which is included in the distribution.
-----------------------------------------------------------------------------
-- |
-- Maintainer  :  bastiaan.heeren@ou.nl
-- Stability   :  provisional
-- Portability :  portable (depends on ghc)
--
-----------------------------------------------------------------------------
module Service.ServiceList (serviceList, Service(..), getService, evalService) where

import Common.Context
import Common.Transformation
import qualified Common.Exercise as E
import Common.Utils (Some(..))
import Common.Exercise hiding (Exercise)
import Control.Monad.Error
import qualified Service.ExerciseList as S
import qualified Service.TypedAbstractService as S
import Service.FeedbackText
import Service.Types 
import Data.List (sortBy)

data Service a = Service 
   { serviceName :: String
   , typedValue  :: TypedValue a
   }

------------------------------------------------------
-- Querying a service

serviceList :: [Service a]
serviceList =
   [ derivationS, allfirstsS, onefirstS, readyS
   , stepsremainingS, applicableS, applyS, generateS
   , submitS
   , onefirsttextS, findbuggyrulesS
   , submittextS, derivationtextS
   , exerciselistS, rulelistS
   ]

getService :: Monad m => String -> m (Service a)
getService txt =
   case filter ((==txt) . serviceName) serviceList of
      [hd] -> return hd
      []   -> fail $ "No service " ++ txt
      _    -> fail $ "Ambiguous service " ++ txt

evalService :: Monad m => Evaluator m inp out a -> Service a -> inp -> m out
evalService f = eval f . typedValue
   
------------------------------------------------------
-- Basic services

derivationS :: Service a
derivationS = Service "derivation" $ 
   S.derivation ::: State :-> List (Pair Rule Term)

allfirstsS :: Service a
allfirstsS = Service "allfirsts" $ 
   S.allfirsts ::: State :-> List (Triple Rule Location State)
        
onefirstS :: Service a
onefirstS = Service "onefirst" $ 
   S.onefirst ::: State :-> Elem (Triple Rule Location State)
  
readyS :: Service a
readyS = Service "ready" $ 
   S.ready ::: State :-> Bool

stepsremainingS :: Service a
stepsremainingS = Service "stepsremaining" $
   S.stepsremaining ::: State :-> Int

applicableS :: Service a
applicableS = Service "applicable" $ 
   S.applicable ::: Location :-> State :-> List Rule

applyS :: Service a
applyS = Service "apply" $ 
   S.apply ::: Rule :-> Location :-> State :-> State

generateS :: Service a
generateS = Service "generate" $ S.generate ::: 
   Exercise :-> Optional 5 Int :-> IO State

findbuggyrulesS :: Service a
findbuggyrulesS = Service "findbuggyrules" $ 
   S.findbuggyrules ::: State :-> Term :-> List Rule

submitS :: Service a
submitS = Service "submit" $ (\a -> S.submit a . fromContext) :::
   State :-> Term :-> Result

------------------------------------------------------
-- Services with a feedback component

onefirsttextS :: Service a
onefirsttextS = Service "onefirsttext" $ 
   onefirsttext ::: State :-> Maybe String :-> Elem (Triple Bool String State)

submittextS :: Service a
submittextS = Service "submittext" $ 
   submittext ::: State :-> String :-> Maybe String :-> Elem (Triple Bool String State)

derivationtextS :: Service a
derivationtextS = Service "derivationtext" $ 
   derivationtext ::: State :-> Maybe String :-> List (Pair String Term)
   
------------------------------------------------------
-- Reflective services
   
exerciselistS :: Service a
exerciselistS = Service "exerciselist" $
   allExercises ::: List (Quadruple (Tag "domain" String) (Tag "identifier" String) (Tag "description" String) (Tag "status" String))

rulelistS :: Service a
rulelistS = Service "rulelist" $ 
   allRules ::: Exercise :-> List (Triple (Tag "name" String) (Tag "buggy" Bool) (Tag "rewriterule" Bool))
      
allExercises :: [(String, String, String, String)]
allExercises  = map make $ sortBy cmp S.exerciseList
 where
   cmp e1 e2  = f e1 `compare` f e2
   f (Some e) = (domain (exerciseCode e), identifier (exerciseCode e))
   make (Some ex) = (domain (exerciseCode ex), identifier (exerciseCode ex), description ex, show (status ex))

allRules :: E.Exercise a -> [(String, Bool, Bool)]
allRules = map make . ruleset
 where  
   make r  = (name r, isBuggyRule r, isRewriteRule r)