AP · Elixir

AP · Découverte

Ce que nous allons construire

Du code aux pixels.
Des exemples à l’intelligence.
À vous de construire la suite.

Aujourd’hui, on essaie les résultats. En cours, on en construit les briques.

Aurélien Noce · Mines Paris – PSL1 / 16

AP1 · Premiers pas en Elixir

Du code que vous pouvez déjà lire

Pouvez-vous deviner le résultat sans avoir appris Elixir ?

panier.exsElixir
prix = 12
quantite = 3

total = prix * quantite
"Total : #{total} €"
Aurélien Noce · Mines Paris – PSL2 / 16

AP1 · Fonctions et motifs

Décrire chaque cas directement

Quelle ligne correspond à un feu vert ?

feu.exsElixir
defmodule Feu do
  def action(:rouge), do: "Stop"
  def action(:orange), do: "Attention"
  def action(:vert), do: "On avance"
end

Feu.action(:vert)
Aurélien Noce · Mines Paris – PSL3 / 16

AP4 · Collections et pipe

Lire les transformations dans l’ordre

Garder les notes validées, puis les classer de la plus haute à la plus basse.

notes.exsElixir
notes = [8, 14, 11, 6, 17]

notes
|> Enum.filter(fn note ->
  note >= 10
end)
|> Enum.sort()
|> Enum.reverse()

Ces trois extraits sont en Elixir. Nous allons maintenant essayer un petit langage différent, dont nous écrirons l’interpréteur en Elixir.

Aurélien Noce · Mines Paris – PSL4 / 16

AP2–AP3 · Langages

Donner un sens à un programme

Que peut-on savoir avant même de lancer un programme ?

Nous lirons ce texte pour construire un arbre, puis calculer sa valeur.

Type de l’expression—
Résultat du programme—

Modifiez un nombre, puis lancez le programme.

Voir l’arbre construit à partir du texte

L’arbre apparaîtra après l’analyse du programme.

Voir aussi les tuples Elixir
L’arbre apparaîtra après l’analyse du programme.

Parser, typeur et interpréteur Elixir du cours, exécutés dans votre navigateur. Premier chargement : environ 11 Mo, avec les modules déjà compilés. Voir la référence exécutée.

Aurélien Noce · Mines Paris – PSL5 / 16

AP3 et AP9 · Machines

Du programme aux pixels

Ce jeu peut-il tenir dans les instructions d’une toute petite machine ?

Chargement de la ROM compilée…

Cliquez sur l’écran, puis utilisez les flèches. Poussez la caisse sur le point ; vous ne pouvez pas la tirer.

Voir la tilemap · les 7 motifs de tile

tile(x, y, indice) dessine l’un de ces motifs de 4 × 4 pixels. Les coordonnées x et y placent son coin supérieur gauche sur l’écran.

Par ex., tile(20.0, 6.0, 3.0) dessine une caisse en (20, 6). Les motifs sont fournis ; draw_cell choisit leur indice selon l’état du jeu.

Le dessin utilise un XOR : redessiner le même motif au même endroit l’efface. Le sol vide ne modifie aucun pixel ; ici, main() efface l’écran avec clear() avant de redessiner le plateau.

Que fait le processeur ?

Activez « Pas à pas », puis appuyez sur une flèche du jeu. Avancez d’une instruction pour voir les valeurs changer, ou continuez jusqu’à la prochaine attente de touche.

Chargement de la machine…0 instructions exécutées

Le programme en mémoire

— octets
Prochaine instruction—

Processeur CHIP-8

Une instruction à la fois
PC · prochaine instruction—
I · adresse mémoire—

16 registres : de petites cases pour calculer

V00
V10
V20
V30
V40
V50
V60
V70
V80
V90
VA0
VB0
VC0
VD0
VE0
VF0
Pile · adresses de retour des fonctionsVide
Dernière instruction exécutéeAucune

Mémoire du jeu

À partir de —

Joueur +0—
Caisse +1—
Cible +2—
Victoire +3—

Convention du programme initial : positions dans la carte ; victoire : 0 ou 1. Le processeur ne connaît pas ces rôles.

Clavier et écran

Dernière toucheAucune
Pixels allumés0 / 2 048

En attente d’une touche, la machine n’exécute plus d’instructions.

Couleur : valeur différente du dernier état affiché.

Adresses et instructions en hexadécimal (0x…) ; valeurs des registres et du jeu en décimal. Le PC indique où lire la prochaine instruction.

Le jeu complet est dans sokoban.ap : carte, fonctions de déplacement et de dessin, initialisation et boucle main(). Les onglets Elixir montrent le compilateur utilisé pour produire la ROM.

La ROM initiale est prête à jouer. « Compiler et jouer » compile uniquement sokoban.ap, avec le compilateur Elixir.

Quelles opérations sont fournies par la machine ?

Le programme définit les fonctions propres au jeu. Six primitives lui donnent accès à l’écran, au clavier, à la mémoire et au calcul de reste. Leur traduction est visible dans codegen.ex. Un u8 est un entier de 0 à 255 ; les calculs débordent modulo 256.

clear() → u8
Efface l’écran et renvoie 0.
read_key() → u8
Attend une touche du clavier CHIP-8. Les flèches de la démo envoient 2, 4, 6 et 8.
tile(x: u8, y: u8, indice: u8) → u8
Dessine une tuile de 4 × 4 pixels par XOR aux coordonnées indiquées, puis renvoie 0. Indices de 0 à 6 ; hors de cet intervalle, ne dessine rien.
load(adresse: u8) → u8
Lit un octet dans les 256 cases de mémoire réservées au programme.
store(adresse: u8, valeur: u8) → u8
Écrit un octet dans cette mémoire et renvoie 0. Le programme décide ce que chaque case représente.
rem(valeur: u8, modulo: u8) → u8
Calcule un reste. Ce backend accepte un modulo constant égal à une puissance de deux.

La fonction main redessine le jeu, attend une touche, applique les règles, puis se rappelle. Ce dernier appel est compilé en saut : la pile ne grandit pas à chaque tour.

Positions, sources et ROM

Le parser vient d’AP2 et le backend entier sur 8 bits d’AP9. Cette démonstration étend le backend avec des fonctions nommées et des appels, dont l’auto-appel terminal de main.

Les positions comptent huit cases par ligne. Sur 8 bits, ajouter 255 revient à reculer d’une case ; ajouter 248 revient à monter d’une ligne. L’émulateur de cette présentation est en JavaScript. Le projet backend d’AP9 fait compiler le programme vers ses instructions.

Le jeu choisit où ranger son état : case mémoire 0 pour le joueur, 1 pour la caisse, 2 pour la cible, 3 pour la victoire. Les nombres de l’initialisation se trouvent juste avant le dernier appel à main().

Aurélien Noce · Mines Paris – PSL6 / 16

AP4–AP5 → AP9 · Image par coordonnées

Cette image est un réseau de neurones

Donnez-lui une position. Il invente la couleur qui va avec.

x 0.72 · y 0.28R — · V — · B —

— paramètresErreur validation : —

Le réseau a appris les couleurs de cette image. Aucune couleur de l’original n’est consultée pour la reconstruire.

Corrigé AP9 « Image par coordonnées », adapté à la couleur. Vrais poids entraînés avec Nx ; le curseur rejoue des étapes enregistrées.

Comprendre l’apprentissage sur quatre points
○ Même signe · × Signes différents
Fond plus bleu : prédiction +1.
0 pas— erreur moyenne
—0DépartMaintenant

— / 4 points correctement classés

(−1, −1)—(−1, +1)—(+1, −1)—(+1, +1)—
Les poids sont tirés au sort. Lancez l’apprentissage.

Calculs réels dans le navigateur, vérifiés contre le corrigé Elixir de micrograd. Ces quatre points servent à apprendre.

Aurélien Noce · Mines Paris – PSL7 / 16

AP9 · Autoencodeur

Abîmez le dessin. Le réseau le reconstruit.

Que peut-il retrouver à partir de ce qui reste ?

01 Votre dessin abîmé

Dessinez, effacez, recommencez.

12 nombrespour retenir le dessin
02 Le réseau reconstruit

Recalculé à chaque geste

Et entre deux dessins ? Explorer le code appris

Le réseau décode les nombres intermédiaires. Un mélange peut donner un chiffre ambigu.

Autoencodeur d’AP9, adapté à MNIST : 12 000 chiffres d’apprentissage. Les exemples ci-dessus viennent d’un lot distinct.

Aurélien Noce · Mines Paris – PSL8 / 16

AP9 · Petit Transformer

À quoi le Transformer fait-il attention ?

Retrouver les bonnes lettres, une prédiction après l’autre.

Choisissez trois lettres parmi a, b, c et d. Les deux réseaux reçoivent le même défi.

Avant d’apprendre

0 pas

Des poids aléatoires.

Après apprentissage

1 200 pas

Les mêmes briques, des poids ajustés.

À l’intérieur du réseau

Comment choisit-il la première lettre ?

Les liens d’attentionUn trait plus épais signifie un poids plus grand.

Contexte disponible Futur inaccessible^ début · | séparateur · ↵ fin

Le prochain caractèreLe plus probable est choisi.

Chargement des poids du petit Transformer.

Explorer la carte d’attention et les règles de l’expérience
Attention causale du contexte courant

Chaque ligne de la carte montre les poids vers les positions déjà disponibles. Les cases hachurées sont masquées : une position ne voit pas la suite.

À température 0, on choisit le caractère le plus probable. Au-dessus, on tire au sort selon les probabilités recalculées : une température plus élevée les étale. « Rejouer » effectue de nouveaux tirages.

L’attention n’explique qu’une partie du calcul : le modèle utilise aussi des connexions résiduelles et un réseau dense.

Une tête d’attention, un bloc, sept caractères.

Vrais poids appris avec Nx · calcul local dans votre navigateur · une tâche de copie, pas un modèle de français. Le projet AP9

Aurélien Noce · Mines Paris – PSL9 / 16

AP6 → AP9 · Ferme de rendu

Une image. Plusieurs travailleurs.

Si un travailleur s’arrête, doit-on perdre toute l’image ?

Aperçu de la fractale de Mandelbrot, en turquoise, violet et corail
Aperçu du résultat640 × 400 pixels
Worker 1
Disponible0 tuile reçue
Worker 2
Disponible0 tuile reçue
Worker 3
Disponible0 tuile reçue
Worker 4
Disponible0 tuile reçue
File de 64 tuilesLes résultats peuvent arriver dans un autre ordre.
□ En attente● En calcul✓ Reçue× Échec isolé

La fractale est calculée ici. Lancez le rendu, puis provoquez une panne : que deviennent les autres tuiles ?

Messages reçus
  1. En attente du premier résultat.

Workers du navigateur ; projet en processus Elixir. Même idée : distribuer des travaux identifiés, recueillir les réponses et détecter les pannes. Délais de livraison ajoutés pour observer les messages ; ce n’est pas un benchmark.

Aurélien Noce · Mines Paris – PSL10 / 16

AP7 → AP9 · Réservations concurrentes

Vingt demandes. Une seule place.

Comment éviter de promettre la dernière place à deux personnes ?

LA DERNIÈRE PLACE
○ Libre◷ Retenue✓ Confirmée
Place sélectionnéeC4Libre
Jeton propriétaire
—
Demandes acceptées
0 / 20
Demandes refusées
0

Une place, un seul propriétaire.

1234567891011121314151617181920SERVEUR0 / 2020 clients · une boîte aux lettres · un état

23 billets vendus, une place libre. Qui l’obtiendra si 20 clients la demandent ?

Observer les messages et la mémoire du serveur

    Protocole simulé dans le navigateur ; GenServer dans le projet Elixir. Chaque demande vérifie et modifie la place dans un seul traitement. Le temps avance ici avec les boutons. La supervision redémarre le processus ; elle ne restaure pas ses réservations en mémoire.

    Aurélien Noce · Mines Paris – PSL11 / 16

    AP6–AP8 → AP9 · Éditeur concurrent

    Deux personnes. Un même texte.

    Écrivez des deux côtés, coupez la connexion, puis retrouvez-vous.

    Essayez une collision

    Alice

    r0
    En attenteCurseur 0

    Bob

    r0
    En attenteCurseur 0
    Les éditions d’Alice et Bob passent par un serveur qui les ordonne et les transforme.ABr0en attenteen attenteSERVEURÉchanges suspendus
    Texte reçu par le serveurDeux versions locales
    On code.

    Chacun a écrit sans recevoir l’autre. Que va devenir la position de l’ajout de Bob ?

    Voir comment les positions changent

      Vous pouvez aussi écrire dans les deux éditeurs. Cette simulation accepte du texte ASCII court (sans accents ni emoji). Les échanges sont ordonnés par un serveur ; une coupure retient les messages en mémoire.

      Le calcul de transformation suit le corrigé du projet OT d’AP9, avec accusés et composition des saisies en attente. Les positions commencent à zéro.

      Revenir au compteur répliqué d’AP8 · CRDT

      Alice

      0contribution(s) connues

      Alice
      0
      Bob
      0
      Carol
      0

      Bob

      0contribution(s) connues

      Alice
      0
      Bob
      0
      Carol
      0

      Carol

      0contribution(s) connues

      Alice
      0
      Bob
      0
      Carol
      0
      Un message d’Alice à Bob

      Aucun message gardé.

      Les échanges sont suspendus. Chacun peut ajouter des contributions.

      À la réception, chaque composante garde le maximum : max(local, reçu).

      Aurélien Noce · Mines Paris – PSL12 / 16

      AP9 · Affectation et algorithmique

      Une place pour chacun ?

      Les mêmes préférences peuvent-elles conduire à des résultats différents ?

      Des élèves proposent leurs vœux à trois groupes de deux placesLes pastilles se déplacent vers les places retenues. Une place provisoire peut être reprise par un candidat prioritaire ; l’élève écarté poursuit alors sa liste de vœux.ÉLÈVES · VŒUXGROUPES · 2 PLACESGroupe A0 / 2Groupe B0 / 2Groupe C0 / 2AdaABobBChloéCDinaDEliEFayF
      0 / 6 élèves placésLes places sont provisoires

      Les règles : quels vœux, quelles priorités ?

      Chaque élève essaie ses groupes de gauche à droite. Les trois groupes utilisent la même priorité fictive : . Une acceptation provisoire peut être remplacée par celle d’un élève plus prioritaire.

      Une paire « élève–groupe » bloque une affectation si l’élève préfère ce groupe et si le groupe pourrait l’accepter à la place d’un candidat moins prioritaire (ou dans une place libre). Aucune paire bloquante : l’affectation est stable. Cela ne garantit ni de placer tout le monde, ni de minimiser la somme des rangs.

      Algorithmes du projet Elixir AP9 « Affectation de groupes », adaptés ici en JavaScript et comparés au corrigé. Les six élèves sont fictifs. Le nombre maximal de places occupables est calculé ici par recherche exhaustive ; le TP le calcule avec un flot.

      Aurélien Noce · Mines Paris – PSL13 / 16

      Neuf séances

      Construire par petites étapes

      1. AP1–AP3

        Décrire et exécuter

        Elixir, les données, les fonctions.
        Un interpréteur, puis un compilateur.

        Dans Livebook
      2. AP4–AP5

        Calculer et apprendre

        Des tenseurs, un gradient.
        Des modèles et des expériences.

        Dans Livebook
      3. AP6–AP8

        Faire coopérer

        Des processus et des messages.
        Un état local, puis répliqué.

        Vers des applications Elixir
      4. AP9

        Approfondir une idée

        Un projet commencé en cours.
        Une réalisation poursuivie à la maison.

        Un sujet au choix

      Prédire. Écrire. Essayer. Expliquer.

      Un bout de code que vous comprenez, un exemple qui le vérifie, puis la prochaine brique.

      Aurélien Noce · Mines Paris – PSL14 / 16

      AP9 · Projet au choix

      Choisir une question à approfondir

      Les interfaces, les données et les squelettes sont fournis. Vous travaillez sur l’idée et son algorithme.

      Explorer le catalogue des projets →

      Aurélien Noce · Mines Paris – PSL15 / 16

      À vous de jouer

      Vous écrirez les briques qui font fonctionner tout cela

      Le programme qui tourne est le point de départ d’une question :
      comment fonctionne-t-il ?

      Quel essai voulez-vous refaire ?

      LangageSokobanImage appriseChiffresTransformerFerme de renduRéservationsÉditeursGroupes