{ "cells": [ { "cell_type": "markdown", "metadata": { "toc": "true" }, "source": [ "# Table of Contents\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Texte d'oral de modélisation - Agrégation Option Informatique\n", "## Préparation à l'agrégation - ENS de Rennes, 2017-18\n", "- *Date* : 6 décembre 2017\n", "- *Auteur* : [Lilian Besson](https://GitHub.com/Naereen/notebooks/)\n", "- *Texte*: Annale 2018, [\"Expressions arithmétiques\" (public2018-D1)](http://agreg.org/Textes/public2018-D1.pdf)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## À propos de ce document\n", "- Ceci est une *proposition* de correction, partielle et probablement non-optimale, pour la partie implémentation d'un [texte d'annale de l'agrégation de mathématiques, option informatique](http://Agreg.org/Textes/).\n", "- Ce document est un [notebook Jupyter](https://www.Jupyter.org/), et [est open-source sous Licence MIT sur GitHub](https://github.com/Naereen/notebooks/tree/master/agreg/), comme les autres solutions de textes de modélisation que [j](https://GitHub.com/Naereen)'ai écrite cette année.\n", "- L'implémentation sera faite en OCaml, version 4+ :" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The OCaml toplevel, version 4.04.2\n" ] }, { "data": { "text/plain": [ "- : int = 0\n" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" }, { "name": "stdout", "output_type": "stream", "text": [ "4.04.2\n" ] }, { "data": { "text/plain": [ "- : unit = ()\n" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Sys.command \"ocaml -version\";;\n", "print_endline Sys.ocaml_version;;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "## Question de programmation\n", "La question de programmation pour ce texte était donnée en fin de page 6 :\n", "\n", "### Modélisation\n", "On est libre de choisir l'implémentation qui nous convient pour les expressions arithmétiques sous forme arborescente.\n", "\n", "Je choisis de ne considérer que les variables et pas les valeurs (on aura des expressions en OCaml comme `F(\"x\")` pour la variable $x$), et uniquement des arbres binaires.\n", "Les noeuds `N(t1, op, t2)` sont étiquetées par un opérateur binaire `op`, dont on fournit à l'avance une liste fixée et finie, et les feuilles `F(s)` sont étiquetées par une variable `s`.\n", "\n", "### Exercice\n", "> « Écrire une fonction qui reçoit en argument une expression algébrique donnée sous forme\n", "arborescente et décore cette expression en calculant pour chaque nœud interne quelle est\n", "la valeur du paramètre ρ et quelle branche doit être évaluée en premier selon l’algorithme\n", "d’Ershov. »" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "## Solution\n", "\n", "On va essayer d'être rapide et de faire simple, donc on choisit une algèbre de termes particulière, mais l'algorithme d'Ershov sera implémenté de façon générique (polymorphique, peu importe la valeur de `op`)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Types et représentations" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "type operateur =\n", " Plus\n", " | Moins\n", " | MoinsDroite\n", " | Mul\n", " | Div\n", " | DivDroite\n", " | Modulo\n", " | Expo\n" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type operateur = Plus | Moins | MoinsDroite | Mul | Div | DivDroite | Modulo | Expo ;;\n", "(* On utilisera MoinsDroite et DivDroite pour la compilation avec la méthode d'Ershov *)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "type ('a, 'b) arbre_binaire =\n", " N of ('a, 'b) arbre_binaire * 'b * ('a, 'b) arbre_binaire\n", " | F of 'a\n" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type ('a, 'b) arbre_binaire = N of (('a,'b) arbre_binaire) * 'b * (('a,'b) arbre_binaire) | F of 'a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Par exemple pour l'expression $\\frac{x - yz}{u - vw}$, c'est-à-dire `(x - y*z)/(u - v*w)` :" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "val exp1 : (string, operateur) arbre_binaire =\n", " N (F \"x\", Moins, N (F \"y\", Mul, F \"z\"))\n" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(* exp1 = (x - y*z) *)\n", "let exp1 =\n", "N(\n", " F(\"x\"),\n", " Moins,\n", " N(\n", " F(\"y\"),\n", " Mul,\n", " F(\"z\")\n", " )\n", ")\n", ";;" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "val exp2 : (string, operateur) arbre_binaire =\n", " N (F \"u\", Moins, N (F \"v\", Mul, F \"w\"))\n" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(* exp2 = (u - v*w) *)\n", "let exp2 =\n", "N(\n", " F(\"u\"),\n", " Moins,\n", " N(\n", " F(\"v\"),\n", " Mul,\n", " F(\"w\")\n", " )\n", ")\n", ";;" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "val exp3 : (string, operateur) arbre_binaire =\n", " N (N (F \"x\", Moins, N (F \"y\", Mul, F \"z\")), Div,\n", " N (F \"u\", Moins, N (F \"v\", Mul, F \"w\")))\n" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(* exp3 = (x - y*z)/(u - v*w) *)\n", "let exp3 =\n", "N(\n", " exp1,\n", " Div,\n", " exp2\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Calcul récursif du nombre $\\rho$\n", "\n", "C'est assez immédiat, en suivant la définition récursive :\n", "$\\rho(F) = 0$ et $\\rho(N(t_1, t_2)) = \\rho(t_1) + 1$ si $\\rho(t_1) = \\rho(t_2)$ et $\\max(\\rho(t_1), \\rho(t_2))$ si $\\rho(t_1) \\neq \\rho(t_2)$. " ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "val nombre_rho : ('a, 'b) arbre_binaire -> int =