module Main where
import Control
.Monad.Identity
import Control.Arrow (second)
import Text.Parsec
| Abs Term
| App Term Term
avnames
= map (\x
-> [x
]) "abcdexyzuw" names
= avnames
++ map ('\'' :
) names
nameidx i n (Abs t) = Abs (nameidx (i + 1) n t)
nameidx i n (App x y) = App (nameidx i n x) (nameidx i n y)
nameidx i n (Idx d)
| i == d = Var n
nameidx _ _ v = v
markfree (Abs t) = Abs (markfree t)
markfree (App x y) = App (markfree x) (markfree y)
markfree (Var s) = Var ('*' : s)
markfree i = i
showTerm (n:ns) (Abs t) =
. showTerm ns (nameidx 0 n t)
showTerm ns (App x y) =
. showTerm ns x
. showTerm ns y
showTerm ns
(Idx i
) = ('#' :
) . (show i
++) showTerm ns (Var s) = (s ++)
show t
= showTerm names
(markfree t
) $ []
type Eval a = Identity a
runEval :: Eval Term -> Term
runEval = runIdentity
eval :: Term -> Eval Term
eval (App x y) = do
x' <- eval x
case x' of
(Abs t) -> eval (subst 0 t y)
subst
:: Int -> Term
-> Term
-> Term
subst i (Idx d) s
| d == i = s
subst i (App x y) s = App (subst i x s) (subst i y s)
subst i (Abs t) s = Abs (subst (i + 1) t s)
subst i v s = v
setidx name i (App x y) = App (setidx name i x) (setidx name i y)
setidx name i (Abs t) = Abs (setidx name (i + 1) t)
setidx name i (Var n)
| name == n = Idx i
setidx _ _ t = t
setVariable
:: Term
-> (String, Term
) -> Term
setVariable (App x y) bind =
App (setVariable x bind) (setVariable y bind)
setVariable (Abs t) bind = Abs (setVariable t bind)
setVariable (Var s) (name, t')
| s == name = t'
setVariable other _ = other
identifier = many1 alphaNum
lambda
:: Parsec
String () Term
lambda = do
char '('
char '\\'
spaces
varname <- identifier
spaces
char '.'
t <- term
char ')'
return $ Abs
(setidx varname
0 t
)
single
:: Parsec
String () Term
single
= (spaces
>>) $ try
(fmap Var identifier
) <|> try lambda
<|> application
application
:: Parsec
String () Term
application = do
char '('
f <- term
char ')'
substitution = do
spaces
char '['
spaces
varname <- identifier
spaces
string "->"
t <- term
char ']'
procBinds
= scanl1 $ \x
-> second
(flip setVariable x
)
term = do
spaces
binds <- many (try substitution)
lambdaEval str =
case parse term "lambda" str of
Right t -> Right $ runEval (eval t)
Left e -> Left e
loop = do
case x of
main = do
putStrLn "Lambda-Expressions Evaluator.\n> " loop
bW9kdWxlIE1haW4gd2hlcmUKCiAgICBpbXBvcnQgQ29udHJvbC5Nb25hZC5JZGVudGl0eQogICAgaW1wb3J0IENvbnRyb2wuQXJyb3cgKHNlY29uZCkKICAgIGltcG9ydCBUZXh0LlBhcnNlYwoKICAgIGRhdGEgVGVybSA9IFZhciBTdHJpbmcKICAgICAgfCBJZHggSW50CiAgICAgIHwgQWJzIFRlcm0KICAgICAgfCBBcHAgVGVybSBUZXJtCiAgICAgIAogICAgYXZuYW1lcyA9IG1hcCAoXHggLT4gW3hdKSAiYWJjZGV4eXp1dyIKICAgIG5hbWVzID0gYXZuYW1lcyArKyBtYXAgKCdcJycgOikgbmFtZXMKICAgIAogICAgbmFtZWlkeCBpIG4gKEFicyB0KSA9IEFicyAobmFtZWlkeCAoaSArIDEpIG4gdCkKICAgIG5hbWVpZHggaSBuIChBcHAgeCB5KSA9IEFwcCAobmFtZWlkeCBpIG4geCkgKG5hbWVpZHggaSBuIHkpCiAgICBuYW1laWR4IGkgbiAoSWR4IGQpCiAgICAgIHwgaSA9PSBkID0gVmFyIG4KICAgICAgfCBvdGhlcndpc2UgPSBJZHggZAogICAgbmFtZWlkeCBfIF8gdiA9IHYKICAgIAogICAgbWFya2ZyZWUgKEFicyB0KSA9IEFicyAobWFya2ZyZWUgdCkKICAgIG1hcmtmcmVlIChBcHAgeCB5KSA9IEFwcCAobWFya2ZyZWUgeCkgKG1hcmtmcmVlIHkpCiAgICBtYXJrZnJlZSAoVmFyIHMpID0gVmFyICgnKicgOiBzKQogICAgbWFya2ZyZWUgaSA9IGkKICAgIAogICAgc2hvd1Rlcm0gOjogW1N0cmluZ10gLT4gVGVybSAtPiBTaG93UwogICAgc2hvd1Rlcm0gKG46bnMpIChBYnMgdCkgPQogICAgICAgICAgc2hvd1N0cmluZyAiKFxcIgogICAgICAgIC4gc2hvd1N0cmluZyBuCiAgICAgICAgLiBzaG93U3RyaW5nICIuICIKICAgICAgICAuIHNob3dUZXJtIG5zIChuYW1laWR4IDAgbiB0KQogICAgICAgIC4gc2hvd1N0cmluZyAiKSIKICAgIHNob3dUZXJtIG5zIChBcHAgeCB5KSA9CiAgICAgICAgICBzaG93Q2hhciAnKCcKICAgICAgICAuIHNob3dUZXJtIG5zIHgKICAgICAgICAuIHNob3dDaGFyICcgJwogICAgICAgIC4gc2hvd1Rlcm0gbnMgeQogICAgICAgIC4gc2hvd0NoYXIgJyknCiAgICBzaG93VGVybSBucyAoSWR4IGkpID0gKCcjJyA6KSAuIChzaG93IGkgKyspCiAgICBzaG93VGVybSBucyAoVmFyIHMpID0gKHMgKyspCiAgICAKICAgIGluc3RhbmNlIFNob3cgVGVybSB3aGVyZQogICAgICAgIHNob3cgdCA9IHNob3dUZXJtIG5hbWVzIChtYXJrZnJlZSB0KSAkIFtdCiAgICAKICAgIHR5cGUgRXZhbCBhID0gSWRlbnRpdHkgYQogICAgCiAgICBydW5FdmFsIDo6IEV2YWwgVGVybSAtPiBUZXJtCiAgICBydW5FdmFsID0gcnVuSWRlbnRpdHkKICAgIAogICAgZXZhbCA6OiBUZXJtIC0+IEV2YWwgVGVybQogICAgZXZhbCAoQXBwIHggeSkgPSBkbwogICAgICAgIHgnIDwtIGV2YWwgeAogICAgICAgIGNhc2UgeCcgb2YKICAgICAgICAgIChBYnMgdCkgLT4gZXZhbCAoc3Vic3QgMCB0IHkpCiAgICAgICAgICBwcm9jIC0+IHJldHVybiAoQXBwIHByb2MgeSkKICAgIGV2YWwgb3RoZXIgPSByZXR1cm4gb3RoZXIKICAgIAogICAgc3Vic3QgOjogSW50IC0+IFRlcm0gLT4gVGVybSAtPiBUZXJtCiAgICBzdWJzdCBpIChJZHggZCkgcwogICAgICB8IGQgPT0gaSA9IHMKICAgICAgfCBvdGhlcndpc2UgPSBJZHggZAogICAgc3Vic3QgaSAoQXBwIHggeSkgcyA9IEFwcCAoc3Vic3QgaSB4IHMpIChzdWJzdCBpIHkgcykKICAgIHN1YnN0IGkgKEFicyB0KSBzID0gQWJzIChzdWJzdCAoaSArIDEpIHQgcykKICAgIHN1YnN0IGkgdiBzID0gdgogICAgCiAgICBzZXRpZHggOjogU3RyaW5nIC0+IEludCAtPiBUZXJtIC0+IFRlcm0KICAgIHNldGlkeCBuYW1lIGkgKEFwcCB4IHkpID0gQXBwIChzZXRpZHggbmFtZSBpIHgpIChzZXRpZHggbmFtZSBpIHkpCiAgICBzZXRpZHggbmFtZSBpIChBYnMgdCkgPSBBYnMgKHNldGlkeCBuYW1lIChpICsgMSkgdCkKICAgIHNldGlkeCBuYW1lIGkgKFZhciBuKQogICAgICB8IG5hbWUgPT0gbiA9IElkeCBpCiAgICAgIHwgb3RoZXJ3aXNlID0gVmFyIG4KICAgIHNldGlkeCBfIF8gdCA9IHQKICAgIAogICAgc2V0VmFyaWFibGUgOjogVGVybSAtPiAoU3RyaW5nLCBUZXJtKSAtPiBUZXJtCiAgICBzZXRWYXJpYWJsZSAoQXBwIHggeSkgYmluZCA9CiAgICAgICAgQXBwIChzZXRWYXJpYWJsZSB4IGJpbmQpIChzZXRWYXJpYWJsZSB5IGJpbmQpCiAgICBzZXRWYXJpYWJsZSAoQWJzIHQpIGJpbmQgPSBBYnMgKHNldFZhcmlhYmxlIHQgYmluZCkKICAgIHNldFZhcmlhYmxlIChWYXIgcykgKG5hbWUsIHQnKQogICAgICB8IHMgPT0gbmFtZSA9IHQnCiAgICAgIHwgb3RoZXJ3aXNlID0gVmFyIHMKICAgIHNldFZhcmlhYmxlIG90aGVyIF8gPSBvdGhlcgogICAgCiAgICBpZGVudGlmaWVyIDo6IFBhcnNlYyBTdHJpbmcgKCkgU3RyaW5nCiAgICBpZGVudGlmaWVyID0gbWFueTEgYWxwaGFOdW0KICAgIAogICAgbGFtYmRhIDo6IFBhcnNlYyBTdHJpbmcgKCkgVGVybQogICAgbGFtYmRhID0gZG8KICAgICAgICBjaGFyICcoJwogICAgICAgIGNoYXIgJ1xcJwogICAgICAgIHNwYWNlcwogICAgICAgIHZhcm5hbWUgPC0gaWRlbnRpZmllcgogICAgICAgIHNwYWNlcwogICAgICAgIGNoYXIgJy4nCiAgICAgICAgdCA8LSB0ZXJtCiAgICAgICAgY2hhciAnKScKICAgICAgICByZXR1cm4gJCBBYnMgKHNldGlkeCB2YXJuYW1lIDAgdCkKICAgICAgICAKICAgIHNpbmdsZSA6OiBQYXJzZWMgU3RyaW5nICgpIFRlcm0KICAgIHNpbmdsZSA9IChzcGFjZXMgPj4pICQgdHJ5IChmbWFwIFZhciBpZGVudGlmaWVyKSA8fD4gdHJ5IGxhbWJkYSA8fD4gYXBwbGljYXRpb24KICAgIAogICAgYXBwbGljYXRpb24gOjogUGFyc2VjIFN0cmluZyAoKSBUZXJtCiAgICBhcHBsaWNhdGlvbiA9IGRvCiAgICAgICAgY2hhciAnKCcKICAgICAgICBmIDwtIHRlcm0KICAgICAgICBjaGFyICcpJwogICAgICAgIHJldHVybiBmCiAgICAKICAgIHN1YnN0aXR1dGlvbiA6OiBQYXJzZWMgU3RyaW5nICgpIChTdHJpbmcsIFRlcm0pCiAgICBzdWJzdGl0dXRpb24gPSBkbwogICAgICAgIHNwYWNlcwogICAgICAgIGNoYXIgJ1snCiAgICAgICAgc3BhY2VzCiAgICAgICAgdmFybmFtZSA8LSBpZGVudGlmaWVyCiAgICAgICAgc3BhY2VzCiAgICAgICAgc3RyaW5nICItPiIKICAgICAgICB0IDwtIHRlcm0KICAgICAgICBjaGFyICddJwogICAgICAgIHJldHVybiAodmFybmFtZSwgdCkKICAgIAogICAgcHJvY0JpbmRzIDo6IFsoU3RyaW5nLCBUZXJtKV0gLT4gWyhTdHJpbmcsIFRlcm0pXQogICAgcHJvY0JpbmRzID0gc2NhbmwxICQgXHggLT4gc2Vjb25kIChmbGlwIHNldFZhcmlhYmxlIHgpCiAgICAKICAgIHRlcm0gOjogUGFyc2VjIFN0cmluZyAoKSBUZXJtCiAgICB0ZXJtID0gZG8KICAgICAgICBzcGFjZXMKICAgICAgICBiaW5kcyA8LSBtYW55ICh0cnkgc3Vic3RpdHV0aW9uKQogICAgICAgIHQgPC0gdHJ5IChmbWFwIChmb2xkbDEgQXBwKSAobWFueTEgc2luZ2xlKSkKICAgICAgICByZXR1cm4gKGZvbGRsIChzZXRWYXJpYWJsZSkgdCAkIHByb2NCaW5kcyBiaW5kcykKICAgICAgICAgICAgCiAgICBsYW1iZGFFdmFsIHN0ciA9CiAgICAgICAgY2FzZSBwYXJzZSB0ZXJtICJsYW1iZGEiIHN0ciBvZgogICAgICAgICAgICBSaWdodCB0IC0+IFJpZ2h0ICQgcnVuRXZhbCAoZXZhbCB0KQogICAgICAgICAgICBMZWZ0IGUgLT4gTGVmdCBlCiAgICAKICAgIGxvb3AgOjogSU8gKCkKICAgIGxvb3AgPSBkbwogICAgICB4IDwtIGdldExpbmUKICAgICAgY2FzZSB4IG9mCiAgICAgICAgICAiOmVuZCIgLT4gcmV0dXJuICgpCiAgICAgICAgICBzdHIgLT4gcHV0U3RyICI+ICIgPj4gcHJpbnQgKGxhbWJkYUV2YWwgeCkgPj4gbG9vcAogICAgCiAgICBtYWluIDo6IElPICgpCiAgICBtYWluID0gZG8KICAgICAgICBwdXRTdHJMbiAiTGFtYmRhLUV4cHJlc3Npb25zIEV2YWx1YXRvci5cbj4gIgogICAgICAgIGxvb3A=