{ "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, 2016-17\n", "- *Date* : 09 mai 2017\n", "- *Auteur* : [Lilian Besson](https://GitHub.com/Naereen/notebooks/)\n", "- *Texte*: Annale 2012, [\"Mots bien formés\"](http://agreg.org/Textes/public2012-D6.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": true }, "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" } ], "source": [ "Sys.command \"ocaml -version\";;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "## Question de programmation\n", "La question de programmation pour ce texte était donnée à la fin, en page 7 :\n", "\n", "> « Programmer la reconnaissance des mots bien formés en écriture préfixe sur la signature de\n", "l’exemple du texte à l’aide du critère fourni par le théorème 3 page 5. Il est conseillé de représenter le mot à valider sous forme d’un tableau ou d’une liste de caractères. »\n", "\n", "Mathématiquement, l'énoncé à implémenter sous forme d'un critère est le suivant :\n", "\n", "### Théorème 3\n", "> Pour que la suite de symboles $s_1,\\dots,s_n \\in \\Omega$ soit l'écriture *préfixe* d'un terme, il faut et il suffit que les $h_p := \\sum_{i=1}^{p} (1 - \\alpha(s_i))$ vérifient :\n", "> $$ h_1,\\dots,h_{n-1} \\leq 0 \\; \\text{et} \\; h_n = 1. $$\n", "\n", "\n", "### Choix d'implémentation\n", "- Ce critère numérique va être très simple à implémenter.\n", "\n", "- Le choix des structures de données à utiliser n'est cependant pas évident.\n", " + Le sujet suggérait d'utiliser un tableau ou une liste de caractères pour représenter la \"suite de symboles\" $s_1,\\dots,s_n \\in \\Omega$\n", " + On va définir un type formel pour l'alphabet $\\Omega$, avec l'exemple du texte, $\\Omega = \\{V, F, \\mathrm{Non}, \\mathrm{Ou}, \\mathrm{Et}, \\mathrm{ITE}\\}$.\n", " + On doit ensuite représenter l'arité, sous forme de tableau, table d'association ou de hashage, ou une fonction, qui permette d'associer un entier $\\alpha(s)$ à chaque symbole $s$. Par simplicité, on choisit d'utiliser une fonction : $\\alpha : \\Omega \\to \\mathbb{N}, s \\mapsto \\alpha(s)$.\n", " + Enfin, la fonction demandée sera récursive, et très rapide à écrire." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "## Réponse à l'exercice requis" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Symboles et arités\n", "On définit :\n", "- les symboles du calcul propositionnel par un type énumération (abstrait) :\n", " $$ \\Omega = \\{V, F, \\mathrm{Non}, \\mathrm{Ou}, \\mathrm{Et}, \\mathrm{ITE}\\} $$\n", " $\\mathrm{ITE}$ correspond au \"If then else\" ternaire (`a ? b : c` en C, `if a then b else c` en OCaml, ou `b if a else c` en Python).\n", "- Et les formules du calcul propositionnel comme une *liste* de symboles." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "type symbole_calcul_prop = F | V | Ou | Et | Non | ITE\n" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "type formule_calcul_prop = symbole_calcul_prop list\n" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type symbole_calcul_prop = F | V | Ou | Et | Non | ITE ;;\n", "\n", "type formule_calcul_prop = symbole_calcul_prop list ;;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Quelques exemples de formules du calcul propositionnel, écrites sous forme préfixes, bien formées ou non :\n", "\n", "- \"$\\mathrm{Ou} \\; \\mathrm{Non} \\; \\mathrm{Ou} \\; F \\; V \\; \\mathrm{Ou} \\; \\mathrm{Non} \\; V \\; F\"$ $\\equiv (\\neg(F \\vee V)) \\vee ((\\neg V) \\vee F)$ est bien formé,\n", "- \"$\\mathrm{Ou} \\; \\mathrm{Non} \\; F \\; \\mathrm{Non}$\" est mal formé,\n", "- \"$\\mathrm{ITE} \\; V \\; F \\; V$\" un exemple de \"If then else\" bien formé,\n", "- \"$\\;$\" la formule vide." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "val ex_correct : symbole_calcul_prop list =\n", " [Ou; Non; Ou; F; V; Ou; Non; V; F]\n" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "val ex_incorrect : symbole_calcul_prop list = [Ou; Non; F; Non]\n" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "val ex_ite : symbole_calcul_prop list = [ITE; V; F; V]\n" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "val ex_vide : 'a list = []\n" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "let ex_correct = [Ou; Non; Ou; F; V; Ou; Non; V; F];;\n", "let ex_incorrect = [Ou; Non; F; Non];;\n", "let ex_ite = [ITE; V; F; V];;\n", "let ex_vide = [];;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cette fonction donne l'arité du symbole du calcul propositionnel pris en argument.\n", "\n", "- $V$ et $F$ ont arités $\\alpha = 0$,\n", "- $\\mathrm{Non}$ a arité $\\alpha = 1$,\n", "- $\\mathrm{Et}$ et $\\mathrm{Ou}$ ont arités $\\alpha = 2$,\n", "- $\\mathrm{ITE}$ a arité $\\alpha = 3$.\n", "\n", "Autrement dit, avec les notations du texte :\n", "$$ S = \\Omega = S_0 \\sqcup S_1 \\sqcup S_2 \\sqcup S_3 \\\\\n", "\\begin{cases}\n", " S_0 &= \\{ V, F \\}, \\\\\n", " S_1 &= \\{ \\mathrm{Non} \\}, \\\\\n", " S_2 &= \\{ \\mathrm{Et}, \\mathrm{Ou} \\}, \\\\\n", " S_3 &= \\{ \\mathrm{ITE} \\}.\n", "\\end{cases}\n", "$$\n", "\n", "> Notez qu'on peut supposer que l'appel à cette fonction d'arité se fait en $\\mathcal{O}(1)$ dans les calculs de complexité, puisqu'après compilation, cette fonction sera une simple lecture d'un tableau." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "val arite_calcul_prop : symbole_calcul_prop -> int =