0 | 0 |
module Language.Fountain.Generator (constructState, generateFrom, obtainResult) where
|
|
1 |
|
|
2 |
import Data.Maybe (mapMaybe)
|
1 | 3 |
|
2 | 4 |
import Language.Fountain.Grammar
|
3 | 5 |
import Language.Fountain.Constraint
|
|
19 | 21 |
-- Alt choices need preconditions because in generating, unlike parsing,
|
20 | 22 |
-- we need some guidance of which one to pick
|
21 | 23 |
--
|
22 | |
getPreCondition :: Expr -> Expr -> Constraint
|
23 | |
getPreCondition alts (Seq (x:xs)) = getPreCondition alts x
|
24 | |
getPreCondition alts (Constraint c) = c
|
25 | |
getPreCondition alts x = error ("No pre-condition present on this Alt choice: " ++ (show alts) ++ " => " ++ (show x))
|
|
24 |
getPreCondition :: Expr -> Maybe Constraint
|
|
25 |
getPreCondition (Seq (x:xs)) = getPreCondition x
|
|
26 |
getPreCondition (Constraint c) = Just c
|
|
27 |
getPreCondition x = Nothing
|
|
28 |
|
|
29 |
missingPreConditions choices =
|
|
30 |
mapMaybe (\x -> case getPreCondition x of
|
|
31 |
Just _ -> Nothing
|
|
32 |
Nothing -> Just x
|
|
33 |
) choices
|
26 | 34 |
|
27 | 35 |
|
28 | 36 |
gen :: Grammar -> GenState -> Expr -> GenState
|
|
37 | 45 |
-- We look at all the choices; each should start with a pre-condition
|
38 | 46 |
-- determining whether we can select it; and we should narrow down our
|
39 | 47 |
-- choices based on that. (Then pick randomly? Or insist deterministic?)
|
40 | |
gen g st@(Generating str store) alts@(Alt s) =
|
41 | |
let
|
42 | |
preConditionedAlts = map (\x -> (getPreCondition alts x, x)) s
|
43 | |
applicableAlts = filter (\(c, x) -> canApplyConstraint c store) preConditionedAlts
|
44 | |
in
|
45 | |
genAlt g st applicableAlts where
|
46 | |
genAlt g st [] = Failure
|
47 | |
genAlt g st ((_, e) : rest) =
|
48 | |
case gen g st e of
|
49 | |
Failure -> genAlt g st rest
|
50 | |
st' -> st'
|
|
48 |
gen g st@(Generating str store) (Alt choices) =
|
|
49 |
case missingPreConditions choices of
|
|
50 |
missing@(_:_) ->
|
|
51 |
error ("No pre-condition present on these Alt choices: " ++ (show missing))
|
|
52 |
[] ->
|
|
53 |
let
|
|
54 |
preConditionedChoices = map (\x -> (getPreCondition x, x)) choices
|
|
55 |
applicableChoices = filter (\(Just c, x) -> canApplyConstraint c store) preConditionedChoices
|
|
56 |
in
|
|
57 |
genAlt g st applicableChoices where
|
|
58 |
genAlt g st [] = Failure
|
|
59 |
genAlt g st ((_, e) : rest) =
|
|
60 |
case gen g st e of
|
|
61 |
Failure -> genAlt g st rest
|
|
62 |
st' -> st'
|
51 | 63 |
|
52 | 64 |
gen g state (Loop l postconditions) =
|
53 | 65 |
genLoop g state l (assertThereAreSome postconditions) where
|