{
"cells": [
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
":opt no-lint"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Untyped $π$-calculus\n",
"νμ
μλ λλ€κ³μ°λ²μ λ¬Έλ²κ³Ό μ€μΌ μ μλ μ(reducible expression)μ κ°λ
λ±μ λν΄ μμλ³Έλ€.\n",
"\n",
"\"μ€μΌ μ μλ μ\"μ΄λΌλ λ§μ΄ λ무 κΈΈκΈ° λλ¬Έμ 'μ£Όλμ'(redex)κ³Ό κ°μ μ€μλ§μ λ³΄ν΅ λ λ§μ΄ μ¬μ©νλ€."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## λ¬Έλ²\n",
"$ x \\in \\textit{Nm} $\n",
"\n",
"$ e \\in \\textit{Tm}\n",
"\\\\ e ::=~ x ~\\mid~ (\\lambda x.e) ~\\mid~ (e_1~e_2)\n",
"$\n",
"\n",
"λ³΄ν΅ μνμμ $f(x) = x^2$κ³Ό κ°μ΄ μ μνλ ν¨μ $f$λ₯Ό λλ€κ³μ°λ²μμλ μλμ κ°μ λ°©μμΌλ‘ νννλ€.\n",
"\n",
"$(\\lambda x.x^2)$\n",
"\n",
"κ·Έλ¦¬κ³ λ³΄ν΅ μνμμ μ μλ ν¨μλ₯Ό νΈμΆνλ $f(3)$κ³Ό κ°μ ννμ λλ€κ³μ°λ²μμλ κ΄νΈ μμ΄ ν¨μμ μΈμλ₯Ό λμ΄νμ¬ μλμ κ°μ λ°©μμΌλ‘ νννλ€.\n",
"\n",
"$((\\lambda x.x^2)~3)$\n",
"\n",
"μνμμλ κ·Έλ λ― λλ€κ³μ°λ²μμλ μ΄λ€ ν¨μκ° λ€λ₯Έ ν¨μλ₯Ό λ°μ λ λ€λ₯Έ ν¨μλ₯Ό λ§λ€μ΄λΌ μ μλ€.\n",
"κ°μ₯ λνμ μΈ μλ‘ 'λ―ΈλΆ'μ΄λΌλ κ°λ
μ ν¨μλ₯Ό λ°μ ν¨μλ₯Ό λλ €μ£Όλ ν¨μλ‘ μ΄ν΄ν μλ μλ€.\n",
"\n",
"$((λ―ΈλΆ~(\\lambda x.x^2))~3) \\longrightarrow\\cdots\\longrightarrow ((\\lambda x.\\,2\\times x)~3) \\longrightarrow 2\\times 3 \\longrightarrow 6$\n",
"\n",
"λ¬Όλ‘ μμν λλ€κ³μ°λ²μλ λ―ΈλΆμ΄λ, μ κ³±, κ³±νκΈ°, λ±μ κ°λ
μ κΈ°λ³Έμ μΌλ‘ μ 곡νμ§λ μμΌλ©° μ¬μ§μ΄ μμ°μλ κΈ°λ³Έ ꡬμ±μμλ‘ μ 곡λμ§ μλλ€. μμ μμ λ κ°λ
μ μΈ μ΄ν΄λ₯Ό λκΈ° μν μ€λͺ
μ΄λ€. μ°Έκ³ λ‘ Alonzo Churchμ λλ€κ³μ°λ²μ Alan Turingμ νλ§λ¨Έμ κ³Ό λ§μ°¬κ°μ§λ‘ κ΄΄λΈμ΄ \"μνλͺ
μ μλνλ³ λ¬Έμ \"κ° ν΄κ²° λΆκ°λ₯ν¨μ μ¦λͺ
ν λΆμμ μ± μ 리λ₯Ό κ·Έλ€ λλ¦μ λ°©μμΌλ‘ μ’λ μ§μ μ μΌλ‘ κ°λ΅νκ² μ¦λͺ
νκΈ° μν μ΄λ‘ μ λꡬ νΉμ μνμΌλ‘ λ§λ€μ΄μ§ κ²μ΄λ€. κ°μ νλ κ²μ΄ μλλΌ νμ§λ§ μ΄ν μ΄λ° μνλ€μ μ΄λ‘ μ κ³μ°λ₯λ ₯μ΄ λμΌνλ€λ κ²μ΄ λ°νμ§λ©΄μ μ€λλ μ°λ¦¬κ° μ΄ν΄νλ μ»΄ν¨ν°λ‘ ν μ μλ λͺ¨λ κ³μ°μ μ΄λ‘ μ λ²μλ₯Ό λ°κ²¬ν κ²μΌλ‘ λ°μλ€μ¬μ§κ³ μλλ° μ΄λ₯Ό μ²μΉ-νλ§ λ
Όμ (Church-Turing thesis)λΌκ³ νλ€. μ΄μ κ΄λ ¨ν μμ¬μ λ°°κ²½ λ° μ’λ μμΈν λ΄μ©μ΄ κΆκΈν μ¬λλ€μ λ€μ μ¨λΌμΈμ 곡κ°λ [μ»΄ν¨ν°κ³Όνμ΄ μ¬λ μΈκ³](https://www.youtube.com/watch?v=HTWSPoDLmHI&list=PL0Nf1KJu6Ui7yoc9RQ2TiiYL9Z0MKoggH) κ°μ μ리μ¦μ 1.4, 1.5, 1.6 λ΄μ© μμ λ±μ΄ μ°Έκ³ κ° λ κ²μ΄λ€."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"-- λ³μ μ΄λ¦μ λ¬Έμμ΄ λνλΈλ€\n",
"type Nm = String\n",
"\n",
"-- λλ€μ λ¬Έλ² κ΅¬μ‘°\n",
"data Tm = Var Nm -- x\n",
" | Lam Nm Tm -- (Ξ»x.e)\n",
" | App Tm Tm -- (e1 e2)\n",
" deriving (Show, Eq)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"-- λλ€μμ 보기μ’κ² λ¬Έμμ΄λ‘ λ³νν΄μ£Όλ ν¨μ\n",
"ppTm (Var x) = x\n",
"ppTm (Lam x e) = \"\\\\\" ++ x ++ \" -> \" ++ ppTm e\n",
"ppTm (App e1 e2) = pp1 e1 ++ \" \" ++ pp2 e2\n",
" where\n",
" pp1 e@(Lam{}) = paren (ppTm e)\n",
" pp1 e = ppTm e\n",
" pp2 e@(Var{}) = ppTm e\n",
" pp2 e = paren (ppTm e)\n",
"\n",
"paren s = \"(\" ++ s ++ \")\"\n",
"brack s = \"[\" ++ s ++ \"]\"\n",
"latex s = \"$\" ++ s ++ \"$\"\n",
"\n",
"-- λλ€μμ 보기μ’κ² TeX μ½λλ‘ λ³νν΄μ£Όλ ν¨μ\n",
"texTm (Var x) = x\n",
"texTm (Lam x e) = \"\\\\lambda \" ++ x ++ \".\" ++ texTm e\n",
"texTm (App e1 e2) = tex1 e1 ++ \"~\" ++ tex2 e2\n",
" where\n",
" tex1 e@(Lam{}) = paren (texTm e)\n",
" tex1 t = texTm t\n",
" tex2 s@(Var{}) = texTm s\n",
" tex2 s = paren (texTm s)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"idTm = Lam \"x\" (Var \"x\")\n",
"ttTm = Lam \"x\" (Lam \"y\" (Var \"x\")) \n",
"ffTm = Lam \"x\" (Lam \"y\" (Var \"y\")) "
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\\x -> x"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"\\x -> \\y -> x"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"\\x -> \\y -> y"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"putStr $ ppTm idTm\n",
"putStr $ ppTm ttTm\n",
"putStr $ ppTm ffTm"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"$\\lambda x.x$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$\\lambda x.\\lambda y.x$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$\\lambda x.\\lambda y.y$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$x~y~z$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$x~(y~z)$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$(\\lambda x.\\lambda y.y)~(\\lambda x.x)~(\\lambda x.\\lambda y.x)$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$(\\lambda x.\\lambda y.y)~((\\lambda x.x)~(\\lambda x.\\lambda y.x))$"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import IHaskell.Display\n",
"\n",
"html . latex $ texTm idTm\n",
"html . latex $ texTm ttTm\n",
"html . latex $ texTm ffTm\n",
"html . latex $ texTm (App (App (Var \"x\") (Var \"y\")) (Var \"z\"))\n",
"html . latex $ texTm (App (Var \"x\") (App (Var \"y\") (Var \"z\")))\n",
"html . latex $ texTm (App (App ffTm idTm) ttTm)\n",
"html . latex $ texTm (App ffTm (App idTm ttTm))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## λΆλΆμ(sub-expression)\n",
"λλ€μμ λΆλΆμμ κ·Έ μμ μΌλΆλ‘ λνλλ λλ€μμ΄λ€. μ 체 μ μ체λ μκΈ° μμ μ λΆλΆμμ΄λΌκ³ νμ.\n",
"\n",
"νμ€μΌ λ°μ΄ν νμ
`Tm`μΌλ‘ ννλ μ΄λ€ λλ€μμ λΆλΆμμ λͺ¨λ λμ΄νλ 리μ€νΈλ₯Ό ꡬνλ ν¨μλ₯Ό λ€μκ³Ό κ°μ΄ μμ±ν μ μλ€."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[2,3,4,7,8]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"[2,3,4] ++ [7,8]"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"subTm :: Tm -> [Tm]\n",
"subTm (Var x) = [(Var x)] -- (Var x) : []\n",
"subTm (Lam x e1) = (Lam x e1) : subTm e1\n",
"subTm (App e1 e2) = (App e1 e2) : subTm e1 ++ subTm e2"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"$(\\lambda x.x)~(\\lambda y.y)$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"[App (Lam \"x\" (Var \"x\")) (Lam \"y\" (Var \"y\")),Lam \"x\" (Var \"x\"),Var \"x\",Lam \"y\" (Var \"y\"),Var \"y\"]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$(\\lambda x.x)~(\\lambda y.y)$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$\\lambda x.x$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$x$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$\\lambda y.y$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$y$"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"e = App (Lam \"x\" (Var \"x\")) (Lam \"y\" (Var \"y\"))\n",
"\n",
"html . latex . texTm $ e\n",
"\n",
"subTm e\n",
"\n",
"map (html . latex . texTm) (subTm e)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ν¨ν΄λ§€μΉμμ λΆλΆλ³λ‘ μ΄λ¦μ λΆμκ³Ό λμμ ꡬ쑰 μ 체μλ μ΄λ¦μ λΆμ¬μ£Όλ €λ©΄ `@`μ νμ©νλ€.\n",
"μ컨λ μμ `subTm`κ³Ό κ°μ ν¨μλ₯Ό λ€μκ³Ό `@`ν¨ν΄μ νμ©νλ©΄ λ κ°κ²°νκ² μ μλλ©°,\n",
"μ»΄νμΌλ¬κ° ꡬ쑰 μ 체λ₯Ό ν¨μ κ²°κ³Όμμ κ·Έλλ‘ μ°Έμ‘°ν μ μλ μΆκ° μ λ³΄κ° λ μ μμΌλ―λ‘\n",
"μ»΄νμΌλ μ½λμ μ±λ₯μ΄ κ°μ λ κ°λ₯μ±λ μλ€."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"subTm' :: Tm -> [Tm]\n",
"subTm' e@(Var _) = [e]\n",
"subTm' e@(Lam x e1) = e : subTm e1\n",
"subTm' e@(App e1 e2) = e : subTm e1 ++ subTm e2"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[App (Lam \"x\" (Var \"x\")) (Lam \"y\" (Var \"y\")),Lam \"x\" (Var \"x\"),Var \"x\",Lam \"y\" (Var \"y\"),Var \"y\"]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$(\\lambda x.x)~(\\lambda y.y)$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$\\lambda x.x$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$x$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$\\lambda y.y$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$y$"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"e = App (Lam \"x\" (Var \"x\")) (Lam \"y\" (Var \"y\"))\n",
"\n",
"subTm' e\n",
"\n",
"map (html . latex . texTm) (subTm' e)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## μ£Όλμ(redex)\n",
"λλ€κ³μ°λ²μ μ€νμλ―Έλ κ·Έ λ¬Έλ²λ§νΌμ΄λ λ§€μ° λ¨μνλ€.\n",
"ν¨μμ μμ $(\\lambda x.e)$λ₯Ό μΈμ $e_2$μ μ μ©ν\n",
"ν¨μμ μ©μ $((\\lambda x.e)~e_2)$λ κ³§λ°λ‘ μ€μΌ μ μλ\n",
"μ£Όλμ(redex)μ΄λ©° κ·Έκ²μ ν κ±Έμ μ€μΈ κ²°κ³Όλ\n",
"$e$μ λνλλ $x$λ₯Ό $e_2$λ‘ μΉνν μ,\n",
"μ¦ $x$μ μ리μ $x$λμ $e_2$λ‘ λΌμλ£μ μμ΄ λλ€.\n",
"λ¬λ¦¬ λ§νμ§λ©΄ μ£Όλμμ΄λ μ¦μ ν¨μ νΈμΆμ ν μ μλ ννμ ν¨μμ μ©μμ λ§νλ κ²μ΄λ€.\n",
"μλνλ©΄ μ¦μ ν¨μ νΈμΆμ΄ κ°λ₯νλ €λ©΄ μΌμͺ½μ μ€λ ν¨μ λΆλΆμ΄ λλ€λ‘ μμνλ ν¨μμ μμμ΄μ΄μΌ νλκΉ.\n",
"μ΄λ¬ν κ³μ° κ·μΉμ $\\beta$-μ€μ΄κΈ°($\\beta$-reduction)μ΄λΌκ³ νλ©°\n",
"μλμ κ°μ΄ λνλΈλ€. μ°Έκ³ λ‘ μ€μ΄λ λ°©λ²μ΄ ν κ°μ§κ° μλλΌ μ¬λ¬ κ°μ§ κ·μΉμ΄ ν¬ν¨λ\n",
"λλ€κ³μ°λ²μ λ³μ΄λ€λ κ°λ₯νλ° κ·Έλ° κ²½μ° νΉμ κ·μΉμ λ°λΌ μ£Όλμμμ νννκΈ° μν΄\n",
"$\\beta$-μ£Όλμ($\\beta$-redex)μ΄λΌκ³ μ€μ΄λ κ·μΉμ μ΄λ¦μ μμ λΆμ¬μ λ§νκΈ°λ νλ€.\n",
"\n",
"$((\\lambda x. e)~e_2) \\longrightarrow \\{x\\mapsto e_2\\}e$\n",
"\n",
"μ¬κΈ°μμ $\\{x\\mapsto e_2\\}e$λ λ°λ‘ $e$μμ $x$λ₯Ό $e_2$λ‘ μΉνν μμ μλ―Ένλ νκΈ°λ²μ΄λ€.\n",
"μ컨λ $\\big(\\big(\\lambda x.(\\lambda y.(y~x)~x)\\big)~z\\big)$λ₯Ό\n",
"μ€μ΄λ©΄ $\\{x\\mapsto z\\}(\\lambda y.(y~x)~x)$ κ·Έλ¬λκΉ $(\\lambda y.(y~z)~z)$κ° λλ€.\n",
"\n",
"μ°Έκ³ λ‘ μμ $\\beta$-μ€μ΄κΈ° κ·μΉμ ν΅μ¬μΌλ‘ νλ, μ΄λ€ μμ΄ κ·Έ μ체λ‘λ $\\beta$-μ€μ΄κΈ° κ·μΉμ\n",
"μ μ© λμμ΄ μλλλΌλ κ·μΉμ΄ μ μ©λλ λΆλΆμ μ°Ύμ κ·Έ λΆλΆμ μμ $\\beta$-μ€μ΄κΈ°λ₯Ό μ μ©νλ\n",
"κ·μΉλ€μ μΆκ°λ‘ μ μν μ μλ€. μ컨λ, $\\big(\\big((\\lambda x.x)~(\\lambda y.y)\\big)~(\\lambda z.z)\\big)$λ\n",
"κ·Έ μ체λ‘λ μ μ 체μ $\\beta$-μ€μ΄κΈ° κ·μΉμ μ μ©ν μ μμ§λ§\n",
"κ·Έ λΆλΆμμΈ $\\big((\\lambda x.x)~(\\lambda y.y)\\big)$μλ $\\beta$-μ€μ΄κΈ° κ·μΉμ μ μ©ν μ μλ€.\n",
"μ¬μ€ λΆλΆμμ $\\beta$-μ€μ΄κΈ°λ₯Ό μ΄λ»κ² μ μ©ν μ§λ μ¬λ¬ κ°μ§\n",
"λ°©λ² νΉμ μ λ΅μ΄ κ°λ₯νλ° μ§κΈμ μΌλ¨ μ λΉν μ무 κ³³μλ μ μ©νλ€κ³ νκ³ λμ΄κ°κΈ°λ‘ νκ³ μ΄νμ\n",
"λ€μ μ΄μ λν΄ μκ°ν΄ λ³΄κ² λ€.\n",
"\n",
"νμ€μΌ λ°μ΄ν νμ
`Tm`μΌλ‘ ννλ μ΄λ€ λλ€μμ΄\n",
"κ·Έ μμ²΄λ‘ $\\beta$-μ€μ΄κΈ° κ·μΉμ λ°λ‘ μ μ©ν μ μλ μ£Όλμ(redex)μΈμ§\n",
"κ²μ¬νλ ν¨μλ₯Ό λ€μκ³Ό κ°μ΄ μμ±ν μ μλ€."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"isRedEx :: Tm -> Bool\n",
"isRedEx (App (Lam{}) _) = True\n",
"isRedEx _ = False"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"$\\lambda x.x$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"False"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$(\\lambda x.x)~(\\lambda x.x)$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$\\lambda x.(\\lambda x.x)~(\\lambda x.x)$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"False"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"e1 = idTm\n",
"e2 = App idTm idTm\n",
"e3 = (Lam \"x\" e2)\n",
"\n",
"html . latex $ texTm e1\n",
"isRedEx e1\n",
"html . latex $ texTm e2\n",
"isRedEx e2\n",
"html . latex $ texTm e3\n",
"isRedEx e3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"μ£Όμ΄μ§ μ μ체λ‘λ μ£Όλμ(redex)μ΄ μλλλΌλ μ΄λ€ λΆλΆμ λΆλΆμμ μ£Όλμμ ν¬ν¨νκ³ μμ μλ μλ€.\n",
"κ·Έ μμ²΄λ‘ μ£Όλ μμΈ κ²½μ° λΏλ§ μλλΌ λΆλΆμμΌλ‘ μ£Όλμμ ν¬ν¨νλ μμΈμ§κΉμ§ κ²μ¬νλ `hasRedEx` ν¨μλ₯Ό\n",
"λ€μκ³Ό κ°μ΄ μμ±ν μ μλ€."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"hasRedEx :: Tm -> Bool\n",
"hasRedEx (Var _) = False\n",
"hasRedEx (Lam _ e1) = hasRedEx e1\n",
"hasRedEx e@(App e1 e2) = isRedEx e || hasRedEx e1 || hasRedEx e2"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"$\\lambda x.x$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"False"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$(\\lambda x.x)~(\\lambda x.x)$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$\\lambda x.(\\lambda x.x)~(\\lambda x.x)$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"e1 = idTm\n",
"e2 = App idTm idTm\n",
"e3 = (Lam \"x\" e2)\n",
"\n",
"html . latex $ texTm e1\n",
"hasRedEx e1\n",
"html . latex $ texTm e2\n",
"hasRedEx e2\n",
"html . latex $ texTm e3\n",
"hasRedEx e3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"μ°Έκ³ λ‘ μμ κ°μ μΌμ νλ λ€λ₯Έ λ°©λ²μΌλ‘λ μ μν μ μλ€.\n",
"μμ μ μν `subTm` ν¨μλ‘ λΆλΆμμ λͺ¨λ λμ΄νμ¬\n",
"κ·Έ μ€ νλλΌλ μ£Όλ μμ΄ μλμ§ κ²μ¬νλ `isRedEx` ν¨μμ ν¨κ»\n",
"νμ€λΌμ΄λΈλ¬λ¦¬ κ³ μ°¨ν¨μ `any`λ₯Ό νμ©νλ©΄ μμλ³Ό μ μμΌλ―λ‘\n",
"λκ°μ μΌμ νλ ν¨μλ₯Ό λ€μκ³Ό κ°μ΄ μ μν μλ μλ€."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"even 3\n",
"even 4"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"any even [1,3,5,7,9]\n",
"any even [1,3,4,7,9]"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"hasRedEx' = any isRedEx . subTm"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"$\\lambda x.x$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"False"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$(\\lambda x.x)~(\\lambda x.x)$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$\\lambda x.(\\lambda x.x)~(\\lambda x.x)$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"e1 = idTm\n",
"e2 = App idTm idTm\n",
"e3 = (Lam \"x\" e2)\n",
"\n",
"html . latex $ texTm e1\n",
"hasRedEx' e1\n",
"html . latex $ texTm e2\n",
"hasRedEx' e2\n",
"html . latex $ texTm e3\n",
"hasRedEx' e3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"----"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"-- texTmμ μ μ ν λ³κ²½νμ¬ ν¨μμ μ©μ (e1 e2)μμ\n",
"-- ν¨μ λΆλΆμΈ e1μ λΉ¨κ° μΈμ λΆλΆμΈ e2μ νλ μ¬κ°ν ν
λ리 μΆκ°\n",
"texTmColor (Var x) = x\n",
"texTmColor (Lam x e) = \"\\\\lambda \" ++ x ++ \".\" ++ texTmColor e\n",
"texTmColor (App e1 e2) = box1(tex1 e1) ++ \"~\" ++ box2(tex2 e2)\n",
" where\n",
" tex1 e@(Lam{}) = paren (texTmColor e)\n",
" tex1 t = texTmColor t\n",
" tex2 s@(Var{}) = texTmColor s\n",
" tex2 s = paren (texTmColor s)\n",
" box1 = red . boxed . black\n",
" box2 = blue . boxed . black\n",
"\n",
"color c s = \"\\\\color{\"++c++\"}{\"++s++\"}\"\n",
"boxed s = \"\\\\boxed{\"++s++\"}\"\n",
"\n",
"black = color \"black\"\n",
"red = color \"red\"\n",
"blue = color \"blue\""
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"$(\\lambda f.(\\lambda x.x)~((\\lambda x.x)~(f~f)))~((\\lambda x.x)~(\\lambda x.x))$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"\\color{red}{\\boxed{\\color{black}{(\\lambda f.\\color{red}{\\boxed{\\color{black}{(\\lambda x.x)}}}~\\color{blue}{\\boxed{\\color{black}{(\\color{red}{\\boxed{\\color{black}{(\\lambda x.x)}}}~\\color{blue}{\\boxed{\\color{black}{(\\color{red}{\\boxed{\\color{black}{f}}}~\\color{blue}{\\boxed{\\color{black}{f}}})}}})}}})}}}~\\color{blue}{\\boxed{\\color{black}{(\\color{red}{\\boxed{\\color{black}{(\\lambda x.x)}}}~\\color{blue}{\\boxed{\\color{black}{(\\lambda x.x)}}})}}}"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$\\color{red}{\\boxed{\\color{black}{(\\lambda f.\\color{red}{\\boxed{\\color{black}{(\\lambda x.x)}}}~\\color{blue}{\\boxed{\\color{black}{(\\color{red}{\\boxed{\\color{black}{(\\lambda x.x)}}}~\\color{blue}{\\boxed{\\color{black}{(\\color{red}{\\boxed{\\color{black}{f}}}~\\color{blue}{\\boxed{\\color{black}{f}}})}}})}}})}}}~\\color{blue}{\\boxed{\\color{black}{(\\color{red}{\\boxed{\\color{black}{(\\lambda x.x)}}}~\\color{blue}{\\boxed{\\color{black}{(\\lambda x.x)}}})}}}$"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"e1 = Lam \"f\" (App idTm (App idTm (Var \"f\" `App` Var \"f\"))) `App` App idTm idTm\n",
"html . latex $ texTm e1\n",
"putStr $ texTmColor e1\n",
"html . latex $ texTmColor e1"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"-- texTmRedEx :: Tm -> String\n",
"-- texTmμ μ μ ν λ³κ²½νμ¬ ν¨μμ μ©μ (e1 e2)μμ\n",
"-- ν¨μ λΆλΆμΈ e1μ λΉ¨κ° μΈμ λΆλΆμΈ e2μ νλ μ¬κ°ν ν
λ리 μΆκ°\n",
"texTmRedEx (Var x) = x\n",
"texTmRedEx (Lam x e) = \"\\\\lambda \" ++ x ++ \".\" ++ texTmRedEx e\n",
"texTmRedEx e@(App e1 e2) =\n",
" if isRedEx e then box1(tex1 e1) ++ \"~\" ++ box2(tex2 e2)\n",
" else tex1 e1 ++ \"~\" ++ tex2 e2\n",
" where\n",
" tex1 e@(Lam{}) = paren (texTmRedEx e)\n",
" tex1 t = texTmRedEx t\n",
" tex2 s@(Var{}) = texTmRedEx s\n",
" tex2 s = paren (texTmRedEx s)\n",
" box1 = red . boxed . black\n",
" box2 = blue . boxed . black"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\\color{red}{\\boxed{\\color{black}{(\\lambda f.\\color{red}{\\boxed{\\color{black}{(\\lambda x.x)}}}~\\color{blue}{\\boxed{\\color{black}{(\\color{red}{\\boxed{\\color{black}{(\\lambda x.x)}}}~\\color{blue}{\\boxed{\\color{black}{(f~f)}}})}}})}}}~\\color{blue}{\\boxed{\\color{black}{(\\color{red}{\\boxed{\\color{black}{(\\lambda x.x)}}}~\\color{blue}{\\boxed{\\color{black}{(\\lambda x.x)}}})}}}"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"$\\color{red}{\\boxed{\\color{black}{(\\lambda f.\\color{red}{\\boxed{\\color{black}{(\\lambda x.x)}}}~\\color{blue}{\\boxed{\\color{black}{(\\color{red}{\\boxed{\\color{black}{(\\lambda x.x)}}}~\\color{blue}{\\boxed{\\color{black}{(f~f)}}})}}})}}}~\\color{blue}{\\boxed{\\color{black}{(\\color{red}{\\boxed{\\color{black}{(\\lambda x.x)}}}~\\color{blue}{\\boxed{\\color{black}{(\\lambda x.x)}}})}}}$"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"e1 = Lam \"f\" (App idTm (App idTm (Var \"f\" `App` Var \"f\"))) `App` App idTm idTm\n",
"putStr $ texTmRedEx e1\n",
"html. latex $ texTmRedEx e1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"----"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## νμ€ν(normal form)\n",
"\n",
"νμ€νμ κ·μΉμ λ°λΌ λ μ΄μ μ€μΌ μ μλ λΆλΆμμ ν¬ν¨νμ§ μλ ννμ λλ€μμ λ§νλ€.\n",
"ꡬ체μ μΌλ‘ $\\beta$-μ€μ΄κΈ°λ‘ λ μ΄μ μ€μΌ μ μλ λΆλΆμμ΄ μ ν ν¬ν¨νμ§ μλ λλ€μμ $\\beta$-νμ€νμ΄λΌ μΌμ»«λλ€.\n",
"\n",
"μ£Όμ΄μ§ λλ€μ $e$μ $\\beta$-μ€μ΄κΈ°λ₯Ό λ°λ³΅μ μΌλ‘ μ μ©ν΄ μ»μ μ μλ $\\beta$-νμ€νμ\n",
"$e$μ $\\beta$-νμ€νμ΄λΌ λ§νλλ°, νμ
μλ λλ€κ³μ°λ²μμλ\n",
"μ£Όμ΄μ§ λλ€μμ $\\beta$-νμ€νμ΄ μ‘΄μ¬νλ€λ©΄ μ μΌνλ€λ\n",
"**μ²μΉ-λ‘μ μ 리(Church-Rosser theorem)**κ° μ±λ¦½νλ€.\n",
"\n",
"λλ€κ³μ°λ²μ μ²μΉ-λ‘μ μ 리λ₯Ό μ§μ μ€λͺ
ν기보λ€λ\n",
"μ°μ μ§κ΄μ μΌλ‘ μ²μΉ-λ‘μ μ λ¦¬κ° μ΄λ€ μ±μ§μ μλ―Ένλμ§ λ§μ
μμ ν΅ν΄ κ°λ¨ν κ°λ
λ§ μμ보μ.\n",
" \n",
"μλ₯Ό λ€μ΄ (1 + 2) + (4 + 5) λΌλ λ§μ
μμ΄ μλ€λ©΄ μ΄λ€ λ§μ
μ λ¨Όμ νλ κ΄κ³μμ΄ νμ κ°μ κ²°κ³Όκ°μ μ»λλ€.\n",
"μ¦ λ§μ
μμμλ λ§μ
μ μ€μ¬λκ°λ κ²μ λν μ²μΉ-λ‘μ μ 리μ μ±μ§μ΄ μ±λ¦½νλ€κ³ λ§ν μ μλ€.\n",
"\n",
"$(1 + 2) + (4 + 5) ~\\longrightarrow~ 3 + (4 + 5) ~\\longrightarrow~ 3 + 9 ~\\longrightarrow~ 12$\n",
"\n",
"$(1 + 2) + (4 + 5) ~\\longrightarrow~ (1 + 2) + 9 ~\\longrightarrow~ 3 + 9 ~\\longrightarrow~ 12$\n",
"\n",
"νμ§λ§ νμ
μλ λλ€κ³μ°λ²μ κ²½μ° κ³μ°μ΄ μΌλ°μ μΌλ‘ νμ λλλ€λ 보μ₯μ΄ μλ€.\n",
"μ¦ μ΄λ€ λλ€μμ νμ€νμ΄ μμ μ‘΄μ¬νμ§ μμ μλ μμΌλ©°\n",
"νμ€νμ΄ μ‘΄μ¬νλλΌλ μ΄λ€ μ€μΌμμ λ¨Όμ κ³μ°νλκ°μ λ°λΌ\n",
"κ³μ°μ΄ λλ μλ μκ³ λλμ§ μμ μλ μλ€. κ·Έλμ νμ
μλ\n",
"λλ€κ³μ°λ²μμμ μ²μΉ-λ‘μ μ 리λ νμ€νμ΄ μ‘΄μ¬νλ μμ κ²½μ°\n",
"νμ€νμ λλ¬ν μ μλ λͺ¨λ κ³μ° κ²½λ‘ λμ μλ νμ€νμ΄ λͺ¨λ \"κ°λ€\"λ μλ―Έμ΄λ€.\n",
"\n",
"μ°Έκ³ λ‘ νμ€νμ΄ μλ λλμ§ μλ κ³μ°μ νλ λνμ μΈ μκ° λ°λ‘ λ€μκ³Ό κ°μ λλ€μμ΄λ€.\n",
"\n",
"$\n",
"\\big((\\lambda x.x~x)~(\\lambda x.x~x)\\big)\n",
"\\longrightarrow\n",
"\\big((\\lambda x.x~x)~(\\lambda x.x~x)\\big)\n",
"\\longrightarrow\n",
"~~\\cdots$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## $\\alpha$-λ³ν ($\\alpha$-conversion), $\\alpha$-λμΉ ($\\alpha$-equivalence)\n",
"\n",
"μ κΉ, κ·Όλ° \"κ°λ€\"λ κ² λ¬΄μμΈμ§ μ°λ¦¬κ° μμ§ μ νν μ μνμ§ μμλ€.\n",
"\n",
"μΌλ¨ νμ€ν κ²μ κΈμ νλλ νλ¦¬μ§ μκ³ λκ°μΌλ©΄ λΆλͺ
ν κ°μ κ²μ΄λ€.\n",
"νμ§λ§ μ΄κ²μ λ무λ νμν κ°μμ μ μλ€.\n",
"μλνλ©΄ $(\\lambda x.x)$μ $(\\lambda y.y)$μ κ²½μ°\n",
"λΉλ‘ κΈμ νλνλλ₯Ό λΉκ΅νλ©΄ λ€λ₯Έ μ μ΄ μκΈ°λ νμ§λ§\n",
"λΆλͺ
ν λκ°μ μμ΄λΌκ³ λ³Ό μ μκΈ° λλ¬Έμ΄λ€.\n",
"$(\\lambda x.x)$μμ ν¨μ μΈμμ μ΄λ¦μ $x$λμ $y$λ‘ λ°κΎΌ ν¨μκ° $(\\lambda y.y)$μ΄λ€.\n",
"μ΄λ κ² ν¨μ μΈμμ μ΄λ¦μ μΌκ΄μ μΌλ‘ λ°κΏλ κ²μ $\\alpha$-λ³νμ΄λΌκ³ νλ©°,\n",
"ν¨μ μΈμ μ΄λ¦λ§ λ°κΏλκ°λ©΄ λκ°μμ§λ κ΄κ³μ μλ λλ€μλ€μ $\\alpha$-λμΉ κ΄κ³μ μλ€κ³ νλ€.\n",
"\n",
"## $\\beta$-λμΉ ($\\beta$-equivalence)\n",
"$((\\lambda x.x)~(\\lambda y.y))$μ $((\\lambda y.(\\lambda x.x))~z)$λ $\\alpha$-λμΉκ° μλλ€.\n",
"νμ§λ§ μ΄λ₯Ό $\\beta$-μ€μ΄κΈ°λ‘ νλ¨κ³λ§ κ³μ°νλ©΄ κ³μ° κ²°κ³Όλ‘ λμ€λ μλ€μ΄ $\\alpha$-λμΉμμ μ μ μλ€.\n",
"\n",
"$((\\lambda x.x)~(\\lambda y.y)) \\longrightarrow (\\lambda y.y)$\n",
"\n",
"$((\\lambda y.(\\lambda x.x))~z) \\longrightarrow (\\lambda x.x)$\n",
"\n",
"\n",
"μ΄μ κ°μ΄ $\\beta$-μ€μ΄κΈ°λ₯Ό (μΌλ°μ μΌλ‘λ ν κ±Έμλ§ μλλΌ μ¬λ¬ κ±ΈμμΌλ‘) μ μ©ν΄μ κ°μμ§λ\n",
"κ΄κ³λ₯Ό $\\beta$-λμΉλΌκ³ νλ€. λ§μ
μμΌλ‘ λΉμ νμλ©΄ ((3+4)+5)μ (2+(5+6))μ²λΌ ꡬ쑰λ μκΉμκ°\n",
"μ€λ Ή λ€λ₯΄λλΌλ κ³μ° κ²°κ³Όκ° κ°μ κ΄κ³μ ν΄λΉνλ€. νμ€νμ΄ μλ λλ€μλΌλ¦¬ λΉκ΅νλ κ²½μ°λΌλ©΄ μ²μΉ-λ‘μ μ 리μ μ±μ§μ\n",
"μκ±°ν΄ μλ‘μ νμ€νμ κ΅¬ν΄ κ°μμ§ μμλ΄μΌλ‘μ¨ $\\beta$-λμΉ κ΄κ³μΈμ§ κ²μ¬κ° κ°λ₯νλ€."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Haskell",
"language": "haskell",
"name": "haskell"
},
"language_info": {
"codemirror_mode": "ihaskell",
"file_extension": ".hs",
"name": "haskell",
"pygments_lexer": "Haskell",
"version": "8.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}