packages feed

CSPM-FiringRules-0.1.0.0: src/CSPM/FiringRules/Test/Mock2.hs

-----------------------------------------------------------------------------
-- |
-- Module      :  CSPM.CoreLanguage.FiringRules.Mock2
-- Copyright   :  (c) Fontaine 2010
-- License     :  BSD
-- 
-- Maintainer  :  fontaine@cs.uni-duesseldorf.de
-- Stability   :  experimental
-- Portability :  GHC-only
--
-- A mock implementation of CSP-Processes.
--
-----------------------------------------------------------------------------

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE EmptyDataDecls, TypeFamilies #-}
{-# LANGUAGE StandaloneDeriving, FlexibleInstances, FlexibleContexts,TypeSynonymInstances #-}
module CSPM.FiringRules.Test.Mock2
where

import CSPM.CoreLanguage
import CSPM.CoreLanguage.Event as Event
import CSPM.CoreLanguage.Field as Field

import CSPM.FiringRules.Test.Gen
import CSPM.FiringRules.HelperClasses

import Test.QuickCheck.Arbitrary
import Test.QuickCheck.Gen
import Data.Set (Set)
import qualified Data.Set as Set
import qualified Data.List as List
import Control.Monad
import Control.Applicative

data M2
m2 :: M2
m2 = undefined

type ProcessM2 = Process M2
type ClosureViewM2 = ClosureView

instance EqOrd M2
instance CSP2 M2
instance CSP1 M2

type instance Field M2 = FieldM2
data FieldM2
  = Chan Int
  | Field Int
  deriving (Show,Eq,Ord)

type instance FieldSet M2 = FieldSetM2
newtype FieldSetM2 = FieldSet {unFieldSet :: (Set FieldM2)}
  deriving (Show,Eq,Ord)

type instance Event M2 = EventM2
newtype EventM2 = Event {unEvent :: [FieldM2]}
  deriving (Show,Eq,Ord)

type instance EventSet M2 = EventSetM2
newtype EventSetM2 = EventSet {unEventSet :: (Set EventM2)}
  deriving (Show,Eq,Ord)

type instance Prefix M2 = PrefixM2
newtype PrefixM2 = PrefixM2 {unPrefixM2 :: InternalPrefix}
  deriving (Show,Eq,Ord)

type instance ExtProcess M2 = ExtProcessM2
newtype ExtProcessM2 = ExtProcess (Process M2)
  deriving (Show,Eq,Ord)

type instance ClosureState M2 = ClosureStateM2
data ClosureStateM2 = ClosureState Int [Field M2] EventSetM2
  deriving (Show)

type instance PrefixState M2 = PrefixStateM2
data PrefixStateM2 = PrefixState Int [Field M2] InternalPrefix
  deriving (Show)

type instance RenamingRelation M2 = RenamingRelationM2
data RenamingRelationM2 = RenamingRelation {unRenamingRelation :: Set (EventM2, EventM2)}
  deriving (Show, Eq, Ord)

deriving instance Show (Process M2)
deriving instance Eq (Process M2)
deriving instance Ord (Process M2)


instance BL M2 where
  prefixNext (PrefixM2 c) event = if Event.member m2 event (allPrefixes c)
    then Just (error "M2 prefixNext p' undefined")
    else Nothing
  switchOn (ExtProcess x) = x

instance BE M2 where
  eventEq _ty a b = a == b
  member _ty a (EventSet s) = a `Set.member` s
  intersection _ty (EventSet a) (EventSet b) = EventSet $ a `Set.intersection` b
  difference _ty (EventSet a) (EventSet b) = EventSet $ a `Set.difference` b
  null _ty (EventSet a) = Set.null a
  singleton _ty a = EventSet $ Set.singleton a
  union = error "BE M2 union undefined (Mock2)"
  insert _ty a (EventSet s) = EventSet $ a `Set.insert` s
  delete _ty a (EventSet s) = EventSet $ a `Set.delete` s
  eventSetToList _ty (EventSet s) = Set.toList s
  allEvents _ty = EventSet $ Set.fromList allEventsList
  isInRenaming _ty (RenamingRelation r) e1 e2 = (e1,e2) `Set.member` r
  imageRenaming _ty (RenamingRelation r) e
    = Set.toList $ Set.map snd $ Set.filter ((==) e . fst) r
  preImageRenaming _ty (RenamingRelation r) e
    = Set.toList $ Set.map fst $ Set.filter ((==) e . snd) r
  isInRenamingDomain _ty e (RenamingRelation r)
    = not $ Set.null $ Set.filter ((==) e . fst) r
  isInRenamingRange _ty e (RenamingRelation r)
    = not $ Set.null $ Set.filter ((==) e . snd) r
  getRenamingDomain _ty = Set.toList . Set.map fst . unRenamingRelation
  getRenamingRange _ty = Set.toList . Set.map snd . unRenamingRelation
  renamingFromList _ty = RenamingRelation . Set.fromList
  renamingToList _ty = Set.toList . unRenamingRelation
  singleEventToClosureSet _ty = EventSet . Set.singleton


allEventsList :: [Event M2]
allEventsList = List.concat [
     Event <$> [[Chan 1]]
    ,Event <$> sequence [[Chan 2],map Field [1,2,3]]
    ,Event <$> sequence [[Chan 3],map Field [1,2,3],map Field [1,2,3]]
    ]

instance Arb M2 where
  genPrefix _ty = genPrefixM2
  arbitraryEvent _ty = elements $ allEventsList
  arbitraryEventSet _ty = elements $ map (EventSet . Set.fromList)
    $ List.subsequences $ allEventsList

genPrefixM2 :: Arbitrary ProcessM2 => EventM2-> Gen (Prefix M2)
genPrefixM2 event = liftM PrefixM2 (genInternalPrefix event)

data InternalPrefix = InternalPrefix {internalPrefixFields :: [MField]}
  deriving (Show,Eq,Ord)

data MField
  = MOut (Field M2)
  | MIn
  | MGuard (FieldSet M2)
  deriving (Show,Eq,Ord)

allPrefixes :: InternalPrefix -> EventSetM2
allPrefixes p
  = EventSet $ Set.fromList $ map (joinFields m2)
     $ mapM enumField $ internalPrefixFields p
  where
    enumField :: MField -> [FieldM2]
    enumField (MOut f) = [f]
    enumField MIn = map Field [1,2,3]
    enumField (MGuard f) = fieldSetToList m2 f

genInternalPrefix :: Event M2 -> Gen InternalPrefix
genInternalPrefix e = do
  f <- genMFields e
  return $ InternalPrefix f

{- generate fields that at least contain the given event -}
genMFields :: Event M2 -> Gen [MField]
genMFields (Event []) = error "Mock2.hs genMFields : empty event"
genMFields (Event (chan:rest)) = do
  l <- mapM genf rest
  return (MOut chan : l)
  where
    genf f = frequency [
       (10,return $ MOut f)
      ,(10,return MIn)
      ,(10,return $ MGuard $ FieldSet $ Set.singleton f) -- todo more interesting guards
      ]

instance BF M2 where
  fieldEq _ty a b = a == b
  member _ty e (FieldSet s) = e `Set.member` s
  intersection _ty (FieldSet a) (FieldSet b) = FieldSet $ a `Set.intersection` b
  difference _ty (FieldSet a) (FieldSet b) = FieldSet $ a `Set.difference` b
  null _ty (FieldSet a) = Set.null a
  singleton _ty a = FieldSet $ Set.singleton a
  union = error "BF M2 union undefined"
  insert _ty a (FieldSet s) = FieldSet $ a `Set.insert` s
  delete _ty a (FieldSet s) = FieldSet $ a `Set.delete` s
  fieldSetToList _ty (FieldSet s) = Set.toList s

  joinFields _ty = Event
  splitFields _ty (Event l) = l
  channelLen _ty (Chan i) = i
  channelLen _ty _ = error "MockM2 channelLen : not a channel field"

  closureStateInit _ty s = ClosureState 0 [] s

  closureStateNext _ty (ClosureState i l s) f = ClosureState (i+1) (l++[f]) s
  closureRestore   _ty (ClosureState _ _ s) = s

  viewClosureState _ty = viewClosureStateM2
  viewClosureFields _ty = viewClosureFieldsM2
  seenPrefixInClosure ty (ClosureState _i l s) = Event.member ty (Event l) s

  prefixStateInit _ty p = PrefixState 0 [] $ unPrefixM2 p
{-
  prefixStateNext _ty (PrefixState i l p) f = Just $ PrefixState (i+1) (l++[f]) p

this assumes that computeNext allways passes valid fields
(this is not the case, but why ?)

-}
  prefixStateNext _ty (PrefixState i l p) field
    = if checkField (internalPrefixFields p !!i) field
        then Just $ PrefixState (i+1) (l++[field]) p
        else Nothing
    where
      checkField :: MField -> Field M2 -> Bool
      checkField f v = case f of
        MOut v2 -> v == v2
        MIn -> True
        MGuard s -> Field.member m2 v s  

  prefixStateFinalize _ty (PrefixState _ _ p)
     = Just $ PrefixM2 p -- just return the original process
  viewPrefixState _ty  (PrefixState i _ (InternalPrefix l)) = case ( l !! i) of
    MOut val -> FieldOut val
    MIn -> FieldIn
    MGuard s -> FieldGuard s  
  fieldSetFromList _ty = FieldSet . Set.fromList


viewClosureStateM2 :: ClosureStateM2 -> ClosureViewM2
viewClosureStateM2 (ClosureState _i p s)
  = if List.null possiblePrefixes
      then NotInClosure
      else MaybeInClosure
  where 
    l :: [Event M2]
    l = eventSetToList m2 s
    possiblePrefixes :: [[Field M2]]
    possiblePrefixes = filter (List.isPrefixOf p) $ map (splitFields m2) l


viewClosureFieldsM2 :: ClosureStateM2 -> FieldSetM2
viewClosureFieldsM2 (ClosureState i p s)
  = FieldSet $ Set.fromList $ map head rests    
  where
    l :: [Event M2]
    l = eventSetToList m2 s
    possiblePrefixes :: [[Field M2]]
    possiblePrefixes = filter (List.isPrefixOf p) $ map (splitFields m2) l
    rests = map (drop i) possiblePrefixes