summaryrefslogtreecommitdiff
path: root/Assignment2/src/DTMC.icl
blob: 7c712e081a7b1d3993bfb82dbbba64dc9b99bbc5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
implementation module DTMC

import StdArray
import StdClass
import StdFile
import StdInt
import StdList
import StdString

import Data.Error
from Data.Func import $
import System.File
import System.FilePath
import Text

parseDTMC :: !FilePath !*World -> *(!DTMC, !*World)
parseDTMC fp w
# (lines,w) = readFileLines fp w
= (parseDTMCFromLines [s % (0,size s-2) \\ s <- fromOk lines], w)

parseDTMCFromLines :: ![String] -> DTMC
parseDTMCFromLines lines
# [nr_states:_:lines] = tl $ dropWhile ((<>) "@nr_states") lines
# states = map parseState $ groupLines "\t" [] lines
=
	{ nr_states = toInt nr_states
	, states    = {s \\ s <- states}
	}
where
	parseState :: ![String] -> State
	parseState [head:actions] =
		{ actions = map parseAction $ groupLines "\t\t" [] actions
		, init    = endsWith "init" head
		}
	where
		parseAction :: ![String] -> Action
		parseAction [head:transitions] =
			{ action_id   = toInt (head % (8, size head-1))
			, transitions = map parseTransition transitions
			}
		where
			parseTransition :: !String -> Transition
			parseTransition s = case split " : " (trim s) of
				[id:prob:_] -> {to_state=toInt id, probability=prob}

	groupLines :: !String ![String] ![String] -> [[String]]
	groupLines head current [] = [reverse current]
	groupLines head current [line:lines]
	| startsWith head line = groupLines head [line:current] lines
	| isEmpty current      = groupLines head [line] lines
	| otherwise            = [reverse current:groupLines head [line] lines]