summaryrefslogtreecommitdiff
path: root/Thue/Interpreter.hs
blob: 8555bab0b533d0b8a02ff81b4b28b93092715db5 (plain)
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
module Interpreter (
	thue
	) where


import System.Random
import Parser




thue :: ThueProgram -> ThueState
thue program =
	let rules = thueRules program
	    state = thueInitialState program
	    gen = mkStdGen 4 --chosen by fair dice roll, guaranteed to be random

    in interpret state rules gen



interpret :: ThueState -> [ThueRule] -> RandomGen -> ThueState
interpret state rules gen =
	let possibleRules = rules `applicableTo` state
	    ruleToApply = possibleRules !! num

        (num, gen') = nextInRange 0 (length possibleRules - 1) gen

	    (before, after) = fromJust (extractInfix (original ruleToApply) state)
	    state' = before ++ (replacement ruleToApply) ++ after

	in if (possibleRules == []) then state else interpret state' rules gen'



extractInfix :: [a] -> [a] -> Maybe ([a], [a])
extractInfix subList list =
	let f = (\pre cur -> case (stripPrefix subList cur) of
		                    Nothing -> f (head cur):pre (tail cur)
		                    Just x -> (reverse pre, x)

	in if (subList `isInfixOf` list) then Just f [] list else Nothing



nextInRange :: Integer -> Integer -> RandomGen -> (Integer,RandomGen)
nextInRange low high random =
	let (genLow, genHigh) = genRange random
	    (rawNext, random') = next random

	    next = (\n -> let irawNext = fromIntegral rawNext
	    	              igenLow = fromIntegral genLow
	    	              igenHigh = fromIntegral genHigh
	    	              ilow = fromIntegral low
	    	              ihigh = fromIntegral high
	    	              n' = ((irawNext - igenLow) / (igenHigh - igenLow)) * (ihigh - ilow) + ilow
	    	          in round n'

	in (next, random')



applicableTo :: [ThueRule] -> ThueState -> [ThueRule]
applicableTo ruleList state =
	filter (\r -> (original r) `isInfixOf` state) ruleList