From bcbe5d3293d4a6080f0ca300d7d035707647bba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Wegrzynowski?= Date: Mon, 15 Feb 2021 11:36:54 +0100 Subject: [PATCH] =?UTF-8?q?r=C3=A9daction=20partie=20lambda-calcul=20(peut?= =?UTF-8?q?-=C3=AAtre)=20termin=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +- lambda_calcul.ipynb | 3660 ++++++++++++++++++++++++++++++++----------- lambda_calcul.md | 886 ++++++++++- lambda_calcul.py | 6 +- 4 files changed, 3585 insertions(+), 981 deletions(-) diff --git a/README.md b/README.md index 68e7fc2..e34dbc9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ # Quelques essais autour du 饾渾-calcul +Fichiers : + +* `lambda_calcul.py` module Python permettant de repr茅senter des 饾渾-termes et de les r茅duire. +* `lambda_calcul.ipynb` calepin Jupyter d茅crivant et illustrant ce qu'est le 饾渾-calcul. +* `lambda_calcul.md` version Markdown du calepin pr茅c茅dent. + + +# Pr茅requis + +* Tout ce travail a 茅t茅 r茅alis茅 avec Python 3.7.3 et Jupyter 6.1. +* L'utilisation du module `lambda_calcul.py` n茅cessite le module [`sly`](https://github.com/dabeaz/sly). + # TODO -R茅diger le texte. +R茅diger le texte de la deuxi猫me partie du calepin. diff --git a/lambda_calcul.ipynb b/lambda_calcul.ipynb index ef8b165..e094cc4 100644 --- a/lambda_calcul.ipynb +++ b/lambda_calcul.ipynb @@ -6,8 +6,9 @@ "source": [ "Ce calepin est compos茅 de deux parties :\n", "\n", - "1. la premi猫re partie est une rapide pr茅sentation du $\\lambda$-calcul illustr茅e par l'utilisation d'un module permettant de d茅finir et transformer des $\\lambda$-termes.\n", - "2. la deuxi猫me partie reprend la partie 芦 pouvoir d'expression du $\\lambda$-calcul 禄 en l'illustrant avec les lambda-expressions du langage Python." + "1. la premi猫re partie est une rapide pr茅sentation du $\\lambda$-calcul illustr茅e par l'utilisation d'un module permettant de d茅finir et transformer des $\\lambda$-termes. \n", + " \n", + "2. la deuxi猫me partie reprend la partie 芦 pouvoir d'expression du $\\lambda$-calcul 禄 en l'illustrant avec les lambda-expressions du langage Python. (CETTE PARTIE RESTE ENCORE A REDIGER)" ] }, { @@ -59,6 +60,19 @@ "En principe, les $\\lambda$-termes sont des mots sur lesquels certaines op茅rations sont possibles. Ces mots ont vocation 脿 pouvoir exprimer des fonctions, ainsi que leur application 脿 un argument. " ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "En $\\lambda$-calcul tout est fonction !\n", + "\n", + "Si $f$ est un $\\lambda$-terme, on doit pouvoir l'appliquer 脿 un autre terme $x$, mais au lieu d'茅crire $f(x)$ comme c'est l'usage en math茅matiques, on 茅crit plut么t $(f\\ x)$ et cela forme un nouveau terme nomm茅 *application*.\n", + "\n", + "Il n'y a pas de fonctions 脿 plusieurs variables : toutes les fonctions ont une et une seule variable. Donc si on a en t锚te de vouloir repr茅senter une fonction 脿 deux variables $f(x,y)$, elle le sera par une fonction 脿 une variable telle que $f(x)$ soit elle aussi une fonction 脿 une variable, et au lieu d'茅crire $f(x,y)$ ou m锚me $f(x)(y)$, on 茅crira $((f\\ x)\\ y)$.\n", + "\n", + "Enfin si $x$ est une variable et $M$ un terme d茅pendant 茅ventuellement de $x$, on doit pouvoir d茅finir la fonction $x\\mapsto M$. Cette construction est nomm茅e *abstraction* en $\\lambda$-calcul et elle est not茅e $\\lambda x.M$." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -556,13 +570,9 @@ "3. Si $T=\\lambda y.S$ est une abstraction, alors il faut distinguer deux cas pour d茅finir $T[x:=R]$\n", " \n", " * si $y\\not\\in FV(R)$, alors $T[x:=R] = \\lambda y.S[x:= R]$.\n", - " * si $y\\in FV(R)$, alors $T[x:=R] = \\lambda z.S[y:=z][x:=R]$, la variable $z$ 茅tant une nouvelle variable n'apparaissant pas dans $S$ ni dans $R$. On proc猫de 脿 un renommage de la variable d'abstraction ($y$) pour 茅viter que les occurrences libres de $y$ de $R$ n'entrent sous la port茅e de l'abstraction." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ + " * si $y\\in FV(R)$, alors $T[x:=R] = \\lambda z.S[y:=z][x:=R]$, la variable $z$ 茅tant une nouvelle variable n'apparaissant pas dans $S$ ni dans $R$. On proc猫de 脿 un renommage de la variable d'abstraction ($y$) pour 茅viter que les occurrences libres de $y$ de $R$ n'entrent sous la port茅e de l'abstraction.\n", + "\n", + "\n", "La m茅thode `subs` renvoie le terme obtenu en substituant un $\\lambda$-terme 脿 toutes les occurrences libres d'une variable." ] }, @@ -1061,16 +1071,15 @@ "output_type": "stream", "text": [ "(位x.(x y) (位x.(x y) x))\n", - " 1: ---> (位x.(x y) (位x.(x y) x))\n", - " 2: ---> ((位x.(x y) x) y)\n", - " 3: ---> ((x y) y)\n", + " 1: ---> ((位x.(x y) x) y)\n", + " 2: ---> ((x y) y)\n", "Forme normale calcul茅e : ((x y) y)\n" ] }, { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 28, @@ -1251,9 +1260,9 @@ "metadata": {}, "source": [ "On peut repr茅senter les deux bool茅ens VRAI et FAUX par les $\\lambda$-termes\n", - "$$ VRAI = \\lambda x.\\lambda y.x,$$\n", + "$$ \\mathtt{VRAI} = \\lambda x.\\lambda y.x,$$\n", "et\n", - "$$ FAUX = \\lambda x.\\lambda y.y.$$" + "$$ \\mathtt{FAUX} = \\lambda x.\\lambda y.y.$$" ] }, { @@ -1266,6 +1275,13 @@ "FAUX = Lambda_terme('!x.!y.y')" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Remarque** les deux termes $\\mathtt{VRAI}$ et $\\mathtt{FAUX}$ sont termes clos irr茅ductibles." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1305,19 +1321,18 @@ "output_type": "stream", "text": [ "(((位c.位a.位s.((c a) s) 位x.位y.x) ALORS) SINON)\n", - " 1: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) ALORS) SINON)\n", - " 2: ---> ((位a.位s.((位x.位y.x a) s) ALORS) SINON)\n", - " 3: ---> (位s.((位x.位y.x ALORS) s) SINON)\n", - " 4: ---> ((位x.位y.x ALORS) SINON)\n", - " 5: ---> (位y.ALORS SINON)\n", - " 6: ---> ALORS\n", + " 1: ---> ((位a.位s.((位x.位y.x a) s) ALORS) SINON)\n", + " 2: ---> (位s.((位x.位y.x ALORS) s) SINON)\n", + " 3: ---> ((位x.位y.x ALORS) SINON)\n", + " 4: ---> (位y.ALORS SINON)\n", + " 5: ---> ALORS\n", "Forme normale calcul茅e : ALORS\n" ] }, { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 33, @@ -1339,19 +1354,18 @@ "output_type": "stream", "text": [ "(((位c.位a.位s.((c a) s) 位x.位y.y) ALORS) SINON)\n", - " 1: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) ALORS) SINON)\n", - " 2: ---> ((位a.位s.((位x.位y.y a) s) ALORS) SINON)\n", - " 3: ---> (位s.((位x.位y.y ALORS) s) SINON)\n", - " 4: ---> ((位x.位y.y ALORS) SINON)\n", - " 5: ---> (位y.y SINON)\n", - " 6: ---> SINON\n", + " 1: ---> ((位a.位s.((位x.位y.y a) s) ALORS) SINON)\n", + " 2: ---> (位s.((位x.位y.y ALORS) s) SINON)\n", + " 3: ---> ((位x.位y.y ALORS) SINON)\n", + " 4: ---> (位y.y SINON)\n", + " 5: ---> SINON\n", "Forme normale calcul茅e : SINON\n" ] }, { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 34, @@ -1387,19 +1401,18 @@ "output_type": "stream", "text": [ "(((位c.位a.位s.((c a) s) 位x.位y.x) ALORS) (位x.(x x) 位x.(x x)))\n", - " 1: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) ALORS) (位x.(x x) 位x.(x x)))\n", - " 2: ---> ((位a.位s.((位x.位y.x a) s) ALORS) (位x.(x x) 位x.(x x)))\n", - " 3: ---> (位s.((位x.位y.x ALORS) s) (位x.(x x) 位x.(x x)))\n", - " 4: ---> ((位x.位y.x ALORS) (位x.(x x) 位x.(x x)))\n", - " 5: ---> (位y.ALORS (位x.(x x) 位x.(x x)))\n", - " 6: ---> ALORS\n", + " 1: ---> ((位a.位s.((位x.位y.x a) s) ALORS) (位x.(x x) 位x.(x x)))\n", + " 2: ---> (位s.((位x.位y.x ALORS) s) (位x.(x x) 位x.(x x)))\n", + " 3: ---> ((位x.位y.x ALORS) (位x.(x x) 位x.(x x)))\n", + " 4: ---> (位y.ALORS (位x.(x x) 位x.(x x)))\n", + " 5: ---> ALORS\n", "Forme normale calcul茅e : ALORS\n" ] }, { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 35, @@ -1421,19 +1434,18 @@ "output_type": "stream", "text": [ "(((位c.位a.位s.((c a) s) 位x.位y.y) (位x.(x x) 位x.(x x))) SINON)\n", - " 1: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) (位x.(x x) 位x.(x x))) SINON)\n", - " 2: ---> ((位a.位s.((位x.位y.y a) s) (位x.(x x) 位x.(x x))) SINON)\n", - " 3: ---> (位s.((位x.位y.y (位x.(x x) 位x.(x x))) s) SINON)\n", - " 4: ---> ((位x.位y.y (位x.(x x) 位x.(x x))) SINON)\n", - " 5: ---> (位y.y SINON)\n", - " 6: ---> SINON\n", + " 1: ---> ((位a.位s.((位x.位y.y a) s) (位x.(x x) 位x.(x x))) SINON)\n", + " 2: ---> (位s.((位x.位y.y (位x.(x x) 位x.(x x))) s) SINON)\n", + " 3: ---> ((位x.位y.y (位x.(x x) 位x.(x x))) SINON)\n", + " 4: ---> (位y.y SINON)\n", + " 5: ---> SINON\n", "Forme normale calcul茅e : SINON\n" ] }, { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 36, @@ -1449,7 +1461,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Le fait que le terme `IF` se comporte bien comme on l'attend r茅sulte du choix de la strat茅gie de r茅duction des redex les plus 脿 gauche en priorit茅. Si la strat茅gie choisie avait 茅t茅 de r茅duire le redex le plus 脿 droite, la r茅duction de chacun des deux termes pr茅c茅dents aurait conduit 脿 la tentative de r茅duire le terme $\\Omega$ qui 茅choue puisque celui-ci n'est pas normalisable comme on l'a vu." + "Le fait que le terme $\\mathtt{IF}$ se comporte bien comme on l'attend r茅sulte du choix de la strat茅gie de r茅duction des redex les plus 脿 gauche en priorit茅. Si la strat茅gie choisie avait 茅t茅 de r茅duire le redex le plus 脿 droite, la r茅duction de chacun des deux termes pr茅c茅dents aurait conduit 脿 la tentative de r茅duire le terme $\\Omega$ qui 茅choue puisque celui-ci n'est pas normalisable comme on l'a vu." ] }, { @@ -1472,7 +1484,7 @@ "source": [ "L'op茅rateur logique de conjonction peut 锚tre d茅fini par\n", "\n", - "$$ ET = \\lambda a.\\lambda b.(((IF\\ a)\\ b)\\ FAUX).$$" + "$$ \\mathtt{ET} = \\lambda a.\\lambda b.(((\\mathtt{IF}\\ a)\\ b)\\ \\mathtt{FAUX}).$$" ] }, { @@ -1518,14 +1530,13 @@ "output_type": "stream", "text": [ "((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) 位x.位y.x) 位x.位y.x)\n", - " 1: ---> ((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) 位x.位y.x) 位x.位y.x)\n", - " 2: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.x) b) 位x.位y.y) 位x.位y.x)\n", - " 3: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.x) 位x.位y.y)\n", - " 4: ---> ((位a.位s.((位x.位y.x a) s) 位x.位y.x) 位x.位y.y)\n", - " 5: ---> (位s.((位x.位y.x 位x.位y.x) s) 位x.位y.y)\n", - " 6: ---> ((位x.位y.x 位x.位y.x) 位x.位y.y)\n", - " 7: ---> (位y.位x.位y.x 位x.位y.y)\n", - " 8: ---> 位x.位y.x\n", + " 1: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.x) b) 位x.位y.y) 位x.位y.x)\n", + " 2: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.x) 位x.位y.y)\n", + " 3: ---> ((位a.位s.((位x.位y.x a) s) 位x.位y.x) 位x.位y.y)\n", + " 4: ---> (位s.((位x.位y.x 位x.位y.x) s) 位x.位y.y)\n", + " 5: ---> ((位x.位y.x 位x.位y.x) 位x.位y.y)\n", + " 6: ---> (位y.位x.位y.x 位x.位y.y)\n", + " 7: ---> 位x.位y.x\n", "Forme normale calcul茅e : 位x.位y.x\n" ] }, @@ -1554,14 +1565,13 @@ "output_type": "stream", "text": [ "((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) 位x.位y.x) 位x.位y.y)\n", - " 1: ---> ((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) 位x.位y.x) 位x.位y.y)\n", - " 2: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.x) b) 位x.位y.y) 位x.位y.y)\n", - " 3: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.y) 位x.位y.y)\n", - " 4: ---> ((位a.位s.((位x.位y.x a) s) 位x.位y.y) 位x.位y.y)\n", - " 5: ---> (位s.((位x.位y.x 位x.位y.y) s) 位x.位y.y)\n", - " 6: ---> ((位x.位y.x 位x.位y.y) 位x.位y.y)\n", - " 7: ---> (位y.位x.位y.y 位x.位y.y)\n", - " 8: ---> 位x.位y.y\n", + " 1: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.x) b) 位x.位y.y) 位x.位y.y)\n", + " 2: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.y) 位x.位y.y)\n", + " 3: ---> ((位a.位s.((位x.位y.x a) s) 位x.位y.y) 位x.位y.y)\n", + " 4: ---> (位s.((位x.位y.x 位x.位y.y) s) 位x.位y.y)\n", + " 5: ---> ((位x.位y.x 位x.位y.y) 位x.位y.y)\n", + " 6: ---> (位y.位x.位y.y 位x.位y.y)\n", + " 7: ---> 位x.位y.y\n", "Forme normale calcul茅e : 位x.位y.y\n" ] }, @@ -1590,14 +1600,13 @@ "output_type": "stream", "text": [ "((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) 位x.位y.y) 位x.位y.x)\n", - " 1: ---> ((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) 位x.位y.y) 位x.位y.x)\n", - " 2: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.y) b) 位x.位y.y) 位x.位y.x)\n", - " 3: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.x) 位x.位y.y)\n", - " 4: ---> ((位a.位s.((位x.位y.y a) s) 位x.位y.x) 位x.位y.y)\n", - " 5: ---> (位s.((位x.位y.y 位x.位y.x) s) 位x.位y.y)\n", - " 6: ---> ((位x.位y.y 位x.位y.x) 位x.位y.y)\n", - " 7: ---> (位y.y 位x.位y.y)\n", - " 8: ---> 位x.位y.y\n", + " 1: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.y) b) 位x.位y.y) 位x.位y.x)\n", + " 2: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.x) 位x.位y.y)\n", + " 3: ---> ((位a.位s.((位x.位y.y a) s) 位x.位y.x) 位x.位y.y)\n", + " 4: ---> (位s.((位x.位y.y 位x.位y.x) s) 位x.位y.y)\n", + " 5: ---> ((位x.位y.y 位x.位y.x) 位x.位y.y)\n", + " 6: ---> (位y.y 位x.位y.y)\n", + " 7: ---> 位x.位y.y\n", "Forme normale calcul茅e : 位x.位y.y\n" ] }, @@ -1626,14 +1635,13 @@ "output_type": "stream", "text": [ "((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) 位x.位y.y) 位x.位y.y)\n", - " 1: ---> ((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) 位x.位y.y) 位x.位y.y)\n", - " 2: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.y) b) 位x.位y.y) 位x.位y.y)\n", - " 3: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.y) 位x.位y.y)\n", - " 4: ---> ((位a.位s.((位x.位y.y a) s) 位x.位y.y) 位x.位y.y)\n", - " 5: ---> (位s.((位x.位y.y 位x.位y.y) s) 位x.位y.y)\n", - " 6: ---> ((位x.位y.y 位x.位y.y) 位x.位y.y)\n", - " 7: ---> (位y.y 位x.位y.y)\n", - " 8: ---> 位x.位y.y\n", + " 1: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.y) b) 位x.位y.y) 位x.位y.y)\n", + " 2: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.y) 位x.位y.y)\n", + " 3: ---> ((位a.位s.((位x.位y.y a) s) 位x.位y.y) 位x.位y.y)\n", + " 4: ---> (位s.((位x.位y.y 位x.位y.y) s) 位x.位y.y)\n", + " 5: ---> ((位x.位y.y 位x.位y.y) 位x.位y.y)\n", + " 6: ---> (位y.y 位x.位y.y)\n", + " 7: ---> 位x.位y.y\n", "Forme normale calcul茅e : 位x.位y.y\n" ] }, @@ -1665,7 +1673,7 @@ "source": [ "L'op茅rateur logique de disjonction peut 锚tre d茅fini par\n", "\n", - "$$ OU = \\lambda a.\\lambda b.(((IF\\ a)\\ VRAI)\\ b).$$" + "$$ \\mathtt{OU} = \\lambda a.\\lambda b.(((\\mathtt{IF}\\ a)\\ \\mathtt{VRAI})\\ b).$$" ] }, { @@ -1711,14 +1719,13 @@ "output_type": "stream", "text": [ "((位a.位b.(((位c.位a.位s.((c a) s) a) 位x.位y.x) b) 位x.位y.x) 位x.位y.x)\n", - " 1: ---> ((位a.位b.(((位c.位a.位s.((c a) s) a) 位x.位y.x) b) 位x.位y.x) 位x.位y.x)\n", - " 2: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.x) b) 位x.位y.x)\n", - " 3: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.x) 位x.位y.x)\n", - " 4: ---> ((位a.位s.((位x.位y.x a) s) 位x.位y.x) 位x.位y.x)\n", - " 5: ---> (位s.((位x.位y.x 位x.位y.x) s) 位x.位y.x)\n", - " 6: ---> ((位x.位y.x 位x.位y.x) 位x.位y.x)\n", - " 7: ---> (位y.位x.位y.x 位x.位y.x)\n", - " 8: ---> 位x.位y.x\n", + " 1: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.x) b) 位x.位y.x)\n", + " 2: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.x) 位x.位y.x)\n", + " 3: ---> ((位a.位s.((位x.位y.x a) s) 位x.位y.x) 位x.位y.x)\n", + " 4: ---> (位s.((位x.位y.x 位x.位y.x) s) 位x.位y.x)\n", + " 5: ---> ((位x.位y.x 位x.位y.x) 位x.位y.x)\n", + " 6: ---> (位y.位x.位y.x 位x.位y.x)\n", + " 7: ---> 位x.位y.x\n", "Forme normale calcul茅e : 位x.位y.x\n" ] }, @@ -1747,14 +1754,13 @@ "output_type": "stream", "text": [ "((位a.位b.(((位c.位a.位s.((c a) s) a) 位x.位y.x) b) 位x.位y.x) 位x.位y.y)\n", - " 1: ---> ((位a.位b.(((位c.位a.位s.((c a) s) a) 位x.位y.x) b) 位x.位y.x) 位x.位y.y)\n", - " 2: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.x) b) 位x.位y.y)\n", - " 3: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.x) 位x.位y.y)\n", - " 4: ---> ((位a.位s.((位x.位y.x a) s) 位x.位y.x) 位x.位y.y)\n", - " 5: ---> (位s.((位x.位y.x 位x.位y.x) s) 位x.位y.y)\n", - " 6: ---> ((位x.位y.x 位x.位y.x) 位x.位y.y)\n", - " 7: ---> (位y.位x.位y.x 位x.位y.y)\n", - " 8: ---> 位x.位y.x\n", + " 1: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.x) b) 位x.位y.y)\n", + " 2: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.x) 位x.位y.y)\n", + " 3: ---> ((位a.位s.((位x.位y.x a) s) 位x.位y.x) 位x.位y.y)\n", + " 4: ---> (位s.((位x.位y.x 位x.位y.x) s) 位x.位y.y)\n", + " 5: ---> ((位x.位y.x 位x.位y.x) 位x.位y.y)\n", + " 6: ---> (位y.位x.位y.x 位x.位y.y)\n", + " 7: ---> 位x.位y.x\n", "Forme normale calcul茅e : 位x.位y.x\n" ] }, @@ -1783,14 +1789,13 @@ "output_type": "stream", "text": [ "((位a.位b.(((位c.位a.位s.((c a) s) a) 位x.位y.x) b) 位x.位y.y) 位x.位y.x)\n", - " 1: ---> ((位a.位b.(((位c.位a.位s.((c a) s) a) 位x.位y.x) b) 位x.位y.y) 位x.位y.x)\n", - " 2: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.x) b) 位x.位y.x)\n", - " 3: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.x) 位x.位y.x)\n", - " 4: ---> ((位a.位s.((位x.位y.y a) s) 位x.位y.x) 位x.位y.x)\n", - " 5: ---> (位s.((位x.位y.y 位x.位y.x) s) 位x.位y.x)\n", - " 6: ---> ((位x.位y.y 位x.位y.x) 位x.位y.x)\n", - " 7: ---> (位y.y 位x.位y.x)\n", - " 8: ---> 位x.位y.x\n", + " 1: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.x) b) 位x.位y.x)\n", + " 2: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.x) 位x.位y.x)\n", + " 3: ---> ((位a.位s.((位x.位y.y a) s) 位x.位y.x) 位x.位y.x)\n", + " 4: ---> (位s.((位x.位y.y 位x.位y.x) s) 位x.位y.x)\n", + " 5: ---> ((位x.位y.y 位x.位y.x) 位x.位y.x)\n", + " 6: ---> (位y.y 位x.位y.x)\n", + " 7: ---> 位x.位y.x\n", "Forme normale calcul茅e : 位x.位y.x\n" ] }, @@ -1819,14 +1824,13 @@ "output_type": "stream", "text": [ "((位a.位b.(((位c.位a.位s.((c a) s) a) 位x.位y.x) b) 位x.位y.y) 位x.位y.y)\n", - " 1: ---> ((位a.位b.(((位c.位a.位s.((c a) s) a) 位x.位y.x) b) 位x.位y.y) 位x.位y.y)\n", - " 2: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.x) b) 位x.位y.y)\n", - " 3: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.x) 位x.位y.y)\n", - " 4: ---> ((位a.位s.((位x.位y.y a) s) 位x.位y.x) 位x.位y.y)\n", - " 5: ---> (位s.((位x.位y.y 位x.位y.x) s) 位x.位y.y)\n", - " 6: ---> ((位x.位y.y 位x.位y.x) 位x.位y.y)\n", - " 7: ---> (位y.y 位x.位y.y)\n", - " 8: ---> 位x.位y.y\n", + " 1: ---> (位b.(((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.x) b) 位x.位y.y)\n", + " 2: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.x) 位x.位y.y)\n", + " 3: ---> ((位a.位s.((位x.位y.y a) s) 位x.位y.x) 位x.位y.y)\n", + " 4: ---> (位s.((位x.位y.y 位x.位y.x) s) 位x.位y.y)\n", + " 5: ---> ((位x.位y.y 位x.位y.x) 位x.位y.y)\n", + " 6: ---> (位y.y 位x.位y.y)\n", + " 7: ---> 位x.位y.y\n", "Forme normale calcul茅e : 位x.位y.y\n" ] }, @@ -1858,7 +1862,7 @@ "source": [ "L'op茅rateur de n茅gation peut 锚tre d茅fini par le terme\n", "\n", - "$$ NON = \\lambda a.(((IF\\ a)\\ FAUX)\\ VRAI).$$" + "$$ \\mathtt{NON} = \\lambda a.(((\\mathtt{IF}\\ a)\\ \\mathtt{FAUX})\\ \\mathtt{VRAI}).$$" ] }, { @@ -1897,13 +1901,12 @@ "output_type": "stream", "text": [ "(位a.(((位c.位a.位s.((c a) s) a) 位x.位y.y) 位x.位y.x) 位x.位y.x)\n", - " 1: ---> (位a.(((位c.位a.位s.((c a) s) a) 位x.位y.y) 位x.位y.x) 位x.位y.x)\n", - " 2: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.y) 位x.位y.x)\n", - " 3: ---> ((位a.位s.((位x.位y.x a) s) 位x.位y.y) 位x.位y.x)\n", - " 4: ---> (位s.((位x.位y.x 位x.位y.y) s) 位x.位y.x)\n", - " 5: ---> ((位x.位y.x 位x.位y.y) 位x.位y.x)\n", - " 6: ---> (位y.位x.位y.y 位x.位y.x)\n", - " 7: ---> 位x.位y.y\n", + " 1: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) 位x.位y.y) 位x.位y.x)\n", + " 2: ---> ((位a.位s.((位x.位y.x a) s) 位x.位y.y) 位x.位y.x)\n", + " 3: ---> (位s.((位x.位y.x 位x.位y.y) s) 位x.位y.x)\n", + " 4: ---> ((位x.位y.x 位x.位y.y) 位x.位y.x)\n", + " 5: ---> (位y.位x.位y.y 位x.位y.x)\n", + " 6: ---> 位x.位y.y\n", "Forme normale calcul茅e : 位x.位y.y\n" ] }, @@ -1932,13 +1935,12 @@ "output_type": "stream", "text": [ "(位a.(((位c.位a.位s.((c a) s) a) 位x.位y.y) 位x.位y.x) 位x.位y.y)\n", - " 1: ---> (位a.(((位c.位a.位s.((c a) s) a) 位x.位y.y) 位x.位y.x) 位x.位y.y)\n", - " 2: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.y) 位x.位y.x)\n", - " 3: ---> ((位a.位s.((位x.位y.y a) s) 位x.位y.y) 位x.位y.x)\n", - " 4: ---> (位s.((位x.位y.y 位x.位y.y) s) 位x.位y.x)\n", - " 5: ---> ((位x.位y.y 位x.位y.y) 位x.位y.x)\n", - " 6: ---> (位y.y 位x.位y.x)\n", - " 7: ---> 位x.位y.x\n", + " 1: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) 位x.位y.y) 位x.位y.x)\n", + " 2: ---> ((位a.位s.((位x.位y.y a) s) 位x.位y.y) 位x.位y.x)\n", + " 3: ---> (位s.((位x.位y.y 位x.位y.y) s) 位x.位y.x)\n", + " 4: ---> ((位x.位y.y 位x.位y.y) 位x.位y.x)\n", + " 5: ---> (位y.y 位x.位y.x)\n", + " 6: ---> 位x.位y.x\n", "Forme normale calcul茅e : 位x.位y.x\n" ] }, @@ -1978,6 +1980,33 @@ "Il existe plusieurs fa莽ons de repr茅senter les entiers naturels par un $\\lambda$-terme. La repr茅sentation donn茅e ici est connue sous le nom de *num茅raux de Church*." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Dans le syst猫me de Church, un entier $n\\in\\mathbb{N}$ est repr茅sent茅 par le $\\lambda$-terme\n", + "\n", + "$$ \\lceil n\\rceil = \\lambda f.\\lambda x. (f^n\\ x),$$\n", + "dans lequel le sous-terme $(f^n\\ x)$ est un raccourci pour signifier\n", + "$$ (f^n\\ x) = (f\\ (f\\ (\\ldots (f\\ x)\\ldots))),$$\n", + "terme dans lequel $f$ appara卯t $n$ fois.\n", + "En quelque sorte le terme repr茅sentant l'entier $n$ est une repr茅sentation unaire de $n$.\n", + "\n", + "Ainsi on a\n", + "\n", + "\\begin{align*}\n", + " \\lceil 0\\rceil &= \\lambda f.\\lambda x.x\\\\\n", + " \\lceil 1\\rceil &= \\lambda f.\\lambda x.(f\\ x)\\\\\n", + " \\lceil 2\\rceil &= \\lambda f.\\lambda x.(f\\ (f\\ x))\\\\\n", + " \\lceil 3\\rceil &= \\lambda f.\\lambda x.(f\\ (f\\ (f\\ x))).\n", + "\\end{align*}\n", + "\n", + "Le $\\lambda$-terme $\\lceil n\\rceil$ est donc un terme capable d'appliquer $n$ fois une fonction $F$ sur une donn茅e $X$. En effet on a\n", + "$$ (\\lceil n\\rceil\\ F) \\twoheadrightarrow_\\beta \\lambda x.(F\\ldots(F\\ x)),$$\n", + "et\n", + "$$ ((\\lceil n\\rceil\\ F)\\ X) \\twoheadrightarrow_\\beta (F\\ldots(F\\ X)).$$\n" + ] + }, { "cell_type": "code", "execution_count": 53, @@ -2009,38 +2038,72 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Successeur" + "Le calcul ci-dessous v茅rifie bien qu'un num茅ral appliqu茅 脿 un terme r茅sulte en une fonction it茅ration du terme." ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位f.位x.(f (f x)) F)\n", + " 1: ---> 位x.(F (F x))\n", + "Forme normale calcul茅e : 位x.(F (F x))\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "SUC = Lambda_terme('!n.!f.!x.(f ((n f) x))')" + "DEUX.applique(Lambda_terme('F')).forme_normale(verbose=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Remarque** les num茅raux de Church sont des $\\lambda$-termes clos irr茅ductibles." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Successeur" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lorsqu'on a compris que pour tout num茅ral $\\lceil n\\rceil$ on a\n", + "\n", + "$$ ((\\lceil n\\rceil\\ F)\\ X) \\twoheadrightarrow_\\beta (F\\ldots(F\\ X)),$$\n", + "\n", + "alors il est facile de concevoir un $\\lambda$-terme $\\mathtt{SUC}$ tel que\n", + "\n", + "$$ (\\mathtt{SUC}\\ \\lceil n\\rceil) =_\\beta \\lceil n+1\\rceil.$$\n" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x)))\n", - " 1: ---> (位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x)))\n", - " 2: ---> 位f.位x.(f ((位f.位x.(f (f x)) f) x))\n", - " 3: ---> 位f.位x.(f (位x.(f (f x)) x))\n", - " 4: ---> 位f.位x.(f (f (f x)))\n", - "Forme normale calcul茅e : 位f.位x.(f (f (f x)))\n" - ] - } - ], + "outputs": [], "source": [ - "TROIS = SUC.applique(DEUX).forme_normale(verbose=True)" + "SUC = Lambda_terme('!n.!f.!x.(f ((n f) x))')" ] }, { @@ -2052,35 +2115,74 @@ "name": "stdout", "output_type": "stream", "text": [ - "((位f.位x.(f (f (f x))) 位n.位f.位x.(f ((n f) x))) 位f.位x.x)\n", - " 1: ---> ((位f.位x.(f (f (f x))) 位n.位f.位x.(f ((n f) x))) 位f.位x.x)\n", - " 2: ---> (位x.(位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) x))) 位f.位x.x)\n", - " 3: ---> (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.x)))\n", - " 4: ---> 位f.位x.(f (((位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.x)) f) x))\n", - " 5: ---> 位f.位x.(f ((位f.位x.(f (((位n.位f.位x.(f ((n f) x)) 位f.位x.x) f) x)) f) x))\n", - " 6: ---> 位f.位x.(f (位x.(f (((位n.位f.位x.(f ((n f) x)) 位f.位x.x) f) x)) x))\n", - " 7: ---> 位f.位x.(f (f (((位n.位f.位x.(f ((n f) x)) 位f.位x.x) f) x)))\n", - " 8: ---> 位f.位x.(f (f ((位f.位x.(f ((位f.位x.x f) x)) f) x)))\n", - " 9: ---> 位f.位x.(f (f (位x.(f ((位f.位x.x f) x)) x)))\n", - " 10: ---> 位f.位x.(f (f (f ((位f.位x.x f) x))))\n", - " 11: ---> 位f.位x.(f (f (f (位x.x x))))\n", - " 12: ---> 位f.位x.(f (f (f x)))\n", - "Forme normale calcul茅e : 位f.位x.(f (f (f x)))\n" + "位n.位f.位x.(f ((n f) x))\n" ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 58, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "TROIS.applique(SUC).applique(ZERO).forme_normale(verbose=True)" + "print(SUC)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x)))\n", + " 1: ---> 位f.位x.(f ((位f.位x.(f (f x)) f) x))\n", + " 2: ---> 位f.位x.(f (位x.(f (f x)) x))\n", + " 3: ---> 位f.位x.(f (f (f x)))\n", + "Forme normale calcul茅e : 位f.位x.(f (f (f x)))\n" + ] + } + ], + "source": [ + "TROIS = SUC.applique(DEUX).forme_normale(verbose=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "La fonction qui suit permet d'obtenir le num茅ral de Church correspondant 脿 un entier naturel (de Python)." + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [], + "source": [ + "def int_en_church(n):\n", + " if n == 0:\n", + " return ZERO\n", + " else:\n", + " return SUC.applique(int_en_church(n - 1)).forme_normale()" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "True\n", + "True\n", + "True\n" + ] + } + ], + "source": [ + "for n, t in enumerate((ZERO, UN, DEUX, TROIS)):\n", + " print(int_en_church(n) == t)" ] }, { @@ -2091,28 +2193,103 @@ ] }, { - "cell_type": "code", - "execution_count": 59, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "ADD = Lambda_terme('!n.!m.!f.!x.((n f) ((m f) x))')" + "En appliquant trois fois de suite le terme $\\mathtt{SUC}$ sur le terme $\\lceil 2\\rceil$ on obtient un terme dont la forme normale est le num茅ral $\\lceil 5\\rceil$." ] }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "((位n.位m.位f.位x.((n f) ((m f) x)) 位f.位x.(f x)) 位f.位x.(f (f (f x))))\n", - " 1: ---> ((位n.位m.位f.位x.((n f) ((m f) x)) 位f.位x.(f x)) 位f.位x.(f (f (f x))))\n", - " 2: ---> (位m.位f.位x.((位f.位x.(f x) f) ((m f) x)) 位f.位x.(f (f (f x))))\n", - " 3: ---> 位f.位x.((位f.位x.(f x) f) ((位f.位x.(f (f (f x))) f) x))\n", - " 4: ---> 位f.位x.(位x.(f x) ((位f.位x.(f (f (f x))) f) x))\n", + "((位f.位x.(f (f (f x))) 位n.位f.位x.(f ((n f) x))) 位f.位x.(f (f x)))\n", + " 1: ---> (位x.(位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) x))) 位f.位x.(f (f x)))\n", + " 2: ---> (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x)))))\n", + " 3: ---> 位f.位x.(f (((位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x)))) f) x))\n", + " 4: ---> 位f.位x.(f ((位f.位x.(f (((位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x))) f) x)) f) x))\n", + " 5: ---> 位f.位x.(f (位x.(f (((位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x))) f) x)) x))\n", + " 6: ---> 位f.位x.(f (f (((位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x))) f) x)))\n", + " 7: ---> 位f.位x.(f (f ((位f.位x.(f ((位f.位x.(f (f x)) f) x)) f) x)))\n", + " 8: ---> 位f.位x.(f (f (位x.(f ((位f.位x.(f (f x)) f) x)) x)))\n", + " 9: ---> 位f.位x.(f (f (f ((位f.位x.(f (f x)) f) x))))\n", + " 10: ---> 位f.位x.(f (f (f (位x.(f (f x)) x))))\n", + " 11: ---> 位f.位x.(f (f (f (f (f x)))))\n", + "Forme normale calcul茅e : 位f.位x.(f (f (f (f (f x)))))\n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "TROIS.applique(SUC).applique(DEUX).forme_normale(verbose=True) == int_en_church(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ainsi on peut d茅finir un $\\lambda$-terme $\\mathtt{ADD}$ qui appliqu茅 脿 deux num茅raux est $\\beta$-茅quivalent au num茅ral somme.\n", + "En d茅finissant donc \n", + "$$ \\mathtt{ADD} = \\lambda n.\\lambda m.((n\\ \\mathtt{SUC})\\ m),$$\n", + "on a\n", + "$$ ((\\mathtt{ADD}\\ \\lceil n\\rceil)\\ \\lceil m\\rceil) =_\\beta \\lceil n+m\\rceil.$$" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [], + "source": [ + "M_ADD = Lambda_terme('!n.!m.((n SUC) m)')\n", + "ADD = M_ADD.subs('SUC', SUC)" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "位n.位m.((n 位n.位f.位x.(f ((n f) x))) m)\n" + ] + } + ], + "source": [ + "print(ADD)" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f x)) 位f.位x.(f (f (f x))))\n", + " 1: ---> (位m.((位f.位x.(f x) 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x))))\n", + " 2: ---> ((位f.位x.(f x) 位n.位f.位x.(f ((n f) x))) 位f.位x.(f (f (f x))))\n", + " 3: ---> (位x.(位n.位f.位x.(f ((n f) x)) x) 位f.位x.(f (f (f x))))\n", + " 4: ---> (位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f (f x))))\n", " 5: ---> 位f.位x.(f ((位f.位x.(f (f (f x))) f) x))\n", " 6: ---> 位f.位x.(f (位x.(f (f (f x))) x))\n", " 7: ---> 位f.位x.(f (f (f (f x))))\n", @@ -2126,21 +2303,27 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 66, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "((位n.位m.位f.位x.((n f) ((m f) x)) 位f.位x.(f (f (f x)))) 位f.位x.(f (f x)))\n", - " 1: ---> ((位n.位m.位f.位x.((n f) ((m f) x)) 位f.位x.(f (f (f x)))) 位f.位x.(f (f x)))\n", - " 2: ---> (位m.位f.位x.((位f.位x.(f (f (f x))) f) ((m f) x)) 位f.位x.(f (f x)))\n", - " 3: ---> 位f.位x.((位f.位x.(f (f (f x))) f) ((位f.位x.(f (f x)) f) x))\n", - " 4: ---> 位f.位x.(位x.(f (f (f x))) ((位f.位x.(f (f x)) f) x))\n", - " 5: ---> 位f.位x.(f (f (f ((位f.位x.(f (f x)) f) x))))\n", - " 6: ---> 位f.位x.(f (f (f (位x.(f (f x)) x))))\n", - " 7: ---> 位f.位x.(f (f (f (f (f x)))))\n", + "((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.(f (f x)))\n", + " 1: ---> (位m.((位f.位x.(f (f (f x))) 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f x)))\n", + " 2: ---> ((位f.位x.(f (f (f x))) 位n.位f.位x.(f ((n f) x))) 位f.位x.(f (f x)))\n", + " 3: ---> (位x.(位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) x))) 位f.位x.(f (f x)))\n", + " 4: ---> (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x)))))\n", + " 5: ---> 位f.位x.(f (((位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x)))) f) x))\n", + " 6: ---> 位f.位x.(f ((位f.位x.(f (((位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x))) f) x)) f) x))\n", + " 7: ---> 位f.位x.(f (位x.(f (((位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x))) f) x)) x))\n", + " 8: ---> 位f.位x.(f (f (((位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f x))) f) x)))\n", + " 9: ---> 位f.位x.(f (f ((位f.位x.(f ((位f.位x.(f (f x)) f) x)) f) x)))\n", + " 10: ---> 位f.位x.(f (f (位x.(f ((位f.位x.(f (f x)) f) x)) x)))\n", + " 11: ---> 位f.位x.(f (f (f ((位f.位x.(f (f x)) f) x))))\n", + " 12: ---> 位f.位x.(f (f (f (位x.(f (f x)) x))))\n", + " 13: ---> 位f.位x.(f (f (f (f (f x)))))\n", "Forme normale calcul茅e : 位f.位x.(f (f (f (f (f x)))))\n" ] } @@ -2151,21 +2334,30 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "((位n.位m.位f.位x.((n f) ((m f) x)) 位f.位x.(f (f (f (f x))))) 位f.位x.(f (f (f x))))\n", - " 1: ---> ((位n.位m.位f.位x.((n f) ((m f) x)) 位f.位x.(f (f (f (f x))))) 位f.位x.(f (f (f x))))\n", - " 2: ---> (位m.位f.位x.((位f.位x.(f (f (f (f x)))) f) ((m f) x)) 位f.位x.(f (f (f x))))\n", - " 3: ---> 位f.位x.((位f.位x.(f (f (f (f x)))) f) ((位f.位x.(f (f (f x))) f) x))\n", - " 4: ---> 位f.位x.(位x.(f (f (f (f x)))) ((位f.位x.(f (f (f x))) f) x))\n", - " 5: ---> 位f.位x.(f (f (f (f ((位f.位x.(f (f (f x))) f) x)))))\n", - " 6: ---> 位f.位x.(f (f (f (f (位x.(f (f (f x))) x)))))\n", - " 7: ---> 位f.位x.(f (f (f (f (f (f (f x)))))))\n", + "((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f (f x))))) 位f.位x.(f (f (f x))))\n", + " 1: ---> (位m.((位f.位x.(f (f (f (f x)))) 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x))))\n", + " 2: ---> ((位f.位x.(f (f (f (f x)))) 位n.位f.位x.(f ((n f) x))) 位f.位x.(f (f (f x))))\n", + " 3: ---> (位x.(位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) x)))) 位f.位x.(f (f (f x))))\n", + " 4: ---> (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f (f x)))))))\n", + " 5: ---> 位f.位x.(f (((位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f (f x)))))) f) x))\n", + " 6: ---> 位f.位x.(f ((位f.位x.(f (((位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f (f x))))) f) x)) f) x))\n", + " 7: ---> 位f.位x.(f (位x.(f (((位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f (f x))))) f) x)) x))\n", + " 8: ---> 位f.位x.(f (f (((位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f (f x))))) f) x)))\n", + " 9: ---> 位f.位x.(f (f ((位f.位x.(f (((位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f (f x)))) f) x)) f) x)))\n", + " 10: ---> 位f.位x.(f (f (位x.(f (((位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f (f x)))) f) x)) x)))\n", + " 11: ---> 位f.位x.(f (f (f (((位n.位f.位x.(f ((n f) x)) 位f.位x.(f (f (f x)))) f) x))))\n", + " 12: ---> 位f.位x.(f (f (f ((位f.位x.(f ((位f.位x.(f (f (f x))) f) x)) f) x))))\n", + " 13: ---> 位f.位x.(f (f (f (位x.(f ((位f.位x.(f (f (f x))) f) x)) x))))\n", + " 14: ---> 位f.位x.(f (f (f (f ((位f.位x.(f (f (f x))) f) x)))))\n", + " 15: ---> 位f.位x.(f (f (f (f (位x.(f (f (f x))) x)))))\n", + " 16: ---> 位f.位x.(f (f (f (f (f (f (f x)))))))\n", "Forme normale calcul茅e : 位f.位x.(f (f (f (f (f (f (f x)))))))\n" ] } @@ -2181,110 +2373,11 @@ "#### Multiplication" ] }, - { - "cell_type": "code", - "execution_count": 63, - "metadata": {}, - "outputs": [], - "source": [ - "MUL = Lambda_terme('!n.!m.!f.(n (m f))')" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "((位n.位m.位f.(n (m f)) 位f.位x.(f (f x))) 位f.位x.(f (f (f x))))\n", - " 1: ---> ((位n.位m.位f.(n (m f)) 位f.位x.(f (f x))) 位f.位x.(f (f (f x))))\n", - " 2: ---> (位m.位f.(位f.位x.(f (f x)) (m f)) 位f.位x.(f (f (f x))))\n", - " 3: ---> 位f.(位f.位x.(f (f x)) (位f.位x.(f (f (f x))) f))\n", - " 4: ---> 位f.位x.((位f.位x.(f (f (f x))) f) ((位f.位x.(f (f (f x))) f) x))\n", - " 5: ---> 位f.位x.(位x.(f (f (f x))) ((位f.位x.(f (f (f x))) f) x))\n", - " 6: ---> 位f.位x.(f (f (f ((位f.位x.(f (f (f x))) f) x))))\n", - " 7: ---> 位f.位x.(f (f (f (位x.(f (f (f x))) x))))\n", - " 8: ---> 位f.位x.(f (f (f (f (f (f x))))))\n", - "Forme normale calcul茅e : 位f.位x.(f (f (f (f (f (f x))))))\n" - ] - } - ], - "source": [ - "SIX = MUL.applique(DEUX).applique(TROIS).forme_normale(verbose=True)" - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### Exponentiation" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "metadata": {}, - "outputs": [], - "source": [ - "EXP = Lambda_terme('!n.!m.(m n)')" - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "((位n.位m.(m n) 位f.位x.(f (f x))) 位f.位x.(f (f (f x))))\n", - " 1: ---> ((位n.位m.(m n) 位f.位x.(f (f x))) 位f.位x.(f (f (f x))))\n", - " 2: ---> (位m.(m 位f.位x.(f (f x))) 位f.位x.(f (f (f x))))\n", - " 3: ---> (位f.位x.(f (f (f x))) 位f.位x.(f (f x)))\n", - " 4: ---> 位x.(位f.位x.(f (f x)) (位f.位x.(f (f x)) (位f.位x.(f (f x)) x)))\n", - " 5: ---> 位x.位x0.((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0))\n", - " 6: ---> 位x.位x0.(位x0.((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) x) x0)) ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0))\n", - " 7: ---> 位x.位x0.((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0)))\n", - " 8: ---> 位x.位x0.(位x0.(x (x x0)) ((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0)))\n", - " 9: ---> 位x.位x0.(x (x ((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0))))\n", - " 10: ---> 位x.位x0.(x (x (位x0.(x (x x0)) ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0))))\n", - " 11: ---> 位x.位x0.(x (x (x (x ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0)))))\n", - " 12: ---> 位x.位x0.(x (x (x (x (位x0.((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) x) x0)) x0)))))\n", - " 13: ---> 位x.位x0.(x (x (x (x ((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) x) x0))))))\n", - " 14: ---> 位x.位x0.(x (x (x (x (位x0.(x (x x0)) ((位f.位x.(f (f x)) x) x0))))))\n", - " 15: ---> 位x.位x0.(x (x (x (x (x (x ((位f.位x.(f (f x)) x) x0)))))))\n", - " 16: ---> 位x.位x0.(x (x (x (x (x (x (位x0.(x (x x0)) x0)))))))\n", - " 17: ---> 位x.位x0.(x (x (x (x (x (x (x (x x0))))))))\n", - "Forme normale calcul茅e : 位x.位x0.(x (x (x (x (x (x (x (x x0))))))))\n" - ] - } - ], - "source": [ - "HUIT = EXP.applique(DEUX).applique(TROIS).forme_normale(verbose=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "HUIT == MUL.applique(DEUX).applique(QUATRE).forme_normale()" + "On pourrait d茅finir un terme pour la multiplication en consid茅rant que multiplier $n$ par $m$ c'est r茅p茅ter $n$ fois l'addition de $m$ 脿 partir de 0." ] }, { @@ -2296,24 +2389,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "((位n.位m.(m n) 位f.位x.(f (f (f x)))) 位f.位x.(f (f x)))\n", - " 1: ---> ((位n.位m.(m n) 位f.位x.(f (f (f x)))) 位f.位x.(f (f x)))\n", - " 2: ---> (位m.(m 位f.位x.(f (f (f x)))) 位f.位x.(f (f x)))\n", - " 3: ---> (位f.位x.(f (f x)) 位f.位x.(f (f (f x))))\n", - " 4: ---> 位x.(位f.位x.(f (f (f x))) (位f.位x.(f (f (f x))) x))\n", - " 5: ---> 位x.位x0.((位f.位x.(f (f (f x))) x) ((位f.位x.(f (f (f x))) x) ((位f.位x.(f (f (f x))) x) x0)))\n", - " 6: ---> 位x.位x0.(位x0.(x (x (x x0))) ((位f.位x.(f (f (f x))) x) ((位f.位x.(f (f (f x))) x) x0)))\n", - " 7: ---> 位x.位x0.(x (x (x ((位f.位x.(f (f (f x))) x) ((位f.位x.(f (f (f x))) x) x0)))))\n", - " 8: ---> 位x.位x0.(x (x (x (位x0.(x (x (x x0))) ((位f.位x.(f (f (f x))) x) x0)))))\n", - " 9: ---> 位x.位x0.(x (x (x (x (x (x ((位f.位x.(f (f (f x))) x) x0)))))))\n", - " 10: ---> 位x.位x0.(x (x (x (x (x (x (位x0.(x (x (x x0))) x0)))))))\n", - " 11: ---> 位x.位x0.(x (x (x (x (x (x (x (x (x x0)))))))))\n", - "Forme normale calcul茅e : 位x.位x0.(x (x (x (x (x (x (x (x (x x0)))))))))\n" + "位n.位m.((n (位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) m)) 位f.位x.x)\n" ] } ], "source": [ - "NEUF = EXP.applique(TROIS).applique(DEUX).forme_normale(verbose=True)" + "M_MUL = Lambda_terme('!n.!m.((n (ADD m)) ZERO)')\n", + "MUL = M_MUL.subs('ADD', ADD).subs('ZERO', ZERO)\n", + "print(MUL)" ] }, { @@ -2321,6 +2404,44 @@ "execution_count": 69, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "((位n.位m.((n (位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) m)) 位f.位x.x) 位f.位x.(f (f x))) 位f.位x.(f (f (f x))))\n", + " 1: ---> (位m.((位f.位x.(f (f x)) (位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) m)) 位f.位x.x) 位f.位x.(f (f (f x))))\n", + " 2: ---> ((位f.位x.(f (f x)) (位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x))))) 位f.位x.x)\n", + " 3: ---> (位x.((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) ((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) x)) 位f.位x.x)\n", + " 4: ---> ((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) ((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.x))\n", + " 5: ---> (位m.((位f.位x.(f (f (f x))) 位n.位f.位x.(f ((n f) x))) m) ((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.x))\n", + " 6: ---> ((位f.位x.(f (f (f x))) 位n.位f.位x.(f ((n f) x))) ((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.x))\n", + " 7: ---> (位x.(位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) x))) ((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.x))\n", + " 8: ---> (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) ((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.x))))\n", + " 9: ---> 位f.位x.(f (((位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) ((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.x))) f) x))\n", + " 10: ---> 位f.位x.(f ((位f.位x.(f (((位n.位f.位x.(f ((n f) x)) ((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.x)) f) x)) f) x))\n", + " 11: ---> 位f.位x.(f (位x.(f (((位n.位f.位x.(f ((n f) x)) ((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.x)) f) x)) x))\n", + " 12: ---> 位f.位x.(f (f (((位n.位f.位x.(f ((n f) x)) ((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.x)) f) x)))\n", + " 13: ---> 位f.位x.(f (f ((位f.位x.(f ((((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.x) f) x)) f) x)))\n", + " 14: ---> 位f.位x.(f (f (位x.(f ((((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.x) f) x)) x)))\n", + " 15: ---> 位f.位x.(f (f (f ((((位n.位m.((n 位n.位f.位x.(f ((n f) x))) m) 位f.位x.(f (f (f x)))) 位f.位x.x) f) x))))\n", + " 16: ---> 位f.位x.(f (f (f (((位m.((位f.位x.(f (f (f x))) 位n.位f.位x.(f ((n f) x))) m) 位f.位x.x) f) x))))\n", + " 17: ---> 位f.位x.(f (f (f ((((位f.位x.(f (f (f x))) 位n.位f.位x.(f ((n f) x))) 位f.位x.x) f) x))))\n", + " 18: ---> 位f.位x.(f (f (f (((位x.(位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) x))) 位f.位x.x) f) x))))\n", + " 19: ---> 位f.位x.(f (f (f (((位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.x))) f) x))))\n", + " 20: ---> 位f.位x.(f (f (f ((位f.位x.(f (((位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.x)) f) x)) f) x))))\n", + " 21: ---> 位f.位x.(f (f (f (位x.(f (((位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.x)) f) x)) x))))\n", + " 22: ---> 位f.位x.(f (f (f (f (((位n.位f.位x.(f ((n f) x)) (位n.位f.位x.(f ((n f) x)) 位f.位x.x)) f) x)))))\n", + " 23: ---> 位f.位x.(f (f (f (f ((位f.位x.(f (((位n.位f.位x.(f ((n f) x)) 位f.位x.x) f) x)) f) x)))))\n", + " 24: ---> 位f.位x.(f (f (f (f (位x.(f (((位n.位f.位x.(f ((n f) x)) 位f.位x.x) f) x)) x)))))\n", + " 25: ---> 位f.位x.(f (f (f (f (f (((位n.位f.位x.(f ((n f) x)) 位f.位x.x) f) x))))))\n", + " 26: ---> 位f.位x.(f (f (f (f (f ((位f.位x.(f ((位f.位x.x f) x)) f) x))))))\n", + " 27: ---> 位f.位x.(f (f (f (f (f (位x.(f ((位f.位x.x f) x)) x))))))\n", + " 28: ---> 位f.位x.(f (f (f (f (f (f ((位f.位x.x f) x)))))))\n", + " 29: ---> 位f.位x.(f (f (f (f (f (f (位x.x x)))))))\n", + " 30: ---> 位f.位x.(f (f (f (f (f (f x))))))\n", + "Forme normale calcul茅e : 位f.位x.(f (f (f (f (f (f x))))))\n" + ] + }, { "data": { "text/plain": [ @@ -2333,14 +2454,22 @@ } ], "source": [ - "NEUF == ADD.applique(SEPT).applique(DEUX).forme_normale()" + "MUL.applique(DEUX).applique(TROIS).forme_normale(verbose=True) == int_en_church(6)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### Nullit茅" + "Mais il s'av猫re plus simple (et plus efficace comme on pourra le constater) de d茅finir le terme $\\mathtt{MUL}$ par\n", + "$$ \\mathtt{MUL} = \\lambda n.\\lambda m.\\lambda f.(n\\ (m\\ f)).$$\n", + "\n", + "En effet, il est clair que\n", + "$$ ((\\mathtt{MUL} \\lceil n\\rceil)\\ \\lceil m\\rceil) \\twoheadrightarrow_\\beta \\lambda f.(\\lceil n\\rceil\\ (\\lceil m\\rceil\\ f)),$$\n", + "et le terme obtenu est la r茅p茅tition $m$ fois du terme $f$, r茅p茅tition r茅p茅t茅e elle-m锚me $n$ fois. Au bilan le terme $f$ est r茅p茅t茅 $n\\times m$ fois.\n", + "\n", + "Et on a donc bien\n", + "$$ ((\\mathtt{MUL} \\lceil n\\rceil)\\ \\lceil m\\rceil) =_\\beta \\lceil n\\times m\\rceil.$$" ] }, { @@ -2349,7 +2478,7 @@ "metadata": {}, "outputs": [], "source": [ - "NUL = Lambda_terme('!n.((n !x.FAUX) VRAI)').subs('FAUX', FAUX).subs('VRAI', VRAI)" + "MUL = Lambda_terme('!n.!m.!f.(n (m f))')" ] }, { @@ -2361,44 +2490,53 @@ "name": "stdout", "output_type": "stream", "text": [ - "位n.((n 位x.位x.位y.y) 位x.位y.x)\n" + "((位n.位m.位f.(n (m f)) 位f.位x.(f (f x))) 位f.位x.(f (f (f x))))\n", + " 1: ---> (位m.位f.(位f.位x.(f (f x)) (m f)) 位f.位x.(f (f (f x))))\n", + " 2: ---> 位f.(位f.位x.(f (f x)) (位f.位x.(f (f (f x))) f))\n", + " 3: ---> 位f.位x.((位f.位x.(f (f (f x))) f) ((位f.位x.(f (f (f x))) f) x))\n", + " 4: ---> 位f.位x.(位x.(f (f (f x))) ((位f.位x.(f (f (f x))) f) x))\n", + " 5: ---> 位f.位x.(f (f (f ((位f.位x.(f (f (f x))) f) x))))\n", + " 6: ---> 位f.位x.(f (f (f (位x.(f (f (f x))) x))))\n", + " 7: ---> 位f.位x.(f (f (f (f (f (f x))))))\n", + "Forme normale calcul茅e : 位f.位x.(f (f (f (f (f (f x))))))\n" ] } ], "source": [ - "print(NUL)" + "SIX = MUL.applique(DEUX).applique(TROIS).forme_normale(verbose=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Le calcul de la forme normale de $((\\mathtt{MUL}\\ \\lceil 2\\rceil)\\ \\lceil 3\\rceil)$ avec cette version de $\\mathtt{MUL}$ est bien plus court que le calcul effectu茅 avec la version pr茅c茅dente." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Exponentiation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Comme pour la multiplication, on pourrait envisager de d茅finir un terme pour l'exponentiation en consid茅rant qu'il suffit de r茅p茅ter $m$ fois le terme $\\mathtt{MUL}$ appliqu茅 脿 $n$ pour obtenir un terme qui se r茅duirait au num茅ral repr茅sentant $n^m$.\n", + "\n", + "Mais il est possible de d茅finir un terme beaucoup plus simple :\n", + "$$ \\mathtt{EXP} = \\lambda n.\\lambda m.(m\\ n).$" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(位n.((n 位x.位x.位y.y) 位x.位y.x) 位f.位x.x)\n", - " 1: ---> (位n.((n 位x.位x.位y.y) 位x.位y.x) 位f.位x.x)\n", - " 2: ---> ((位f.位x.x 位x.位x.位y.y) 位x.位y.x)\n", - " 3: ---> (位x.x 位x.位y.x)\n", - " 4: ---> 位x.位y.x\n", - "Forme normale calcul茅e : 位x.位y.x\n" - ] - }, - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 72, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "NUL.applique(ZERO).forme_normale(verbose=True) == VRAI" + "EXP = Lambda_terme('!n.!m.(m n)')" ] }, { @@ -2410,44 +2548,49 @@ "name": "stdout", "output_type": "stream", "text": [ - "(位n.((n 位x.位x.位y.y) 位x.位y.x) 位f.位x.(f (f (f x))))\n", - " 1: ---> (位n.((n 位x.位x.位y.y) 位x.位y.x) 位f.位x.(f (f (f x))))\n", - " 2: ---> ((位f.位x.(f (f (f x))) 位x.位x.位y.y) 位x.位y.x)\n", - " 3: ---> (位x.(位x.位x.位y.y (位x.位x.位y.y (位x.位x.位y.y x))) 位x.位y.x)\n", - " 4: ---> (位x.位x.位y.y (位x.位x.位y.y (位x.位x.位y.y 位x.位y.x)))\n", - " 5: ---> 位x.位y.y\n", - "Forme normale calcul茅e : 位x.位y.y\n" + "((位n.位m.(m n) 位f.位x.(f (f x))) 位f.位x.(f (f (f x))))\n", + " 1: ---> (位m.(m 位f.位x.(f (f x))) 位f.位x.(f (f (f x))))\n", + " 2: ---> (位f.位x.(f (f (f x))) 位f.位x.(f (f x)))\n", + " 3: ---> 位x.(位f.位x.(f (f x)) (位f.位x.(f (f x)) (位f.位x.(f (f x)) x)))\n", + " 4: ---> 位x.位x0.((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0))\n", + " 5: ---> 位x.位x0.(位x0.((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) x) x0)) ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0))\n", + " 6: ---> 位x.位x0.((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0)))\n", + " 7: ---> 位x.位x0.(位x0.(x (x x0)) ((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0)))\n", + " 8: ---> 位x.位x0.(x (x ((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0))))\n", + " 9: ---> 位x.位x0.(x (x (位x0.(x (x x0)) ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0))))\n", + " 10: ---> 位x.位x0.(x (x (x (x ((位f.位x.(f (f x)) (位f.位x.(f (f x)) x)) x0)))))\n", + " 11: ---> 位x.位x0.(x (x (x (x (位x0.((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) x) x0)) x0)))))\n", + " 12: ---> 位x.位x0.(x (x (x (x ((位f.位x.(f (f x)) x) ((位f.位x.(f (f x)) x) x0))))))\n", + " 13: ---> 位x.位x0.(x (x (x (x (位x0.(x (x x0)) ((位f.位x.(f (f x)) x) x0))))))\n", + " 14: ---> 位x.位x0.(x (x (x (x (x (x ((位f.位x.(f (f x)) x) x0)))))))\n", + " 15: ---> 位x.位x0.(x (x (x (x (x (x (位x0.(x (x x0)) x0)))))))\n", + " 16: ---> 位x.位x0.(x (x (x (x (x (x (x (x x0))))))))\n", + "Forme normale calcul茅e : 位x.位x0.(x (x (x (x (x (x (x (x x0))))))))\n" ] - }, - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 73, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "NUL.applique(TROIS).forme_normale(verbose=True) == FAUX" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Couples et listes" + "HUIT = EXP.applique(DEUX).applique(TROIS).forme_normale(verbose=True)" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "CONS = Lambda_terme('!x.!y.!s.(((IF s) x) y)').subs('IF', IF)" + "HUIT == int_en_church(8)" ] }, { @@ -2459,12 +2602,23 @@ "name": "stdout", "output_type": "stream", "text": [ - "位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y)\n" + "((位n.位m.(m n) 位f.位x.(f (f (f x)))) 位f.位x.(f (f x)))\n", + " 1: ---> (位m.(m 位f.位x.(f (f (f x)))) 位f.位x.(f (f x)))\n", + " 2: ---> (位f.位x.(f (f x)) 位f.位x.(f (f (f x))))\n", + " 3: ---> 位x.(位f.位x.(f (f (f x))) (位f.位x.(f (f (f x))) x))\n", + " 4: ---> 位x.位x0.((位f.位x.(f (f (f x))) x) ((位f.位x.(f (f (f x))) x) ((位f.位x.(f (f (f x))) x) x0)))\n", + " 5: ---> 位x.位x0.(位x0.(x (x (x x0))) ((位f.位x.(f (f (f x))) x) ((位f.位x.(f (f (f x))) x) x0)))\n", + " 6: ---> 位x.位x0.(x (x (x ((位f.位x.(f (f (f x))) x) ((位f.位x.(f (f (f x))) x) x0)))))\n", + " 7: ---> 位x.位x0.(x (x (x (位x0.(x (x (x x0))) ((位f.位x.(f (f (f x))) x) x0)))))\n", + " 8: ---> 位x.位x0.(x (x (x (x (x (x ((位f.位x.(f (f (f x))) x) x0)))))))\n", + " 9: ---> 位x.位x0.(x (x (x (x (x (x (位x0.(x (x (x x0))) x0)))))))\n", + " 10: ---> 位x.位x0.(x (x (x (x (x (x (x (x (x x0)))))))))\n", + "Forme normale calcul茅e : 位x.位x0.(x (x (x (x (x (x (x (x (x x0)))))))))\n" ] } ], "source": [ - "print(CONS)" + "NEUF = EXP.applique(TROIS).applique(DEUX).forme_normale(verbose=True)" ] }, { @@ -2473,31 +2627,65 @@ "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.(f x)) 位f.位x.(f (f x)))\n", - " 1: ---> ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.(f x)) 位f.位x.(f (f x)))\n", - " 2: ---> (位y.位s.(((位c.位a.位s.((c a) s) s) 位f.位x.(f x)) y) 位f.位x.(f (f x)))\n", - " 3: ---> 位s.(((位c.位a.位s.((c a) s) s) 位f.位x.(f x)) 位f.位x.(f (f x)))\n", - " 4: ---> 位s.((位a.位s0.((s a) s0) 位f.位x.(f x)) 位f.位x.(f (f x)))\n", - " 5: ---> 位s.(位s0.((s 位f.位x.(f x)) s0) 位f.位x.(f (f x)))\n", - " 6: ---> 位s.((s 位f.位x.(f x)) 位f.位x.(f (f x)))\n", - "Forme normale calcul茅e : 位s.((s 位f.位x.(f x)) 位f.位x.(f (f x)))\n" - ] + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 76, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "UN_DEUX = CONS.applique(UN).applique(DEUX).forme_normale(verbose=True)" + "NEUF == int_en_church(9)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Nullit茅" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Consid茅rons le terme $((\\lceil n\\rceil\\ \\lambda x.\\mathtt{FAUX})\\ \\mathtt{VRAI})$. Si $n=0$ on a \n", + "$$((\\lceil 0\\rceil\\ \\lambda x.\\mathtt{FAUX})\\ \\mathtt{VRAI}) \\twoheadrightarrow_\\beta (\\lambda x.x\\ \\mathtt{VRAI}) \\rightarrow_\\beta \\mathtt{VRAI}.$$\n", + "Et si $n\\neq 0$ on a\n", + "$$((\\lceil n\\rceil\\ \\lambda x.\\mathtt{FAUX})\\ \\mathtt{VRAI}) \\twoheadrightarrow_\\beta (\\lambda x.\\mathtt{FAUX}\\ \\mathtt{VRAI}) \\rightarrow_\\beta \\mathtt{FAUX}.$$\n", + "\n", + "Avec une abstraction, on obtient le $\\lambda$-terme \n", + "$$ \\mathtt{NUL} = \\lambda n.(),$$\n", + "tel que pour $n=0$\n", + "$$ (\\mathtt{NUL}\\ \\lceil 0\\rceil) =_\\beta \\mathtt{VRAI},$$\n", + "et pour $n\\neq 0$\n", + "$$ (\\mathtt{NUL}\\ \\lceil n\\rceil) =_\\beta \\mathtt{FAUX}.$$\n", + "\n", + "En d'autres termes, le $\\lambda$-terme $\\mathtt{NUL}$ correspond 脿 un pr茅dicat permettant de tester la nullit茅 d'un entier." ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "位n.((n 位x.FAUX) VRAI)\n", + "位n.((n 位x.位x.位y.y) 位x.位y.x)\n" + ] + } + ], "source": [ - "CAR = Lambda_terme('!c.(c VRAI)').subs('VRAI', VRAI)" + "M_NUL = Lambda_terme('!n.((n !x.FAUX) VRAI)')\n", + "print(M_NUL)\n", + "NUL = M_NUL.subs('FAUX', FAUX).subs('VRAI', VRAI)\n", + "print(NUL)" ] }, { @@ -2509,12 +2697,26 @@ "name": "stdout", "output_type": "stream", "text": [ - "位c.(c 位x.位y.x)\n" + "(位n.((n 位x.位x.位y.y) 位x.位y.x) 位f.位x.x)\n", + " 1: ---> ((位f.位x.x 位x.位x.位y.y) 位x.位y.x)\n", + " 2: ---> (位x.x 位x.位y.x)\n", + " 3: ---> 位x.位y.x\n", + "Forme normale calcul茅e : 位x.位y.x\n" ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "print(CAR)" + "NUL.applique(ZERO).forme_normale(verbose=True) == VRAI" ] }, { @@ -2526,13 +2728,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "(位c.(c 位x.位y.x) 位s.((s 位f.位x.(f x)) 位f.位x.(f (f x))))\n", - " 1: ---> (位c.(c 位x.位y.x) 位s.((s 位f.位x.(f x)) 位f.位x.(f (f x))))\n", - " 2: ---> (位s.((s 位f.位x.(f x)) 位f.位x.(f (f x))) 位x.位y.x)\n", - " 3: ---> ((位x.位y.x 位f.位x.(f x)) 位f.位x.(f (f x)))\n", - " 4: ---> (位y.位f.位x.(f x) 位f.位x.(f (f x)))\n", - " 5: ---> 位f.位x.(f x)\n", - "Forme normale calcul茅e : 位f.位x.(f x)\n" + "(位n.((n 位x.位x.位y.y) 位x.位y.x) 位f.位x.(f (f (f x))))\n", + " 1: ---> ((位f.位x.(f (f (f x))) 位x.位x.位y.y) 位x.位y.x)\n", + " 2: ---> (位x.(位x.位x.位y.y (位x.位x.位y.y (位x.位x.位y.y x))) 位x.位y.x)\n", + " 3: ---> (位x.位x.位y.y (位x.位x.位y.y (位x.位x.位y.y 位x.位y.x)))\n", + " 4: ---> 位x.位y.y\n", + "Forme normale calcul茅e : 位x.位y.y\n" ] }, { @@ -2547,16 +2748,83 @@ } ], "source": [ - "CAR.applique(UN_DEUX).forme_normale(verbose=True) == UN" + "NUL.applique(TROIS).forme_normale(verbose=True) == FAUX" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Remarque** Arriv茅 脿 ce stade, il nous manque une op茅ration arithm茅tique de base : la soustraction, et la possibilit茅 de comparaison plus g茅n茅rale permettant de d茅cider si un entier est inf茅rieur 脿 un autre. Ce manque sera combl茅 une fois que nous aurons vu une repr茅sentation des couples." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Couples et listes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Constructeur et s茅lecteurs de couples" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Comment exprimer un couple de $\\lambda$-termes 脿 l'aide d'un $\\lambda$-terme ? Une fois ce couple exprim茅 comment en extraire chacune des deux composantes ? " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Soient $M$ et $N$ deux $\\lambda$-termes quelconques. Consid茅rons les deux termes $((\\mathtt{VRAI}\\ M)\\ N)$ et $((\\mathtt{FAUX}\\ M)\\ N)$. Il est facile de v茅rifier que\n", + "$$ ((\\mathtt{VRAI}\\ M)\\ N) =_\\beta M,$$\n", + "et\n", + "$$ ((\\mathtt{FAUX}\\ M)\\ N) =_\\beta N.$$\n", + "\n", + "On d茅duit de ce constat que \n", + "$$[M, N] = \\lambda s.((s\\ M)\\ N)$$\n", + "est un $\\lambda$-terme pouvant repr茅senter le couple $(M, N)$ et que la s茅lection de l'une ou l'autre des deux composantes peut se faire en appliquant le terme sur l'un ou l'autre des deux termes $\\mathtt{VRAI}$ ou $\\mathtt{FAUX}$ :\n", + "\n", + "$$ ([M, N]\\ \\mathtt{VRAI}) =_\\beta M,$$\n", + "et\n", + "$$ ([M, N]\\ \\mathtt{FAUX}) =_\\beta N.$$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ces consid茅rations am猫nent 脿 d茅finir le terme constructeur de couple $\\mathtt{CONS}$\n", + "$$ \\mathtt{CONS} = \\lambda x.\\lambda y.\\lambda s.((s\\ x)\\ y),$$\n", + "ainsi que les deux s茅lecteurs $\\mathtt{CAR}$, pour acc茅der 脿 la premi猫re composante, et $\\mathtt{CDR}$, pour acc茅der 脿 la deuxi猫me composante\n", + "$$\\mathtt{CAR} = \\lambda c.(c\\ \\mathtt{VRAI}),$$\n", + "et\n", + "$$\\mathtt{CDR} = \\lambda c.(c\\ \\mathtt{FAUX}).$$" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "位x.位y.位s.((s x) y)\n" + ] + } + ], "source": [ - "CDR = Lambda_terme('!c.(c FAUX)').subs('FAUX', FAUX)" + "CONS = Lambda_terme('!x.!y.!s.((s x) y)')\n", + "print(CONS)" ] }, { @@ -2568,12 +2836,15 @@ "name": "stdout", "output_type": "stream", "text": [ - "位c.(c 位x.位y.y)\n" + "((位x.位y.位s.((s x) y) 位f.位x.(f x)) 位f.位x.(f (f x)))\n", + " 1: ---> (位y.位s.((s 位f.位x.(f x)) y) 位f.位x.(f (f x)))\n", + " 2: ---> 位s.((s 位f.位x.(f x)) 位f.位x.(f (f x)))\n", + "Forme normale calcul茅e : 位s.((s 位f.位x.(f x)) 位f.位x.(f (f x)))\n" ] } ], "source": [ - "print(CDR)" + "UN_DEUX = CONS.applique(UN).applique(DEUX).forme_normale(verbose=True)" ] }, { @@ -2585,13 +2856,33 @@ "name": "stdout", "output_type": "stream", "text": [ - "(位c.(c 位x.位y.y) 位s.((s 位f.位x.(f x)) 位f.位x.(f (f x))))\n", - " 1: ---> (位c.(c 位x.位y.y) 位s.((s 位f.位x.(f x)) 位f.位x.(f (f x))))\n", - " 2: ---> (位s.((s 位f.位x.(f x)) 位f.位x.(f (f x))) 位x.位y.y)\n", - " 3: ---> ((位x.位y.y 位f.位x.(f x)) 位f.位x.(f (f x)))\n", - " 4: ---> (位y.y 位f.位x.(f (f x)))\n", - " 5: ---> 位f.位x.(f (f x))\n", - "Forme normale calcul茅e : 位f.位x.(f (f x))\n" + "位c.(c VRAI)\n", + "位c.(c 位x.位y.x)\n" + ] + } + ], + "source": [ + "M_CAR = Lambda_terme('!c.(c VRAI)')\n", + "print(M_CAR)\n", + "CAR = M_CAR.subs('VRAI', VRAI)\n", + "print(CAR)" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位c.(c 位x.位y.x) 位s.((s 位f.位x.(f x)) 位f.位x.(f (f x))))\n", + " 1: ---> (位s.((s 位f.位x.(f x)) 位f.位x.(f (f x))) 位x.位y.x)\n", + " 2: ---> ((位x.位y.x 位f.位x.(f x)) 位f.位x.(f (f x)))\n", + " 3: ---> (位y.位f.位x.(f x) 位f.位x.(f (f x)))\n", + " 4: ---> 位f.位x.(f x)\n", + "Forme normale calcul茅e : 位f.位x.(f x)\n" ] }, { @@ -2600,23 +2891,13 @@ "True" ] }, - "execution_count": 82, + "execution_count": 83, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "CDR.applique(UN_DEUX).forme_normale(verbose=True) == DEUX" - ] - }, - { - "cell_type": "code", - "execution_count": 83, - "metadata": {}, - "outputs": [], - "source": [ - "M = Lambda_terme('M')\n", - "CPLE_M = CONS.applique(CAR.applique(M)).applique(CDR.applique(M))" + "CAR.applique(UN_DEUX).forme_normale(verbose=True) == UN" ] }, { @@ -2628,34 +2909,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "(位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.x) M)) (位c.(c 位x.位y.y) M)))\n", - " 1: ---> (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.x) M)) (位c.(c 位x.位y.y) M)))\n", - " 2: ---> (((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.x) M)) (位c.(c 位x.位y.y) M)) 位x.位y.y)\n", - " 3: ---> ((位y.位s.(((位c.位a.位s.((c a) s) s) (位c.(c 位x.位y.x) M)) y) (位c.(c 位x.位y.y) M)) 位x.位y.y)\n", - " 4: ---> (位s.(((位c.位a.位s.((c a) s) s) (位c.(c 位x.位y.x) M)) (位c.(c 位x.位y.y) M)) 位x.位y.y)\n", - " 5: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) (位c.(c 位x.位y.x) M)) (位c.(c 位x.位y.y) M))\n", - " 6: ---> ((位a.位s.((位x.位y.y a) s) (位c.(c 位x.位y.x) M)) (位c.(c 位x.位y.y) M))\n", - " 7: ---> (位s.((位x.位y.y (位c.(c 位x.位y.x) M)) s) (位c.(c 位x.位y.y) M))\n", - " 8: ---> ((位x.位y.y (位c.(c 位x.位y.x) M)) (位c.(c 位x.位y.y) M))\n", - " 9: ---> (位y.y (位c.(c 位x.位y.y) M))\n", - " 10: ---> (位c.(c 位x.位y.y) M)\n", - " 11: ---> (M 位x.位y.y)\n", - "Forme normale calcul茅e : (M 位x.位y.y)\n" + "位c.(c FAUX)\n", + "位c.(c 位x.位y.y)\n" ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 84, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "CDR.applique(CPLE_M).forme_normale(verbose=True)" + "M_CDR = Lambda_terme('!c.(c FAUX)')\n", + "print(M_CDR)\n", + "CDR = M_CDR.subs('FAUX', FAUX)\n", + "print(CDR)" ] }, { @@ -2667,65 +2930,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "位n.(CAR ((n 位c.((CONS (CDR c)) (SUC (CDR c)))) ((CONS ZERO) ZERO)))\n", - "位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))\n" - ] - } - ], - "source": [ - "M_PRED = Lambda_terme('!n.(CAR ((n !c.((CONS (CDR c)) (SUC (CDR c)))) ((CONS ZERO) ZERO)))')\n", - "print(M_PRED)\n", - "PRED = M_PRED.subs('CAR', CAR).subs('CONS', CONS).subs('CDR', CDR).subs('SUC', SUC).subs('ZERO', ZERO)\n", - "print(PRED)" - ] - }, - { - "cell_type": "code", - "execution_count": 86, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f (f x)))\n", - " 1: ---> (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f (f x)))\n", - " 2: ---> (位c.(c 位x.位y.x) ((位f.位x.(f (f x)) 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))\n", - " 3: ---> (((位f.位x.(f (f x)) 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.x)\n", - " 4: ---> ((位x.(位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) x)) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.x)\n", - " 5: ---> ((位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位x.位y.x)\n", - " 6: ---> (((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.x)\n", - " 7: ---> ((位y.位s.(((位c.位a.位s.((c a) s) s) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.x)\n", - " 8: ---> (位s.(((位c.位a.位s.((c a) s) s) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.x)\n", - " 9: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))\n", - " 10: ---> ((位a.位s.((位x.位y.x a) s) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))\n", - " 11: ---> (位s.((位x.位y.x (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) s) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))\n", - " 12: ---> ((位x.位y.x (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))\n", - " 13: ---> (位y.(位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))\n", - " 14: ---> (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))\n", - " 15: ---> ((位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.y)\n", - " 16: ---> (((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y)\n", - " 17: ---> ((位y.位s.(((位c.位a.位s.((c a) s) s) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y)\n", - " 18: ---> (位s.(((位c.位a.位s.((c a) s) s) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y)\n", - " 19: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))\n", - " 20: ---> ((位a.位s.((位x.位y.y a) s) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))\n", - " 21: ---> (位s.((位x.位y.y (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) s) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))\n", - " 22: ---> ((位x.位y.y (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))\n", - " 23: ---> (位y.y (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))\n", - " 24: ---> (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))\n", - " 25: ---> 位f.位x.(f (((位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)) f) x))\n", - " 26: ---> 位f.位x.(f (((((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x) 位x.位y.y) f) x))\n", - " 27: ---> 位f.位x.(f ((((位y.位s.(((位c.位a.位s.((c a) s) s) 位f.位x.x) y) 位f.位x.x) 位x.位y.y) f) x))\n", - " 28: ---> 位f.位x.(f (((位s.(((位c.位a.位s.((c a) s) s) 位f.位x.x) 位f.位x.x) 位x.位y.y) f) x))\n", - " 29: ---> 位f.位x.(f (((((位c.位a.位s.((c a) s) 位x.位y.y) 位f.位x.x) 位f.位x.x) f) x))\n", - " 30: ---> 位f.位x.(f ((((位a.位s.((位x.位y.y a) s) 位f.位x.x) 位f.位x.x) f) x))\n", - " 31: ---> 位f.位x.(f (((位s.((位x.位y.y 位f.位x.x) s) 位f.位x.x) f) x))\n", - " 32: ---> 位f.位x.(f ((((位x.位y.y 位f.位x.x) 位f.位x.x) f) x))\n", - " 33: ---> 位f.位x.(f (((位y.y 位f.位x.x) f) x))\n", - " 34: ---> 位f.位x.(f ((位f.位x.x f) x))\n", - " 35: ---> 位f.位x.(f (位x.x x))\n", - " 36: ---> 位f.位x.(f x)\n", - "Forme normale calcul茅e : 位f.位x.(f x)\n" + "(位c.(c 位x.位y.y) 位s.((s 位f.位x.(f x)) 位f.位x.(f (f x))))\n", + " 1: ---> (位s.((s 位f.位x.(f x)) 位f.位x.(f (f x))) 位x.位y.y)\n", + " 2: ---> ((位x.位y.y 位f.位x.(f x)) 位f.位x.(f (f x)))\n", + " 3: ---> (位y.y 位f.位x.(f (f x)))\n", + " 4: ---> 位f.位x.(f (f x))\n", + "Forme normale calcul茅e : 位f.位x.(f (f x))\n" ] }, { @@ -2734,13 +2944,23 @@ "True" ] }, - "execution_count": 86, + "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "PRED.applique(DEUX).forme_normale(verbose=True) == UN" + "CDR.applique(UN_DEUX).forme_normale(verbose=True) == DEUX" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": {}, + "outputs": [], + "source": [ + "M = Lambda_terme('M')\n", + "CPLE_M = CONS.applique(CAR.applique(M)).applique(CDR.applique(M))" ] }, { @@ -2752,27 +2972,21 @@ "name": "stdout", "output_type": "stream", "text": [ - "(位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.x)\n", - " 1: ---> (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.x)\n", - " 2: ---> (位c.(c 位x.位y.x) ((位f.位x.x 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))\n", - " 3: ---> (((位f.位x.x 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.x)\n", - " 4: ---> ((位x.x ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.x)\n", - " 5: ---> (((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x) 位x.位y.x)\n", - " 6: ---> ((位y.位s.(((位c.位a.位s.((c a) s) s) 位f.位x.x) y) 位f.位x.x) 位x.位y.x)\n", - " 7: ---> (位s.(((位c.位a.位s.((c a) s) s) 位f.位x.x) 位f.位x.x) 位x.位y.x)\n", - " 8: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) 位f.位x.x) 位f.位x.x)\n", - " 9: ---> ((位a.位s.((位x.位y.x a) s) 位f.位x.x) 位f.位x.x)\n", - " 10: ---> (位s.((位x.位y.x 位f.位x.x) s) 位f.位x.x)\n", - " 11: ---> ((位x.位y.x 位f.位x.x) 位f.位x.x)\n", - " 12: ---> (位y.位f.位x.x 位f.位x.x)\n", - " 13: ---> 位f.位x.x\n", - "Forme normale calcul茅e : 位f.位x.x\n" + "(位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) (位c.(c 位x.位y.x) M)) (位c.(c 位x.位y.y) M)))\n", + " 1: ---> (((位x.位y.位s.((s x) y) (位c.(c 位x.位y.x) M)) (位c.(c 位x.位y.y) M)) 位x.位y.y)\n", + " 2: ---> ((位y.位s.((s (位c.(c 位x.位y.x) M)) y) (位c.(c 位x.位y.y) M)) 位x.位y.y)\n", + " 3: ---> (位s.((s (位c.(c 位x.位y.x) M)) (位c.(c 位x.位y.y) M)) 位x.位y.y)\n", + " 4: ---> ((位x.位y.y (位c.(c 位x.位y.x) M)) (位c.(c 位x.位y.y) M))\n", + " 5: ---> (位y.y (位c.(c 位x.位y.y) M))\n", + " 6: ---> (位c.(c 位x.位y.y) M)\n", + " 7: ---> (M 位x.位y.y)\n", + "Forme normale calcul茅e : (M 位x.位y.y)\n" ] }, { "data": { "text/plain": [ - "True" + "" ] }, "execution_count": 87, @@ -2781,7 +2995,34 @@ } ], "source": [ - "PRED.applique(ZERO).forme_normale(verbose=True) == ZERO" + "CDR.applique(CPLE_M).forme_normale(verbose=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Remarques** \n", + "1. le terme $((\\mathtt{CONS}\\ M)\\ N)$ est clos si et seulement si $M$ et $N$ le sont, et il est normalisable si et seulement si $M$ et $N$ le sont.\n", + "\n", + "2. les noms donn茅s aux termes $\\mathtt{CONS}$, $\\mathtt{CAR}$ et $\\mathtt{CDR}$ font r茅f茅rence aux noms donn茅s aux constructeurs et s茅lecteurs de paires dans le langage de programmation LISP (et ses successeurs comme SCHEME)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Pr茅d茅cesseur d'un entier, soustraction" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Envisageons la fonction $F$ qui, 脿 un couple $(m, n)$ d'entiers, associe le couple $(n, n+1)$. En partant du couple $(0,0)$ et en it茅rant $n$ fois cette fonction, on obtient le couple $(n-1, n)$. La premi猫re composante de ce couple est l'entier $n-1$, donc l'entier qui pr茅c猫de $n$.\n", + "\n", + "C'est l'id茅e de base pour d茅finir un $\\lambda$-terme $\\mathtt{PRED}$ tel que pour tout entier $n\\geq 1$ on ait\n", + "$$ (\\mathtt{PRED}\\ \\lceil n\\rceil) =_\\beta \\lceil n-1\\rceil.$$" ] }, { @@ -2793,16 +3034,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "位n.位m.((m PRED) n)\n", - "位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n)\n" + "位c.((CONS (CDR c)) (SUC (CDR c)))\n", + "位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))\n" ] } ], "source": [ - "M_SUB = Lambda_terme('!n.!m.((m PRED) n)')\n", - "print(M_SUB)\n", - "SUB = M_SUB.subs('PRED', PRED)\n", - "print(SUB)" + "M_F = Lambda_terme('!c.((CONS (CDR c)) (SUC (CDR c)))')\n", + "print(M_F)\n", + "F = M_F.subs('CONS', CONS).subs('CDR', CDR).subs('SUC', SUC)\n", + "print(F)" ] }, { @@ -2810,67 +3051,6 @@ "execution_count": 89, "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) 位f.位x.(f (f (f x)))) 位f.位x.(f x))\n", - " 1: ---> ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) 位f.位x.(f (f (f x)))) 位f.位x.(f x))\n", - " 2: ---> (位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) 位f.位x.(f (f (f x)))) 位f.位x.(f x))\n", - " 3: ---> ((位f.位x.(f x) 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) 位f.位x.(f (f (f x))))\n", - " 4: ---> (位x.(位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) x) 位f.位x.(f (f (f x))))\n", - " 5: ---> (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f (f (f x))))\n", - " 6: ---> (位c.(c 位x.位y.x) ((位f.位x.(f (f (f x))) 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))\n", - " 7: ---> (((位f.位x.(f (f (f x))) 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.x)\n", - " 8: ---> ((位x.(位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) x))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.x)\n", - " 9: ---> ((位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.x)\n", - " 10: ---> (((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))) 位x.位y.x)\n", - " 11: ---> ((位y.位s.(((位c.位a.位s.((c a) s) s) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))) 位x.位y.x)\n", - " 12: ---> (位s.(((位c.位a.位s.((c a) s) s) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))) 位x.位y.x)\n", - " 13: ---> (((位c.位a.位s.((c a) s) 位x.位y.x) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))))\n", - " 14: ---> ((位a.位s.((位x.位y.x a) s) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))))\n", - " 15: ---> (位s.((位x.位y.x (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) s) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))))\n", - " 16: ---> ((位x.位y.x (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))))\n", - " 17: ---> (位y.(位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))))\n", - " 18: ---> (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))\n", - " 19: ---> ((位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位x.位y.y)\n", - " 20: ---> (((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.y)\n", - " 21: ---> ((位y.位s.(((位c.位a.位s.((c a) s) s) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.y)\n", - " 22: ---> (位s.(((位c.位a.位s.((c a) s) s) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.y)\n", - " 23: ---> (((位c.位a.位s.((c a) s) 位x.位y.y) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))\n", - " 24: ---> ((位a.位s.((位x.位y.y a) s) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))\n", - " 25: ---> (位s.((位x.位y.y (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) s) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))\n", - " 26: ---> ((位x.位y.y (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))\n", - " 27: ---> (位y.y (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))))\n", - " 28: ---> (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))))\n", - " 29: ---> 位f.位x.(f (((位c.(c 位x.位y.y) (位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) f) x))\n", - " 30: ---> 位f.位x.(f ((((位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.y) f) x))\n", - " 31: ---> 位f.位x.(f (((((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y) f) x))\n", - " 32: ---> 位f.位x.(f ((((位y.位s.(((位c.位a.位s.((c a) s) s) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y) f) x))\n", - " 33: ---> 位f.位x.(f (((位s.(((位c.位a.位s.((c a) s) s) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y) f) x))\n", - " 34: ---> 位f.位x.(f (((((位c.位a.位s.((c a) s) 位x.位y.y) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) f) x))\n", - " 35: ---> 位f.位x.(f ((((位a.位s.((位x.位y.y a) s) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) f) x))\n", - " 36: ---> 位f.位x.(f (((位s.((位x.位y.y (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) s) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) f) x))\n", - " 37: ---> 位f.位x.(f ((((位x.位y.y (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) f) x))\n", - " 38: ---> 位f.位x.(f (((位y.y (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) f) x))\n", - " 39: ---> 位f.位x.(f (((位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) f) x))\n", - " 40: ---> 位f.位x.(f ((位f.位x.(f (((位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)) f) x)) f) x))\n", - " 41: ---> 位f.位x.(f (位x.(f (((位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)) f) x)) x))\n", - " 42: ---> 位f.位x.(f (f (((位c.(c 位x.位y.y) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)) f) x)))\n", - " 43: ---> 位f.位x.(f (f (((((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x) 位x.位y.y) f) x)))\n", - " 44: ---> 位f.位x.(f (f ((((位y.位s.(((位c.位a.位s.((c a) s) s) 位f.位x.x) y) 位f.位x.x) 位x.位y.y) f) x)))\n", - " 45: ---> 位f.位x.(f (f (((位s.(((位c.位a.位s.((c a) s) s) 位f.位x.x) 位f.位x.x) 位x.位y.y) f) x)))\n", - " 46: ---> 位f.位x.(f (f (((((位c.位a.位s.((c a) s) 位x.位y.y) 位f.位x.x) 位f.位x.x) f) x)))\n", - " 47: ---> 位f.位x.(f (f ((((位a.位s.((位x.位y.y a) s) 位f.位x.x) 位f.位x.x) f) x)))\n", - " 48: ---> 位f.位x.(f (f (((位s.((位x.位y.y 位f.位x.x) s) 位f.位x.x) f) x)))\n", - " 49: ---> 位f.位x.(f (f ((((位x.位y.y 位f.位x.x) 位f.位x.x) f) x)))\n", - " 50: ---> 位f.位x.(f (f (((位y.y 位f.位x.x) f) x)))\n", - " 51: ---> 位f.位x.(f (f ((位f.位x.x f) x)))\n", - " 52: ---> 位f.位x.(f (f (位x.x x)))\n", - " 53: ---> 位f.位x.(f (f x))\n", - "Forme normale calcul茅e : 位f.位x.(f (f x))\n" - ] - }, { "data": { "text/plain": [ @@ -2883,7 +3063,16 @@ } ], "source": [ - "SUB.applique(TROIS).applique(UN).forme_normale(verbose=True) == DEUX" + "QUATRE.applique(F).applique(CONS.applique(ZERO).applique(ZERO)).forme_normale() == CONS.applique(TROIS).applique(QUATRE).forme_normale()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Le $\\lambda$-terme $\\mathtt{PRED}$ est d茅fini par\n", + "\n", + "$$ \\mathtt{PRED} = \\lambda n.(\\mathtt{CAR} ((n \\lambda c.((\\mathtt{CONS}\\ (\\mathtt{CDR}\\ c))\\ (\\mathtt{SUC} (\\mathtt{CDR}\\ c)))) ((\\mathtt{CONS}\\ \\mathtt{ZERO})\\ \\mathtt{ZERO}))).$$" ] }, { @@ -2895,14 +3084,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "位n.位m.(NUL ((SUB n) m))\n" + "位n.(CAR ((n 位c.((CONS (CDR c)) (SUC (CDR c)))) ((CONS ZERO) ZERO)))\n", + "位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))\n" ] } ], "source": [ - "M_INF = Lambda_terme('!n.!m.(NUL ((SUB n) m))')\n", - "print(M_INF)\n", - "INF = M_INF.subs('NUL', NUL).subs('SUB', SUB)" + "M_PRED = Lambda_terme('!n.(CAR ((n !c.((CONS (CDR c)) (SUC (CDR c)))) ((CONS ZERO) ZERO)))')\n", + "print(M_PRED)\n", + "PRED = M_PRED.subs('CAR', CAR).subs('CONS', CONS).subs('CDR', CDR).subs('SUC', SUC).subs('ZERO', ZERO)\n", + "print(PRED)" ] }, { @@ -2910,6 +3101,70 @@ "execution_count": 91, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f (f (f (f (f x))))))\n", + " 1: ---> (位c.(c 位x.位y.x) ((位f.位x.(f (f (f (f (f x))))) 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))\n", + " 2: ---> (((位f.位x.(f (f (f (f (f x))))) 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.x)\n", + " 3: ---> ((位x.(位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) x))))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.x)\n", + " 4: ---> ((位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) 位x.位y.x)\n", + " 5: ---> (((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))))) 位x.位y.x)\n", + " 6: ---> ((位y.位s.((s (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))))) 位x.位y.x)\n", + " 7: ---> (位s.((s (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))))) 位x.位y.x)\n", + " 8: ---> ((位x.位y.x (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))))\n", + " 9: ---> (位y.(位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))))\n", + " 10: ---> (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))\n", + " 11: ---> ((位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.y)\n", + " 12: ---> (((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))) 位x.位y.y)\n", + " 13: ---> ((位y.位s.((s (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))) 位x.位y.y)\n", + " 14: ---> (位s.((s (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))) 位x.位y.y)\n", + " 15: ---> ((位x.位y.y (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))))\n", + " 16: ---> (位y.y (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))))\n", + " 17: ---> (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))\n", + " 18: ---> 位f.位x.(f (((位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) f) x))\n", + " 19: ---> 位f.位x.(f ((((位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y) f) x))\n", + " 20: ---> 位f.位x.(f (((((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) 位x.位y.y) f) x))\n", + " 21: ---> 位f.位x.(f ((((位y.位s.((s (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) 位x.位y.y) f) x))\n", + " 22: ---> 位f.位x.(f (((位s.((s (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) 位x.位y.y) f) x))\n", + " 23: ---> 位f.位x.(f ((((位x.位y.y (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) f) x))\n", + " 24: ---> 位f.位x.(f (((位y.y (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) f) x))\n", + " 25: ---> 位f.位x.(f (((位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) f) x))\n", + " 26: ---> 位f.位x.(f ((位f.位x.(f (((位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) f) x)) f) x))\n", + " 27: ---> 位f.位x.(f (位x.(f (((位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) f) x)) x))\n", + " 28: ---> 位f.位x.(f (f (((位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) f) x)))\n", + " 29: ---> 位f.位x.(f (f ((((位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位x.位y.y) f) x)))\n", + " 30: ---> 位f.位x.(f (f (((((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.y) f) x)))\n", + " 31: ---> 位f.位x.(f (f ((((位y.位s.((s (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.y) f) x)))\n", + " 32: ---> 位f.位x.(f (f (((位s.((s (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.y) f) x)))\n", + " 33: ---> 位f.位x.(f (f ((((位x.位y.y (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) f) x)))\n", + " 34: ---> 位f.位x.(f (f (((位y.y (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) f) x)))\n", + " 35: ---> 位f.位x.(f (f (((位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) f) x)))\n", + " 36: ---> 位f.位x.(f (f ((位f.位x.(f (((位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) f) x)) f) x)))\n", + " 37: ---> 位f.位x.(f (f (位x.(f (((位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) f) x)) x)))\n", + " 38: ---> 位f.位x.(f (f (f (((位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) f) x))))\n", + " 39: ---> 位f.位x.(f (f (f ((((位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.y) f) x))))\n", + " 40: ---> 位f.位x.(f (f (f (((((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y) f) x))))\n", + " 41: ---> 位f.位x.(f (f (f ((((位y.位s.((s (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y) f) x))))\n", + " 42: ---> 位f.位x.(f (f (f (((位s.((s (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y) f) x))))\n", + " 43: ---> 位f.位x.(f (f (f ((((位x.位y.y (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) f) x))))\n", + " 44: ---> 位f.位x.(f (f (f (((位y.y (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) f) x))))\n", + " 45: ---> 位f.位x.(f (f (f (((位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) f) x))))\n", + " 46: ---> 位f.位x.(f (f (f ((位f.位x.(f (((位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) f) x)) f) x))))\n", + " 47: ---> 位f.位x.(f (f (f (位x.(f (((位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) f) x)) x))))\n", + " 48: ---> 位f.位x.(f (f (f (f (((位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) f) x)))))\n", + " 49: ---> 位f.位x.(f (f (f (f (((((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x) 位x.位y.y) f) x)))))\n", + " 50: ---> 位f.位x.(f (f (f (f ((((位y.位s.((s 位f.位x.x) y) 位f.位x.x) 位x.位y.y) f) x)))))\n", + " 51: ---> 位f.位x.(f (f (f (f (((位s.((s 位f.位x.x) 位f.位x.x) 位x.位y.y) f) x)))))\n", + " 52: ---> 位f.位x.(f (f (f (f ((((位x.位y.y 位f.位x.x) 位f.位x.x) f) x)))))\n", + " 53: ---> 位f.位x.(f (f (f (f (((位y.y 位f.位x.x) f) x)))))\n", + " 54: ---> 位f.位x.(f (f (f (f ((位f.位x.x f) x)))))\n", + " 55: ---> 位f.位x.(f (f (f (f (位x.x x)))))\n", + " 56: ---> 位f.位x.(f (f (f (f x))))\n", + "Forme normale calcul茅e : 位f.位x.(f (f (f (f x))))\n" + ] + }, { "data": { "text/plain": [ @@ -2922,7 +3177,14 @@ } ], "source": [ - "INF.applique(TROIS).applique(UN).forme_normale() == FAUX" + "PRED.applique(CINQ).forme_normale(verbose=True) == QUATRE" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Remarque** le terme $(\\mathtt{PRED}\\ \\mathtt{ZERO})$ est normalisable et sa forme normale est $\\mathtt{ZERO}$." ] }, { @@ -2930,6 +3192,23 @@ "execution_count": 92, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.x)\n", + " 1: ---> (位c.(c 位x.位y.x) ((位f.位x.x 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))\n", + " 2: ---> (((位f.位x.x 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.x)\n", + " 3: ---> ((位x.x ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.x)\n", + " 4: ---> (((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x) 位x.位y.x)\n", + " 5: ---> ((位y.位s.((s 位f.位x.x) y) 位f.位x.x) 位x.位y.x)\n", + " 6: ---> (位s.((s 位f.位x.x) 位f.位x.x) 位x.位y.x)\n", + " 7: ---> ((位x.位y.x 位f.位x.x) 位f.位x.x)\n", + " 8: ---> (位y.位f.位x.x 位f.位x.x)\n", + " 9: ---> 位f.位x.x\n", + "Forme normale calcul茅e : 位f.位x.x\n" + ] + }, { "data": { "text/plain": [ @@ -2942,7 +3221,14 @@ } ], "source": [ - "INF.applique(UN).applique(TROIS).forme_normale() == VRAI" + "PRED.applique(ZERO).forme_normale(verbose=True) == ZERO" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Une fois le pr茅desseur exprim茅, il est facile de d茅finir la soustraction comme une it茅ration du pr茅d茅cesseur." ] }, { @@ -2951,18 +3237,19 @@ "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 93, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "位n.位m.((m PRED) n)\n", + "位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) n)\n" + ] } ], "source": [ - "INF.applique(UN).applique(UN).forme_normale() == VRAI" + "M_SUB = Lambda_terme('!n.!m.((m PRED) n)')\n", + "print(M_SUB)\n", + "SUB = M_SUB.subs('PRED', PRED)\n", + "print(SUB)" ] }, { @@ -2974,16 +3261,78 @@ "name": "stdout", "output_type": "stream", "text": [ - "位n.位m.((ET ((INF n) m)) ((INF m) n))\n", - "位n.位m.((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) n) m)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) m) n))\n" + "((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) n) 位f.位x.(f (f (f x)))) 位f.位x.(f x))\n", + " 1: ---> (位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) 位f.位x.(f (f (f x)))) 位f.位x.(f x))\n", + " 2: ---> ((位f.位x.(f x) 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) 位f.位x.(f (f (f x))))\n", + " 3: ---> (位x.(位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) x) 位f.位x.(f (f (f x))))\n", + " 4: ---> (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f (f (f x))))\n", + " 5: ---> (位c.(c 位x.位y.x) ((位f.位x.(f (f (f x))) 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))\n", + " 6: ---> (((位f.位x.(f (f (f x))) 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.x)\n", + " 7: ---> ((位x.(位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) x))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.x)\n", + " 8: ---> ((位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.x)\n", + " 9: ---> (((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) 位x.位y.x)\n", + " 10: ---> ((位y.位s.((s (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) 位x.位y.x)\n", + " 11: ---> (位s.((s (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))) 位x.位y.x)\n", + " 12: ---> ((位x.位y.x (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))\n", + " 13: ---> (位y.(位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))))\n", + " 14: ---> (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))\n", + " 15: ---> ((位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位x.位y.y)\n", + " 16: ---> (((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.y)\n", + " 17: ---> ((位y.位s.((s (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.y)\n", + " 18: ---> (位s.((s (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))) 位x.位y.y)\n", + " 19: ---> ((位x.位y.y (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))\n", + " 20: ---> (位y.y (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))))\n", + " 21: ---> (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))))\n", + " 22: ---> 位f.位x.(f (((位c.(c 位x.位y.y) (位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) f) x))\n", + " 23: ---> 位f.位x.(f ((((位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) 位x.位y.y) f) x))\n", + " 24: ---> 位f.位x.(f (((((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y) f) x))\n", + " 25: ---> 位f.位x.(f ((((位y.位s.((s (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y) f) x))\n", + " 26: ---> 位f.位x.(f (((位s.((s (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) 位x.位y.y) f) x))\n", + " 27: ---> 位f.位x.(f ((((位x.位y.y (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) f) x))\n", + " 28: ---> 位f.位x.(f (((位y.y (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) f) x))\n", + " 29: ---> 位f.位x.(f (((位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) f) x))\n", + " 30: ---> 位f.位x.(f ((位f.位x.(f (((位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) f) x)) f) x))\n", + " 31: ---> 位f.位x.(f (位x.(f (((位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) f) x)) x))\n", + " 32: ---> 位f.位x.(f (f (((位c.(c 位x.位y.y) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)) f) x)))\n", + " 33: ---> 位f.位x.(f (f (((((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x) 位x.位y.y) f) x)))\n", + " 34: ---> 位f.位x.(f (f ((((位y.位s.((s 位f.位x.x) y) 位f.位x.x) 位x.位y.y) f) x)))\n", + " 35: ---> 位f.位x.(f (f (((位s.((s 位f.位x.x) 位f.位x.x) 位x.位y.y) f) x)))\n", + " 36: ---> 位f.位x.(f (f ((((位x.位y.y 位f.位x.x) 位f.位x.x) f) x)))\n", + " 37: ---> 位f.位x.(f (f (((位y.y 位f.位x.x) f) x)))\n", + " 38: ---> 位f.位x.(f (f ((位f.位x.x f) x)))\n", + " 39: ---> 位f.位x.(f (f (位x.x x)))\n", + " 40: ---> 位f.位x.(f (f x))\n", + "Forme normale calcul茅e : 位f.位x.(f (f x))\n" ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "M_EGAL = Lambda_terme('!n.!m.((ET ((INF n) m)) ((INF m) n))')\n", - "print(M_EGAL)\n", - "EGAL = M_EGAL.subs('ET', ET).subs('INF', INF)\n", - "print(EGAL)" + "SUB.applique(TROIS).applique(UN).forme_normale(verbose=True) == DEUX" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Inf茅riorit茅, 茅galit茅" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Remarque** on a l'茅quivalence \n", + "$$ n <= m \\Longleftrightarrow ((\\mathtt{SUB}\\ \\lceil n\\rceil)\\ \\lceil m\\rceil) =_\\beta \\mathtt{ZERO}.$$" ] }, { @@ -3003,7 +3352,21 @@ } ], "source": [ - "EGAL.applique(UN).applique(UN).forme_normale() == VRAI" + "SUB.applique(TROIS).applique(QUATRE).forme_normale() == ZERO" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "De l脿 vient l'id茅e de d茅finir le $\\lambda$-terme\n", + "$$\\mathtt{INF} = \\lambda n.\\lambda m.(\\mathtt{NUL}\\ ((\\mathtt{SUB}\\ n)\\ m)),$$\n", + "qui est tel que pour tout couple d'entier $(n, m)$, on a\n", + "\n", + "* si $n \\leq m$\n", + " $$ ((\\mathtt{INF}\\ \\lceil n\\rceil)\\ \\lceil m\\rceil) =_\\beta \\mathtt{VRAI},$$\n", + "* et si $n > m$\n", + " $$ ((\\mathtt{INF}\\ \\lceil n\\rceil)\\ \\lceil m\\rceil) =_\\beta \\mathtt{FAUX}.$$" ] }, { @@ -3012,25 +3375,19 @@ "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 96, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "位n.位m.(NUL ((SUB n) m))\n", + "位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) n) n) m))\n" + ] } ], "source": [ - "EGAL.applique(UN).applique(DEUX).forme_normale() == FAUX" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### It茅ration" + "M_INF = Lambda_terme('!n.!m.(NUL ((SUB n) m))')\n", + "print(M_INF)\n", + "INF = M_INF.subs('NUL', NUL).subs('SUB', SUB)\n", + "print(INF)" ] }, { @@ -3039,19 +3396,18 @@ "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "位n.(CDR ((n 位c.((CONS (SUC (CAR c))) ((MUL (SUC (CAR c))) (CDR c)))) ((CONS ZERO) UN)))\n", - "位n.(位c.(c 位x.位y.y) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.x) c))) ((位n.位m.位f.(n (m f)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.x) c))) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.(f x))))\n" - ] + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "M_FACTv1 = Lambda_terme('!n.(CDR ((n !c.((CONS (SUC (CAR c))) ((MUL (SUC (CAR c))) (CDR c)))) ((CONS ZERO) UN)))')\n", - "print(M_FACTv1)\n", - "FACTv1 = M_FACTv1.subs('CONS', CONS).subs('CAR', CAR).subs('CDR', CDR).subs('SUC', SUC).subs('MUL', MUL).subs('UN', UN).subs('ZERO', ZERO)\n", - "print(FACTv1)" + "INF.applique(TROIS).applique(UN).forme_normale() == FAUX" ] }, { @@ -3071,7 +3427,7 @@ } ], "source": [ - "FACTv1.applique(ZERO).forme_normale() == UN" + "INF.applique(UN).applique(TROIS).forme_normale() == VRAI" ] }, { @@ -3091,7 +3447,21 @@ } ], "source": [ - "FACTv1.applique(UN).forme_normale() == UN" + "INF.applique(UN).applique(UN).forme_normale() == VRAI" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Et 脿 partir de $\\mathtt{INF}$ on peut d茅finir le terme\n", + "$$ \\mathtt{EGAL} = \\lambda n.\\lambda m.((\\mathtt{ET}\\ ((\\mathtt{INF}\\ \\lceil n\\rceil)\\ \\lceil m\\rceil))\\ ((\\mathtt{INF}\\ \\lceil m\\rceil)\\ \\lceil n\\rceil)),$$\n", + "qui est tel que pour tout couple d'entier $(n, m)$, on a\n", + "\n", + "* si $n = m$\n", + " $$ ((\\mathtt{EGAL}\\ \\lceil n\\rceil)\\ \\lceil m\\rceil) =_\\beta \\mathtt{VRAI},$$\n", + "* et si $n \\neq m$\n", + " $$ ((\\mathtt{EGAL}\\ \\lceil n\\rceil)\\ \\lceil m\\rceil) =_\\beta \\mathtt{FAUX}.$$" ] }, { @@ -3103,12 +3473,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "None\n" + "位n.位m.((ET ((INF n) m)) ((INF m) n))\n", + "位n.位m.((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) n) m)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) m) n))\n" ] } ], "source": [ - "print(FACTv1.applique(DEUX).forme_normale())" + "M_EGAL = Lambda_terme('!n.!m.((ET ((INF n) m)) ((INF m) n))')\n", + "print(M_EGAL)\n", + "EGAL = M_EGAL.subs('ET', ET).subs('INF', INF)\n", + "print(EGAL)" ] }, { @@ -3128,7 +3502,7 @@ } ], "source": [ - "FACTv1.applique(DEUX).forme_normale(nb_etapes_max=118) == DEUX" + "EGAL.applique(UN).applique(UN).forme_normale() == VRAI" ] }, { @@ -3148,34 +3522,61 @@ } ], "source": [ - "FACTv1.applique(TROIS).forme_normale(nb_etapes_max=403) == SIX" - ] - }, - { - "cell_type": "code", - "execution_count": 103, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 103, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "FACTv1.applique(QUATRE).forme_normale(nb_etapes_max=1672) == MUL.applique(QUATRE).applique(SIX).forme_normale()" + "EGAL.applique(UN).applique(DEUX).forme_normale() == FAUX" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Et la r茅cursivit茅 ? " + "#### Listes de termes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Classiquement, on peut consid茅rer une liste de termes $ $ comme un couple dont la premi猫re composante est l'茅l茅ment en t锚te de la liste, et la seconde composante est la liste des 茅l茅ments qui restent :\n", + "$$ = [M_1, ].$$\n", + "Ainsi une liste de trois 茅l茅ments est un embo卯tement de trois couples :\n", + "\n", + "$$ = [M_1, [M_2, [M3, <>]]],$$\n", + "la deuxi猫me composante du couple le plus interne, $<>$ d茅signant la liste vide.\n", + "\n", + "On voit bien comment construire des listes ($\\mathtt{CONS}$), acc茅der 脿 leur t锚te ($\\mathtt{CAR}$) et 脿 leur reste ($\\mathtt{CDR}$).\n", + "\n", + "Il reste 脿 trouver une repr茅sentation de la liste vide et un terme permettant de distinguer la liste vide de celles qui ne le sont pas. \n", + "\n", + "Et le probl猫me de la vacuit茅 d'une liste va imposer de mettre une couche d'abstraction suppl茅mentaire sur notre repr茅sentation des listes." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "脡tant donn茅s $n$ $\\lambda$-termes $M_1$, $M_2$, ..., $M_n$, on peut repr茅senter la liste de ces termes par le $\\lambda$-terme\n", + "\n", + "$$ = \\lambda x.[M_1, [M_2, \\ldots[M_n, <>]\\ldots],$$\n", + "d茅finition dans laquelle $<>$ d茅signe la liste vide qui peut 锚tre repr茅sent茅e par \n", + "$$ <> = \\lambda x.\\lambda s.x\\,\\, (= \\mathtt{FAUX}).$$" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": {}, + "outputs": [], + "source": [ + "LVIDE = Lambda_terme('!x.!s.x')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Le terme $\\mathtt{LCONS}$ permettant d'ajouter un terme $t$ en t锚te d'une liste $r$ peut alors 锚tre facilement 茅crit de la mani猫re suivante en utilisant $\\mathtt{CONS}$.\n", + "\n", + "$$ \\mathtt{LCONS} = \\lambda t.\\lambda r.\\lambda x.((\\mathtt{CONS}\\ t)\\ r).$$" ] }, { @@ -3187,16 +3588,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "位f.位n.(((IF ((EGAL n) ZERO)) UN) ((MUL n) (f (PRED n))))\n", - "位f.位n.(((位c.位a.位s.((c a) s) ((位n.位m.((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) n) m)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) m) n)) n) 位f.位x.x)) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) n) (f (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) n))))\n" + "位t.位r.位x.((CONS t) r)\n", + "位t.位r.位x.((位x.位y.位s.((s x) y) t) r)\n" ] } ], "source": [ - "M_PHI_FACT = Lambda_terme('!f.!n.(((IF ((EGAL n) ZERO)) UN) ((MUL n) (f (PRED n))))')\n", - "print(M_PHI_FACT)\n", - "PHI_FACT = M_PHI_FACT.subs('IF', IF).subs('EGAL', EGAL).subs('ZERO', ZERO).subs('UN', UN).subs('MUL', MUL).subs('PRED', PRED)\n", - "print(PHI_FACT)" + "M_LCONS = Lambda_terme('!t.!r.!x.((CONS t) r)')\n", + "print(M_LCONS)\n", + "LCONS = M_LCONS.subs('CONS', CONS)\n", + "print(LCONS)" ] }, { @@ -3208,22 +3609,47 @@ "name": "stdout", "output_type": "stream", "text": [ - "位y.(位x.(x x) 位x.(x x))\n" + "位x.位s.((s M1) 位x.位s.((s M2) 位x.位s.((s M3) 位x.位s.x)))\n" ] } ], "source": [ - "BOTTOM = Lambda_terme('!y.OMEGA').subs('OMEGA', OMEGA)\n", - "print(BOTTOM)" + "M1 = Lambda_terme('M1')\n", + "M2 = Lambda_terme('M2')\n", + "M3 = Lambda_terme('M3')\n", + "L = LCONS.applique(M1).applique(LCONS.applique(M2).applique(LCONS.applique(M3).applique(LVIDE)))\n", + "print(L.forme_normale())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notons que si $L$ est une liste non vide, alors quelque soit le terme $M$, $(L\\ M)$ se r茅duit en un couple dont la seconde composante est la liste reste de $L$. En particulier, le terme $M$ a disparu." ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "位s.((s M1) 位x.位s.((s M2) 位x.位s.((s M3) 位x.位s.x)))\n" + ] + } + ], "source": [ - "FACT0 = PHI_FACT.applique(BOTTOM)" + "print(L.applique(Lambda_terme('M')).forme_normale())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Et dans le cas de la liste vide, $(\\mathtt{LVIDE}\\ M)$ se r茅duit en $\\lambda s.M$." ] }, { @@ -3232,18 +3658,31 @@ "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 107, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "位s.M\n" + ] } ], "source": [ - "FACT0.applique(ZERO).forme_normale() == UN" + "print(LVIDE.applique(Lambda_terme('M')).forme_normale())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Les deux remarques pr茅c茅dentes sont 脿 la base de la d茅finition des s茅lecteurs $\\mathtt{LCAR}$ et $\\mathtt{LCDR}$ pr茅sent茅s maintenant." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Le s茅lecteur $\\mathtt{LCAR}$ permettant d'obtenir l'茅l茅ment de t锚te d'une liste est construit en utilisant $\\mathtt{CAR}$.\n", + "\n", + "$$ \\mathtt{LCAR} = \\lambda l.(\\mathtt{CAR}\\ (l\\ \\mathtt{VRAI})).$$" ] }, { @@ -3255,42 +3694,62 @@ "name": "stdout", "output_type": "stream", "text": [ - "((位f.位n.(((位c.位a.位s.((c a) s) ((位n.位m.((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) n) m)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) m) n)) n) 位f.位x.x)) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) n) (f (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) n)))) 位y.(位x.(x x) 位x.(x x))) 位f.位x.(f x))\n", - " 1: ---> ((位f.位n.(((位c.位a.位s.((c a) s) ((位n.位m.((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) n) m)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) m) n)) n) 位f.位x.x)) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) n) (f (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) n)))) 位y.(位x.(x x) 位x.(x x))) 位f.位x.(f x))\n", - " 2: ---> (位n.(((位c.位a.位s.((c a) s) ((位n.位m.((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) n) m)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) m) n)) n) 位f.位x.x)) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) n) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) n)))) 位f.位x.(f x))\n", - " 3: ---> (((位c.位a.位s.((c a) s) ((位n.位m.((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) n) m)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) m) n)) 位f.位x.(f x)) 位f.位x.x)) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 4: ---> ((位a.位s.((((位n.位m.((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) n) m)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) m) n)) 位f.位x.(f x)) 位f.位x.x) a) s) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 5: ---> (位s.((((位n.位m.((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) n) m)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) m) n)) 位f.位x.(f x)) 位f.位x.x) 位f.位x.(f x)) s) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 6: ---> ((((位n.位m.((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) n) m)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) m) n)) 位f.位x.(f x)) 位f.位x.x) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 7: ---> (((位m.((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.(f x)) m)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) m) 位f.位x.(f x))) 位f.位x.x) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 8: ---> ((((位a.位b.(((位c.位a.位s.((c a) s) a) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.(f x)) 位f.位x.x)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 9: ---> (((位b.(((位c.位a.位s.((c a) s) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.(f x)) 位f.位x.x)) b) 位x.位y.y) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 10: ---> (((((位c.位a.位s.((c a) s) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.(f x)) 位f.位x.x)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) 位x.位y.y) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 11: ---> ((((位a.位s.((((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.(f x)) 位f.位x.x) a) s) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) 位x.位y.y) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 12: ---> (((位s.((((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.(f x)) 位f.位x.x) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) s) 位x.位y.y) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 13: ---> ((((((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.(f x)) 位f.位x.x) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) 位x.位y.y) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 14: ---> (((((位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) 位f.位x.(f x)) m)) 位f.位x.x) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) 位x.位y.y) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 15: ---> (((((位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) 位f.位x.(f x)) 位f.位x.x)) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) 位x.位y.y) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 16: ---> ((((((((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) 位f.位x.(f x)) 位f.位x.x) 位x.位x.位y.y) 位x.位y.x) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) 位x.位y.y) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 17: ---> (((((((位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) 位f.位x.(f x)) 位f.位x.x) 位x.位x.位y.y) 位x.位y.x) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) 位x.位y.y) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 18: ---> ((((((((位f.位x.x 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) 位f.位x.(f x)) 位x.位x.位y.y) 位x.位y.x) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) 位x.位y.y) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 19: ---> (((((((位x.x 位f.位x.(f x)) 位x.位x.位y.y) 位x.位y.x) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) 位x.位y.y) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - " 20: ---> ((((((位f.位x.(f x) 位x.位x.位y.y) 位x.位y.x) ((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) 位f.位x.x) 位f.位x.(f x))) 位x.位y.y) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.(((位c.位a.位s.((c a) s) s) x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", - "Pas de forme normale atteinte apr猫s 20 茅tapes de r茅duction\n" + "位l.(CAR (l VRAI))\n", + "位l.(位c.(c 位x.位y.x) (l 位x.位y.x))\n" ] } ], "source": [ - "FACT0.applique(UN).forme_normale(verbose=True, nb_etapes_max=20)" + "M_LCAR = Lambda_terme('!l.(CAR (l VRAI))')\n", + "print(M_LCAR)\n", + "L_CAR = M_LCAR.subs('CAR', CAR).subs('VRAI', VRAI)\n", + "print(L_CAR)" ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位l.(位c.(c 位x.位y.x) (l 位x.位y.x)) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))))\n", + " 1: ---> (位c.(c 位x.位y.x) (((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x))\n", + " 2: ---> ((((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x) 位x.位y.x)\n", + " 3: ---> (((位r.位x.((位x.位y.位s.((s x) y) M1) r) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x) 位x.位y.x)\n", + " 4: ---> ((位x.((位x.位y.位s.((s x) y) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x) 位x.位y.x)\n", + " 5: ---> (((位x.位y.位s.((s x) y) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x)\n", + " 6: ---> ((位y.位s.((s M1) y) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x)\n", + " 7: ---> (位s.((s M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x)\n", + " 8: ---> ((位x.位y.x M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x)))\n", + " 9: ---> (位y.M1 ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x)))\n", + " 10: ---> M1\n", + "Forme normale calcul茅e : M1\n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 109, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "FACT1 = PHI_FACT.applique(FACT0)" + "L_CAR.applique(L).forme_normale(verbose=True) == Lambda_terme('M1')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notons que \n", + "$$(\\mathtt{LCAR}\\ \\mathtt{LVIDE}) \\twoheadrightarrow_\\beta \\mathtt{LVIDE}.$$ " ] }, { @@ -3298,6 +3757,18 @@ "execution_count": 110, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位l.(位c.(c 位x.位y.x) (l 位x.位y.x)) 位x.位s.x)\n", + " 1: ---> (位c.(c 位x.位y.x) (位x.位s.x 位x.位y.x))\n", + " 2: ---> ((位x.位s.x 位x.位y.x) 位x.位y.x)\n", + " 3: ---> (位s.位x.位y.x 位x.位y.x)\n", + " 4: ---> 位x.位y.x\n", + "Forme normale calcul茅e : 位x.位y.x\n" + ] + }, { "data": { "text/plain": [ @@ -3310,7 +3781,16 @@ } ], "source": [ - "FACT1.applique(ZERO).forme_normale() == UN" + "L_CAR.applique(LVIDE).forme_normale(verbose=True) == LVIDE" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Le s茅lecteur $\\mathtt{LCDR}$ permettant d'obtenir le reste d'une liste se d茅finit 脿 l'aide de $\\mathtt{CDR}$.\n", + "\n", + "$$ CDR = \\lambda l.(\\mathtt{CDR}\\ (l\\ \\mathtt{VRAI})).$$" ] }, { @@ -3319,18 +3799,19 @@ "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 111, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "位l.(CDR (l VRAI))\n", + "位l.(位c.(c 位x.位y.y) (l 位x.位y.x))\n" + ] } ], "source": [ - "FACT1.applique(UN).forme_normale(nb_etapes_max=110) == UN" + "M_LCDR = Lambda_terme('!l.(CDR (l VRAI))')\n", + "print(M_LCDR)\n", + "LCDR = M_LCDR.subs('CDR', CDR).subs('VRAI', VRAI)\n", + "print(LCDR)" ] }, { @@ -3342,22 +3823,90 @@ "name": "stdout", "output_type": "stream", "text": [ - "位f.(位x.(f (x x)) 位x.(f (x x)))\n" + "(位l.(位c.(c 位x.位y.y) (l 位x.位y.x)) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))))\n", + " 1: ---> (位c.(c 位x.位y.y) (((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x))\n", + " 2: ---> ((((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x) 位x.位y.y)\n", + " 3: ---> (((位r.位x.((位x.位y.位s.((s x) y) M1) r) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x) 位x.位y.y)\n", + " 4: ---> ((位x.((位x.位y.位s.((s x) y) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x) 位x.位y.y)\n", + " 5: ---> (((位x.位y.位s.((s x) y) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.y)\n", + " 6: ---> ((位y.位s.((s M1) y) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.y)\n", + " 7: ---> (位s.((s M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.y)\n", + " 8: ---> ((位x.位y.y M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x)))\n", + " 9: ---> (位y.y ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x)))\n", + " 10: ---> ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))\n", + " 11: ---> (位r.位x.((位x.位y.位s.((s x) y) M2) r) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))\n", + " 12: ---> 位x.((位x.位y.位s.((s x) y) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))\n", + " 13: ---> 位x.(位y.位s.((s M2) y) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))\n", + " 14: ---> 位x.位s.((s M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))\n", + " 15: ---> 位x.位s.((s M2) (位r.位x.((位x.位y.位s.((s x) y) M3) r) 位x.位s.x))\n", + " 16: ---> 位x.位s.((s M2) 位x.((位x.位y.位s.((s x) y) M3) 位x.位s.x))\n", + " 17: ---> 位x.位s.((s M2) 位x.(位y.位s.((s M3) y) 位x.位s.x))\n", + " 18: ---> 位x.位s.((s M2) 位x.位s.((s M3) 位x.位s.x))\n", + "Forme normale calcul茅e : 位x.位s.((s M2) 位x.位s.((s M3) 位x.位s.x))\n" ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 112, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "FIX_CURRY = Lambda_terme('!f.(!x.(f (x x)) !x.(f (x x)))')\n", - "print(FIX_CURRY)" + "LCDR.applique(L).forme_normale(verbose=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notons que \n", + "$$(\\mathtt{LCDR}\\ \\mathtt{LVIDE}) \\twoheadrightarrow_\\beta \\mathtt{LVIDE}.$$ " ] }, { "cell_type": "code", "execution_count": 113, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位l.(位c.(c 位x.位y.y) (l 位x.位y.x)) 位x.位s.x)\n", + " 1: ---> (位c.(c 位x.位y.y) (位x.位s.x 位x.位y.x))\n", + " 2: ---> ((位x.位s.x 位x.位y.x) 位x.位y.y)\n", + " 3: ---> (位s.位x.位y.x 位x.位y.y)\n", + " 4: ---> 位x.位y.x\n", + "Forme normale calcul茅e : 位x.位y.x\n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 113, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "FACTv2 = FIX_CURRY.applique(PHI_FACT)" + "LCDR.applique(LVIDE).forme_normale(verbose=True) == LVIDE" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Le terme qui permet de distinguer une liste vide d'une liste qui ne l'est pas est\n", + "\n", + "$$ \\mathtt{LESTVIDE} = \\lambda l.((l\\ \\mathtt{VRAI})\\ \\lambda t.\\lambda r.\\mathtt{FAUX}).$$" ] }, { @@ -3366,18 +3915,17 @@ "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 114, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "位l.((l VRAI) 位t.位r.FAUX)\n" + ] } ], "source": [ - "FACTv2.applique(ZERO).forme_normale() == UN" + "M_LESTVIDE = Lambda_terme('!l.((l VRAI) !t.!r.FAUX)')\n", + "print(M_LESTVIDE)\n", + "LESTVIDE = M_LESTVIDE.subs('VRAI', VRAI).subs('FAUX', FAUX)" ] }, { @@ -3385,6 +3933,17 @@ "execution_count": 115, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位l.((l 位x.位y.x) 位t.位r.位x.位y.y) 位x.位s.x)\n", + " 1: ---> ((位x.位s.x 位x.位y.x) 位t.位r.位x.位y.y)\n", + " 2: ---> (位s.位x.位y.x 位t.位r.位x.位y.y)\n", + " 3: ---> 位x.位y.x\n", + "Forme normale calcul茅e : 位x.位y.x\n" + ] + }, { "data": { "text/plain": [ @@ -3397,7 +3956,7 @@ } ], "source": [ - "FACTv2.applique(UN).forme_normale(nb_etapes_max=113) == UN" + "LESTVIDE.applique(LVIDE).forme_normale(verbose=True) == VRAI" ] }, { @@ -3405,6 +3964,23 @@ "execution_count": 116, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位l.((l 位x.位y.x) 位t.位r.位x.位y.y) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))))\n", + " 1: ---> ((((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x) 位t.位r.位x.位y.y)\n", + " 2: ---> (((位r.位x.((位x.位y.位s.((s x) y) M1) r) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x) 位t.位r.位x.位y.y)\n", + " 3: ---> ((位x.((位x.位y.位s.((s x) y) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位x.位y.x) 位t.位r.位x.位y.y)\n", + " 4: ---> (((位x.位y.位s.((s x) y) M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位t.位r.位x.位y.y)\n", + " 5: ---> ((位y.位s.((s M1) y) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位t.位r.位x.位y.y)\n", + " 6: ---> (位s.((s M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x))) 位t.位r.位x.位y.y)\n", + " 7: ---> ((位t.位r.位x.位y.y M1) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x)))\n", + " 8: ---> (位r.位x.位y.y ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M2) ((位t.位r.位x.((位x.位y.位s.((s x) y) t) r) M3) 位x.位s.x)))\n", + " 9: ---> 位x.位y.y\n", + "Forme normale calcul茅e : 位x.位y.y\n" + ] + }, { "data": { "text/plain": [ @@ -3417,7 +3993,65 @@ } ], "source": [ - "FACTv2.applique(DEUX).forme_normale(nb_etapes_max=516) == DEUX" + "LESTVIDE.applique(L).forme_normale(verbose=True) == FAUX" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### It茅ration" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On l'a vu 脿 plusieurs occasions ($\\mathtt{ADD}$, $\\mathtt{MUL}$, $\\mathtt{EXP}$, $\\mathtt{NUL}$, $\\mathtt{SUB}$), les num茅raux de Church permettent d'it茅rer l'application d'un terme." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "脡tudions encore un cas d'茅cole avec la classique fonction factorielle qui peut se programmer en Python 脿 l'aide d'une boucle `for`.\n", + "\n", + "~~~python\n", + "def fact(n):\n", + " f = 1\n", + " for i in range(n+1):\n", + " f = f*i\n", + " return f\n", + "~~~" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ce programme utilise deux variables $\\mathtt{i}$ et $\\mathtt{f}$.\n", + "\n", + "Si on ajoute la valeur fictive 0 pour la variable $\\mathtt{i}$ avant la boucle `for`, le couple ($\\mathtt{i}$, $\\mathtt{f}$) prend les valeurs successives : (0, 1), (1, 1), (2, 2), (3, 6), ..., ($n$, $n!$). Ainsi 脿 chaque 茅tape de l'it茅ration le couple est transform茅 selon la r猫gle :\n", + "\n", + "$$ (i, f) \\rightarrow (i+1, f\\times i).$$\n", + "\n", + "C'est cette r猫gle qui est it茅r茅e $n$ fois. Et cette r猫gle peut 锚tre repr茅sent茅e par un $\\lambda$-terme transformant un couple $[\\lceil i\\rceil, \\lceil f\\rceil]$ en le couple $[\\lceil i+1\\rceil, \\lceil f\\times i\\rceil]$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ce qui peut 锚tre fait par \n", + "\n", + "$$ \\mathtt{FACT} = \\lambda n.(CDR\\ ((n\\ \\lambda c.[(SUC\\ (CAR\\ c)), ((MUL\\ (CAR\\ c))\\ (CDR\\ c))])\\ [ZERO, ZERO])).$$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Voici une r茅alisation de ce terme (que nous nommons $\\mathtt{FACTv1}$ puisque d'autre r茅alisations de $\\mathtt{}$ seront envisag茅es dans la suite)." ] }, { @@ -3426,18 +4060,19 @@ "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 117, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "位n.(CDR ((n 位c.((CONS (SUC (CAR c))) ((MUL (SUC (CAR c))) (CDR c)))) ((CONS ZERO) UN)))\n", + "位n.(位c.(c 位x.位y.y) ((n 位c.((位x.位y.位s.((s x) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.x) c))) ((位n.位m.位f.(n (m f)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.x) c))) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.(f x))))\n" + ] } ], "source": [ - "FACTv2.applique(TROIS).forme_normale(nb_etapes_max=2882) == SIX" + "M_FACTv1 = Lambda_terme('!n.(CDR ((n !c.((CONS (SUC (CAR c))) ((MUL (SUC (CAR c))) (CDR c)))) ((CONS ZERO) UN)))')\n", + "print(M_FACTv1)\n", + "FACTv1 = M_FACTv1.subs('CONS', CONS).subs('CAR', CAR).subs('CDR', CDR).subs('SUC', SUC).subs('MUL', MUL).subs('UN', UN).subs('ZERO', ZERO)\n", + "print(FACTv1)" ] }, { @@ -3457,16 +4092,27 @@ } ], "source": [ - "FACTv2.applique(QUATRE).forme_normale(nb_etapes_max=18668) == MUL.applique(QUATRE).applique(SIX).forme_normale()" + "FACTv1.applique(ZERO).forme_normale() == UN" ] }, { "cell_type": "code", "execution_count": 119, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 119, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "PF = FIX_CURRY.applique(Lambda_terme('M'))" + "FACTv1.applique(UN).forme_normale() == UN" ] }, { @@ -3475,26 +4121,25 @@ "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "(位f.(位x.(f (x x)) 位x.(f (x x))) M)\n", - " 1: ---> (位f.(位x.(f (x x)) 位x.(f (x x))) M)\n", - " 2: ---> (位x.(M (x x)) 位x.(M (x x)))\n", - " 3: ---> (M (位x.(M (x x)) 位x.(M (x x))))\n", - " 4: ---> (M (M (位x.(M (x x)) 位x.(M (x x)))))\n", - " 5: ---> (M (M (M (位x.(M (x x)) 位x.(M (x x))))))\n", - " 6: ---> (M (M (M (M (位x.(M (x x)) 位x.(M (x x)))))))\n", - " 7: ---> (M (M (M (M (M (位x.(M (x x)) 位x.(M (x x))))))))\n", - " 8: ---> (M (M (M (M (M (M (位x.(M (x x)) 位x.(M (x x)))))))))\n", - " 9: ---> (M (M (M (M (M (M (M (位x.(M (x x)) 位x.(M (x x))))))))))\n", - " 10: ---> (M (M (M (M (M (M (M (M (位x.(M (x x)) 位x.(M (x x)))))))))))\n", - "Pas de forme normale atteinte apr猫s 10 茅tapes de r茅duction\n" - ] + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 120, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "PF.forme_normale(verbose=True, nb_etapes_max=10)" + "FACTv1.applique(DEUX).forme_normale() == DEUX" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pour calculer $(\\mathtt{FACTv1}\\ \\mathtt{TROIS})$, il faut au moins 309 茅tapes de r茅duction." ] }, { @@ -3503,25 +4148,132 @@ "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "(位x.位y.(y ((x x) y)) 位x.位y.(y ((x x) y)))\n" - ] + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 121, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "FIX_TURING = Lambda_terme('(!x.!y.(y ((x x) y)) !x.!y.(y ((x x) y)))')\n", - "print(FIX_TURING)" + "FACTv1.applique(TROIS).forme_normale(nb_etapes_max=309) == SIX" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Et pour (饾櫟饾櫚饾櫜饾殐饾殶饾煼 QUATRE), il en faut au moins 1284." ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 122, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "FACTv3 = FIX_TURING.applique(PHI_FACT)" + "FACTv1.applique(QUATRE).forme_normale(nb_etapes_max=1284) == MUL.applique(QUATRE).applique(SIX).forme_normale()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "En suivant le principe qui a conduit 脿 茅crire le terme $\\mathtt{FACTv1}$, on comprend que n'importe quelle fonction qui peut 锚tre programm茅e (en Python, ou tout autre langage) peut 锚tre repr茅sent茅e par un $\\lambda$-terme." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Et la r茅cursivit茅 ? Et les boucles `while` ? " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Dernier point de notre exploration du pouvoir d'expression du $\\lambda$-calcul qui ach猫vera (peut-锚tre) de nous convaincre que c'est un langage de programmation : peut-on repr茅senter des fonctions r茅cursives ? peut-on repr茅senter des fonctions dont l'algorithme n茅cessite une boucle `while` ?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Exprimer la r茅cursivit茅 sans nom ?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Prenons encore la fonction factorielle comme exemple classique de fonction r茅cursive. En Python on peut l'茅crire de la fa莽on suivante\n", + "\n", + "~~~python\n", + "def fact(n):\n", + " if n == 0:\n", + " return 1\n", + " else:\n", + " return n * fact(n - 1)\n", + "~~~" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "En examinant le code de cette version r茅cursive de la fonction factorielle, on s'aper莽oit que nous disposons de tous les ingr茅dients pour 茅crire un $\\lambda$-terme analogue. Le voici :\n", + "\n", + "$$ \\mathtt{FACT} = \\lambda n.(((\\mathtt{IF}\\ (\\mathtt{NUL}\\ n))\\ \\lceil 1\\rceil)\\ ((\\mathtt{MUL}\\ n)\\ (\\mathtt{FACT}\\ (\\mathtt{PRED}\\ n)))).$$\n", + "\n", + "\n", + "Hmmm ... Trop facile ! Il y a un hic !\n", + "Ce terme n'est pas valide car dans le terme d茅sign茅 par le nom $\\mathtt{FACT}$, il y a le nom $\\mathtt{FACT}$, et en $\\lambda$-calcul les seuls noms intervenants dans les $\\lambda$-termes sont les variables. Donc le nom $\\mathtt{FACT}$ dans le $\\lambda$-terme ci-dessus est juste une variable et n'est pas le $\\lambda$-terme nomm茅 $\\mathtt{FACT}$. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "En programmation on dit souvent d'une fonction qu'elle est r茅cursive lorsqu'elle fait appel 脿 elle-m锚me, comme le fait la fonction `fact` ci-dessus. Et l'appel 脿 une fonction se fait par le nom de cette fonction.\n", + "\n", + "Comme en $\\lambda$-calcul, il n'y a pas de nom, il semble, en apparence, que la d茅finition de $\\lambda$-termes suivant un sch茅ma r茅cursif soit impossible.\n", + "\n", + "On va voir qu'il n'en est rien." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Avec une couche d'abstraction suppl茅mentaire" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Dans l'essai de $\\lambda$-terme pour d茅finir $\\mathtt{FACT}$, rempla莽ons le nom $\\mathtt{}$ par une variable, $f$ par exemple, et ajoutons une couche d'abstraction sur cette variable afin qu'elle soit li茅e. Nous obtenons un terme que nous nommerons $\\Phi_{fact}$.\n", + "\n", + "$$ \\Phi_{fact} = \\lambda f.\\lambda n.(((\\mathtt{IF}\\ (\\mathtt{NUL}\\ n))\\ \\lceil 1\\rceil)\\ ((\\mathtt{MUL}\\ n)\\ (f\\ (\\mathtt{PRED}\\ n)))).$$\n", + "\n", + "Ce $\\lambda$-terme est parfaitement valide. \n", + "\n", + "Mais, compte-tenu de la couche d'abstraction suppl茅mentaire, ce n'est certainement pas un terme candidat pour 锚tre le terme $\\mathtt{FACT}$ que nous recherchons." ] }, { @@ -3530,18 +4282,44 @@ "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 123, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "位f.位n.(((IF (NUL n)) UN) ((MUL n) (f (PRED n))))\n", + "位f.位n.(((位c.位a.位s.((c a) s) (位n.((n 位x.位x.位y.y) 位x.位y.x) n)) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) n) (f (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) n))))\n" + ] } ], "source": [ - "FACTv3.applique(ZERO).forme_normale() == UN" + "M_PHI_FACT = Lambda_terme('!f.!n.(((IF (NUL n)) UN) ((MUL n) (f (PRED n))))')\n", + "print(M_PHI_FACT)\n", + "PHI_FACT = M_PHI_FACT.subs('IF', IF).subs('NUL', NUL).subs('UN', UN).subs('MUL', MUL).subs('PRED', PRED)\n", + "print(PHI_FACT)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "En fait pour envisager d'utiliser ce terme pour calculer des factorielles, il faut d'abord l'appliquer 脿 un terme (une fonction) $f$ puis appliquer 脿 un entier (de Church). Autrement dit suivre le sch茅ma\n", + "\n", + "$$((\\Phi_{fact}\\ f)\\ \\lceil n\\rceil).$$\n", + "\n", + "Mais quel terme (ou fonction) $f$ utiliser ?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Et si on commen莽ait par une fonction (un peu bizarre) nulle part d茅finie, ou dit en termes plus $\\lambda$-calculesque, par un terme dont aucune application ne poss猫de une forme normale :\n", + "\n", + "$$ \\mathtt{BOTTOM} = \\lambda y.\\Omega,$$\n", + "o霉, pour rappel, $\\Omega = (\\lambda x.(x\\ x)\\ \\lambda x.(x\\ x))$ qui, comme on l'a vu, n'est pas normalisable. \n", + "\n", + "Il est clair que pour n'importe quel terme $M$, on a\n", + "\n", + "$$(\\mathtt{BOTTOM}\\ M) \\rightarrow_\\beta\\Omega\\rightarrow_\\beta\\Omega\\rightarrow_\\beta\\ldots.$$" ] }, { @@ -3550,18 +4328,16 @@ "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 124, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "位y.(位x.(x x) 位x.(x x))\n" + ] } ], "source": [ - "FACTv3.applique(UN).forme_normale(nb_etapes_max=114) == UN" + "BOTTOM = Lambda_terme('!y.OMEGA').subs('OMEGA', OMEGA)\n", + "print(BOTTOM)" ] }, { @@ -3570,38 +4346,42 @@ "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 125, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "(位y.(位x.(x x) 位x.(x x)) M)\n", + " 1: ---> (位x.(x x) 位x.(x x))\n", + " 2: ---> (位x.(x x) 位x.(x x))\n", + " 3: ---> (位x.(x x) 位x.(x x))\n", + "Pas de forme normale atteinte apr猫s 3 茅tapes de r茅duction\n" + ] } ], "source": [ - "FACTv3.applique(DEUX).forme_normale(nb_etapes_max=520) == DEUX" + "BOTTOM.applique(Lambda_terme('M')).forme_normale(verbose=True, nb_etapes_max=3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Appliquons notre terme $\\Phi_{fact}$ 脿 $\\mathtt{BOTTOM}$," ] }, { "cell_type": "code", "execution_count": 126, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 126, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "FACTv3.applique(TROIS).forme_normale(nb_etapes_max=2897) == SIX" + "F1 = PHI_FACT.applique(BOTTOM)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "et appliquons ensuite le terme obtenu 脿 des entiers de Church." ] }, { @@ -3621,12 +4401,1065 @@ } ], "source": [ - "FACTv3.applique(QUATRE).forme_normale(nb_etapes_max=18732) == MUL.applique(QUATRE).applique(SIX).forme_normale()" + "F1.applique(ZERO).forme_normale() == UN" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "((位f.位n.(((位c.位a.位s.((c a) s) (位n.((n 位x.位x.位y.y) 位x.位y.x) n)) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) n) (f (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) n)))) 位y.(位x.(x x) 位x.(x x))) 位f.位x.(f x))\n", + " 1: ---> (位n.(((位c.位a.位s.((c a) s) (位n.((n 位x.位x.位y.y) 位x.位y.x) n)) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) n) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) n)))) 位f.位x.(f x))\n", + " 2: ---> (((位c.位a.位s.((c a) s) (位n.((n 位x.位x.位y.y) 位x.位y.x) 位f.位x.(f x))) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", + " 3: ---> ((位a.位s.(((位n.((n 位x.位x.位y.y) 位x.位y.x) 位f.位x.(f x)) a) s) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", + " 4: ---> (位s.(((位n.((n 位x.位x.位y.y) 位x.位y.x) 位f.位x.(f x)) 位f.位x.(f x)) s) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", + " 5: ---> (((位n.((n 位x.位x.位y.y) 位x.位y.x) 位f.位x.(f x)) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", + " 6: ---> ((((位f.位x.(f x) 位x.位x.位y.y) 位x.位y.x) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", + " 7: ---> (((位x.(位x.位x.位y.y x) 位x.位y.x) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", + " 8: ---> (((位x.位x.位y.y 位x.位y.x) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", + " 9: ---> ((位x.位y.y 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", + " 10: ---> (位y.y ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x)))))\n", + " 11: ---> ((位n.位m.位f.(n (m f)) 位f.位x.(f x)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x))))\n", + " 12: ---> (位m.位f.(位f.位x.(f x) (m f)) (位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x))))\n", + " 13: ---> 位f.(位f.位x.(f x) ((位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x))) f))\n", + " 14: ---> 位f.位x.(((位y.(位x.(x x) 位x.(x x)) (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) 位f.位x.(f x))) f) x)\n", + " 15: ---> 位f.位x.(((位x.(x x) 位x.(x x)) f) x)\n", + " 16: ---> 位f.位x.(((位x.(x x) 位x.(x x)) f) x)\n", + " 17: ---> 位f.位x.(((位x.(x x) 位x.(x x)) f) x)\n", + " 18: ---> 位f.位x.(((位x.(x x) 位x.(x x)) f) x)\n", + " 19: ---> 位f.位x.(((位x.(x x) 位x.(x x)) f) x)\n", + " 20: ---> 位f.位x.(((位x.(x x) 位x.(x x)) f) x)\n", + "Pas de forme normale atteinte apr猫s 20 茅tapes de r茅duction\n" + ] + } + ], + "source": [ + "F1.applique(UN).forme_normale(verbose=True, nb_etapes_max=20) " ] }, { "cell_type": "markdown", "metadata": {}, + "source": [ + "Le terme $F_1$ appliqu茅 脿 $\\lceil 0\\rceil$ donne $\\lceil 1\\rceil$. Mais, l'application 脿 tout autre entier de Church n'est pas normalisable.\n", + "\n", + "Autrement dit la fonction repr茅sent茅e par $F_1$ calcule bien $0! = 1$, ... et c'est tout. C'est tout de m锚me mieux que $\\mathtt{BOTTOM}$ !\n", + "\n", + "Continuons et d茅finissons $F_2 = (\\Phi_{fact}\\ F_1)$." + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "metadata": {}, + "outputs": [], + "source": [ + "F2 = PHI_FACT.applique(F1)" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 130, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "F2.applique(ZERO).forme_normale() == UN" + ] + }, + { + "cell_type": "code", + "execution_count": 131, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 131, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "F2.applique(UN).forme_normale() == UN" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "metadata": {}, + "outputs": [], + "source": [ + "F2.applique(DEUX).forme_normale()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Le terme $F_2$ appliqu茅 脿 $\\lceil n\\rceil$, avec $n=0\\mbox{ ou }1$ donne bien $\\lceil n!\\rceil$. Mais pour tout autre entier l'application n'est pas normalisable. On progresse.\n", + "\n", + "En fait si on d茅finit la suite de termes $F_n$ par r茅currence en posant\n", + "\n", + "\\begin{align}\n", + " F_0 &= \\mathtt{BOTTOM}\\\\\n", + " F_1 &= (\\Phi_{fact}\\ F_0)\\\\\n", + " F_2 &= (\\Phi_{fact}\\ F_1)\\\\\n", + " \\vdots\\\\\n", + " F_{n+1} &= (\\Phi_{fact}\\ F_n)\n", + "\\end{align}\n", + "chacun des termes de cette suite est en mesure de repr茅senter une fonction factorielle partielle. Plus pr茅cis茅ment, pour chaque entier $n$ on a\n", + "\n", + "$$ (F_n\\ \\lceil k\\rceil) \\twoheadrightarrow_\\beta \\lceil k!\\rceil \\mbox{ si } 0\\leq k < n,$$\n", + "et $(F_n\\ \\lceil k\\rceil)$ n'est pas normalisable si $k\\geq n$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "V茅rifions cela sur le terme $F_4$." + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "metadata": {}, + "outputs": [], + "source": [ + "F4 = QUATRE.applique(PHI_FACT).applique(BOTTOM)" + ] + }, + { + "cell_type": "code", + "execution_count": 134, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 134, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "F4.applique(ZERO).forme_normale() == UN" + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 135, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "F4.applique(UN).forme_normale() == UN" + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 136, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "F4.applique(DEUX).forme_normale(nb_etapes_max=244) == DEUX" + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 137, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "F4.applique(TROIS).forme_normale(nb_etapes_max=1510) == SIX" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Avec le terme $\\Phi_{fact}$, nous sommes en mesure de d茅finir des fonctions 芦 approximant 禄 de mieux en mieux la fonction factorielle, mais le proc茅d茅 it茅ratif d茅crit ne permet pas d'obtenir le terme $\\mathtt{FACT}$ voulu.\n", + "\n", + "Remarquons n茅anmoins que si nous avons ce terme $\\mathtt{FACT}$, alors on a\n", + "\n", + "$$ (\\Phi_{fact}\\ \\mathtt{FACT}) \\rightarrow_\\beta\n", + " \\lambda n.(((\\mathtt{IF}\\ (\\mathtt{NUL}\\ n))\\ \\lceil 1\\rceil)\\ ((\\mathtt{MUL}\\ n)\\ (\\mathtt{FACT}\\ (\\mathtt{PRED}\\ n)))),$$\n", + "qui est un terme correspondant exactement 脿 ce que nous recherchons depuis le d茅but. De cette r茅duction, on peut d茅duire que\n", + "$$ (\\Phi_{fact}\\ \\mathtt{FACT}) =_\\beta \\mathtt{FACT},$$\n", + "et cette 茅quivalence montre que le terme $\\mathtt{FACT}$ que l'on recherche est un point fixe du terme $\\Phi_{fact}$. Or on a vu comment construire un terme point fixe d'un autre. \n", + "\n", + "$$\\mathtt{FACT} = (\\lambda x.(\\Phi_{fact}\\ (x\\ x))\\ \\lambda x.(\\Phi_{fact}\\ (x\\ x))).$$\n", + "Ce terme est un $\\lambda$-terme valide qui v茅rifie pour tout entier $n\\geq 0$\n", + "$$(\\mathtt{FACT}\\ \\lceil n\\rceil) =_\\beta \\lceil n!\\rceil.$$" + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位x.(位f.位n.(((位c.位a.位s.((c a) s) (位n.((n 位x.位x.位y.y) 位x.位y.x) n)) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) n) (f (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) n)))) (x x)) 位x.(位f.位n.(((位c.位a.位s.((c a) s) (位n.((n 位x.位x.位y.y) 位x.位y.x) n)) 位f.位x.(f x)) ((位n.位m.位f.(n (m f)) n) (f (位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x))) n)))) (x x)))\n" + ] + } + ], + "source": [ + "W = Lambda_terme('!x.(PHIFACT (x x))').subs('PHIFACT', PHI_FACT)\n", + "FACTv2 = Lambda_terme('(W W)').subs('W', W)\n", + "print(FACTv2)" + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 139, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv2.applique(ZERO).forme_normale() == UN" + ] + }, + { + "cell_type": "code", + "execution_count": 140, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 140, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv2.applique(UN).forme_normale() == UN" + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 141, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv2.applique(DEUX).forme_normale(nb_etapes_max=247) == DEUX" + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 142, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv2.applique(TROIS).forme_normale(nb_etapes_max=1524) == SIX" + ] + }, + { + "cell_type": "code", + "execution_count": 143, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 143, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv2.applique(QUATRE).forme_normale(nb_etapes_max=10383) == int_en_church(24)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Combinateur de point fixe" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Le combinateur de point fixe de Curry est d茅fini par\n", + "\n", + "$$ Y = \\lambda f.(\\lambda x.(f\\ (x\\ x))\\ \\lambda x.(f\\ (x\\ x))).$$\n", + "\n", + "Il permet de construire un terme point fixe de n'importe quel terme $\\Phi$, ce terme se d茅finissant par $F = (Y\\ \\Phi).$. En effet,\n", + "\n", + "$$ F = (Y\\ \\Phi) \\rightarrow_\\beta (\\lambda x.(\\Phi\\ (x\\ x))\\ \\lambda x.(\\Phi\\ (x\\ x)) \\rightarrow_\\beta\n", + " (\\Phi\\ (\\lambda x.(\\Phi\\ (x\\ x)\\ \\lambda x.(\\Phi\\ (x\\ x))),$$\n", + "et\n", + "$$ (\\Phi\\ F) = (\\Phi\\ (Y\\ \\Phi)) \\rightarrow_\\beta\n", + " (\\Phi\\ (\\lambda x.(\\Phi\\ (x\\ x)\\ \\lambda x.(\\Phi\\ (x\\ x))),$$\n", + "ce qui permet de conclure que\n", + "$$ F =_\\beta (\\Phi\\ F).$$" + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "位f.(位x.(f (x x)) 位x.(f (x x)))\n" + ] + } + ], + "source": [ + "Y = Lambda_terme('!f.(!x.(f (x x)) !x.(f (x x)))')\n", + "print(Y)" + ] + }, + { + "cell_type": "code", + "execution_count": 145, + "metadata": {}, + "outputs": [], + "source": [ + "FACTv3 = Y.applique(PHI_FACT)" + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 146, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv3.applique(ZERO).forme_normale() == UN" + ] + }, + { + "cell_type": "code", + "execution_count": 147, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 147, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv3.applique(UN).forme_normale() == UN" + ] + }, + { + "cell_type": "code", + "execution_count": 148, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 148, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv3.applique(DEUX).forme_normale(nb_etapes_max=248) == DEUX" + ] + }, + { + "cell_type": "code", + "execution_count": 149, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 149, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv3.applique(TROIS).forme_normale(nb_etapes_max=1525) == SIX" + ] + }, + { + "cell_type": "code", + "execution_count": 150, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 150, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv3.applique(QUATRE).forme_normale(nb_etapes_max=10384) == int_en_church(24)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Remarque** $Y$ n'est pas normalisable, et quelque soit le $\\lambda$-terme $M$, $(Y\\ M)$ ne l'est pas. Pourtant ces derniers termes peuvent s'av茅rer utiles. " + ] + }, + { + "cell_type": "code", + "execution_count": 151, + "metadata": {}, + "outputs": [], + "source": [ + "PF = Y.applique(Lambda_terme('M'))" + ] + }, + { + "cell_type": "code", + "execution_count": 152, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位f.(位x.(f (x x)) 位x.(f (x x))) M)\n", + " 1: ---> (位x.(M (x x)) 位x.(M (x x)))\n", + " 2: ---> (M (位x.(M (x x)) 位x.(M (x x))))\n", + " 3: ---> (M (M (位x.(M (x x)) 位x.(M (x x)))))\n", + " 4: ---> (M (M (M (位x.(M (x x)) 位x.(M (x x))))))\n", + " 5: ---> (M (M (M (M (位x.(M (x x)) 位x.(M (x x)))))))\n", + " 6: ---> (M (M (M (M (M (位x.(M (x x)) 位x.(M (x x))))))))\n", + " 7: ---> (M (M (M (M (M (M (位x.(M (x x)) 位x.(M (x x)))))))))\n", + " 8: ---> (M (M (M (M (M (M (M (位x.(M (x x)) 位x.(M (x x))))))))))\n", + " 9: ---> (M (M (M (M (M (M (M (M (位x.(M (x x)) 位x.(M (x x)))))))))))\n", + " 10: ---> (M (M (M (M (M (M (M (M (M (位x.(M (x x)) 位x.(M (x x))))))))))))\n", + "Pas de forme normale atteinte apr猫s 10 茅tapes de r茅duction\n" + ] + } + ], + "source": [ + "PF.forme_normale(verbose=True, nb_etapes_max=10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Un autre combinateur de point fixe" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Voici un autre combinateur de point fixe, d没 脿 Turing.\n", + "\n", + "$$\\Theta = (\\lambda x.\\lambda y.(y\\ ((x\\ x)\\ y))\\ \\lambda x.\\lambda y.(y\\ ((x\\ x)\\ y))).$$" + ] + }, + { + "cell_type": "code", + "execution_count": 153, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(位x.位y.(y ((x x) y)) 位x.位y.(y ((x x) y)))\n" + ] + } + ], + "source": [ + "THETA = Lambda_terme('(!x.!y.(y ((x x) y)) !x.!y.(y ((x x) y)))')\n", + "print(THETA)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ce combinateur est un redex, et c'est le seul redex parmi ses sous-termes.une 茅tape de r茅duction donne\n", + "\n", + "$$ \\Theta \\rightarrow_\\beta \\lambda y.(y\\ (\\Theta\\ y)).$$\n", + "\n", + "Par cons茅quent, en r茅duisant le redex le plus 脿 gauche, en deux 茅tapes on obtient\n", + "$$ (\\Theta\\ \\Phi) \\rightarrow_\\beta (\\lambda y.(y\\ (\\Theta\\ y))\\ \\Phi) \\rightarrow_\\beta\n", + " (\\Phi\\ (\\Theta\\ \\Phi)).$$\n", + "Ce qui 茅tablit que $\\Theta$ est bien un combinateur de point fixe, mais aussi que contrairement 脿 $Y$\n", + "$$ (\\Theta\\ \\Phi) \\twoheadrightarrow_\\beta (\\Phi\\ (\\Theta\\ \\Phi)).$$" + ] + }, + { + "cell_type": "code", + "execution_count": 154, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "位y.(y ((位x.位y.(y ((x x) y)) 位x.位y.(y ((x x) y))) y))\n" + ] + } + ], + "source": [ + "red_theta, _ = THETA.reduit()\n", + "print(red_theta)" + ] + }, + { + "cell_type": "code", + "execution_count": 155, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "((位x.位y.(y ((x x) y)) 位x.位y.(y ((x x) y))) PHI)\n", + " 1: ---> (位y.(y ((位x.位y.(y ((x x) y)) 位x.位y.(y ((x x) y))) y)) PHI)\n", + " 2: ---> (PHI ((位x.位y.(y ((x x) y)) 位x.位y.(y ((x x) y))) PHI))\n", + "Pas de forme normale atteinte apr猫s 2 茅tapes de r茅duction\n" + ] + } + ], + "source": [ + "THETA.applique(Lambda_terme('PHI')).forme_normale(verbose=True, nb_etapes_max=2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Utilisons $\\Theta$ pour d茅finir une quatri猫me version de $\\mathtt{FACT}$. " + ] + }, + { + "cell_type": "code", + "execution_count": 156, + "metadata": {}, + "outputs": [], + "source": [ + "FACTv4 = THETA.applique(PHI_FACT)" + ] + }, + { + "cell_type": "code", + "execution_count": 157, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 157, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv4.applique(ZERO).forme_normale() == UN" + ] + }, + { + "cell_type": "code", + "execution_count": 158, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 158, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv4.applique(UN).forme_normale() == UN" + ] + }, + { + "cell_type": "code", + "execution_count": 159, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 159, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv4.applique(DEUX).forme_normale(nb_etapes_max=252) == DEUX" + ] + }, + { + "cell_type": "code", + "execution_count": 160, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 160, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv4.applique(TROIS).forme_normale(nb_etapes_max=1540) == SIX" + ] + }, + { + "cell_type": "code", + "execution_count": 161, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 161, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FACTv4.applique(QUATRE).forme_normale(nb_etapes_max=10448) == int_en_church(24)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Au titre d'un autre exemple, envisageons maintenant d'茅tablir un $\\lambda$-terme qui permet de calculer la longueur d'une liste.\n", + "\n", + "La longueur d'une liste s'exprime r茅cursivement par\n", + "\n", + "\\begin{align}\n", + " \\mbox{long(<>)} &= 0\\\\\n", + " \\mbox{long()} &= 1 + \\mbox{long(L)}.\n", + "\\end{align}\n", + "\n", + "Avec une couche d'abstraction suppl茅mentaire nous d茅finissons le terme\n", + "\n", + "$$\\Phi_{long} = \\lambda f.\\lambda l.(((\\mathtt{IF}\\ (\\mathtt{LESTVIDE}\\ l))\\ \\mathtt{ZERO})\\ (\\mathtt{SUC}\\ (f\\ (\\mathtt{LCDR}\\ l)))).$$" + ] + }, + { + "cell_type": "code", + "execution_count": 162, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "位f.位l.(((IF (LESTVIDE l)) ZERO) (SUC (f (LCDR l))))\n" + ] + } + ], + "source": [ + "M_PHI_LONG = Lambda_terme('!f.!l.(((IF (LESTVIDE l)) ZERO)(SUC (f (LCDR l))))')\n", + "print(M_PHI_LONG)\n", + "PHI_LONG = M_PHI_LONG.subs('IF', IF).subs('LESTVIDE', LESTVIDE).subs('ZERO', ZERO).subs('SUC', SUC).subs('LCDR', LCDR)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "D茅finissions le terme $\\mathtt{LONG}$ 脿 l'aide de l'un ou l'autre de nos deux combinateurs de point fixe.\n", + "\n", + "$$ \\mathtt{LONG} = (\\Theta\\ \\Phi_{long}).$$" + ] + }, + { + "cell_type": "code", + "execution_count": 163, + "metadata": {}, + "outputs": [], + "source": [ + "LONG = THETA.applique(PHI_LONG)" + ] + }, + { + "cell_type": "code", + "execution_count": 164, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 164, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "LONG.applique(LVIDE).forme_normale() == ZERO" + ] + }, + { + "cell_type": "code", + "execution_count": 165, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 165, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "M1 = Lambda_terme('M1')\n", + "M2 = Lambda_terme('M2')\n", + "M3 = Lambda_terme('M3')\n", + "L = LCONS.applique(M1).applique(LCONS.applique(M2).applique(LCONS.applique(M3).applique(LVIDE)))\n", + "LONG.applique(L).forme_normale(nb_etapes_max=135) == TROIS" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Et la boucle `while` ?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Bien ! on voit comment construire un $\\lambda$-terme exprimant un algorithme r茅cursif. Mais comment exprimer une it茅ration conditionnelle (boucle `while`) ? " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "La r茅ponse tient simplement dans le fait qu'une it茅ration conditionnelle s'exprime g茅n茅ralement en suivant le sch茅ma\n", + "\n", + "~~~python\n", + "while p(e):\n", + " e = t(e)\n", + "~~~\n", + "dans lequel \n", + "\n", + "* `e` d茅signe l'茅tat courant des variables, \n", + "* `p(e)` exprime une condition d茅pendant de l'茅tat courant \n", + "* et `t(e)` est un traitement pouvant modifier l'茅tat courant.\n", + "\n", + "Ce sch茅ma peut 锚tre reformul茅 de mani猫re r茅cursive en 茅crivant\n", + "\n", + "~~~python\n", + "def tq(e):\n", + " if p(e):\n", + " e = t(e)\n", + " return tq(e)\n", + " else:\n", + " return e\n", + "~~~" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Il suffit donc de consid茅rer le $\\lambda$-terme\n", + "\n", + "$$\\Phi_{while} = \\lambda f.\\lambda p.\\lambda t.\\lambda e.(((\\mathtt{IF}\\ (p\\ e))\\ (((f\\ p)\\ t)\\ (t\\ e))\\ e),$$\n", + "\n", + "puis de d茅finir le terme\n", + "\n", + "$$ \\mathtt{WHILE} = (Y\\ \\Phi_{while}),$$\n", + "ou \n", + "$$ \\mathtt{WHILE} = (\\Theta\\ \\Phi_{while}).$$" + ] + }, + { + "cell_type": "code", + "execution_count": 166, + "metadata": {}, + "outputs": [], + "source": [ + "M_PHI_WHILE = Lambda_terme('!f.!p.!t.!e.(((IF (p e)) (((f p) t) (t e))) e)')\n", + "PHI_WHILE = M_PHI_WHILE.subs('IF', IF)\n", + "WHILE = Y.applique(PHI_WHILE)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pour terminer, utilisons notre terme $\\mathtt{WHILE}$ pour construire une terme permettant de calculer la division euclidienne de deux entiers, derni猫re op茅ration arithm茅tique de base que nous n'avons pas r茅alis茅e." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On veut un terme $\\mathtt{DIV}$ qui comme la fonction `divmod` de Python donne, sous forme d'un couple, le quotient et le reste de la division d'un entier $m$ par un entier $n$.\n", + "\n", + "On pourrait programmer cette fonction en Python de cette fa莽on :\n", + "\n", + "~~~python\n", + "def divmod(m, n):\n", + " q, r = 0, m\n", + " while r >= n:\n", + " q, r = q + 1, r - n\n", + " return (q, r)\n", + "~~~\n", + "Dans cet algorithme \n", + "* l'茅tat `e` est le triplet de variables `(q, r, n)`\n", + "* la condition `p(e)` est exprim茅e par l'in茅galit茅 `r >= n`\n", + "* et le traitement `t(e)` modifiant l'茅tat courant est le construction du couple `(q + 1, r - n, n)`.\n", + "\n", + "\\begin{align}\n", + " P &= \\lambda e.((\\mathtt{INF}\\ (\\mathtt{CDR}\\ (\\mathtt{CDR}\\ e))) (\\mathtt{CAR}\\ (\\mathtt{CDR}\\ e)))\\\\\n", + " T &= \\lambda e.((\\mathtt{CONS}\\ (\\mathtt{SUC}\\ (\\mathtt{CAR}\\ e))) ((\\mathtt{CONS}\\ ((\\mathtt{SUB}\\ (\\mathtt{CAR}\\ (\\mathtt{CDR}\\ e))) (\\mathtt{CDR}\\ (\\mathtt{CDR}\\ e)))) (\\mathtt{CDR}\\ (\\mathtt{CDR}\\ e))))\\\\\n", + " \\mathtt{DIVMOD} &= \\lambda m.\\lambda n.((((\\mathtt{WHILE}\\ P))\\ T)\\ [\\lceil 0\\rceil, [m, n]]).\n", + "\\end{align}" + ] + }, + { + "cell_type": "code", + "execution_count": 167, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "位e.((INF (CDR (CDR e))) (CAR (CDR e)))\n", + "位e.((CONS (SUC (CAR e))) ((CONS ((SUB (CAR (CDR e))) (CDR (CDR e)))) (CDR (CDR e))))\n", + "位m.位n.(((WHILE P) T) ((CONS ZERO) ((CONS m) n)))\n", + "位m.位n.((((位f.(位x.(f (x x)) 位x.(f (x x))) 位f.位p.位t.位e.(((位c.位a.位s.((c a) s) (p e)) (((f p) t) (t e))) e)) 位e.((位n.位m.(位n.((n 位x.位x.位y.y) 位x.位y.x) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) n) n) m)) (位c.(c 位x.位y.y) (位c.(c 位x.位y.y) e))) (位c.(c 位x.位y.x) (位c.(c 位x.位y.y) e)))) 位e.((位x.位y.位s.((s x) y) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.x) e))) ((位x.位y.位s.((s x) y) ((位n.位m.((m 位n.(位c.(c 位x.位y.x) ((n 位c.((位x.位y.位s.((s x) y) (位c.(c 位x.位y.y) c)) (位n.位f.位x.(f ((n f) x)) (位c.(c 位x.位y.y) c)))) ((位x.位y.位s.((s x) y) 位f.位x.x) 位f.位x.x)))) n) (位c.(c 位x.位y.x) (位c.(c 位x.位y.y) e))) (位c.(c 位x.位y.y) (位c.(c 位x.位y.y) e)))) (位c.(c 位x.位y.y) (位c.(c 位x.位y.y) e))))) ((位x.位y.位s.((s x) y) 位f.位x.x) ((位x.位y.位s.((s x) y) m) n)))\n" + ] + } + ], + "source": [ + "M_P = Lambda_terme('!e.((INF (CDR (CDR e))) (CAR (CDR e)))')\n", + "print(M_P)\n", + "P = M_P.subs('INF', INF).subs('CAR', CAR).subs('CDR', CDR)\n", + "M_T = Lambda_terme('!e.((CONS (SUC (CAR e))) ((CONS ((SUB (CAR (CDR e))) (CDR (CDR e)))) (CDR (CDR e))))')\n", + "print(M_T)\n", + "T = M_T.subs('CONS', CONS).subs('CAR', CAR).subs('CDR', CDR).subs('SUC', SUC).subs('SUB', SUB)\n", + "M_DIVMOD = Lambda_terme('!m.!n.(((WHILE P) T) ((CONS ZERO) ((CONS m) n)))')\n", + "print(M_DIVMOD)\n", + "DIVMOD = M_DIVMOD.subs('WHILE', WHILE).subs('P', P).subs('T', T).subs('CONS', CONS).subs('ZERO', ZERO)\n", + "print(DIVMOD)" + ] + }, + { + "cell_type": "code", + "execution_count": 168, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 17.1 s, sys: 7.09 ms, total: 17.1 s\n", + "Wall time: 17.1 s\n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 168, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "tests = []\n", + "for a in range(10):\n", + " for b in range(1, 10):\n", + " q, r = divmod(a, b)\n", + " A, B = int_en_church(a), int_en_church(b)\n", + " Q, R = int_en_church(q), int_en_church(r)\n", + " res = DIVMOD.applique(A).applique(B).forme_normale(nb_etapes_max=10000)\n", + " #print(res)\n", + " tests.append((a, b, res == CONS.applique(Q).applique(CONS.applique(R).applique(B)).forme_normale()))\n", + "all(t[2] for t in tests)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Conclusion" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Nous arr锚tons l脿 ce premier contact avec le $\\lambda$-calcul.\n", + "\n", + "Nous avons vu que ce langage tr猫s 茅l茅mentaire, avec l'abstraction et l'application pour seules constructions, et la r猫gle de $\\beta$-r茅duction pour seule transformation de $\\lambda$-termes, permet de repr茅senter les donn茅es de base de n'importe quel langage de programmation, les bool茅ens, les entiers, les couples, les listes, et permet d'exprimer les expressions conditionnelles, les it茅rations conditionnelles ou non, et la r茅cursivit茅. En fait le $\\lambda$-calcul est un langage Turing-complet ... m锚me s'il est particuli猫rement inefficace.\n", + "\n", + "D'autres sujets relatifs au $\\lambda$-calcul n'ont pas 茅t茅 abord茅s :\n", + "\n", + "* strat茅gies de r茅duction : paresseuse, par valeurs ..., et leurs cons茅quences.\n", + "* $\\lambda$-calcul typ茅." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "incorrectly_encoded_metadata": "toc-hr-collapsed=true toc-nb-collapsed=true" + }, "source": [ "# $\\lambda$-calcul avec les lambda-expressions de Python" ] @@ -3642,14 +5475,16 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "incorrectly_encoded_metadata": "toc-hr-collapsed=true toc-nb-collapsed=true" + }, "source": [ "## Les bool茅ens" ] }, { "cell_type": "code", - "execution_count": 128, + "execution_count": 169, "metadata": {}, "outputs": [], "source": [ @@ -3659,7 +5494,7 @@ }, { "cell_type": "code", - "execution_count": 129, + "execution_count": 170, "metadata": {}, "outputs": [], "source": [ @@ -3669,7 +5504,7 @@ }, { "cell_type": "code", - "execution_count": 130, + "execution_count": 171, "metadata": {}, "outputs": [ { @@ -3678,7 +5513,7 @@ "(True, False)" ] }, - "execution_count": 130, + "execution_count": 171, "metadata": {}, "output_type": "execute_result" } @@ -3689,7 +5524,7 @@ }, { "cell_type": "code", - "execution_count": 131, + "execution_count": 172, "metadata": {}, "outputs": [], "source": [ @@ -3698,7 +5533,7 @@ }, { "cell_type": "code", - "execution_count": 132, + "execution_count": 173, "metadata": {}, "outputs": [ { @@ -3707,7 +5542,7 @@ "1" ] }, - "execution_count": 132, + "execution_count": 173, "metadata": {}, "output_type": "execute_result" } @@ -3718,7 +5553,7 @@ }, { "cell_type": "code", - "execution_count": 133, + "execution_count": 174, "metadata": {}, "outputs": [ { @@ -3727,7 +5562,7 @@ "2" ] }, - "execution_count": 133, + "execution_count": 174, "metadata": {}, "output_type": "execute_result" } @@ -3738,7 +5573,7 @@ }, { "cell_type": "code", - "execution_count": 134, + "execution_count": 175, "metadata": {}, "outputs": [], "source": [ @@ -3747,7 +5582,7 @@ }, { "cell_type": "code", - "execution_count": 135, + "execution_count": 176, "metadata": {}, "outputs": [], "source": [ @@ -3756,7 +5591,7 @@ }, { "cell_type": "code", - "execution_count": 136, + "execution_count": 177, "metadata": {}, "outputs": [ { @@ -3765,7 +5600,7 @@ "(False, True)" ] }, - "execution_count": 136, + "execution_count": 177, "metadata": {}, "output_type": "execute_result" } @@ -3776,7 +5611,7 @@ }, { "cell_type": "code", - "execution_count": 137, + "execution_count": 178, "metadata": {}, "outputs": [], "source": [ @@ -3785,7 +5620,7 @@ }, { "cell_type": "code", - "execution_count": 138, + "execution_count": 179, "metadata": {}, "outputs": [ { @@ -3794,7 +5629,7 @@ "(True, False, False, False)" ] }, - "execution_count": 138, + "execution_count": 179, "metadata": {}, "output_type": "execute_result" } @@ -3806,7 +5641,7 @@ }, { "cell_type": "code", - "execution_count": 139, + "execution_count": 180, "metadata": {}, "outputs": [], "source": [ @@ -3815,7 +5650,7 @@ }, { "cell_type": "code", - "execution_count": 140, + "execution_count": 181, "metadata": {}, "outputs": [ { @@ -3824,7 +5659,7 @@ "(True, True, True, False)" ] }, - "execution_count": 140, + "execution_count": 181, "metadata": {}, "output_type": "execute_result" } @@ -3836,14 +5671,16 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "incorrectly_encoded_metadata": "toc-hr-collapsed=true toc-nb-collapsed=true" + }, "source": [ "## Les entiers de Church" ] }, { "cell_type": "code", - "execution_count": 141, + "execution_count": 182, "metadata": {}, "outputs": [], "source": [ @@ -3852,7 +5689,7 @@ }, { "cell_type": "code", - "execution_count": 142, + "execution_count": 183, "metadata": {}, "outputs": [], "source": [ @@ -3861,7 +5698,7 @@ }, { "cell_type": "code", - "execution_count": 143, + "execution_count": 184, "metadata": {}, "outputs": [], "source": [ @@ -3870,7 +5707,7 @@ }, { "cell_type": "code", - "execution_count": 144, + "execution_count": 185, "metadata": {}, "outputs": [], "source": [ @@ -3879,7 +5716,7 @@ }, { "cell_type": "code", - "execution_count": 145, + "execution_count": 186, "metadata": {}, "outputs": [], "source": [ @@ -3889,7 +5726,7 @@ }, { "cell_type": "code", - "execution_count": 146, + "execution_count": 187, "metadata": {}, "outputs": [ { @@ -3898,7 +5735,7 @@ "(0, 1, 2, 3)" ] }, - "execution_count": 146, + "execution_count": 187, "metadata": {}, "output_type": "execute_result" } @@ -3909,7 +5746,7 @@ }, { "cell_type": "code", - "execution_count": 147, + "execution_count": 188, "metadata": {}, "outputs": [], "source": [ @@ -3918,7 +5755,7 @@ }, { "cell_type": "code", - "execution_count": 148, + "execution_count": 189, "metadata": {}, "outputs": [ { @@ -3927,7 +5764,7 @@ "(1, 2, 3, 4)" ] }, - "execution_count": 148, + "execution_count": 189, "metadata": {}, "output_type": "execute_result" } @@ -3938,7 +5775,7 @@ }, { "cell_type": "code", - "execution_count": 149, + "execution_count": 190, "metadata": {}, "outputs": [], "source": [ @@ -3951,7 +5788,7 @@ }, { "cell_type": "code", - "execution_count": 150, + "execution_count": 191, "metadata": {}, "outputs": [ { @@ -3960,7 +5797,7 @@ "(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)" ] }, - "execution_count": 150, + "execution_count": 191, "metadata": {}, "output_type": "execute_result" } @@ -3971,7 +5808,7 @@ }, { "cell_type": "code", - "execution_count": 151, + "execution_count": 192, "metadata": {}, "outputs": [], "source": [ @@ -3980,7 +5817,7 @@ }, { "cell_type": "code", - "execution_count": 152, + "execution_count": 193, "metadata": {}, "outputs": [ { @@ -3989,7 +5826,7 @@ "5" ] }, - "execution_count": 152, + "execution_count": 193, "metadata": {}, "output_type": "execute_result" } @@ -4001,7 +5838,7 @@ }, { "cell_type": "code", - "execution_count": 153, + "execution_count": 194, "metadata": {}, "outputs": [], "source": [ @@ -4010,7 +5847,7 @@ }, { "cell_type": "code", - "execution_count": 154, + "execution_count": 195, "metadata": {}, "outputs": [ { @@ -4019,7 +5856,7 @@ "6" ] }, - "execution_count": 154, + "execution_count": 195, "metadata": {}, "output_type": "execute_result" } @@ -4031,7 +5868,7 @@ }, { "cell_type": "code", - "execution_count": 155, + "execution_count": 196, "metadata": {}, "outputs": [], "source": [ @@ -4040,7 +5877,7 @@ }, { "cell_type": "code", - "execution_count": 156, + "execution_count": 197, "metadata": {}, "outputs": [ { @@ -4049,7 +5886,7 @@ "8" ] }, - "execution_count": 156, + "execution_count": 197, "metadata": {}, "output_type": "execute_result" } @@ -4061,7 +5898,7 @@ }, { "cell_type": "code", - "execution_count": 157, + "execution_count": 198, "metadata": {}, "outputs": [ { @@ -4070,7 +5907,7 @@ "9" ] }, - "execution_count": 157, + "execution_count": 198, "metadata": {}, "output_type": "execute_result" } @@ -4082,7 +5919,7 @@ }, { "cell_type": "code", - "execution_count": 158, + "execution_count": 199, "metadata": {}, "outputs": [], "source": [ @@ -4091,7 +5928,7 @@ }, { "cell_type": "code", - "execution_count": 159, + "execution_count": 200, "metadata": {}, "outputs": [ { @@ -4100,7 +5937,7 @@ "(True, False, False, False, False, False, False)" ] }, - "execution_count": 159, + "execution_count": 200, "metadata": {}, "output_type": "execute_result" } @@ -4112,14 +5949,16 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "incorrectly_encoded_metadata": "toc-hr-collapsed=true toc-nb-collapsed=true" + }, "source": [ "## Les couples" ] }, { "cell_type": "code", - "execution_count": 160, + "execution_count": 201, "metadata": {}, "outputs": [], "source": [ @@ -4128,7 +5967,7 @@ }, { "cell_type": "code", - "execution_count": 161, + "execution_count": 202, "metadata": {}, "outputs": [], "source": [ @@ -4137,7 +5976,7 @@ }, { "cell_type": "code", - "execution_count": 162, + "execution_count": 203, "metadata": {}, "outputs": [], "source": [ @@ -4147,7 +5986,7 @@ }, { "cell_type": "code", - "execution_count": 163, + "execution_count": 204, "metadata": {}, "outputs": [ { @@ -4156,7 +5995,7 @@ "(1, 2)" ] }, - "execution_count": 163, + "execution_count": 204, "metadata": {}, "output_type": "execute_result" } @@ -4167,7 +6006,7 @@ }, { "cell_type": "code", - "execution_count": 164, + "execution_count": 205, "metadata": {}, "outputs": [], "source": [ @@ -4176,7 +6015,7 @@ }, { "cell_type": "code", - "execution_count": 165, + "execution_count": 206, "metadata": {}, "outputs": [ { @@ -4185,7 +6024,7 @@ "(0, 0, 1, 2, 3, 4, 5, 6, 7, 8)" ] }, - "execution_count": 165, + "execution_count": 206, "metadata": {}, "output_type": "execute_result" } @@ -4196,7 +6035,7 @@ }, { "cell_type": "code", - "execution_count": 166, + "execution_count": 207, "metadata": {}, "outputs": [], "source": [ @@ -4205,7 +6044,7 @@ }, { "cell_type": "code", - "execution_count": 167, + "execution_count": 208, "metadata": {}, "outputs": [ { @@ -4214,7 +6053,7 @@ "5" ] }, - "execution_count": 167, + "execution_count": 208, "metadata": {}, "output_type": "execute_result" } @@ -4225,7 +6064,7 @@ }, { "cell_type": "code", - "execution_count": 168, + "execution_count": 209, "metadata": {}, "outputs": [], "source": [ @@ -4234,7 +6073,7 @@ }, { "cell_type": "code", - "execution_count": 169, + "execution_count": 210, "metadata": {}, "outputs": [ { @@ -4243,7 +6082,7 @@ "(True, True, True, True, True, True, False, False, False, False)" ] }, - "execution_count": 169, + "execution_count": 210, "metadata": {}, "output_type": "execute_result" } @@ -4255,7 +6094,7 @@ }, { "cell_type": "code", - "execution_count": 170, + "execution_count": 211, "metadata": {}, "outputs": [], "source": [ @@ -4264,7 +6103,7 @@ }, { "cell_type": "code", - "execution_count": 171, + "execution_count": 212, "metadata": {}, "outputs": [ { @@ -4273,7 +6112,7 @@ "(False, False, False, False, False, True, False, False, False, False)" ] }, - "execution_count": 171, + "execution_count": 212, "metadata": {}, "output_type": "execute_result" } @@ -4285,14 +6124,16 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "incorrectly_encoded_metadata": "toc-hr-collapsed=true toc-nb-collapsed=true" + }, "source": [ "## It茅ration" ] }, { "cell_type": "code", - "execution_count": 172, + "execution_count": 213, "metadata": {}, "outputs": [], "source": [ @@ -4301,7 +6142,7 @@ }, { "cell_type": "code", - "execution_count": 173, + "execution_count": 214, "metadata": {}, "outputs": [ { @@ -4310,7 +6151,7 @@ "(1, 1, 2, 6, 24, 120, 720)" ] }, - "execution_count": 173, + "execution_count": 214, "metadata": {}, "output_type": "execute_result" } @@ -4321,14 +6162,16 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "incorrectly_encoded_metadata": "toc-hr-collapsed=true toc-nb-collapsed=true" + }, "source": [ "## Combinateur de point fixe" ] }, { "cell_type": "code", - "execution_count": 174, + "execution_count": 215, "metadata": {}, "outputs": [], "source": [ @@ -4337,7 +6180,7 @@ }, { "cell_type": "code", - "execution_count": 175, + "execution_count": 216, "metadata": {}, "outputs": [], "source": [ @@ -4346,7 +6189,7 @@ }, { "cell_type": "code", - "execution_count": 176, + "execution_count": 217, "metadata": {}, "outputs": [], "source": [ @@ -4359,7 +6202,7 @@ }, { "cell_type": "code", - "execution_count": 177, + "execution_count": 218, "metadata": {}, "outputs": [ { @@ -4368,7 +6211,7 @@ "(1, 1, 2, 6)" ] }, - "execution_count": 177, + "execution_count": 218, "metadata": {}, "output_type": "execute_result" } @@ -4379,7 +6222,7 @@ }, { "cell_type": "code", - "execution_count": 178, + "execution_count": 219, "metadata": {}, "outputs": [], "source": [ @@ -4392,7 +6235,7 @@ }, { "cell_type": "code", - "execution_count": 179, + "execution_count": 220, "metadata": {}, "outputs": [], "source": [ @@ -4401,7 +6244,7 @@ }, { "cell_type": "code", - "execution_count": 180, + "execution_count": 221, "metadata": {}, "outputs": [ { @@ -4410,7 +6253,7 @@ "(1, 1, 2, 6, 24, 120, 720)" ] }, - "execution_count": 180, + "execution_count": 221, "metadata": {}, "output_type": "execute_result" } @@ -4421,7 +6264,7 @@ }, { "cell_type": "code", - "execution_count": 181, + "execution_count": 222, "metadata": {}, "outputs": [], "source": [ @@ -4430,7 +6273,7 @@ }, { "cell_type": "code", - "execution_count": 182, + "execution_count": 223, "metadata": {}, "outputs": [], "source": [ @@ -4439,7 +6282,7 @@ }, { "cell_type": "code", - "execution_count": 183, + "execution_count": 224, "metadata": {}, "outputs": [ { @@ -4448,7 +6291,7 @@ "(1, 1, 2, 6, 24, 120, 720)" ] }, - "execution_count": 183, + "execution_count": 224, "metadata": {}, "output_type": "execute_result" } @@ -4459,14 +6302,16 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "incorrectly_encoded_metadata": "toc-hr-collapsed=true toc-nb-collapsed=true" + }, "source": [ "## Un programme obscur" ] }, { "cell_type": "code", - "execution_count": 184, + "execution_count": 225, "metadata": {}, "outputs": [ { @@ -4490,7 +6335,7 @@ }, { "cell_type": "code", - "execution_count": 185, + "execution_count": 226, "metadata": {}, "outputs": [], "source": [ @@ -4499,7 +6344,7 @@ }, { "cell_type": "code", - "execution_count": 186, + "execution_count": 227, "metadata": {}, "outputs": [ { @@ -4508,7 +6353,7 @@ "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" ] }, - "execution_count": 186, + "execution_count": 227, "metadata": {}, "output_type": "execute_result" } @@ -4519,7 +6364,7 @@ }, { "cell_type": "code", - "execution_count": 187, + "execution_count": 228, "metadata": {}, "outputs": [], "source": [ @@ -4528,7 +6373,7 @@ }, { "cell_type": "code", - "execution_count": 188, + "execution_count": 229, "metadata": {}, "outputs": [ { @@ -4537,7 +6382,7 @@ "[1, 4, 9, 16]" ] }, - "execution_count": 188, + "execution_count": 229, "metadata": {}, "output_type": "execute_result" } @@ -4548,7 +6393,7 @@ }, { "cell_type": "code", - "execution_count": 189, + "execution_count": 230, "metadata": {}, "outputs": [], "source": [ @@ -4557,7 +6402,7 @@ }, { "cell_type": "code", - "execution_count": 190, + "execution_count": 231, "metadata": {}, "outputs": [ { @@ -4566,7 +6411,7 @@ "24" ] }, - "execution_count": 190, + "execution_count": 231, "metadata": {}, "output_type": "execute_result" } @@ -4604,6 +6449,7 @@ "pygments_lexer": "ipython3", "version": "3.7.3" }, + "toc-autonumbering": true, "toc-showcode": false, "toc-showmarkdowntxt": false, "widgets": { diff --git a/lambda_calcul.md b/lambda_calcul.md index df6331c..7fda7b3 100644 --- a/lambda_calcul.md +++ b/lambda_calcul.md @@ -15,8 +15,9 @@ jupyter: Ce calepin est compos茅 de deux parties : -1. la premi猫re partie est une rapide pr茅sentation du $\lambda$-calcul illustr茅e par l'utilisation d'un module permettant de d茅finir et transformer des $\lambda$-termes. -2. la deuxi猫me partie reprend la partie 芦 pouvoir d'expression du $\lambda$-calcul 禄 en l'illustrant avec les lambda-expressions du langage Python. +1. la premi猫re partie est une rapide pr茅sentation du $\lambda$-calcul illustr茅e par l'utilisation d'un module permettant de d茅finir et transformer des $\lambda$-termes. + +2. la deuxi猫me partie reprend la partie 芦 pouvoir d'expression du $\lambda$-calcul 禄 en l'illustrant avec les lambda-expressions du langage Python. (CETTE PARTIE RESTE ENCORE A REDIGER) # $\lambda$-calcul @@ -44,6 +45,15 @@ Le tout illustr茅 avec une classe Python pour repr茅senter et manipuler des $\la En principe, les $\lambda$-termes sont des mots sur lesquels certaines op茅rations sont possibles. Ces mots ont vocation 脿 pouvoir exprimer des fonctions, ainsi que leur application 脿 un argument. +En $\lambda$-calcul tout est fonction ! + +Si $f$ est un $\lambda$-terme, on doit pouvoir l'appliquer 脿 un autre terme $x$, mais au lieu d'茅crire $f(x)$ comme c'est l'usage en math茅matiques, on 茅crit plut么t $(f\ x)$ et cela forme un nouveau terme nomm茅 *application*. + +Il n'y a pas de fonctions 脿 plusieurs variables : toutes les fonctions ont une et une seule variable. Donc si on a en t锚te de vouloir repr茅senter une fonction 脿 deux variables $f(x,y)$, elle le sera par une fonction 脿 une variable telle que $f(x)$ soit elle aussi une fonction 脿 une variable, et au lieu d'茅crire $f(x,y)$ ou m锚me $f(x)(y)$, on 茅crira $((f\ x)\ y)$. + +Enfin si $x$ est une variable et $M$ un terme d茅pendant 茅ventuellement de $x$, on doit pouvoir d茅finir la fonction $x\mapsto M$. Cette construction est nomm茅e *abstraction* en $\lambda$-calcul et elle est not茅e $\lambda x.M$. + + Formellement, l'alphabet $\Sigma$ utilis茅 pour les $\lambda$-termes est constitu茅 : * d'un ensemble infini d茅nombrable de variables $V=\{x, y, z, t, ...\}$ ; @@ -507,15 +517,18 @@ Bref, d'un certain point de vue le $\lambda$-calcul est un langage de programmat On peut repr茅senter les deux bool茅ens VRAI et FAUX par les $\lambda$-termes -$$ VRAI = \lambda x.\lambda y.x,$$ +$$ \mathtt{VRAI} = \lambda x.\lambda y.x,$$ et -$$ FAUX = \lambda x.\lambda y.y.$$ +$$ \mathtt{FAUX} = \lambda x.\lambda y.y.$$ ```python VRAI = Lambda_terme('!x.!y.x') FAUX = Lambda_terme('!x.!y.y') ``` +**Remarque** les deux termes $\mathtt{VRAI}$ et $\mathtt{FAUX}$ sont termes clos irr茅ductibles. + + #### Le terme IF @@ -556,7 +569,7 @@ IF.applique(VRAI).applique(Lambda_terme('ALORS')).applique(OMEGA).forme_normale( IF.applique(FAUX).applique(OMEGA).applique(Lambda_terme('SINON')).forme_normale(verbose=True) ``` -Le fait que le terme `IF` se comporte bien comme on l'attend r茅sulte du choix de la strat茅gie de r茅duction des redex les plus 脿 gauche en priorit茅. Si la strat茅gie choisie avait 茅t茅 de r茅duire le redex le plus 脿 droite, la r茅duction de chacun des deux termes pr茅c茅dents aurait conduit 脿 la tentative de r茅duire le terme $\Omega$ qui 茅choue puisque celui-ci n'est pas normalisable comme on l'a vu. +Le fait que le terme $\mathtt{IF}$ se comporte bien comme on l'attend r茅sulte du choix de la strat茅gie de r茅duction des redex les plus 脿 gauche en priorit茅. Si la strat茅gie choisie avait 茅t茅 de r茅duire le redex le plus 脿 droite, la r茅duction de chacun des deux termes pr茅c茅dents aurait conduit 脿 la tentative de r茅duire le terme $\Omega$ qui 茅choue puisque celui-ci n'est pas normalisable comme on l'a vu. Il est facile de d茅finir les op茅rateurs logiques de base : conjonction, disjonction et n茅gation. @@ -567,7 +580,7 @@ Il est facile de d茅finir les op茅rateurs logiques de base : conjonction, disjon L'op茅rateur logique de conjonction peut 锚tre d茅fini par -$$ ET = \lambda a.\lambda b.(((IF\ a)\ b)\ FAUX).$$ +$$ \mathtt{ET} = \lambda a.\lambda b.(((\mathtt{IF}\ a)\ b)\ \mathtt{FAUX}).$$ ```python ET = IF.applique(Lambda_terme('a')).applique(Lambda_terme('b')).applique(FAUX).abstrait('b').abstrait('a') @@ -600,7 +613,7 @@ ET.applique(FAUX).applique(FAUX).forme_normale(verbose=True) == FAUX L'op茅rateur logique de disjonction peut 锚tre d茅fini par -$$ OU = \lambda a.\lambda b.(((IF\ a)\ VRAI)\ b).$$ +$$ \mathtt{OU} = \lambda a.\lambda b.(((\mathtt{IF}\ a)\ \mathtt{VRAI})\ b).$$ ```python OU = IF.applique(Lambda_terme('a')).applique(VRAI).applique(Lambda_terme('b')).abstrait('b').abstrait('a') @@ -633,7 +646,7 @@ OU.applique(FAUX).applique(FAUX).forme_normale(verbose=True) == FAUX L'op茅rateur de n茅gation peut 锚tre d茅fini par le terme -$$ NON = \lambda a.(((IF\ a)\ FAUX)\ VRAI).$$ +$$ \mathtt{NON} = \lambda a.(((\mathtt{IF}\ a)\ \mathtt{FAUX})\ \mathtt{VRAI}).$$ ```python NON = IF.applique(Lambda_terme('a')).applique(FAUX).applique(VRAI).abstrait('a') @@ -659,6 +672,30 @@ NON.applique(FAUX).forme_normale(verbose=True) == VRAI Il existe plusieurs fa莽ons de repr茅senter les entiers naturels par un $\lambda$-terme. La repr茅sentation donn茅e ici est connue sous le nom de *num茅raux de Church*. + +Dans le syst猫me de Church, un entier $n\in\mathbb{N}$ est repr茅sent茅 par le $\lambda$-terme + +$$ \lceil n\rceil = \lambda f.\lambda x. (f^n\ x),$$ +dans lequel le sous-terme $(f^n\ x)$ est un raccourci pour signifier +$$ (f^n\ x) = (f\ (f\ (\ldots (f\ x)\ldots))),$$ +terme dans lequel $f$ appara卯t $n$ fois. +En quelque sorte le terme repr茅sentant l'entier $n$ est une repr茅sentation unaire de $n$. + +Ainsi on a + +\begin{align*} + \lceil 0\rceil &= \lambda f.\lambda x.x\\ + \lceil 1\rceil &= \lambda f.\lambda x.(f\ x)\\ + \lceil 2\rceil &= \lambda f.\lambda x.(f\ (f\ x))\\ + \lceil 3\rceil &= \lambda f.\lambda x.(f\ (f\ (f\ x))). +\end{align*} + +Le $\lambda$-terme $\lceil n\rceil$ est donc un terme capable d'appliquer $n$ fois une fonction $F$ sur une donn茅e $X$. En effet on a +$$ (\lceil n\rceil\ F) \twoheadrightarrow_\beta \lambda x.(F\ldots(F\ x)),$$ +et +$$ ((\lceil n\rceil\ F)\ X) \twoheadrightarrow_\beta (F\ldots(F\ X)).$$ + + ```python ZERO = Lambda_terme('!f.!x.x') ``` @@ -671,24 +708,76 @@ UN = Lambda_terme('!f.!x.(f x)') DEUX = Lambda_terme('!f.!x.(f (f x))') ``` +Le calcul ci-dessous v茅rifie bien qu'un num茅ral appliqu茅 脿 un terme r茅sulte en une fonction it茅ration du terme. + +```python +DEUX.applique(Lambda_terme('F')).forme_normale(verbose=True) +``` + +**Remarque** les num茅raux de Church sont des $\lambda$-termes clos irr茅ductibles. + + #### Successeur + +Lorsqu'on a compris que pour tout num茅ral $\lceil n\rceil$ on a + +$$ ((\lceil n\rceil\ F)\ X) \twoheadrightarrow_\beta (F\ldots(F\ X)),$$ + +alors il est facile de concevoir un $\lambda$-terme $\mathtt{SUC}$ tel que + +$$ (\mathtt{SUC}\ \lceil n\rceil) =_\beta \lceil n+1\rceil.$$ + + ```python SUC = Lambda_terme('!n.!f.!x.(f ((n f) x))') ``` ```python -TROIS = SUC.applique(DEUX).forme_normale(verbose=True) +print(SUC) ``` ```python -TROIS.applique(SUC).applique(ZERO).forme_normale(verbose=True) +TROIS = SUC.applique(DEUX).forme_normale(verbose=True) +``` + +La fonction qui suit permet d'obtenir le num茅ral de Church correspondant 脿 un entier naturel (de Python). + +```python +def int_en_church(n): + if n == 0: + return ZERO + else: + return SUC.applique(int_en_church(n - 1)).forme_normale() +``` + +```python +for n, t in enumerate((ZERO, UN, DEUX, TROIS)): + print(int_en_church(n) == t) ``` #### Addition + +En appliquant trois fois de suite le terme $\mathtt{SUC}$ sur le terme $\lceil 2\rceil$ on obtient un terme dont la forme normale est le num茅ral $\lceil 5\rceil$. + ```python -ADD = Lambda_terme('!n.!m.!f.!x.((n f) ((m f) x))') +TROIS.applique(SUC).applique(DEUX).forme_normale(verbose=True) == int_en_church(5) +``` + +Ainsi on peut d茅finir un $\lambda$-terme $\mathtt{ADD}$ qui appliqu茅 脿 deux num茅raux est $\beta$-茅quivalent au num茅ral somme. +En d茅finissant donc +$$ \mathtt{ADD} = \lambda n.\lambda m.((n\ \mathtt{SUC})\ m),$$ +on a +$$ ((\mathtt{ADD}\ \lceil n\rceil)\ \lceil m\rceil) =_\beta \lceil n+m\rceil.$$ + +```python +M_ADD = Lambda_terme('!n.!m.((n SUC) m)') +ADD = M_ADD.subs('SUC', SUC) +``` + +```python +print(ADD) ``` ```python @@ -705,6 +794,29 @@ SEPT = ADD.applique(QUATRE).applique(TROIS).forme_normale(verbose=True) #### Multiplication + +On pourrait d茅finir un terme pour la multiplication en consid茅rant que multiplier $n$ par $m$ c'est r茅p茅ter $n$ fois l'addition de $m$ 脿 partir de 0. + +```python +M_MUL = Lambda_terme('!n.!m.((n (ADD m)) ZERO)') +MUL = M_MUL.subs('ADD', ADD).subs('ZERO', ZERO) +print(MUL) +``` + +```python +MUL.applique(DEUX).applique(TROIS).forme_normale(verbose=True) == int_en_church(6) +``` + +Mais il s'av猫re plus simple (et plus efficace comme on pourra le constater) de d茅finir le terme $\mathtt{MUL}$ par +$$ \mathtt{MUL} = \lambda n.\lambda m.\lambda f.(n\ (m\ f)).$$ + +En effet, il est clair que +$$ ((\mathtt{MUL} \lceil n\rceil)\ \lceil m\rceil) \twoheadrightarrow_\beta \lambda f.(\lceil n\rceil\ (\lceil m\rceil\ f)),$$ +et le terme obtenu est la r茅p茅tition $m$ fois du terme $f$, r茅p茅tition r茅p茅t茅e elle-m锚me $n$ fois. Au bilan le terme $f$ est r茅p茅t茅 $n\times m$ fois. + +Et on a donc bien +$$ ((\mathtt{MUL} \lceil n\rceil)\ \lceil m\rceil) =_\beta \lceil n\times m\rceil.$$ + ```python MUL = Lambda_terme('!n.!m.!f.(n (m f))') ``` @@ -713,8 +825,17 @@ MUL = Lambda_terme('!n.!m.!f.(n (m f))') SIX = MUL.applique(DEUX).applique(TROIS).forme_normale(verbose=True) ``` +Le calcul de la forme normale de $((\mathtt{MUL}\ \lceil 2\rceil)\ \lceil 3\rceil)$ avec cette version de $\mathtt{MUL}$ est bien plus court que le calcul effectu茅 avec la version pr茅c茅dente. + + #### Exponentiation + +Comme pour la multiplication, on pourrait envisager de d茅finir un terme pour l'exponentiation en consid茅rant qu'il suffit de r茅p茅ter $m$ fois le terme $\mathtt{MUL}$ appliqu茅 脿 $n$ pour obtenir un terme qui se r茅duirait au num茅ral repr茅sentant $n^m$. + +Mais il est possible de d茅finir un terme beaucoup plus simple : +$$ \mathtt{EXP} = \lambda n.\lambda m.(m\ n).$ + ```python EXP = Lambda_terme('!n.!m.(m n)') ``` @@ -724,7 +845,7 @@ HUIT = EXP.applique(DEUX).applique(TROIS).forme_normale(verbose=True) ``` ```python -HUIT == MUL.applique(DEUX).applique(QUATRE).forme_normale() +HUIT == int_en_church(8) ``` ```python @@ -732,16 +853,30 @@ NEUF = EXP.applique(TROIS).applique(DEUX).forme_normale(verbose=True) ``` ```python -NEUF == ADD.applique(SEPT).applique(DEUX).forme_normale() +NEUF == int_en_church(9) ``` #### Nullit茅 -```python -NUL = Lambda_terme('!n.((n !x.FAUX) VRAI)').subs('FAUX', FAUX).subs('VRAI', VRAI) -``` + +Consid茅rons le terme $((\lceil n\rceil\ \lambda x.\mathtt{FAUX})\ \mathtt{VRAI})$. Si $n=0$ on a +$$((\lceil 0\rceil\ \lambda x.\mathtt{FAUX})\ \mathtt{VRAI}) \twoheadrightarrow_\beta (\lambda x.x\ \mathtt{VRAI}) \rightarrow_\beta \mathtt{VRAI}.$$ +Et si $n\neq 0$ on a +$$((\lceil n\rceil\ \lambda x.\mathtt{FAUX})\ \mathtt{VRAI}) \twoheadrightarrow_\beta (\lambda x.\mathtt{FAUX}\ \mathtt{VRAI}) \rightarrow_\beta \mathtt{FAUX}.$$ + +Avec une abstraction, on obtient le $\lambda$-terme +$$ \mathtt{NUL} = \lambda n.(),$$ +tel que pour $n=0$ +$$ (\mathtt{NUL}\ \lceil 0\rceil) =_\beta \mathtt{VRAI},$$ +et pour $n\neq 0$ +$$ (\mathtt{NUL}\ \lceil n\rceil) =_\beta \mathtt{FAUX}.$$ + +En d'autres termes, le $\lambda$-terme $\mathtt{NUL}$ correspond 脿 un pr茅dicat permettant de tester la nullit茅 d'un entier. ```python +M_NUL = Lambda_terme('!n.((n !x.FAUX) VRAI)') +print(M_NUL) +NUL = M_NUL.subs('FAUX', FAUX).subs('VRAI', VRAI) print(NUL) ``` @@ -753,13 +888,41 @@ NUL.applique(ZERO).forme_normale(verbose=True) == VRAI NUL.applique(TROIS).forme_normale(verbose=True) == FAUX ``` +**Remarque** Arriv茅 脿 ce stade, il nous manque une op茅ration arithm茅tique de base : la soustraction, et la possibilit茅 de comparaison plus g茅n茅rale permettant de d茅cider si un entier est inf茅rieur 脿 un autre. Ce manque sera combl茅 une fois que nous aurons vu une repr茅sentation des couples. + + ### Couples et listes -```python -CONS = Lambda_terme('!x.!y.!s.(((IF s) x) y)').subs('IF', IF) -``` + +#### Constructeur et s茅lecteurs de couples + + +Comment exprimer un couple de $\lambda$-termes 脿 l'aide d'un $\lambda$-terme ? Une fois ce couple exprim茅 comment en extraire chacune des deux composantes ? + + +Soient $M$ et $N$ deux $\lambda$-termes quelconques. Consid茅rons les deux termes $((\mathtt{VRAI}\ M)\ N)$ et $((\mathtt{FAUX}\ M)\ N)$. Il est facile de v茅rifier que +$$ ((\mathtt{VRAI}\ M)\ N) =_\beta M,$$ +et +$$ ((\mathtt{FAUX}\ M)\ N) =_\beta N.$$ + +On d茅duit de ce constat que +$$[M, N] = \lambda s.((s\ M)\ N)$$ +est un $\lambda$-terme pouvant repr茅senter le couple $(M, N)$ et que la s茅lection de l'une ou l'autre des deux composantes peut se faire en appliquant le terme sur l'un ou l'autre des deux termes $\mathtt{VRAI}$ ou $\mathtt{FAUX}$ : + +$$ ([M, N]\ \mathtt{VRAI}) =_\beta M,$$ +et +$$ ([M, N]\ \mathtt{FAUX}) =_\beta N.$$ + + +Ces consid茅rations am猫nent 脿 d茅finir le terme constructeur de couple $\mathtt{CONS}$ +$$ \mathtt{CONS} = \lambda x.\lambda y.\lambda s.((s\ x)\ y),$$ +ainsi que les deux s茅lecteurs $\mathtt{CAR}$, pour acc茅der 脿 la premi猫re composante, et $\mathtt{CDR}$, pour acc茅der 脿 la deuxi猫me composante +$$\mathtt{CAR} = \lambda c.(c\ \mathtt{VRAI}),$$ +et +$$\mathtt{CDR} = \lambda c.(c\ \mathtt{FAUX}).$$ ```python +CONS = Lambda_terme('!x.!y.!s.((s x) y)') print(CONS) ``` @@ -768,10 +931,9 @@ UN_DEUX = CONS.applique(UN).applique(DEUX).forme_normale(verbose=True) ``` ```python -CAR = Lambda_terme('!c.(c VRAI)').subs('VRAI', VRAI) -``` - -```python +M_CAR = Lambda_terme('!c.(c VRAI)') +print(M_CAR) +CAR = M_CAR.subs('VRAI', VRAI) print(CAR) ``` @@ -780,10 +942,9 @@ CAR.applique(UN_DEUX).forme_normale(verbose=True) == UN ``` ```python -CDR = Lambda_terme('!c.(c FAUX)').subs('FAUX', FAUX) -``` - -```python +M_CDR = Lambda_terme('!c.(c FAUX)') +print(M_CDR) +CDR = M_CDR.subs('FAUX', FAUX) print(CDR) ``` @@ -800,6 +961,35 @@ CPLE_M = CONS.applique(CAR.applique(M)).applique(CDR.applique(M)) CDR.applique(CPLE_M).forme_normale(verbose=True) ``` +**Remarques** +1. le terme $((\mathtt{CONS}\ M)\ N)$ est clos si et seulement si $M$ et $N$ le sont, et il est normalisable si et seulement si $M$ et $N$ le sont. + +2. les noms donn茅s aux termes $\mathtt{CONS}$, $\mathtt{CAR}$ et $\mathtt{CDR}$ font r茅f茅rence aux noms donn茅s aux constructeurs et s茅lecteurs de paires dans le langage de programmation LISP (et ses successeurs comme SCHEME). + + +#### Pr茅d茅cesseur d'un entier, soustraction + + +Envisageons la fonction $F$ qui, 脿 un couple $(m, n)$ d'entiers, associe le couple $(n, n+1)$. En partant du couple $(0,0)$ et en it茅rant $n$ fois cette fonction, on obtient le couple $(n-1, n)$. La premi猫re composante de ce couple est l'entier $n-1$, donc l'entier qui pr茅c猫de $n$. + +C'est l'id茅e de base pour d茅finir un $\lambda$-terme $\mathtt{PRED}$ tel que pour tout entier $n\geq 1$ on ait +$$ (\mathtt{PRED}\ \lceil n\rceil) =_\beta \lceil n-1\rceil.$$ + +```python +M_F = Lambda_terme('!c.((CONS (CDR c)) (SUC (CDR c)))') +print(M_F) +F = M_F.subs('CONS', CONS).subs('CDR', CDR).subs('SUC', SUC) +print(F) +``` + +```python +QUATRE.applique(F).applique(CONS.applique(ZERO).applique(ZERO)).forme_normale() == CONS.applique(TROIS).applique(QUATRE).forme_normale() +``` + +Le $\lambda$-terme $\mathtt{PRED}$ est d茅fini par + +$$ \mathtt{PRED} = \lambda n.(\mathtt{CAR} ((n \lambda c.((\mathtt{CONS}\ (\mathtt{CDR}\ c))\ (\mathtt{SUC} (\mathtt{CDR}\ c)))) ((\mathtt{CONS}\ \mathtt{ZERO})\ \mathtt{ZERO}))).$$ + ```python M_PRED = Lambda_terme('!n.(CAR ((n !c.((CONS (CDR c)) (SUC (CDR c)))) ((CONS ZERO) ZERO)))') print(M_PRED) @@ -808,13 +998,17 @@ print(PRED) ``` ```python -PRED.applique(DEUX).forme_normale(verbose=True) == UN +PRED.applique(CINQ).forme_normale(verbose=True) == QUATRE ``` +**Remarque** le terme $(\mathtt{PRED}\ \mathtt{ZERO})$ est normalisable et sa forme normale est $\mathtt{ZERO}$. + ```python PRED.applique(ZERO).forme_normale(verbose=True) == ZERO ``` +Une fois le pr茅desseur exprim茅, il est facile de d茅finir la soustraction comme une it茅ration du pr茅d茅cesseur. + ```python M_SUB = Lambda_terme('!n.!m.((m PRED) n)') print(M_SUB) @@ -826,10 +1020,30 @@ print(SUB) SUB.applique(TROIS).applique(UN).forme_normale(verbose=True) == DEUX ``` +#### Inf茅riorit茅, 茅galit茅 + + +**Remarque** on a l'茅quivalence +$$ n <= m \Longleftrightarrow ((\mathtt{SUB}\ \lceil n\rceil)\ \lceil m\rceil) =_\beta \mathtt{ZERO}.$$ + +```python +SUB.applique(TROIS).applique(QUATRE).forme_normale() == ZERO +``` + +De l脿 vient l'id茅e de d茅finir le $\lambda$-terme +$$\mathtt{INF} = \lambda n.\lambda m.(\mathtt{NUL}\ ((\mathtt{SUB}\ n)\ m)),$$ +qui est tel que pour tout couple d'entier $(n, m)$, on a + +* si $n \leq m$ + $$ ((\mathtt{INF}\ \lceil n\rceil)\ \lceil m\rceil) =_\beta \mathtt{VRAI},$$ +* et si $n > m$ + $$ ((\mathtt{INF}\ \lceil n\rceil)\ \lceil m\rceil) =_\beta \mathtt{FAUX}.$$ + ```python M_INF = Lambda_terme('!n.!m.(NUL ((SUB n) m))') print(M_INF) INF = M_INF.subs('NUL', NUL).subs('SUB', SUB) +print(INF) ``` ```python @@ -844,6 +1058,15 @@ INF.applique(UN).applique(TROIS).forme_normale() == VRAI INF.applique(UN).applique(UN).forme_normale() == VRAI ``` +Et 脿 partir de $\mathtt{INF}$ on peut d茅finir le terme +$$ \mathtt{EGAL} = \lambda n.\lambda m.((\mathtt{ET}\ ((\mathtt{INF}\ \lceil n\rceil)\ \lceil m\rceil))\ ((\mathtt{INF}\ \lceil m\rceil)\ \lceil n\rceil)),$$ +qui est tel que pour tout couple d'entier $(n, m)$, on a + +* si $n = m$ + $$ ((\mathtt{EGAL}\ \lceil n\rceil)\ \lceil m\rceil) =_\beta \mathtt{VRAI},$$ +* et si $n \neq m$ + $$ ((\mathtt{EGAL}\ \lceil n\rceil)\ \lceil m\rceil) =_\beta \mathtt{FAUX}.$$ + ```python M_EGAL = Lambda_terme('!n.!m.((ET ((INF n) m)) ((INF m) n))') print(M_EGAL) @@ -859,8 +1082,162 @@ EGAL.applique(UN).applique(UN).forme_normale() == VRAI EGAL.applique(UN).applique(DEUX).forme_normale() == FAUX ``` +#### Listes de termes + + +Classiquement, on peut consid茅rer une liste de termes $ $ comme un couple dont la premi猫re composante est l'茅l茅ment en t锚te de la liste, et la seconde composante est la liste des 茅l茅ments qui restent : +$$ = [M_1, ].$$ +Ainsi une liste de trois 茅l茅ments est un embo卯tement de trois couples : + +$$ = [M_1, [M_2, [M3, <>]]],$$ +la deuxi猫me composante du couple le plus interne, $<>$ d茅signant la liste vide. + +On voit bien comment construire des listes ($\mathtt{CONS}$), acc茅der 脿 leur t锚te ($\mathtt{CAR}$) et 脿 leur reste ($\mathtt{CDR}$). + +Il reste 脿 trouver une repr茅sentation de la liste vide et un terme permettant de distinguer la liste vide de celles qui ne le sont pas. + +Et le probl猫me de la vacuit茅 d'une liste va imposer de mettre une couche d'abstraction suppl茅mentaire sur notre repr茅sentation des listes. + + +脡tant donn茅s $n$ $\lambda$-termes $M_1$, $M_2$, ..., $M_n$, on peut repr茅senter la liste de ces termes par le $\lambda$-terme + +$$ = \lambda x.[M_1, [M_2, \ldots[M_n, <>]\ldots],$$ +d茅finition dans laquelle $<>$ d茅signe la liste vide qui peut 锚tre repr茅sent茅e par +$$ <> = \lambda x.\lambda s.x\,\, (= \mathtt{FAUX}).$$ + +```python +LVIDE = Lambda_terme('!x.!s.x') +``` + +Le terme $\mathtt{LCONS}$ permettant d'ajouter un terme $t$ en t锚te d'une liste $r$ peut alors 锚tre facilement 茅crit de la mani猫re suivante en utilisant $\mathtt{CONS}$. + +$$ \mathtt{LCONS} = \lambda t.\lambda r.\lambda x.((\mathtt{CONS}\ t)\ r).$$ + +```python +M_LCONS = Lambda_terme('!t.!r.!x.((CONS t) r)') +print(M_LCONS) +LCONS = M_LCONS.subs('CONS', CONS) +print(LCONS) +``` + +```python +M1 = Lambda_terme('M1') +M2 = Lambda_terme('M2') +M3 = Lambda_terme('M3') +L = LCONS.applique(M1).applique(LCONS.applique(M2).applique(LCONS.applique(M3).applique(LVIDE))) +print(L.forme_normale()) +``` + +Notons que si $L$ est une liste non vide, alors quelque soit le terme $M$, $(L\ M)$ se r茅duit en un couple dont la seconde composante est la liste reste de $L$. En particulier, le terme $M$ a disparu. + +```python +print(L.applique(Lambda_terme('M')).forme_normale()) +``` + +Et dans le cas de la liste vide, $(\mathtt{LVIDE}\ M)$ se r茅duit en $\lambda s.M$. + +```python +print(LVIDE.applique(Lambda_terme('M')).forme_normale()) +``` + +Les deux remarques pr茅c茅dentes sont 脿 la base de la d茅finition des s茅lecteurs $\mathtt{LCAR}$ et $\mathtt{LCDR}$ pr茅sent茅s maintenant. + + +Le s茅lecteur $\mathtt{LCAR}$ permettant d'obtenir l'茅l茅ment de t锚te d'une liste est construit en utilisant $\mathtt{CAR}$. + +$$ \mathtt{LCAR} = \lambda l.(\mathtt{CAR}\ (l\ \mathtt{VRAI})).$$ + +```python +M_LCAR = Lambda_terme('!l.(CAR (l VRAI))') +print(M_LCAR) +L_CAR = M_LCAR.subs('CAR', CAR).subs('VRAI', VRAI) +print(L_CAR) +``` + +```python +L_CAR.applique(L).forme_normale(verbose=True) == Lambda_terme('M1') +``` + +Notons que +$$(\mathtt{LCAR}\ \mathtt{LVIDE}) \twoheadrightarrow_\beta \mathtt{LVIDE}.$$ + +```python +L_CAR.applique(LVIDE).forme_normale(verbose=True) == LVIDE +``` + +Le s茅lecteur $\mathtt{LCDR}$ permettant d'obtenir le reste d'une liste se d茅finit 脿 l'aide de $\mathtt{CDR}$. + +$$ CDR = \lambda l.(\mathtt{CDR}\ (l\ \mathtt{VRAI})).$$ + +```python +M_LCDR = Lambda_terme('!l.(CDR (l VRAI))') +print(M_LCDR) +LCDR = M_LCDR.subs('CDR', CDR).subs('VRAI', VRAI) +print(LCDR) +``` + +```python +LCDR.applique(L).forme_normale(verbose=True) +``` + +Notons que +$$(\mathtt{LCDR}\ \mathtt{LVIDE}) \twoheadrightarrow_\beta \mathtt{LVIDE}.$$ + +```python +LCDR.applique(LVIDE).forme_normale(verbose=True) == LVIDE +``` + +Le terme qui permet de distinguer une liste vide d'une liste qui ne l'est pas est + +$$ \mathtt{LESTVIDE} = \lambda l.((l\ \mathtt{VRAI})\ \lambda t.\lambda r.\mathtt{FAUX}).$$ + +```python +M_LESTVIDE = Lambda_terme('!l.((l VRAI) !t.!r.FAUX)') +print(M_LESTVIDE) +LESTVIDE = M_LESTVIDE.subs('VRAI', VRAI).subs('FAUX', FAUX) +``` + +```python +LESTVIDE.applique(LVIDE).forme_normale(verbose=True) == VRAI +``` + +```python +LESTVIDE.applique(L).forme_normale(verbose=True) == FAUX +``` + ### It茅ration + +On l'a vu 脿 plusieurs occasions ($\mathtt{ADD}$, $\mathtt{MUL}$, $\mathtt{EXP}$, $\mathtt{NUL}$, $\mathtt{SUB}$), les num茅raux de Church permettent d'it茅rer l'application d'un terme. + + +脡tudions encore un cas d'茅cole avec la classique fonction factorielle qui peut se programmer en Python 脿 l'aide d'une boucle `for`. + +~~~python +def fact(n): + f = 1 + for i in range(n+1): + f = f*i + return f +~~~ + + +Ce programme utilise deux variables $\mathtt{i}$ et $\mathtt{f}$. + +Si on ajoute la valeur fictive 0 pour la variable $\mathtt{i}$ avant la boucle `for`, le couple ($\mathtt{i}$, $\mathtt{f}$) prend les valeurs successives : (0, 1), (1, 1), (2, 2), (3, 6), ..., ($n$, $n!$). Ainsi 脿 chaque 茅tape de l'it茅ration le couple est transform茅 selon la r猫gle : + +$$ (i, f) \rightarrow (i+1, f\times i).$$ + +C'est cette r猫gle qui est it茅r茅e $n$ fois. Et cette r猫gle peut 锚tre repr茅sent茅e par un $\lambda$-terme transformant un couple $[\lceil i\rceil, \lceil f\rceil]$ en le couple $[\lceil i+1\rceil, \lceil f\times i\rceil]$. + + +Ce qui peut 锚tre fait par + +$$ \mathtt{FACT} = \lambda n.(CDR\ ((n\ \lambda c.[(SUC\ (CAR\ c)), ((MUL\ (CAR\ c))\ (CDR\ c))])\ [ZERO, ZERO])).$$ + + +Voici une r茅alisation de ce terme (que nous nommons $\mathtt{FACTv1}$ puisque d'autre r茅alisations de $\mathtt{}$ seront envisag茅es dans la suite). + ```python M_FACTv1 = Lambda_terme('!n.(CDR ((n !c.((CONS (SUC (CAR c))) ((MUL (SUC (CAR c))) (CDR c)))) ((CONS ZERO) UN)))') print(M_FACTv1) @@ -877,66 +1254,198 @@ FACTv1.applique(UN).forme_normale() == UN ``` ```python -print(FACTv1.applique(DEUX).forme_normale()) +FACTv1.applique(DEUX).forme_normale() == DEUX ``` +Pour calculer $(\mathtt{FACTv1}\ \mathtt{TROIS})$, il faut au moins 309 茅tapes de r茅duction. + ```python -FACTv1.applique(DEUX).forme_normale(nb_etapes_max=118) == DEUX +FACTv1.applique(TROIS).forme_normale(nb_etapes_max=309) == SIX ``` +Et pour (饾櫟饾櫚饾櫜饾殐饾殶饾煼 QUATRE), il en faut au moins 1284. + ```python -FACTv1.applique(TROIS).forme_normale(nb_etapes_max=403) == SIX +FACTv1.applique(QUATRE).forme_normale(nb_etapes_max=1284) == MUL.applique(QUATRE).applique(SIX).forme_normale() ``` -```python -FACTv1.applique(QUATRE).forme_normale(nb_etapes_max=1672) == MUL.applique(QUATRE).applique(SIX).forme_normale() -``` +En suivant le principe qui a conduit 脿 茅crire le terme $\mathtt{FACTv1}$, on comprend que n'importe quelle fonction qui peut 锚tre programm茅e (en Python, ou tout autre langage) peut 锚tre repr茅sent茅e par un $\lambda$-terme. -### Et la r茅cursivit茅 ? + +### Et la r茅cursivit茅 ? Et les boucles `while` ? + + +Dernier point de notre exploration du pouvoir d'expression du $\lambda$-calcul qui ach猫vera (peut-锚tre) de nous convaincre que c'est un langage de programmation : peut-on repr茅senter des fonctions r茅cursives ? peut-on repr茅senter des fonctions dont l'algorithme n茅cessite une boucle `while` ? + + +#### Exprimer la r茅cursivit茅 sans nom ? + + +Prenons encore la fonction factorielle comme exemple classique de fonction r茅cursive. En Python on peut l'茅crire de la fa莽on suivante + +~~~python +def fact(n): + if n == 0: + return 1 + else: + return n * fact(n - 1) +~~~ + + +En examinant le code de cette version r茅cursive de la fonction factorielle, on s'aper莽oit que nous disposons de tous les ingr茅dients pour 茅crire un $\lambda$-terme analogue. Le voici : + +$$ \mathtt{FACT} = \lambda n.(((\mathtt{IF}\ (\mathtt{NUL}\ n))\ \lceil 1\rceil)\ ((\mathtt{MUL}\ n)\ (\mathtt{FACT}\ (\mathtt{PRED}\ n)))).$$ + + +Hmmm ... Trop facile ! Il y a un hic ! +Ce terme n'est pas valide car dans le terme d茅sign茅 par le nom $\mathtt{FACT}$, il y a le nom $\mathtt{FACT}$, et en $\lambda$-calcul les seuls noms intervenants dans les $\lambda$-termes sont les variables. Donc le nom $\mathtt{FACT}$ dans le $\lambda$-terme ci-dessus est juste une variable et n'est pas le $\lambda$-terme nomm茅 $\mathtt{FACT}$. + + +En programmation on dit souvent d'une fonction qu'elle est r茅cursive lorsqu'elle fait appel 脿 elle-m锚me, comme le fait la fonction `fact` ci-dessus. Et l'appel 脿 une fonction se fait par le nom de cette fonction. + +Comme en $\lambda$-calcul, il n'y a pas de nom, il semble, en apparence, que la d茅finition de $\lambda$-termes suivant un sch茅ma r茅cursif soit impossible. + +On va voir qu'il n'en est rien. + + +#### Avec une couche d'abstraction suppl茅mentaire + + +Dans l'essai de $\lambda$-terme pour d茅finir $\mathtt{FACT}$, rempla莽ons le nom $\mathtt{}$ par une variable, $f$ par exemple, et ajoutons une couche d'abstraction sur cette variable afin qu'elle soit li茅e. Nous obtenons un terme que nous nommerons $\Phi_{fact}$. + +$$ \Phi_{fact} = \lambda f.\lambda n.(((\mathtt{IF}\ (\mathtt{NUL}\ n))\ \lceil 1\rceil)\ ((\mathtt{MUL}\ n)\ (f\ (\mathtt{PRED}\ n)))).$$ + +Ce $\lambda$-terme est parfaitement valide. + +Mais, compte-tenu de la couche d'abstraction suppl茅mentaire, ce n'est certainement pas un terme candidat pour 锚tre le terme $\mathtt{FACT}$ que nous recherchons. ```python -M_PHI_FACT = Lambda_terme('!f.!n.(((IF ((EGAL n) ZERO)) UN) ((MUL n) (f (PRED n))))') +M_PHI_FACT = Lambda_terme('!f.!n.(((IF (NUL n)) UN) ((MUL n) (f (PRED n))))') print(M_PHI_FACT) -PHI_FACT = M_PHI_FACT.subs('IF', IF).subs('EGAL', EGAL).subs('ZERO', ZERO).subs('UN', UN).subs('MUL', MUL).subs('PRED', PRED) +PHI_FACT = M_PHI_FACT.subs('IF', IF).subs('NUL', NUL).subs('UN', UN).subs('MUL', MUL).subs('PRED', PRED) print(PHI_FACT) ``` +En fait pour envisager d'utiliser ce terme pour calculer des factorielles, il faut d'abord l'appliquer 脿 un terme (une fonction) $f$ puis appliquer 脿 un entier (de Church). Autrement dit suivre le sch茅ma + +$$((\Phi_{fact}\ f)\ \lceil n\rceil).$$ + +Mais quel terme (ou fonction) $f$ utiliser ? + + +Et si on commen莽ait par une fonction (un peu bizarre) nulle part d茅finie, ou dit en termes plus $\lambda$-calculesque, par un terme dont aucune application ne poss猫de une forme normale : + +$$ \mathtt{BOTTOM} = \lambda y.\Omega,$$ +o霉, pour rappel, $\Omega = (\lambda x.(x\ x)\ \lambda x.(x\ x))$ qui, comme on l'a vu, n'est pas normalisable. + +Il est clair que pour n'importe quel terme $M$, on a + +$$(\mathtt{BOTTOM}\ M) \rightarrow_\beta\Omega\rightarrow_\beta\Omega\rightarrow_\beta\ldots.$$ + ```python BOTTOM = Lambda_terme('!y.OMEGA').subs('OMEGA', OMEGA) print(BOTTOM) ``` ```python -FACT0 = PHI_FACT.applique(BOTTOM) +BOTTOM.applique(Lambda_terme('M')).forme_normale(verbose=True, nb_etapes_max=3) +``` + +Appliquons notre terme $\Phi_{fact}$ 脿 $\mathtt{BOTTOM}$, + +```python +F1 = PHI_FACT.applique(BOTTOM) +``` + +et appliquons ensuite le terme obtenu 脿 des entiers de Church. + +```python +F1.applique(ZERO).forme_normale() == UN ``` ```python -FACT0.applique(ZERO).forme_normale() == UN +F1.applique(UN).forme_normale(verbose=True, nb_etapes_max=20) +``` + +Le terme $F_1$ appliqu茅 脿 $\lceil 0\rceil$ donne $\lceil 1\rceil$. Mais, l'application 脿 tout autre entier de Church n'est pas normalisable. + +Autrement dit la fonction repr茅sent茅e par $F_1$ calcule bien $0! = 1$, ... et c'est tout. C'est tout de m锚me mieux que $\mathtt{BOTTOM}$ ! + +Continuons et d茅finissons $F_2 = (\Phi_{fact}\ F_1)$. + +```python +F2 = PHI_FACT.applique(F1) ``` ```python -FACT0.applique(UN).forme_normale(verbose=True, nb_etapes_max=20) +F2.applique(ZERO).forme_normale() == UN ``` ```python -FACT1 = PHI_FACT.applique(FACT0) +F2.applique(UN).forme_normale() == UN ``` ```python -FACT1.applique(ZERO).forme_normale() == UN +F2.applique(DEUX).forme_normale() +``` + +Le terme $F_2$ appliqu茅 脿 $\lceil n\rceil$, avec $n=0\mbox{ ou }1$ donne bien $\lceil n!\rceil$. Mais pour tout autre entier l'application n'est pas normalisable. On progresse. + +En fait si on d茅finit la suite de termes $F_n$ par r茅currence en posant + +\begin{align} + F_0 &= \mathtt{BOTTOM}\\ + F_1 &= (\Phi_{fact}\ F_0)\\ + F_2 &= (\Phi_{fact}\ F_1)\\ + \vdots\\ + F_{n+1} &= (\Phi_{fact}\ F_n) +\end{align} +chacun des termes de cette suite est en mesure de repr茅senter une fonction factorielle partielle. Plus pr茅cis茅ment, pour chaque entier $n$ on a + +$$ (F_n\ \lceil k\rceil) \twoheadrightarrow_\beta \lceil k!\rceil \mbox{ si } 0\leq k < n,$$ +et $(F_n\ \lceil k\rceil)$ n'est pas normalisable si $k\geq n$. + + +V茅rifions cela sur le terme $F_4$. + +```python +F4 = QUATRE.applique(PHI_FACT).applique(BOTTOM) ``` ```python -FACT1.applique(UN).forme_normale(nb_etapes_max=110) == UN +F4.applique(ZERO).forme_normale() == UN ``` ```python -FIX_CURRY = Lambda_terme('!f.(!x.(f (x x)) !x.(f (x x)))') -print(FIX_CURRY) +F4.applique(UN).forme_normale() == UN ``` ```python -FACTv2 = FIX_CURRY.applique(PHI_FACT) +F4.applique(DEUX).forme_normale(nb_etapes_max=244) == DEUX +``` + +```python +F4.applique(TROIS).forme_normale(nb_etapes_max=1510) == SIX +``` + +Avec le terme $\Phi_{fact}$, nous sommes en mesure de d茅finir des fonctions 芦 approximant 禄 de mieux en mieux la fonction factorielle, mais le proc茅d茅 it茅ratif d茅crit ne permet pas d'obtenir le terme $\mathtt{FACT}$ voulu. + +Remarquons n茅anmoins que si nous avons ce terme $\mathtt{FACT}$, alors on a + +$$ (\Phi_{fact}\ \mathtt{FACT}) \rightarrow_\beta + \lambda n.(((\mathtt{IF}\ (\mathtt{NUL}\ n))\ \lceil 1\rceil)\ ((\mathtt{MUL}\ n)\ (\mathtt{FACT}\ (\mathtt{PRED}\ n)))),$$ +qui est un terme correspondant exactement 脿 ce que nous recherchons depuis le d茅but. De cette r茅duction, on peut d茅duire que +$$ (\Phi_{fact}\ \mathtt{FACT}) =_\beta \mathtt{FACT},$$ +et cette 茅quivalence montre que le terme $\mathtt{FACT}$ que l'on recherche est un point fixe du terme $\Phi_{fact}$. Or on a vu comment construire un terme point fixe d'un autre. + +$$\mathtt{FACT} = (\lambda x.(\Phi_{fact}\ (x\ x))\ \lambda x.(\Phi_{fact}\ (x\ x))).$$ +Ce terme est un $\lambda$-terme valide qui v茅rifie pour tout entier $n\geq 0$ +$$(\mathtt{FACT}\ \lceil n\rceil) =_\beta \lceil n!\rceil.$$ + +```python +W = Lambda_terme('!x.(PHIFACT (x x))').subs('PHIFACT', PHI_FACT) +FACTv2 = Lambda_terme('(W W)').subs('W', W) +print(FACTv2) ``` ```python @@ -944,36 +1453,45 @@ FACTv2.applique(ZERO).forme_normale() == UN ``` ```python -FACTv2.applique(UN).forme_normale(nb_etapes_max=113) == UN +FACTv2.applique(UN).forme_normale() == UN ``` ```python -FACTv2.applique(DEUX).forme_normale(nb_etapes_max=516) == DEUX +FACTv2.applique(DEUX).forme_normale(nb_etapes_max=247) == DEUX ``` ```python -FACTv2.applique(TROIS).forme_normale(nb_etapes_max=2882) == SIX +FACTv2.applique(TROIS).forme_normale(nb_etapes_max=1524) == SIX ``` ```python -FACTv2.applique(QUATRE).forme_normale(nb_etapes_max=18668) == MUL.applique(QUATRE).applique(SIX).forme_normale() +FACTv2.applique(QUATRE).forme_normale(nb_etapes_max=10383) == int_en_church(24) +``` + +#### Combinateur de point fixe + + +Le combinateur de point fixe de Curry est d茅fini par + +$$ Y = \lambda f.(\lambda x.(f\ (x\ x))\ \lambda x.(f\ (x\ x))).$$ + +Il permet de construire un terme point fixe de n'importe quel terme $\Phi$, ce terme se d茅finissant par $F = (Y\ \Phi).$. En effet, + +$$ F = (Y\ \Phi) \rightarrow_\beta (\lambda x.(\Phi\ (x\ x))\ \lambda x.(\Phi\ (x\ x)) \rightarrow_\beta + (\Phi\ (\lambda x.(\Phi\ (x\ x)\ \lambda x.(\Phi\ (x\ x))),$$ +et +$$ (\Phi\ F) = (\Phi\ (Y\ \Phi)) \rightarrow_\beta + (\Phi\ (\lambda x.(\Phi\ (x\ x)\ \lambda x.(\Phi\ (x\ x))),$$ +ce qui permet de conclure que +$$ F =_\beta (\Phi\ F).$$ + +```python +Y = Lambda_terme('!f.(!x.(f (x x)) !x.(f (x x)))') +print(Y) ``` ```python -PF = FIX_CURRY.applique(Lambda_terme('M')) -``` - -```python -PF.forme_normale(verbose=True, nb_etapes_max=10) -``` - -```python -FIX_TURING = Lambda_terme('(!x.!y.(y ((x x) y)) !x.!y.(y ((x x) y)))') -print(FIX_TURING) -``` - -```python -FACTv3 = FIX_TURING.applique(PHI_FACT) +FACTv3 = Y.applique(PHI_FACT) ``` ```python @@ -981,30 +1499,248 @@ FACTv3.applique(ZERO).forme_normale() == UN ``` ```python -FACTv3.applique(UN).forme_normale(nb_etapes_max=114) == UN +FACTv3.applique(UN).forme_normale() == UN ``` ```python -FACTv3.applique(DEUX).forme_normale(nb_etapes_max=520) == DEUX +FACTv3.applique(DEUX).forme_normale(nb_etapes_max=248) == DEUX ``` ```python -FACTv3.applique(TROIS).forme_normale(nb_etapes_max=2897) == SIX +FACTv3.applique(TROIS).forme_normale(nb_etapes_max=1525) == SIX ``` ```python -FACTv3.applique(QUATRE).forme_normale(nb_etapes_max=18732) == MUL.applique(QUATRE).applique(SIX).forme_normale() +FACTv3.applique(QUATRE).forme_normale(nb_etapes_max=10384) == int_en_church(24) ``` +**Remarque** $Y$ n'est pas normalisable, et quelque soit le $\lambda$-terme $M$, $(Y\ M)$ ne l'est pas. Pourtant ces derniers termes peuvent s'av茅rer utiles. + +```python +PF = Y.applique(Lambda_terme('M')) +``` + +```python +PF.forme_normale(verbose=True, nb_etapes_max=10) +``` + +#### Un autre combinateur de point fixe + + +Voici un autre combinateur de point fixe, d没 脿 Turing. + +$$\Theta = (\lambda x.\lambda y.(y\ ((x\ x)\ y))\ \lambda x.\lambda y.(y\ ((x\ x)\ y))).$$ + +```python +THETA = Lambda_terme('(!x.!y.(y ((x x) y)) !x.!y.(y ((x x) y)))') +print(THETA) +``` + +Ce combinateur est un redex, et c'est le seul redex parmi ses sous-termes.une 茅tape de r茅duction donne + +$$ \Theta \rightarrow_\beta \lambda y.(y\ (\Theta\ y)).$$ + +Par cons茅quent, en r茅duisant le redex le plus 脿 gauche, en deux 茅tapes on obtient +$$ (\Theta\ \Phi) \rightarrow_\beta (\lambda y.(y\ (\Theta\ y))\ \Phi) \rightarrow_\beta + (\Phi\ (\Theta\ \Phi)).$$ +Ce qui 茅tablit que $\Theta$ est bien un combinateur de point fixe, mais aussi que contrairement 脿 $Y$ +$$ (\Theta\ \Phi) \twoheadrightarrow_\beta (\Phi\ (\Theta\ \Phi)).$$ + +```python +red_theta, _ = THETA.reduit() +print(red_theta) +``` + +```python +THETA.applique(Lambda_terme('PHI')).forme_normale(verbose=True, nb_etapes_max=2) +``` + +Utilisons $\Theta$ pour d茅finir une quatri猫me version de $\mathtt{FACT}$. + +```python +FACTv4 = THETA.applique(PHI_FACT) +``` + +```python +FACTv4.applique(ZERO).forme_normale() == UN +``` + +```python +FACTv4.applique(UN).forme_normale() == UN +``` + +```python +FACTv4.applique(DEUX).forme_normale(nb_etapes_max=252) == DEUX +``` + +```python +FACTv4.applique(TROIS).forme_normale(nb_etapes_max=1540) == SIX +``` + +```python +FACTv4.applique(QUATRE).forme_normale(nb_etapes_max=10448) == int_en_church(24) +``` + +Au titre d'un autre exemple, envisageons maintenant d'茅tablir un $\lambda$-terme qui permet de calculer la longueur d'une liste. + +La longueur d'une liste s'exprime r茅cursivement par + +\begin{align} + \mbox{long(<>)} &= 0\\ + \mbox{long()} &= 1 + \mbox{long(L)}. +\end{align} + +Avec une couche d'abstraction suppl茅mentaire nous d茅finissons le terme + +$$\Phi_{long} = \lambda f.\lambda l.(((\mathtt{IF}\ (\mathtt{LESTVIDE}\ l))\ \mathtt{ZERO})\ (\mathtt{SUC}\ (f\ (\mathtt{LCDR}\ l)))).$$ + +```python +M_PHI_LONG = Lambda_terme('!f.!l.(((IF (LESTVIDE l)) ZERO)(SUC (f (LCDR l))))') +print(M_PHI_LONG) +PHI_LONG = M_PHI_LONG.subs('IF', IF).subs('LESTVIDE', LESTVIDE).subs('ZERO', ZERO).subs('SUC', SUC).subs('LCDR', LCDR) +``` + +D茅finissions le terme $\mathtt{LONG}$ 脿 l'aide de l'un ou l'autre de nos deux combinateurs de point fixe. + +$$ \mathtt{LONG} = (\Theta\ \Phi_{long}).$$ + +```python +LONG = THETA.applique(PHI_LONG) +``` + +```python +LONG.applique(LVIDE).forme_normale() == ZERO +``` + +```python +M1 = Lambda_terme('M1') +M2 = Lambda_terme('M2') +M3 = Lambda_terme('M3') +L = LCONS.applique(M1).applique(LCONS.applique(M2).applique(LCONS.applique(M3).applique(LVIDE))) +LONG.applique(L).forme_normale(nb_etapes_max=135) == TROIS +``` + +#### Et la boucle `while` ? + + +Bien ! on voit comment construire un $\lambda$-terme exprimant un algorithme r茅cursif. Mais comment exprimer une it茅ration conditionnelle (boucle `while`) ? + + +La r茅ponse tient simplement dans le fait qu'une it茅ration conditionnelle s'exprime g茅n茅ralement en suivant le sch茅ma + +~~~python +while p(e): + e = t(e) +~~~ +dans lequel + +* `e` d茅signe l'茅tat courant des variables, +* `p(e)` exprime une condition d茅pendant de l'茅tat courant +* et `t(e)` est un traitement pouvant modifier l'茅tat courant. + +Ce sch茅ma peut 锚tre reformul茅 de mani猫re r茅cursive en 茅crivant + +~~~python +def tq(e): + if p(e): + e = t(e) + return tq(e) + else: + return e +~~~ + + +Il suffit donc de consid茅rer le $\lambda$-terme + +$$\Phi_{while} = \lambda f.\lambda p.\lambda t.\lambda e.(((\mathtt{IF}\ (p\ e))\ (((f\ p)\ t)\ (t\ e))\ e),$$ + +puis de d茅finir le terme + +$$ \mathtt{WHILE} = (Y\ \Phi_{while}),$$ +ou +$$ \mathtt{WHILE} = (\Theta\ \Phi_{while}).$$ + +```python +M_PHI_WHILE = Lambda_terme('!f.!p.!t.!e.(((IF (p e)) (((f p) t) (t e))) e)') +PHI_WHILE = M_PHI_WHILE.subs('IF', IF) +WHILE = Y.applique(PHI_WHILE) +``` + +Pour terminer, utilisons notre terme $\mathtt{WHILE}$ pour construire une terme permettant de calculer la division euclidienne de deux entiers, derni猫re op茅ration arithm茅tique de base que nous n'avons pas r茅alis茅e. + + +On veut un terme $\mathtt{DIV}$ qui comme la fonction `divmod` de Python donne, sous forme d'un couple, le quotient et le reste de la division d'un entier $m$ par un entier $n$. + +On pourrait programmer cette fonction en Python de cette fa莽on : + +~~~python +def divmod(m, n): + q, r = 0, m + while r >= n: + q, r = q + 1, r - n + return (q, r) +~~~ +Dans cet algorithme +* l'茅tat `e` est le triplet de variables `(q, r, n)` +* la condition `p(e)` est exprim茅e par l'in茅galit茅 `r >= n` +* et le traitement `t(e)` modifiant l'茅tat courant est le construction du couple `(q + 1, r - n, n)`. + +\begin{align} + P &= \lambda e.((\mathtt{INF}\ (\mathtt{CDR}\ (\mathtt{CDR}\ e))) (\mathtt{CAR}\ (\mathtt{CDR}\ e)))\\ + T &= \lambda e.((\mathtt{CONS}\ (\mathtt{SUC}\ (\mathtt{CAR}\ e))) ((\mathtt{CONS}\ ((\mathtt{SUB}\ (\mathtt{CAR}\ (\mathtt{CDR}\ e))) (\mathtt{CDR}\ (\mathtt{CDR}\ e)))) (\mathtt{CDR}\ (\mathtt{CDR}\ e))))\\ + \mathtt{DIVMOD} &= \lambda m.\lambda n.((((\mathtt{WHILE}\ P))\ T)\ [\lceil 0\rceil, [m, n]]). +\end{align} + +```python +M_P = Lambda_terme('!e.((INF (CDR (CDR e))) (CAR (CDR e)))') +print(M_P) +P = M_P.subs('INF', INF).subs('CAR', CAR).subs('CDR', CDR) +M_T = Lambda_terme('!e.((CONS (SUC (CAR e))) ((CONS ((SUB (CAR (CDR e))) (CDR (CDR e)))) (CDR (CDR e))))') +print(M_T) +T = M_T.subs('CONS', CONS).subs('CAR', CAR).subs('CDR', CDR).subs('SUC', SUC).subs('SUB', SUB) +M_DIVMOD = Lambda_terme('!m.!n.(((WHILE P) T) ((CONS ZERO) ((CONS m) n)))') +print(M_DIVMOD) +DIVMOD = M_DIVMOD.subs('WHILE', WHILE).subs('P', P).subs('T', T).subs('CONS', CONS).subs('ZERO', ZERO) +print(DIVMOD) +``` + +```python +%%time +tests = [] +for a in range(10): + for b in range(1, 10): + q, r = divmod(a, b) + A, B = int_en_church(a), int_en_church(b) + Q, R = int_en_church(q), int_en_church(r) + res = DIVMOD.applique(A).applique(B).forme_normale(nb_etapes_max=10000) + #print(res) + tests.append((a, b, res == CONS.applique(Q).applique(CONS.applique(R).applique(B)).forme_normale())) +all(t[2] for t in tests) +``` + +## Conclusion + + +Nous arr锚tons l脿 ce premier contact avec le $\lambda$-calcul. + +Nous avons vu que ce langage tr猫s 茅l茅mentaire, avec l'abstraction et l'application pour seules constructions, et la r猫gle de $\beta$-r茅duction pour seule transformation de $\lambda$-termes, permet de repr茅senter les donn茅es de base de n'importe quel langage de programmation, les bool茅ens, les entiers, les couples, les listes, et permet d'exprimer les expressions conditionnelles, les it茅rations conditionnelles ou non, et la r茅cursivit茅. En fait le $\lambda$-calcul est un langage Turing-complet ... m锚me s'il est particuli猫rement inefficace. + +D'autres sujets relatifs au $\lambda$-calcul n'ont pas 茅t茅 abord茅s : + +* strat茅gies de r茅duction : paresseuse, par valeurs ..., et leurs cons茅quences. +* $\lambda$-calcul typ茅. + + # $\lambda$-calcul avec les lambda-expressions de Python - + Dans cette partie, les lambda-expressions de Python vont 锚tre utilis茅es pour repr茅senter les abstractions, et les applications seront des appels de fonction. Les seuls mots du langage Python que nous utiliserons seront `lambda` et `if`. Les autres mots (`def`, `while`, `for` ...) seront bannis. Nous utiliserons aussi les entiers pr茅d茅finis dans le langage avec certaines op茅rations arithm茅tiques. - + ## Les bool茅ens + ```python vrai = lambda x: lambda y: x @@ -1062,7 +1798,9 @@ tuple(booleen_en_bool(ou(b1)(b2)) for b1 in (vrai, faux) for b2 in (vrai, faux)) ``` + ## Les entiers de Church + ```python zero = lambda f: lambda x: x @@ -1150,7 +1888,9 @@ tuple(booleen_en_bool(est_nul(n)) for n in (zero, un, deux, trois, cinq, six, huit)) ``` + ## Les couples + ```python cons = lambda x: lambda y: lambda z: z(x)(y) @@ -1203,7 +1943,9 @@ tuple(booleen_en_bool(est_egal(cinq)(int_en_entier_church(n))) for n in range(10)) ``` + ## It茅ration + ```python fact = lambda n: cdr(n(lambda c: (cons(suc(car(c)))(mul(suc(car(c)))(cdr(c)))))(cons(zero)(un))) @@ -1213,7 +1955,9 @@ fact = lambda n: cdr(n(lambda c: (cons(suc(car(c)))(mul(suc(car(c)))(cdr(c)))))( tuple(entier_church_en_int(fact(int_en_entier_church(n))) for n in range(7)) ``` + ## Combinateur de point fixe + ```python phi_fact = lambda f: lambda n: 1 if n == 0 else n*f(n-1) @@ -1263,7 +2007,9 @@ fact3 = fix_curry(phi_fact) tuple(fact3(n) for n in range(7)) ``` + ## Un programme obscur + ```python print((lambda x: (lambda y: lambda z: x(y(y))(z))(lambda y: lambda z: x(y(y))(z))) diff --git a/lambda_calcul.py b/lambda_calcul.py index 2a90c1b..5101a89 100644 --- a/lambda_calcul.py +++ b/lambda_calcul.py @@ -224,7 +224,7 @@ class Lambda_terme(): def __eq__(self, terme): if not isinstance(terme, Lambda_terme): - raise Lambda_termeError('Comparaison inpossible impossible') + raise Lambda_termeError('Comparaison impossible') if self.est_variable(): return terme.est_variable() and self._content[1] == terme._content[1] elif self.est_application(): @@ -350,8 +350,8 @@ class Lambda_terme(): while not forme_normale_atteinte and etape < nb_etapes_max: etape += 1 terme_reduit, est_reduit = lambda_terme.reduit() - if verbose: print('{:3d}: ---> {:s}'.format(etape, str(lambda_terme), str(terme_reduit))) - forme_normale_atteinte = not est_reduit + if verbose: print('{:3d}: ---> {:s}'.format(etape, str(terme_reduit))) + forme_normale_atteinte = terme_reduit.est_forme_normale() lambda_terme = terme_reduit if forme_normale_atteinte: if verbose: print('Forme normale calcul茅e : {:s}'.format(str(terme_reduit)))