SeqSim/src/SeqSim/Evaluator.elm

74 lines
2.1 KiB
Elm
Raw Normal View History

2020-11-21 19:48:10 -08:00
module SeqSim.Evaluator exposing (allOutcomes)
import SeqSim.Parser exposing (Prog, Source(..))
import Dict exposing (Dict, get, insert)
import Tuple exposing (first, second)
import List.Extra exposing (uniqueBy)
shuffle : List a -> List a -> List (List a)
shuffle l1 l2 =
case (l1, l2) of
([], _) -> [l2]
(_, []) -> [l1]
(x::xs, y::ys) ->
List.map ((::) x) (shuffle xs l2) ++
List.map ((::) y) (shuffle l1 ys)
shuffleAll : List (List a) -> List (List a)
shuffleAll l =
case l of
[] -> [[]]
(x::xs) -> List.concatMap (shuffle x) <| shuffleAll xs
type alias State = Dict String Int
type alias Evaluator a = State -> (a, State)
succeed : a -> Evaluator a
succeed a = \s -> (a, s)
andThen : (a -> Evaluator b) -> Evaluator a -> Evaluator b
andThen f e = \s -> let (a, ss) = e s in f a ss
map : (a -> b) -> Evaluator a -> Evaluator b
map f e = \s -> let (a, ss) = e s in (f a, ss)
run : Evaluator a -> State -> (a, State)
run e s = e s
getVar : String -> Evaluator Int
getVar x = \s -> (Maybe.withDefault 0 (Dict.get x s), s)
setVar : String -> Int -> Evaluator ()
setVar x v = \s -> ((), Dict.insert x v s)
mapM_ : (a -> Evaluator b) -> List a -> Evaluator ()
mapM_ f l = map (\_ -> ()) <| mapM f l
mapM : (a -> Evaluator b) -> List a -> Evaluator (List b)
mapM f l =
case l of
[] -> succeed []
(x::xs) -> andThen (\b -> map ((::) b) <| mapM f xs) (f x)
evalSource : Source -> Evaluator Int
evalSource s =
case s of
Var x -> getVar x
Const i -> succeed i
evalCmd : (String, Source) -> Evaluator ()
evalCmd (x, s) = evalSource s |> andThen (setVar x)
evalProg : Prog -> Evaluator ()
evalProg = mapM_ evalCmd
runShuffled : List String -> List Prog -> List (Prog, List Int)
runShuffled xs ps =
let
getVars = mapM getVar xs
runProg p = (p, first <| run (evalProg p |> andThen (\_ -> getVars)) Dict.empty)
in
List.map runProg <| shuffleAll ps
allOutcomes : List String -> List Prog -> List (Prog, List Int)
allOutcomes xs ps = uniqueBy second <| runShuffled xs ps