Corrigé X-ENS 2025 Informatique A MP — Partie IV (Q17 à Q20) : Récursion ouverte, preuve par invariant et séparation-évaluation
Sujet officiel du concours X-ENS, session 2025, épreuve Informatique A MP. Corrigé rédigé par Ibrahim Alame.
Sujet officiel (PDF, site du concours)
Énoncé
On ne construit plus la liste de tous les arbres. La fonction de la figure 1 doit, pour un état et une liste de caractères , renvoyer avec optimal pour et . Elle n'est pas récursive : l'argument oracle tient lieu d'appel récursif (récursion ouverte).
let arbre_optimal_avec_oracle
(oracle : etat -> caractere list -> arbre * float)
(etat : etat)
(caracteres : caractere list) : arbre * float =
if caracteres = [] then
(Feuille etat, 0.)
else
let caracteres_a_tester = ref caracteres in
let score_optimal = ref infinity in
let arbre_optimal = ref None in
while !caracteres_a_tester <> [] do
let caractere = List.hd !caracteres_a_tester in
let score_total = ref 1. in
let enfants : (float * arbre) array =
Array.init num.(caractere) (fun valeur ->
let p_valeur = proba_etat etat caractere valeur in
let sous_arbre, score_sous_arbre =
if p_valeur = 0. then Impossible,0. else
let etat' = reponse etat caractere valeur in
let caracteres_restants =
List.filter (fun c -> c <> caractere) caracteres
in
oracle etat' caracteres_restants
in
score_total := !score_total +. p_valeur *. score_sous_arbre;
(p_valeur, sous_arbre))
in
if !score_total < !score_optimal then
(arbre_optimal := Some (Noeud {caractere=caractere;enfants=enfants});
score_optimal := !score_total);
caracteres_a_tester := List.tl !caracteres_a_tester
done;
match !arbre_optimal with
| Some a -> a, !score_optimal
| None -> assert false
Q17. Donner des préconditions aussi précises que possible sur , et oracle sous lesquelles cette fonction termine et renvoie avec optimal pour et (après avoir réfléchi à Q18 et Q19).
Q18. Démontrer qu'elle satisfait cette spécification, en énonçant l'invariant de boucle.
Q19. Écrire une fonction récursive arbre_optimal : etat -> caractere list -> arbre * float, fondée sur la précédente, qui renvoie un arbre optimal ; donner sa spécification et la prouver.
Q20. Écrire arbre_optimal_opt : etat -> caractere list -> float -> (arbre * float) option, qui interrompt la construction d'un arbre dès que son score dépasse le meilleur courant : elle renvoie None si tous les arbres de décision ont une hauteur moyenne supérieure au score maximal donné, et sinon un arbre optimal (preuve non demandée).
Corrigé
Dans toute la partie, on raisonne en arithmétique exacte, comme l'énoncé : les flottants sont vus comme des réels. On note la hauteur moyenne d'un arbre optimal pour et . Deux remarques servent partout.
- (R1) Si , le seul arbre de décision est
Feuille(un nœud exige un caractère de ), de hauteur . Si est une dirac,Feuilleest un arbre de décision de hauteur , donc optimal, alors que tout nœud a une hauteur moyenne . Si n'est pas une dirac et , les arbres de décision sont exactement des nœuds dont le caractère est dans . - (R2) Pour un caractère fixé, les arbres de décision de racine sont les
Noeuddont l'enfant de rang vaut si , et sinon, avec arbre de décision quelconque pour et , ces choix étant indépendants. Comme avec , la plus petite hauteur moyenne d'un arbre de racine est , atteinte en prenant chaque optimal.
Q17. Préconditions :
- (P1) est un état valide : une distribution sur codée selon l'invariant (poids , sans doublons, de somme 1), dont les espèces ont mesures, la -ième étant une distribution sur ;
- (P2) est une liste sans doublons de caractères de ;
- (P3) ou n'est pas une dirac ;
- (P4) pour tout et toute valeur telle que , l'appel
oracle, où est la liste obtenue parList.filter, termine et renvoie avec optimal pour et .
(P4) ne porte que sur les appels effectivement faits : rien n'est demandé à l'oracle sur d'autres arguments. (P3) est indispensable : si et , la fonction renvoie un Noeud, de hauteur moyenne , alors que Feuille , de hauteur , est optimal (R1). En revanche, (P4) exige que l'oracle soit correct aussi sur les états dirac qu'il peut recevoir : ce sera le rôle du test de dirac en Q19.
Q18. Les numéros de ligne sont ceux de la figure 1. Cas (lignes 5-6) : la fonction renvoie , optimal d'après (R1).
Cas avec . Corps de boucle, pour le caractère : pour chaque valeur , si l'enfant est et contribue ; sinon reponse est définie (Q7) et, d'après (P4), l'oracle termine et renvoie avec optimal pour et . À la fin de l'Array.init (lignes 14-27), : c'est la hauteur moyenne de , qui est un arbre de décision (les enfants ont la forme exigée), et d'après (R2) est la plus petite hauteur moyenne d'un arbre de décision de racine .
Invariant de la boucle while (ligne 11). Après tours () :
100 % gratuit
La suite du corrigé est sur Adloun
Le corrigé rédigé en entier, question par question, et le tuteur pour poser des questions sur ce sujet.
Voir le corrigé complet, gratuitementInscription gratuite en 30 secondes (e-mail, nom d'utilisateur, mot de passe, classe ou profil), sans carte bancaire : arrivée directe sur le corrigé.