import scala.
util.
parsing.
combinator.
RegexParsers
}
}
}
def reduce
(term
: Term
): Option
[Term
] }
case App
(left, right
) => reduce
(left
) match { case Some
(Fun
(leftVarname, leftBody
)) => reduce
(apply
(leftBody, leftVarname, right
)) }
}
def apply
(body
: Term, varname
: String, term
: Term
) : Term
= body
match { case Var
(varname1
) => if(varname1
== varname
) term
else Var
(varname1
) case Fun
(varname1, body1
) => Fun
(varname1, apply
(body1, varname, term
)) case App
(left, right
) => App
(apply
(left, varname, term
), apply
(right, varname, term
)) }
}
def variable
: Parser
[Term
] = "\\w+".
r ^^
{ x => Var(x)
}
def function
: Parser
[Term
] = "\\(\\\\".
r ~ variable ~
"\\.".
r ~ term ~
"\\)".
r ^^
{ case _ ~ Var
(varname
) ~
_ ~ body ~
_ => Fun
(varname, body
) }
def application
: Parser
[Term
] = "\\(".
r ~ term ~
"\\s".
r ~ term ~
"\\)".
r ^^
{ case _ ~ left ~
_ ~ right ~
_ => App
(left, right
) }
def term
= function | application | variable
}
def eval
(expression
: String
) : String
= { val term
= LambdaParsers.
parse(LambdaParsers.
term, expression
).
get NormalOrder.
reduce(term
) match { case Some
(result
) => result.
toString case None
=> "Something wrong!" }
}
}
def main
(args
: Array
[String
]) = { println(TopLevel.eval(raw"(((\x.(\y.(x y))) (\z.z)) a)"))
}
}
aW1wb3J0IHNjYWxhLnV0aWwucGFyc2luZy5jb21iaW5hdG9yLlJlZ2V4UGFyc2VycwoKYWJzdHJhY3QgY2xhc3MgVGVybQoKY2FzZSBjbGFzcyBWYXIobmFtZSA6IFN0cmluZykgZXh0ZW5kcyBUZXJtIHsKICBvdmVycmlkZSBkZWYgdG9TdHJpbmcgPSBuYW1lCn0KCmNhc2UgY2xhc3MgRnVuKHZhcm5hbWUgOiBTdHJpbmcsIGJvZHkgOiBUZXJtKSBleHRlbmRzIFRlcm0gewogIG92ZXJyaWRlIGRlZiB0b1N0cmluZyA9IHMiKFxcJHZhcm5hbWUuJGJvZHkpIgp9CgpjYXNlIGNsYXNzIEFwcChsZWZ0IDogVGVybSwgcmlnaHQgOiBUZXJtKSBleHRlbmRzIFRlcm0gewogIG92ZXJyaWRlIGRlZiB0b1N0cmluZyA9IHMiKCRsZWZ0ICRyaWdodCkiCn0KCnRyYWl0IFNlbWFudGljIHsKICBkZWYgcmVkdWNlKHRlcm0gOiBUZXJtKTogT3B0aW9uW1Rlcm1dCn0KCm9iamVjdCBOb3JtYWxPcmRlciBleHRlbmRzIFNlbWFudGljIHsKICBvdmVycmlkZSBkZWYgcmVkdWNlKHRlcm0gOiBUZXJtKTogT3B0aW9uW1Rlcm1dID0gdGVybSBtYXRjaCB7CiAgICBjYXNlIEFwcChsZWZ0LCByaWdodCkgPT4gcmVkdWNlKGxlZnQpIG1hdGNoIHsKICAgICAgY2FzZSBTb21lKEZ1bihsZWZ0VmFybmFtZSwgbGVmdEJvZHkpKSA9PiByZWR1Y2UoYXBwbHkobGVmdEJvZHksIGxlZnRWYXJuYW1lLCByaWdodCkpCiAgICAgIGNhc2UgXyA9PiBOb25lCiAgICB9CiAgICBjYXNlIF8gPT4gU29tZSh0ZXJtKQogIH0KCiAgZGVmIGFwcGx5KGJvZHkgOiBUZXJtLCB2YXJuYW1lIDogU3RyaW5nLCB0ZXJtIDogVGVybSkgOiBUZXJtID0gYm9keSBtYXRjaCB7CiAgICBjYXNlIFZhcih2YXJuYW1lMSkgPT4gaWYodmFybmFtZTEgPT0gdmFybmFtZSkgdGVybSBlbHNlIFZhcih2YXJuYW1lMSkKICAgIGNhc2UgRnVuKHZhcm5hbWUxLCBib2R5MSkgPT4gRnVuKHZhcm5hbWUxLCBhcHBseShib2R5MSwgdmFybmFtZSwgdGVybSkpCiAgICBjYXNlIEFwcChsZWZ0LCByaWdodCkgPT4gQXBwKGFwcGx5KGxlZnQsIHZhcm5hbWUsIHRlcm0pLCBhcHBseShyaWdodCwgdmFybmFtZSwgdGVybSkpCiAgfQp9CgpvYmplY3QgTGFtYmRhUGFyc2VycyBleHRlbmRzIFJlZ2V4UGFyc2VycyB7CiAgb3ZlcnJpZGUgZGVmIHNraXBXaGl0ZXNwYWNlID0gZmFsc2UKCiAgZGVmIHZhcmlhYmxlIDogUGFyc2VyW1Rlcm1dID0gIlxcdysiLnIgXl4gewogICAgeCA9PiBWYXIoeCkKICB9CgogIGRlZiBmdW5jdGlvbiA6IFBhcnNlcltUZXJtXSA9ICJcXChcXFxcIi5yIH4gdmFyaWFibGUgfiAiXFwuIi5yIH4gdGVybSB+ICJcXCkiLnIgXl4gewogICAgY2FzZSBfIH4gVmFyKHZhcm5hbWUpIH4gXyB+IGJvZHkgfiBfID0+IEZ1bih2YXJuYW1lLCBib2R5KQogIH0KCiAgZGVmIGFwcGxpY2F0aW9uIDogUGFyc2VyW1Rlcm1dID0gIlxcKCIuciB+IHRlcm0gfiAiXFxzIi5yIH4gdGVybSB+ICJcXCkiLnIgXl4gewogICAgY2FzZSBfIH4gbGVmdCB+IF8gfiByaWdodCB+IF8gPT4gQXBwKGxlZnQsIHJpZ2h0KQogIH0KCiAgZGVmIHRlcm0gPSBmdW5jdGlvbiB8IGFwcGxpY2F0aW9uIHwgdmFyaWFibGUKfQoKb2JqZWN0IFRvcExldmVsIHsKICBkZWYgZXZhbChleHByZXNzaW9uIDogU3RyaW5nKSA6IFN0cmluZyA9IHsKICAgIHZhbCB0ZXJtID0gTGFtYmRhUGFyc2Vycy5wYXJzZShMYW1iZGFQYXJzZXJzLnRlcm0sIGV4cHJlc3Npb24pLmdldAogICAgTm9ybWFsT3JkZXIucmVkdWNlKHRlcm0pIG1hdGNoIHsKICAgICAgY2FzZSBTb21lKHJlc3VsdCkgPT4gcmVzdWx0LnRvU3RyaW5nCiAgICAgIGNhc2UgTm9uZSA9PiAiU29tZXRoaW5nIHdyb25nISIKICAgIH0KICB9Cn0KCm9iamVjdCBNYWluIHsKICBkZWYgbWFpbihhcmdzIDogQXJyYXlbU3RyaW5nXSkgPSB7CiAgICBwcmludGxuKFRvcExldmVsLmV2YWwocmF3IigoKFx4LihceS4oeCB5KSkpIChcei56KSkgYSkiKSkKICB9Cn0K