J-0
00m
00j
00h
00min
00s

Version interactive avec LaTeX compilé

Mines Option Informatique MP 2015

Notez ce sujet en cliquant sur l'étoile
0.0(0 votes)
Logo mines
2025_08_29_0e682df7716ab42f41f1g
A 2015 INFO. MP
École DES Ponts ParisTech, SUPAERO (ISAE), ENSTA PARISTECH, TÉLÉCOM PARISTECH, MINES PARISTECH, MINES DE SAINT-ÉTIENNE, MINES NANCY, TÉLÉCOM BRETAGNE, ENSAE PARISTECH (FILIERE MP), ÉCOLE POLYTECHNIQUE (FILIÈRE TSI)
Concours 2015
Épreuve d'Informatique
Filière: MP
Durée de l'épreuve: 3 heures.
L'utilisation d'une calculatrice est autorisée.

Sujet mis à la disposition des concours:Cycle international, Écoles des Mines, Télécom Sud Paris, TPE-Eivp.L'énoncé de cette épreuve comporte 10 pages.Les candidats sont priés de mentionner de façon apparentesur la première page de la copie:INFORMATIQUE - MP

Recommandations aux candidats

  • Si, au cours de l'épreuve, un candidat repère ce qui lui semble être une erreur d'énoncé, il le signale sur sa copie et poursuit sa composition en expliquant les raisons des initiatives qu'il est amené à prendre.
  • Tout résultat fourni dans l'énoncé peut être utilisé pour les questions ultérieures même s'il n'a pas été démontré.
  • Il ne faut pas hésiter à formuler les commentaires qui semblent pertinents même lorsque l'énoncé ne le demande pas explicitement.

Composition de l'épreuve

L'épreuve comporte un unique problème (pages 2 à 10), comportant 32 questions.

Problème : Automates d'arbre

Préliminaire concernant la programmation

Il faudra coder des fonctions à l'aide du langage de programmation Caml, tout autre langage étant exclu. Lorsque le candidat écrira une fonction, il pourra faire appel à d'autres fonctions définies dans les questions précédentes; il pourra aussi définir des fonctions auxiliaires. Quand l'énoncé demande de coder une fonction, il n'est pas nécessaire de justifier que celle-ci est correcte, sauf si l'énoncé le demande explicitement. Enfin, si les paramètres d'une fonction à coder sont supposés vérifier certaines hypothèses, il ne sera pas utile dans l'écriture de cette fonction de tester si les hypothèses sont bien vérifiées.
Dans les énoncés du problème, un même identificateur écrit dans deux polices de caractères différentes désignera la même entité, mais du point de vue mathématique pour la police en italique (par exemple ) et du point de vue informatique pour celle en romain avec espacement fixe (par exemple n ).

Fonctions utilitaires

Dans cette partie, on code quelques fonctions générales qui seront utiles par la suite. On ne cherchera pas à proposer l'implémentation la plus efficace possible de chaque fonction.
Quand il est question de donner la complexité d'une fonction, il s'agit de calculer la complexité asymptotique en temps, en notation , de cette fonction dans le pire des cas. Il est inutile de donner une preuve de cette complexité.
- Coder une fonction Caml contient: 'a list -> 'a -> bool telle que contient li x renvoie un booléen qui vaut Vrai si et seulement si la liste li contient l'élément x . Donner la complexité de cette fonction.
- En utilisant la fonction contient, coder une fonction Caml union: 'a list -> 'a list -> 'a list telle que union 1112 , où 11 et 12 sont deux listes d'éléments sans doublon dans un ordre arbitraire, renvoie une liste sans doublon contenant l'union des éléments des deux listes, dans un ordre arbitraire. Donner la complexité de cette fonction.
- En utilisant la fonction union, coder une fonction Caml fusion: 'a list list -> 'a list telle que fusion 1 , où 1 est une liste de listes d'éléments, chacune de ces listes étant sans doublon, renvoie une liste de tous les éléments contenus dans au moins une des listes de la liste 1 , sans doublon et dans un ordre arbitraire. En notant la liste codée par 1 et en posant , donner la complexité de la fonction fusion en fonction de .
- Coder produit: 'a list -> 'b list -> ('a * 'b) list, telle que produit 1112 renvoie une liste de tous les couples ( ) avec x un élément de 11 et y un élément de 12 . On supposera les listes 11 et 12 sans doublon. La liste résultante doit avoir pour longueur le produit des longueurs des deux listes. Donner la complexité de cette fonction.

Arbres binaires étiquetés

Soit un ensemble fini non vide de symboles, appelé alphabet. En Caml, on représentera le symbole (pour ) par l'entier . Cet alphabet sera supposé fixé dans tout l'énoncé.
Un arbre binaire étiqueté par (simplement appelé, dans ce problème, arbre) est soit l'arbre vide (noté ), soit un quintuplet ( ), où :
(i) est un ensemble fini non vide dont les éléments sont appelés nœuds;
(ii) est la racine de ;
(iii) est une application associant à chaque nœud de une étiquette de ;
(iv) , où , est une application injective associant à un noeud de un noeud appelé fils gauche de ;
(v) , où , est une application injective associant à un noud de un nœud appelé fils droit de .
On dit qu'un nœud est descendant d'un nœud s'il existe une séquence de nœuds avec telle que et, pour tout , soit , soit .
On requiert que tout nœud sauf la racine soit le fils gauche ou droit d'un unique nœud, et qu'aucun nœud ne soit à la fois fils gauche et fils droit :
Par ailleurs, tout nœud de doit être descendant de .
Un arbre admet une représentation graphique naturelle. Par exemple, l'arbre est représenté ci-contre, avec :
On utilisera en Caml le type de données suivant pour coder un arbre :
type Arbre = Noeud of Noeud | Vide
    and Noeud = { etiquette: int; gauche: Arbre; droit: Arbre; };;
Dans ce codage, un arbre non vide est représenté par une instance du type Noeud décrivant sa racine; un nœud est décrit par son étiquette (codée comme un entier), son fils gauche, son fils droit; le fils gauche et le fils droit peuvent, à nouveau, être décrits par une instance du type Noeud, ou par le constructeur Vide, qui décrit leur absence.
Par exemple, l'arbre pourra être décrit par la variable to comme suit :
let t0 = Noeud {
    etiquette=1;
    gauche=Noeud
        {etiquette=1; gauche=Vide; droit=Vide};
    droit=Noeud
        {etiquette=0;
            gauche=Noeud {etiquette=1; gauche=Vide; droit=Vide};
            droit=Vide}
};;;
5 - Pour simplifier l'écriture d'arbres, coder en Caml une fonction arbre telle que si x représente une étiquette et ag et ad représentent deux arbres et , alors arbre x ag ad représente un arbre dont la racine est étiquetée par , avec pour fils gauche la racine de (avec ses propres fils) et pour fils droit la racine de (avec ses propres fils). Ainsi, cette fonction doit permettre de construire avec :
let t0 = arbre 1 (arbre 1 Vide Vide)
    (arbre 0 (arbre 1 Vide Vide) Vide);;
- Coder en Caml une fonction taille_arbre prenant en argument une variable t représentant un arbre et renvoyant le nombre de nœuds de l'arbre .

Langages d'arbres

Soit l'ensemble de tous les arbres étiquetés par . Un langage d'arbres sur un alphabet est un ensemble (fini ou infini) d'arbres étiquetés par , c'est-à-dire un sous-ensemble de .
On considère dans ce problème certains langages particuliers, tous définis sur l'alphabet :
  • est l'ensemble des arbres dont au moins un nœud est étiqueté par .
  • Un arbre est complet s'il ne contient aucun nœud ayant un seul fils (c'est-à-dire, tout nœud a un fils gauche si et seulement s'il a un fils droit); conventionnellement, est considéré comme complet. Le langage est l'ensemble de tous les arbres complets.
  • Un arbre ( ) est un arbre-chaîne s'il a uniquement des fils gauches : ; conventionnellement, est également un arbre-chaîne. Le langage î est l'ensemble de tous les arbres-chaînes.
  • Un arbre ( ) est impartial s'il a autant de fils gauches que de fils droits, c'est-à-dire si on a ; conventionnellement, est également impartial. On note l'ensemble de tous les arbres impartiaux.
    - Pour chacun des quatre langages î, donner (sans justification) un exemple d'arbre avec au moins deux nœuds qui appartient au langage, et un exemple d'arbre avec au moins deux nœuds qui n'y appartient pas.
    - Démontrer que tout arbre complet est impartial, mais que la réciproque est fausse.
    - Démontrer que tout arbre impartial non vide a un nombre impair de nœuds.

Automates d'arbres descendants déterministes

Un automate d'arbres descendant déterministe (ou simplement automate descendant déterministe) sur l'alphabet est un quadruplet où :
(i) est un ensemble fini non vide dont les éléments sont appelés états;
(ii) est appelé état initial ;
(iii) est un ensemble dont les éléments sont appelés états finals;
(iv) est une application appelée fonction de transition; pour tout , pour tout est un couple d'états .
Un automate descendant déterministe reconnaît un arbre si :
  • soit et ;
  • soit et il existe une application avec :
    (i) ;
    (ii) pour tout , si :
  • si est défini , alors on a , sinon on a ;
  • si est défini , alors on a , sinon on a .
Noter que quand une telle application existe, elle est nécessairement unique.
Le langage reconnu par un automate descendant déterministe , noté , est l'ensemble de tous les arbres reconnus par .
- Donner un automate descendant déterministe reconnaissant le langage î; aucune justification n'est demandée.
- Montrer qu'il n'existe pas d'automate descendant déterministe qui reconnaît .
En Caml, un état de est codé par l'entier . L'ensemble des états finals est codé par un vecteur de booléens finals_desc de taille , tel que finals_desc. (i) contient Vrai si et seulement si . Enfin, les transitions sont codées par une matrice de couples d'entiers, telle que transitions_desc.(i).(k) est le couple vérifiant .
On représente ainsi en Caml un automate descendant déterministe ( ) avec le type suivant :
type Automate_Descendant_Deterministe = {
    finals_desc: bool vect;
    transitions_desc: (int*int) vect vect
};;;
12 - Pour un automate descendant déterministe et , on note l'automate descendant déterministe ( ) identique à sauf pour l'état initial. Coder une fonction applique_desc telle que applique_desc add q t , où add représente un automate descendant déterministe , q un état et t un arbre , renvoie un booléen qui vaut Vrai si et seulement reconnait .
- En utilisant applique_desc, coder une fonction evalue_desc telle que evalue_desc add t, où add représente un automate descendant déterministe et t un arbre , renvoie un booléen qui vaut Vrai si et seulement si reconnaît .

Automates descendants et langages rationnels de mots

À tout mot non vide avec , on associe un arbre-chaîne vérifiant : pour et pour , n'étant défini pour aucun , et étant non défini. Par convention, chaîne (où le premier est le mot vide, le second l'arbre vide).
Pour un langage de mots , on définit le langage d'arbres chaîne chaîne .
- Soit un langage de mots, supposé rationnel. Il existe donc un automate de mots déterministe reconnaissant . Soient . On construit l'automate d'arbres descendant déterministe avec pour et, pour et pour . Démontrer que reconnaît chaîne .
- Montrer que pour tout langage de mots , si chaîne est reconnu par un automate d'arbres descendant déterministe, alors est rationnel.
- Soit é le langage de mots sur l'alphabet formé des mots contenant autant de que de . Supposons par l'absurde qu'il existe un automate (de mots) déterministe é reconnaissant é et soit le nombre d'états de é. En considérant le mot , montrer que l'on aboutit à une contradiction, et que donc é n'est pas un langage rationnel.
En déduire qu'il n'existe aucun automate descendant déterministe reconnaissant é.

Automates d'arbres ascendants

Un automate d'arbres ascendant (ou simplement automate ascendant) sur l'alphabet est un quadruplet où :
(i) est un ensemble fini non vide dont les éléments sont appelés états;
(ii) est un ensemble dont les éléments sont appelés états initiaux;
(iii) est un ensemble dont les éléments sont appelés états finals;
(iv) , où désigne l'ensemble des parties de , est une application appelée fonction de transition; pour tout , et tout est un ensemble d'états.
Par exemple, on définit un automate ascendant sur l'alphabet avec :
(i) ;
(ii) ;
(iii) ;
(iv) est donnée par la table de transition suivante :
Un automate ascendant reconnaît un arbre si :
  • soit et ;
  • soit et il existe une application avec :
    (i) ;
    (ii) pour tout , il existe tels que et :
  • si est défini , alors on a , sinon ;
  • si est défini , alors on a , sinon .
Noter que, contrairement au cas des automates descendants déterministes, quand une telle application existe, elle n'est pas nécessairement unique.
On observe que ne reconnaît pas et que reconnaît l'arbre défini page 3 via l'application représentée ci-dessous :
Le langage reconnu par un automate ascendant , noté , est l'ensemble de tous les arbres reconnus par . On dit qu'un langage d'arbres est rationnel s'il existe un automate ascendant qui reconnaît .
On dit qu'un automate ascendant ( ) est déterministe si et, pour tout .
- Montrer que l'on a .
- Soit un langage d'arbres. Montrer que s'il existe un automate descendant déterministe reconnaissant , alors est un langage d'arbres rationnel.
En Caml, un état de est codé par l'entier . L'ensemble des états initiaux est codé par leur liste initiaux_asc, dans un ordre arbitraire; l'ensemble des états finals est codé par un vecteur de booléens finals_asc de taille , dont la composante de position contient Vrai si et seulement si . Finalement, les transitions sont codées par un tableau tridimensionnel de listes d'entiers, telle que transitions_asc. (i). (j). (k) est une liste dans un ordre arbitraire des états q avec .
On représente ainsi en Caml un automate ascendant ( ) avec le type cidessous :
type Automate_Ascendant = {
    initiaux_asc: int list;
    finals_asc: bool vect;
    transitions_asc: int list vect vect vect
};;;
L'automate peut alors être codé par :
let aa0 = {
    initiaux_asc=[0];
    finals_asc = [| false; true |];
    transitions_asc=[|
        [| [| [1]; [0] |]; [| [1]; [1] |] |];
        [| [| [1]; [1] |]; [| [1]; [1] |] |]
    |]
};;;
19 - Coder une fonction nombre_etats_asc prenant en argument la représentation aa d'un automate ascendant et renvoyant le nombre d'états de cet automate.
- Coder une fonction nombre_symboles_asc prenant en argument la représentation aa d'un automate ascendant et renvoyant le nombre de symboles de l'alphabet sur lequel cet automate est défini.
- Coder une fonction Caml applique_asc telle que applique_asc aa t, où aa représente un automate ascendant et t un arbre , renvoie une liste sans doublon des états pour lesquels il existe une application avec qui vérifie la condition (ii) de la définition de reconnaissance d'un arbre par un automate ascendant page 7. Si , la fonction applique_asc doit renvoyer la liste des états initiaux de . On pourra utiliser les fonctions utilitaires des questions 1 à 4 .
- En utilisant applique_asc, coder une fonction evalue_asc telle que evalue_asc aa t, où aa représente un automate ascendant et t un arbre , renvoie un booléen qui vaut Vrai si et seulement si reconnaît . On pourra utiliser la fonction contient.
- Montrer qu'un langage d'arbres est un langage d'arbres rationnel si et seulement s'il existe un automate ascendant déterministe reconnaissant .
- Coder deux fonctions Caml identifiant_partie: int list -> int et partie_identifiant: int -> int list réciproques l'une de l'autre, codant une bijection entre les parties de (une partie étant représentée par une liste d'entiers sans doublon, dans un ordre arbitraire) et les entiers de 0 à . On rappelle qu'en Caml l'expression 1 lsl i calcule l'entier .
25 - En s'appuyant sur identifiant_partie et partie_identifiant et sur la réponse à la question 23, coder une fonction determinise_asc prenant en argument la représentation aa d'un automate ascendant et renvoyant la représentation d'un automate ascendant déterministe reconnaissant le même langage que .
- Montrer que si est un langage d'arbres rationnel, alors est un langage d'arbres rationnel.
- Coder une fonction complementaire_asc prenant en entrée la représentation aa d'un automate ascendant reconnaissant un langage et renvoyant la représentation d'un automate ascendant reconnaissant .
- Montrer que si et sont deux langages d'arbres rationnels, alors est un langage d'arbres rationnel.
- Coder une fonction union_asc prenant en entrée les représentations aa1 et aa2 de deux automates ascendants reconnaissant respectivement les langages et et renvoyant la représentation d'un automate ascendant reconnaissant .
- Montrer que si et sont deux langages d'arbres rationnels, alors est un langage d'arbres rationnel.
- Coder une fonction intersection_asc prenant en entrée les représentations aa1 et aa2 de deux automates ascendants reconnaissant respectivement les langages et et renvoyant la représentation d'un automate ascendant reconnaissant .
- Sans chercher à utiliser les propriétés de clôture par union, complémentation ou intersection, montrer que le langage n'est pas un langage d'arbres rationnel.

Fin de l'épreuve


    1. La notion de langages d'arbres rationnels est distincte de la notion de langages de mots rationnels.
Mines Option Informatique MP 2015 - Version Web LaTeX | WikiPrépa | WikiPrépa