diff --git a/MyIA.AI.Notebooks/Sudoku/Sudoku-13-SymbolicAutomata-Python.ipynb b/MyIA.AI.Notebooks/Sudoku/Sudoku-13-SymbolicAutomata-Python.ipynb index 05e026ece8..ec5137ae76 100644 --- a/MyIA.AI.Notebooks/Sudoku/Sudoku-13-SymbolicAutomata-Python.ipynb +++ b/MyIA.AI.Notebooks/Sudoku/Sudoku-13-SymbolicAutomata-Python.ipynb @@ -973,12 +973,12 @@ "## 9. L'automate symbolique en Python — diagrammes de decision binaires (BDD)\n", "\n", "Le titre de ce notebook parle d'**automates symboliques**, mais jusqu'ici la\n", - "« symbolique » reste abstraite : Z3 manipule des entiers et des chaines sans\n", + "« symbolique » reste abstraite : Z3 manipule des entiers et des chaînes sans\n", "montrer la structure d'automate. Le twin C# (Annexe S10) construit un tel\n", - "automate via `Microsoft.Z3` ; voici l'equivalent Python avec la librairie `dd`,\n", + "automate via `Microsoft.Z3` ; voici l'équivalent Python avec la librairie `dd`,\n", "qui implemente les **diagrammes de decision binaires** (BDD).\n", "\n", - "Un BDD est un **automate deterministe acyclique** : chaque variable booleenne\n", + "Un BDD est un **automate déterministe acyclique** : chaque variable booleenne\n", "est un niveau de branchement (vrai/faux), et les feuilles sont 0 (rejet) ou\n", "1 (acceptation). C'est exactement la structure d'un automate compile une fois\n", "pour toutes, puis parcourue en lecture seule. La vertu : un BDD **factorise**\n", @@ -1093,15 +1093,15 @@ "**Le plafond honnete.** Cet exemple tient en 6 variables. La contrainte\n", "« tous-distincts » est en fait connue comme **dure pour les BDD** : sur la\n", "vraie ligne Sudoku (9 cellules, 4 bits chacune = 36 variables), le BDD\n", - "explose a plusieurs millions de noeuds. C'est precisement pour cela que Z3\n", - "n'utilise PAS un BDD brut pour le Sudoku : il dispose d'une **theorie\n", + "explose a plusieurs millions de noeuds. C'est précisément pour cela que Z3\n", + "n'utilise PAS un BDD brut pour le Sudoku : il dispose d'une **théorie\n", "specialisee** des entiers (Distinct, arithmetique) bien plus compacte qu'une\n", "explosion booleenne. Le BDD reste l'outil de choix pour la logique purement\n", "booleenne (circuits, model-checking) ; le solveur SMT regne sur l'arithmetique.\n", "\n", - "> **Pont avec le twin C#.** L'Annexe S10 construit le meme genre d'automate\n", - "> symbolique via `Microsoft.Z3` ; ici `dd` (PyPI) joue ce role cote Python.\n", - "> Les deux instancient la meme idee : compiler une contrainte en un graphe\n", + "> **Pont avec le twin C#.** L'Annexe S10 construit le même genre d'automate\n", + "> symbolique via `Microsoft.Z3` ; ici `dd` (PyPI) joue ce rôle cote Python.\n", + "> Les deux instancient la même idee : compiler une contrainte en un graphe\n", "> de decision parcourable en temps lineaire.\n" ] }, diff --git a/MyIA.AI.Notebooks/Sudoku/Sudoku-14-BDD-Python.ipynb b/MyIA.AI.Notebooks/Sudoku/Sudoku-14-BDD-Python.ipynb index fdcda56edb..5c35b2f09c 100644 --- a/MyIA.AI.Notebooks/Sudoku/Sudoku-14-BDD-Python.ipynb +++ b/MyIA.AI.Notebooks/Sudoku/Sudoku-14-BDD-Python.ipynb @@ -710,7 +710,7 @@ "### Lecture des tests : des tautologies réduites à un seul nœud\n", "\n", "Trois résultats, trois leçons. **Test 1** : `x AND NOT x` s'évalue en `False` avec **1 nœud** — l'application de l'opérateur détecte la contradiction au niveau des terminaux et renvoie directement la feuille : à aucun moment un arbre n'est développé, c'est du calcul **symbolique**, pas de l'énumération. **Test 2** : `x OR NOT x`, symétriquement, donne `True` sur 1 nœud. **Test 3** (distributivité) : les deux expressions de la loi distributive occupent **7 nœuds chacune** et sont vérifiées équivalentes — d'abord sur une assignation témoin, puis **sur les 8 assignations** exhaustives des trois variables. Notez la limite de cette vérification : l'équivalence par évaluation est exponentielle en le nombre de variables — praticable à 3 variables, pas à 81 cellules de Sudoku ; l'équivalence **structurelle** (DAG identiques après canonisation) est ce qui la remplacera à grande échelle.\n", - " L'equivalence structurelle est aussi ce qui rendra le comptage de noeuds significatif : deux formules equivalentes, deux DAG de meme taille canonique." + " L'equivalence structurelle est aussi ce qui rendra le comptage de noeuds significatif : deux formules equivalentes, deux DAG de même taille canonique." ] }, { diff --git a/MyIA.AI.Notebooks/Sudoku/Sudoku-15-Infer-Python.ipynb b/MyIA.AI.Notebooks/Sudoku/Sudoku-15-Infer-Python.ipynb index 0e4817d94e..f3d25bbe72 100644 --- a/MyIA.AI.Notebooks/Sudoku/Sudoku-15-Infer-Python.ipynb +++ b/MyIA.AI.Notebooks/Sudoku/Sudoku-15-Infer-Python.ipynb @@ -33,7 +33,7 @@ "\n", "## Introduction : Programmation Probabiliste et Sudoku\n", "\n", - "Ce notebook implemente l'equivalent Python du **RobustProbabilisticSolver** du notebook C# Infer.NET. Les deux approches utilisent des distributions **Dirichlet** pour modeliser les probabilites des cellules.\n", + "Ce notebook implemente l'équivalent Python du **RobustProbabilisticSolver** du notebook C# Infer.NET. Les deux approches utilisent des distributions **Dirichlet** pour modeliser les probabilites des cellules.\n", "\n", "### Comparaison des approches\n", "\n", @@ -142,7 +142,7 @@ "source": [ "### Interpretation : Environnement NumPyro/JAX\n", "\n", - "**Résultats obtenus** : L'environnement est correctement configure : la cellule ci-dessus imprime les versions de JAX et NumPyro (execution sur CPU).\n", + "**Résultats obtenus** : L'environnement est correctement configure : la cellule ci-dessus imprime les versions de JAX et NumPyro (exécution sur CPU).\n", "\n", "| Composant | Rôle |\n", "|-----------|------|\n", @@ -150,7 +150,7 @@ "| NumPyro | Programmation probabiliste sur JAX |\n", "| Device (CPU) | Exécution sur CPU (pas de GPU requis) |\n", "\n", - "**Points cles** :\n", + "**Points clés** :\n", "1. **JAX comme backend** : JAX fournit la differenciation automatique et la compilation JIT necessaires a NumPyro\n", "2. **Exécution CPU** : Ce notebook fonctionne sur CPU, pas besoin de GPU (contrairement au Deep Learning)\n", "3. **Version recente** : NumPyro (version stable recente) offre un SVI bien optimise\n", @@ -336,7 +336,7 @@ "| Cellules initiales | ~25-35 | Puzzles Easy ont ~30% de cases pre-remplies |\n", "| Encodage | Chiffres 0-9 | 0 = vide, 1-9 = valeurs connues |\n", "\n", - "**Points cles** :\n", + "**Points clés** :\n", "1. **Stratégie de chargement robuste** : Le code essaie deux chemins possibles (relatif et absolu)\n", "2. **Fallback** : Si aucun fichier n'est trouve, un puzzle de test par defaut est utilise\n", "3. **Format compact** : 81 caractères suffisent pour representer un grille 9x9\n", @@ -359,9 +359,9 @@ "tags": [] }, "source": [ - "## 3. Modèle NumPyro avec Dirichlet (Equivalent RobustProbabilisticSolver)\n", + "## 3. Modèle NumPyro avec Dirichlet (Équivalent RobustProbabilisticSolver)\n", "\n", - "Ce modèle est l'equivalent Python du `RobustSudokuModel` du notebook C# Infer.NET. Il utilise :\n", + "Ce modèle est l'équivalent Python du `RobustSudokuModel` du notebook C# Infer.NET. Il utilise :\n", "\n", "1. **Distributions Dirichlet** pour les probabilites des cellules (comme Infer.NET)\n", "2. **Contraintes douces** via `numpyro.factor` (au lieu de `ConstrainFalse`)\n", @@ -490,9 +490,9 @@ "tags": [] }, "source": [ - "## 4. Solveur Probabiliste Pur (Equivalent RobustProbabilisticSolver)\n", + "## 4. Solveur Probabiliste Pur (Équivalent RobustProbabilisticSolver)\n", "\n", - "Ce solveur est l'equivalent Python direct du `RobustProbabilisticSolver` C# :\n", + "Ce solveur est l'équivalent Python direct du `RobustProbabilisticSolver` C# :\n", "- Une seule passe d'inference\n", "- Recupere le mode de chaque distribution Dirichlet\n", "- Pas de propagation déterministe" @@ -711,15 +711,15 @@ "\n", "**Résultats obtenus** : Une seule passe d'inference SVI (300 itérations) suffit pour resoudre ce puzzle Easy avec succes.\n", "\n", - "| Metrique | Valeur | Analyse |\n", + "| Métrique | Valeur | Analyse |\n", "|----------|--------|---------|\n", - "| Itérations SVI | 300 | Equivalent a ~50 EP itérations Infer.NET |\n", + "| Itérations SVI | 300 | Équivalent a ~50 EP itérations Infer.NET |\n", "| Temps inference | ~6 s | ~180x plus lent que C# (~34ms) |\n", "| Convergence | True | Solution valide obtenue |\n", "| Erreurs | 0 | Toutes les contraintes respectees |\n", "| Cellules initiales | 45 | 36 cellules a determiner |\n", "\n", - "**Points cles** :\n", + "**Points clés** :\n", "1. **Mode des distributions** : Le solveur selectionne la valeur la plus probable de chaque distribution Dirichlet (argmax)\n", "2. **Contraintes douces** : Les penalites `numpyro.factor` encouragent la cohérence sans garantir les contraintes Sudoku\n", "3. **Performance acceptable** : ~6 secondes pour un puzzle Easy est raisonnable pour un prototype pedagogique\n", @@ -750,7 +750,7 @@ "1. `entropy(probs)` : calculer l'entropie d'une distribution (mesure d'incertitude)\n", "2. `analyze_confidence(grid, probs)` : identifier les cellules les plus certaines et les plus incertaines\n", "\n", - "**Concepts cles** :\n", + "**Concepts clés** :\n", "- **Entropie** : quantifie l'incertitude d'une distribution. Valeur faible = modèle certain, valeur elevee = modèle hesitant\n", "- **Confiance** : probabilite maximale de la distribution pour une cellule\n", "- **Distribution uniforme** : 9 valeurs equiprobables, entropie = ln(9) ~ 2.20 nats\n", @@ -995,9 +995,9 @@ "tags": [] }, "source": [ - "## 5. Solveur Iteratif (Equivalent IterativeSudokuModel)\n", + "## 5. Solveur Iteratif (Équivalent IterativeSudokuModel)\n", "\n", - "Ce solveur est l'equivalent Python du `IterativeSudokuModel` C# qui fixe iterativement les cellules les plus certaines." + "Ce solveur est l'équivalent Python du `IterativeSudokuModel` C# qui fixe iterativement les cellules les plus certaines." ] }, { @@ -1213,7 +1213,7 @@ "\n", "**Résultats obtenus** : Le solveur iteratif fixe progressivement les cellules avec une confiance superieure au seuil de 0.25, en re-injectant les valeurs fixees dans le modèle.\n", "\n", - "| Metrique | Puzzle 1 | Puzzle 2 | Moyenne |\n", + "| Métrique | Puzzle 1 | Puzzle 2 | Moyenne |\n", "|----------|----------|----------|---------|\n", "| Étapes requises | 36 | 49 | 42.5 |\n", "| Cellules fixees | 36 | 49 | 42.5 |\n", @@ -1222,7 +1222,7 @@ "| Temps par étape | ~5s | ~5s | ~5s |\n", "| Statut final | OK | OK | 100% succes |\n", "\n", - "**Points cles** :\n", + "**Points clés** :\n", "1. **Processus iteratif** : Chaque étape fixe 1 cellule (paramètre `cells_per_iteration=1`) et relance l'inference\n", "2. **Convergence garantie** : Les deux puzzles convergent vers une solution valide, contrairement au solveur robuste\n", "3. **Cout temporel** : ~200 secondes par puzzle, soit ~30x plus lent que le solveur robuste (~6 s)\n", @@ -1842,26 +1842,26 @@ "source": [ "### Interpretation : le message passing domine le SVI, la relaxation par paires cale\n", "\n", - "Trois constats sur ces mesures (run de ce notebook, meme machine que les\n", + "Trois constats sur ces mesures (run de ce notebook, même machine que les\n", "cellules SVI ci-dessus) :\n", "\n", "1. **Vitesse** : le BP decimation resout Easy51 a ~0,5 s par grille, contre ~5-8 s\n", " pour le SVI pur et ~3 minutes pour le SVI iteratif (qui re-execute 300\n", - " iterations a chaque cellule fixee). Messages exacts par facteur, warm start\n", + " itérations a chaque cellule fixee). Messages exacts par facteur, warm start\n", " entre decisions, pas de taux d'apprentissage ni de poids de contrainte a regler.\n", "2. **Couverture Easy** : 36/51 pour la decimation pure, contre 1/3 pour le SVI pur\n", - " sur sa propre selection. Le repli borne n'ajoute rien ici (35/51) : sur les\n", + " sur sa propre sélection. Le repli borne n'ajoute rien ici (35/51) : sur les\n", " grilles faciles, quand la decimation echoue, c'est la *croyance* qui est\n", " fausse, pas l'irrevocabilite de la decision.\n", "3. **Le mur des corpus durs** : 0/15 sur top95, 3-4/11 sur hardest. Ce n'est pas\n", " un defaut d'implementation mais une limite structurelle : avec 810 facteurs\n", - " binaires `!=`, deux cellules d'une meme unite cantonnees a {3,7} s'envoient des\n", + " binaires `!=`, deux cellules d'une même unite cantonnees a {3,7} s'envoient des\n", " messages symetriques qui s'annulent (ensemble de Hall de taille 2 invisible\n", " pour la relaxation par paires). La v3 C# franchit ce mur en hybrident avec de\n", " la propagation de contraintes (la \"voie facile\") ; la suite principielle est\n", " la v4 (section 7) : des facteurs AllDiff d'arite 9 dont les messages exacts\n", " (permanente ou affectation hongroise sur une matrice 9x9) capturent les\n", - " ensembles de Hall sans aucun apport deterministe externe." + " ensembles de Hall sans aucun apport déterministe externe." ] }, { @@ -3141,7 +3141,7 @@ "\n", "### Ce que nous avons implemente\n", "\n", - "| Classe Python | Equivalent C# | Description |\n", + "| Classe Python | Équivalent C# | Description |\n", "|---------------|---------------|-------------|\n", "| `RobustProbabilisticSolverPy` | `RobustProbabilisticSolver` | Une seule inference, mode des Dirichlet |\n", "| `IterativeProbabilisticSolverPy` | `IterativeSudokuModel` | Fixation iterative des cellules certaines |\n", @@ -3154,7 +3154,7 @@ "1. **Infer.NET reste superieur pour les CSP** : Expectation Propagation + contraintes dures\n", "2. **NumPyro fonctionne avec des limitations** : Contraintes douces moins efficaces\n", "3. **L'arité 9 franchit Medium sans propagation déterministe** : 9/11 (82 %) sur hardest en décimation max-product randomisée\n", - "4. **Le BP vectorise domine le SVI sur ce probleme** : messages exacts par facteur, ~10x plus rapide que le SVI pur (0,5 s vs 5-8 s) et ~350x que le SVI iteratif (0,5 s vs ~3 min), et la decimation couvre 71% de Easy51 la ou le SVI pur resout 1/3 de sa selection -- mais la relaxation **par paires** cale sur les corpus durs (top95, hardest) : les ensembles de Hall sont invisibles pour des facteurs binaires\n", + "4. **Le BP vectorise domine le SVI sur ce problème** : messages exacts par facteur, ~10x plus rapide que le SVI pur (0,5 s vs 5-8 s) et ~350x que le SVI iteratif (0,5 s vs ~3 min), et la decimation couvre 71% de Easy51 la ou le SVI pur resout 1/3 de sa sélection -- mais la relaxation **par paires** cale sur les corpus durs (top95, hardest) : les ensembles de Hall sont invisibles pour des facteurs binaires\n", "5. **Un cran sur le graphe, pas sur l'outil** : la v4 (facteurs AllDiff d'arité 9, messages exacts permanente/hongrois + restarts randomisés) franchit le même mur que la propagation de contraintes en restant purement probabiliste — là où la v3 C# payait ce mur avec du déterminisme externe\n", "\n", "> **Recommandation** : Pour resoudre des Sudokus en production, utiliser OR-Tools, Z3 ou Choco. La programmation probabiliste est un outil pedagogique pour comprendre l'inference bayesienne." diff --git a/MyIA.AI.Notebooks/Sudoku/Sudoku-17-LLM-Python.ipynb b/MyIA.AI.Notebooks/Sudoku/Sudoku-17-LLM-Python.ipynb index b7d5bde969..f69dd74359 100644 --- a/MyIA.AI.Notebooks/Sudoku/Sudoku-17-LLM-Python.ipynb +++ b/MyIA.AI.Notebooks/Sudoku/Sudoku-17-LLM-Python.ipynb @@ -332,7 +332,7 @@ "| **Puzzle exemple** | 45 indices | Niveau de difficulte facile (environ 56% de cases remplies) |\n", "| **Format de stockage** | Chaîne 81 caractères | Representation compacte (0 pour vide, 1-9 pour valeurs) |\n", "\n", - "**Points cles** :\n", + "**Points clés** :\n", "1. **Strategy d'echantillonnage** : `max_puzzles=5` limite les puzzles faciles pour des tests plus rapides\n", "2. **Conversion automatique** : La fonction `puzzle_to_grid()` transforme les chaînes en matrices 9x9\n", "3. **Affichage structure** : La fonction `print_grid()` ajoute des separateurs visuels pour les blocs 3x3\n", @@ -435,12 +435,12 @@ "\n", "La bibliotheque `openai` etant installee, nous pouvons maintenant configurer un client generique qui permet d'appeler différents modèles LLM. Ce client supporte :\n", "\n", - "- **Mode API reelle** : quand la variable d'environnement `LOCAL_LLM_API_KEY` est definie, le notebook appelle un vrai modele (compatible OpenAI). Les sorties committees de ce notebook ont ete produites ainsi, avec **Qwen3.6-35B-A3B** servi par un serveur **vLLM** local.\n", + "- **Mode API reelle** : quand la variable d'environnement `LOCAL_LLM_API_KEY` est définie, le notebook appelle un vrai modèle (compatible OpenAI). Les sorties committees de ce notebook ont ete produites ainsi, avec **Qwen3.6-35B-A3B** servi par un serveur **vLLM** local.\n", "- **Mode simulation** (fallback) : sans cle, des reponses predefinies permettent d'executer le notebook de bout en bout sans infrastructure.\n", "\n", "Cette abstraction nous permettra de comparer facilement les approches sans nous soucier de l'infrastructure d'appel.\n", "\n", - "> **Note technique (modele de raisonnement)** : Qwen3.6 est un modele *de raisonnement*. Sans desactiver explicitement le mode \"thinking\" (`chat_template_kwargs.enable_thinking=False`), il consomme l'integralite du budget de tokens en reflexion interne et renvoie un contenu vide. Le client desactive donc ce mode pour obtenir une reponse directe et deterministe (`temperature=0.0`).\n", + "> **Note technique (modèle de raisonnement)** : Qwen3.6 est un modèle *de raisonnement*. Sans desactiver explicitement le mode \"thinking\" (`chat_template_kwargs.enable_thinking=False`), il consomme l'integralite du budget de tokens en reflexion interne et renvoie un contenu vide. Le client desactive donc ce mode pour obtenir une reponse directe et déterministe (`temperature=0.0`).\n", "\n" ] }, @@ -897,18 +897,18 @@ "source": [ "### Interpretation du Test Zero-Shot\n", "\n", - "L'approche zero-shot a **echoue** a resoudre le puzzle. Sur cette realisation, le modele s'est lance dans un long raisonnement etape par etape mais n'a pas emis de grille au format attendu : la reponse n'est **pas analysable** (`Impossible de parser la reponse du LLM`).\n", + "L'approche zero-shot a **echoue** a resoudre le puzzle. Sur cette realisation, le modèle s'est lance dans un long raisonnement étape par étape mais n'a pas emis de grille au format attendu : la reponse n'est **pas analysable** (`Impossible de parser la reponse du LLM`).\n", "\n", "| Aspect | Valeur | Signification |\n", "|--------|--------|---------------|\n", - "| **Solution** | Non analysable | Le modele a produit un raisonnement texte sans grille exploitable |\n", - "| **Temps** | ~1.4 s (cf. benchmark) | Appel API reel au modele Qwen3.6 |\n", - "| **Cause principale** | Format non controle | Sans exemple ni contrainte de format, le modele derive en explications |\n", + "| **Solution** | Non analysable | Le modèle a produit un raisonnement texte sans grille exploitable |\n", + "| **Temps** | ~1.4 s (cf. benchmark) | Appel API reel au modèle Qwen3.6 |\n", + "| **Cause principale** | Format non contrôlé | Sans exemple ni contrainte de format, le modèle derive en explications |\n", "\n", - "**Points cles** :\n", - "1. **Non-fiabilite du zero-shot** : selon la realisation, le modele peut soit deriver en un long raisonnement non-analysable (cellule 14), soit emettre une grille invalide (cellule 25) ; dans les deux cas, zero-shot ne resout pas le puzzle\n", + "**Points clés** :\n", + "1. **Non-fiabilite du zero-shot** : selon la realisation, le modèle peut soit deriver en un long raisonnement non-analysable (cellule 14), soit emettre une grille invalide (cellule 25) ; dans les deux cas, zero-shot ne resout pas le puzzle\n", "2. **Parsing indispensable** : la fonction `parse_llm_response()` detecte proprement l'absence de grille exploitable\n", - "3. **Limite fondamentale** : sans exemples ni raisonnement controle par le programme, un LLM ne resout pas fiablement un probleme combinatoire non trivial\n", + "3. **Limite fondamentale** : sans exemples ni raisonnement contrôlé par le programme, un LLM ne resout pas fiablement un problème combinatoire non trivial\n", "\n", "> **Pourquoi le LLM echoue** : resoudre un Sudoku demande une recherche combinatoire avec retour-arriere. Un LLM genere des tokens un par un et ne peut pas \"revenir\" sur une affectation incompatible decidée plus tot ; il derive donc en explications sans converger vers une solution exploitable.\n", "\n" @@ -1125,21 +1125,21 @@ "source": [ "### Interpretation du Test Few-Shot\n", "\n", - "L'approche few-shot **echoue egalement** : a la difference du zero-shot (reponse non-analysable), le few-shot produit cette fois une grille bien formee mais **invalide** (violations des contraintes). Les exemples cadrent donc le *format*, mais pas la *correction*.\n", + "L'approche few-shot **echoue également** : a la différence du zero-shot (reponse non-analysable), le few-shot produit cette fois une grille bien formee mais **invalide** (violations des contraintes). Les exemples cadrent donc le *format*, mais pas la *correction*.\n", "\n", "| Aspect | Valeur | Signification |\n", "|--------|--------|---------------|\n", "| **Solution valide** | False | La grille respecte le format 9x9 mais viole les contraintes (doublons) |\n", - "| **Temps** | ~1.3 s | Appel API reel au modele Qwen3.6 |\n", + "| **Temps** | ~1.3 s | Appel API reel au modèle Qwen3.6 |\n", "| **Cause principale** | Verification combinatoire absente | Le LLM respecte le format mais n'effectue pas la verification des contraintes |\n", "\n", - "**Points cles** :\n", - "1. **Format cadre, contenu toujours faux** : les exemples few-shot apprennent au modele la *forme* attendue (grille 9x9), pas la *correction* combinatoire\n", + "**Points clés** :\n", + "1. **Format cadre, contenu toujours faux** : les exemples few-shot apprennent au modèle la *forme* attendue (grille 9x9), pas la *correction* combinatoire\n", "2. **Avantage partiel vs zero-shot** : le few-shot produit au moins une grille analysable (la ou le zero-shot a derive en raisonnement), mais elle est invalide\n", "3. **Même type d'erreur** : doublons dans lignes/colonnes/blocs\n", - "4. **Conclusion** : la difficulte n'est pas de communiquer le format au LLM, mais la *verification combinatoire* qu'il n'effectue pas de lui-meme\n", + "4. **Conclusion** : la difficulte n'est pas de communiquer le format au LLM, mais la *verification combinatoire* qu'il n'effectue pas de lui-même\n", "\n", - "> **Transition** : ni le zero-shot ni le few-shot ne fonctionnent car ils demandent au LLM de produire directement la solution. L'approche suivante change de strategie : demander au LLM d'ecrire un *solveur*, puis executer ce solveur.\n", + "> **Transition** : ni le zero-shot ni le few-shot ne fonctionnent car ils demandent au LLM de produire directement la solution. L'approche suivante change de stratégie : demander au LLM d'ecrire un *solveur*, puis executer ce solveur.\n", "\n" ] }, @@ -1354,18 +1354,18 @@ "| Aspect | Valeur | Signification |\n", "|--------|--------|---------------|\n", "| **Solution valide** | True | La grille completee respecte toutes les contraintes Sudoku |\n", - "| **Temps** | ~4.2 s | Generation du code (appel LLM) + execution du solveur genere |\n", + "| **Temps** | ~4.2 s | Generation du code (appel LLM) + exécution du solveur genere |\n", "| **Approche** | Generation de code | Le LLM ecrit un solveur Python, ensuite execute par le notebook |\n", "\n", - "**Points cles** :\n", - "1. **Changement de strategie decisif** : au lieu de demander la solution *directement* (peu fiable), on demande au LLM d'*ecrire un solveur* (generation de code) — une tache ou les LLM excellent\n", - "2. **Code backtracking correct** : le modele a genere un solveur par retour-arriere, l'algorithme canonique et complet pour le Sudoku\n", + "**Points clés** :\n", + "1. **Changement de stratégie decisif** : au lieu de demander la solution *directement* (peu fiable), on demande au LLM d'*ecrire un solveur* (generation de code) — une tâche ou les LLM excellent\n", + "2. **Code backtracking correct** : le modèle a genere un solveur par retour-arriere, l'algorithme canonique et complet pour le Sudoku\n", "3. **Validation automatique** : `validate_solution()` confirme que la grille originale est preservee et que toutes les contraintes sont respectees\n", "4. **Environnement securise** : le code genere est execute dans un espace restreint (`exec_globals` ne contient que les fonctions necessaires)\n", "5. **Robustesse** : un `deepcopy` de la grille est passe au solveur genere, car certains solveurs mutent la grille en place\n", "6. **Cout en temps** : l'approche est plus lente (~4.2 s) que la generation directe (~1.4 s) car elle genere puis execute du code, mais c'est le prix de la fiabilite\n", "\n", - "> **Lecon cles** : la *delegation* de la verification combinatoire a un algorithme execute est ce qui fait basculer le resultat d'0% (generation directe) a 100% (generation de code). Le LLM est un excellent *producteur de code*, mais un mauvais *solveur direct*.\n", + "> **Lecon clés** : la *delegation* de la verification combinatoire a un algorithme execute est ce qui fait basculer le résultat d'0% (generation directe) a 100% (generation de code). Le LLM est un excellent *producteur de code*, mais un mauvais *solveur direct*.\n", "\n" ] }, @@ -1559,11 +1559,11 @@ "tags": [] }, "source": [ - "### Interpretation des Resultats du Benchmark\n", + "### Interpretation des Résultats du Benchmark\n", "\n", - "Avec le **modele reel Qwen3.6-35B-A3B** (serveur vLLM local, 2 puzzles par approche), le benchmark **confirme la tendance de la litterature** : la generation de code bat nettement la generation directe de grille.\n", + "Avec le **modèle reel Qwen3.6-35B-A3B** (serveur vLLM local, 2 puzzles par approche), le benchmark **confirme la tendance de la litterature** : la generation de code bat nettement la generation directe de grille.\n", "\n", @@ -1579,11 +1579,11 @@ "\n", - "**Points cles** :\n", + "**Points clés** :\n", - "1. **Generation directe = echec systematique** : zero-shot et few-shot echouent (reponse non-analysable ou grille invalide) ; le LLM ne verifie pas les contraintes combinatoires\n", + "1. **Generation directe = echec systématique** : zero-shot et few-shot echouent (reponse non-analysable ou grille invalide) ; le LLM ne verifie pas les contraintes combinatoires\n", - "2. **Generation de code = succes systematique** : le code-interpreter delegue la recherche combinatoire a un algorithme execute, garantissant la validite\n", + "2. **Generation de code = succes systématique** : le code-interpreter delegue la recherche combinatoire a un algorithme execute, garantissant la validite\n", "3. **La fiabilite a un cout en temps** : le code-interpreter (~4.2 s) est plus lent que la generation directe (~1.4 s) car il genere puis execute du code — mais seule cette approche resout le puzzle\n", @@ -1595,7 +1595,7 @@ "\n", - "> **Reproductibilite et non-determinisme** : meme avec `temperature=0.0`, les sorties du modele peuvent varier legerement d'une execution a l'autre (nondeterminisme numerique du serveur). Les taux (0% / 0% / 100%) sont robustes, mais les temps et le detail des reponses (ex. grille invalide vs reponse non-analysable en zero-shot) peuvent differer d'une realisation a l'autre. Pour reproduire, definir `LOCAL_LLM_API_KEY`, `LOCAL_LLM_BASE_URL` et `LOCAL_LLM_MODEL` dans l'environnement (serveur vLLM compatible OpenAI). Sans cle, le client bascule en mode simulation (fallback pedagogique) et les taux ci-dessus ne s'observent pas.\n", + "> **Reproductibilite et non-determinisme** : même avec `temperature=0.0`, les sorties du modèle peuvent varier legerement d'une exécution a l'autre (nondeterminisme numérique du serveur). Les taux (0% / 0% / 100%) sont robustes, mais les temps et le detail des reponses (ex. grille invalide vs reponse non-analysable en zero-shot) peuvent differer d'une realisation a l'autre. Pour reproduire, définir `LOCAL_LLM_API_KEY`, `LOCAL_LLM_BASE_URL` et `LOCAL_LLM_MODEL` dans l'environnement (serveur vLLM compatible OpenAI). Sans cle, le client bascule en mode simulation (fallback pedagogique) et les taux ci-dessus ne s'observent pas.\n", "\n", @@ -2253,7 +2253,7 @@ "\n", "Les LLM commettent souvent des erreurs lorsqu'on leur demande de resoudre directement un Sudoku. Une approche plus prometteuse est de combiner :\n", "1. **Chain-of-Thought** : Le LLM explique son raisonnement et propose une affectation a la fois\n", - "2. **Validation locale** : A chaque etape, on verifie que l'affectation proposee est valide\n", + "2. **Validation locale** : A chaque étape, on verifie que l'affectation proposee est valide\n", "3. **Correction interactive** : Si une erreur est detectee, on redemande au LLM\n", "\n", "### Solution de reference\n", @@ -2263,11 +2263,11 @@ "1. **Prompt CoT** : Le prompt demande au LLM d'identifier la case la plus contrainte et de proposer une affectation unique\n", "2. **Parser** : Extraction de l'affectation `(row, col) = value` depuis la reponse du LLM\n", "3. **Validation** : Chaque affectation est verifiee avant d'etre appliquee a la grille\n", - "4. **Budget de corrections** : Apres un nombre limite d'affectations invalides consecutives, le solveur abandonne (`Echec de la resolution`)\n", + "4. **Budget de corrections** : Après un nombre limite d'affectations invalides consecutives, le solveur abandonne (`Echec de la resolution`)\n", "\n", - "### Resultat de l'execution reelle\n", + "### Résultat de l'exécution reelle\n", "\n", - "Avec le modele Qwen3.6, ce solveur **ne resout pas le puzzle** dans le budget de corrections : les affectations proposees par le LLM sont frequemment invalides, et le budget s'epuise avant la resolution complete. Ce resultat est honnete et instructif : meme avec validation iterative cellule par cellule, la fiabilite limitee du LLM sur le raisonnement combinatoire rend l'approche fragile sur des puzzles non triviaux. La generation de code (approche 3) reste superieure car elle delegue *toute* la recherche a un algorithme execute.\n", + "Avec le modèle Qwen3.6, ce solveur **ne resout pas le puzzle** dans le budget de corrections : les affectations proposees par le LLM sont frequemment invalides, et le budget s'epuise avant la resolution complete. Ce résultat est honnete et instructif : même avec validation iterative cellule par cellule, la fiabilite limitee du LLM sur le raisonnement combinatoire rend l'approche fragile sur des puzzles non triviaux. La generation de code (approche 3) reste superieure car elle delegue *toute* la recherche a un algorithme execute.\n", "\n", "### Contrainte\n", "\n", @@ -2461,7 +2461,7 @@ "\n", "Dans ce notebook, nous avons explore l'utilisation des **Large Language Models** pour la resolution de Sudoku :\n", "\n", - "### Points Cles\n", + "### Points Clés\n", "\n", "1. **Trois approches principales** :\n", " - Zero-shot : Simple mais limite\n", diff --git a/MyIA.AI.Notebooks/Sudoku/Sudoku-18-Comparison-CSharp.ipynb b/MyIA.AI.Notebooks/Sudoku/Sudoku-18-Comparison-CSharp.ipynb index 2f7fee59ad..509cbc9132 100644 --- a/MyIA.AI.Notebooks/Sudoku/Sudoku-18-Comparison-CSharp.ipynb +++ b/MyIA.AI.Notebooks/Sudoku/Sudoku-18-Comparison-CSharp.ipynb @@ -62,7 +62,7 @@ "| 5 | [Dancing Links](Sudoku-02-DancingLinks-Python.ipynb) | Couverture exacte | Reduire a un problème de sélection de sous-ensembles |\n", "| 6 | [Infer.NET](Sudoku-15-Infer-Python.ipynb) | Inference probabiliste | Propager des distributions de probabilite |\n", "| 7 | [Norvig](Sudoku-07-Norvig-Python.ipynb) | Propagation de contraintes | Eliminer les impossibilites avant de chercher |\n", - "| 8 | Simulated Annealing | Recuit simule | Optimiser par perturbations aleatoires avec refroidissement |\n", + "| 8 | Simulated Annealing | Recuit simule | Optimiser par perturbations aléatoires avec refroidissement |\n", "| 10 | Neural Network | Apprentissage profond | Apprendre les motifs de resolution a partir d'exemples |\n", "\n", "Ce notebook final propose une **comparaison systématique** de ces approches selon plusieurs dimensions : vitesse, fiabilite, elegance du code et scalabilite. Nous implementerons 4 solveurs Python representatifs et les testerons sur un benchmark commun.\n", @@ -339,7 +339,7 @@ "\n", "| méthode | Principe | Fiabilite | Notebook |\n", "|---------|----------|-----------|----------|\n", - "| **Reseau de neurones** | Apprentissage supervise | Approximation, necessite données | Sudoku-16 |\n", + "| **Réseau de neurones** | Apprentissage supervise | Approximation, necessite données | Sudoku-16 |\n", "\n", "### 2.5 méthodes probabilistes\n", "\n", @@ -364,7 +364,7 @@ "source": [ "## 3. Implementations C# des solveurs\n", "\n", - "Pour une comparaison equitable, nous implementons **4 solveurs representatifs** dans le même environnement .NET (twin du notebook Python : memes solveurs, memes corpus, meme protocole statistique — seuls les idiomes different). Chaque solveur represente une catégorie différente.\n", + "Pour une comparaison equitable, nous implementons **4 solveurs representatifs** dans le même environnement .NET (twin du notebook Python : mêmes solveurs, mêmes corpus, même protocole statistique — seuls les idiomes different). Chaque solveur represente une catégorie différente.\n", "\n", "| Solveur | catégorie | Pourquoi ce choix |\n", "|---------|-----------|-------------------|\n", @@ -569,7 +569,7 @@ "| `clone` | Copie independante | Evite les interferences entre solveurs |\n", "| `is_valid_placement` | Valide un placement (ligne/colonne/bloc) | Utilisee par le backtracking |\n", "| `find_empty` | Trouve la première case vide | Parcours naive pour le backtracking simple |\n", - "| `count_empty` | Compte les cases vides | Metrique de difficulte |\n", + "| `count_empty` | Compte les cases vides | Métrique de difficulte |\n", "| `to_string` | Convertit en chaîne | Interface avec le solveur Norvig |\n", "\n", "**Grille de test** : 49 cases vides sur 81 (60% de la grille). C'est un puzzle de difficulte moyenne-facile qui servira de validation rapide pour chaque solveur.\n", @@ -688,12 +688,12 @@ "source": [ "### Interpretation : Solveur Backtracking simple\n", "\n", - "**résultat** : Le backtracking simple resout le puzzle de test en 201 appels recursifs (temps en ms en sortie live de la cellule ci-dessus -- regle #9434, non fige en prose car machine-dependant).\n", + "**résultat** : Le backtracking simple resout le puzzle de test en 201 appels recursifs (temps en ms en sortie live de la cellule ci-dessus -- règle #9434, non fige en prose car machine-dependant).\n", "\n", - "| Metrique | Valeur | Contexte |\n", + "| Métrique | Valeur | Contexte |\n", "|----------|--------|----------|\n", "| Appels recursifs | 201 | Nombre d'entrees dans `_backtrack` |\n", - "| Temps | (ms live, regle #9434) | Rapide pour ce puzzle facile |\n", + "| Temps | (ms live, règle #9434) | Rapide pour ce puzzle facile |\n", "| résultat | Succes | Solution trouvee |\n", "\n", "**Analyse** :\n", @@ -997,12 +997,12 @@ "source": [ "### Interpretation : Solveur Backtracking avec MRV\n", "\n", - "**résultat** : Le backtracking avec MRV resout le puzzle en 50 appels recursifs (temps en ms en sortie live -- regle #9434).\n", + "**résultat** : Le backtracking avec MRV resout le puzzle en 50 appels recursifs (temps en ms en sortie live -- règle #9434).\n", "\n", - "| Metrique | Backtracking simple | BT + MRV | Amelioration |\n", + "| Métrique | Backtracking simple | BT + MRV | Amelioration |\n", "|----------|--------------------|---------|-------------|\n", "| Appels recursifs | 201 | 50 | **4x moins** |\n", - "| Temps | (ms live -- regle #9434) | (ms live) | Plus lent |\n", + "| Temps | (ms live -- règle #9434) | (ms live) | Plus lent |\n", "\n", "**Paradoxe apparent** : MRV fait moins d'appels mais prend plus de temps. Cela s'explique par le cout de l'heuristique :\n", "\n", @@ -1203,12 +1203,12 @@ "source": [ "### Interpretation : Solveur Norvig (propagation de contraintes)\n", "\n", - "**résultat** : Norvig resout le puzzle en **1 appel récursif** (temps en ms en sortie live -- regle #9434).\n", + "**résultat** : Norvig resout le puzzle en **1 appel récursif** (temps en ms en sortie live -- règle #9434).\n", "\n", - "| Metrique | Valeur | Observation |\n", + "| Métrique | Valeur | Observation |\n", "|----------|--------|-------------|\n", "| Appels recursifs | 1 | Aucune recherche necessaire |\n", - "| Temps | (ms live, regle #9434) | Le plus lent sur ce puzzle facile (l'initialisation des structures domine) |\n", + "| Temps | (ms live, règle #9434) | Le plus lent sur ce puzzle facile (l'initialisation des structures domine) |\n", "\n", "**Pourquoi un seul appel ?**\n", "\n", @@ -1221,7 +1221,7 @@ "\n", "**Comparaison avec le backtracking** : Le solveur simple a necessite 201 appels recursifs pour le même puzzle. Norvig atteint la même solution en un seul appel grace a la propagation qui elimine les branches inutiles avant même de les explorer.\n", "\n", - "> **Point cle** : La force de Norvig n'est pas la vitesse pure sur un cas trivial -- sur ce puzzle facile, l'initialisation des structures de propagation (Squares/Units/Peers) coute plus cher que la recherche elle-même, d'où un temps supérieur au backtracking brut (ms live -- regle #9434). Cet investissement est rentabilisé dès que le puzzle résiste : sur le benchmark complet (cellule suivante), Norvig devient le plus rapide sur Medium/Hard/Expert la où le backtracking simple explose (ms live -- regle #9434). La vraie force de Norvig est la capacite a resoudre sans recherche, pas la vitesse pure.\n" + "> **Point cle** : La force de Norvig n'est pas la vitesse pure sur un cas trivial -- sur ce puzzle facile, l'initialisation des structures de propagation (Squares/Units/Peers) coute plus cher que la recherche elle-même, d'où un temps supérieur au backtracking brut (ms live -- règle #9434). Cet investissement est rentabilisé dès que le puzzle résiste : sur le benchmark complet (cellule suivante), Norvig devient le plus rapide sur Medium/Hard/Expert la où le backtracking simple explose (ms live -- règle #9434). La vraie force de Norvig est la capacite a resoudre sans recherche, pas la vitesse pure.\n" ] }, { @@ -1355,11 +1355,11 @@ "source": [ "### Interpretation : Solveur OR-Tools CP-SAT\n", "\n", - "**résultat** : OR-Tools resout le puzzle avec succes (temps en ms en sortie live -- regle #9434).\n", + "**résultat** : OR-Tools resout le puzzle avec succes (temps en ms en sortie live -- règle #9434).\n", "\n", - "| Metrique | Valeur | Observation |\n", + "| Métrique | Valeur | Observation |\n", "|----------|--------|-------------|\n", - "| Temps | (ms live, regle #9434) | Plus lent que Norvig sur ce puzzle (overhead de modelisation) |\n", + "| Temps | (ms live, règle #9434) | Plus lent que Norvig sur ce puzzle (overhead de modelisation) |\n", "| Appels | 1 | Le solveur gere tout en interne |\n", "\n", "**Analyse** :\n", @@ -1953,7 +1953,7 @@ "source": [ "### Lancement du benchmark\n", "\n", - "Nous executons le benchmark statistique sur les solveurs du framework : 5 grilles par difficulte, repetitions des runs rapides, et un timeout **cooperatif** de 30 secondes par essai -- chaque solveur consulte l'echeance `BenchClock` et leve `SolverTimeoutException`, le calcul est reellement interrompu (aucune tache orpheline ne survit au budget)." + "Nous executons le benchmark statistique sur les solveurs du framework : 5 grilles par difficulte, repetitions des runs rapides, et un timeout **cooperatif** de 30 secondes par essai -- chaque solveur consulte l'echeance `BenchClock` et leve `SolverTimeoutException`, le calcul est reellement interrompu (aucune tâche orpheline ne survit au budget)." ] }, { @@ -2423,7 +2423,7 @@ "source": [ "### Visualisation : mediane par difficulte\n", "\n", - "Le graphique en barres groupees montre la **mediane** de resolution pour chaque solveur sur chaque niveau de difficulte. L'echelle logarithmique permet de comparer des ordres de grandeur tres differents ; une barre nulle (listee sous le graphique) signale une difficulte entierement censuree (timeouts) -- information en soi." + "Le graphique en barres groupees montre la **mediane** de resolution pour chaque solveur sur chaque niveau de difficulte. L'echelle logarithmique permet de comparer des ordres de grandeur très différents ; une barre nulle (listee sous le graphique) signale une difficulte entierement censuree (timeouts) -- information en soi." ] }, { @@ -2884,10 +2884,10 @@ "\n", "### Implementation\n", "\n", - "Le solveur demarre par un **pre-remplissage structure** : chaque ligne est completee par une permutation aleatoire des chiffres qui lui manquent, de sorte que chaque ligne soit valide (permutation de 1..9) des le depart -- les conflits ne residuent plus que dans les colonnes et les blocs. Ensuite, a chaque pas, le solveur **echange (swap)** les valeurs de deux cases non-verrouillees prises dans une même ligne : ce move preserve la validite de la ligne, seuls les conflits de colonnes et de blocs peuvent changer. L'acceptation d'un move degradeur suit le critere de Metropolis (probabilite exp(-delta/T) qui decroit avec la \"temperature\" T). Le succes est obtenu quand le score (nombre de doublons sur les 9 colonnes et 9 blocs) tombe a 0.\n", + "Le solveur demarre par un **pre-remplissage structure** : chaque ligne est completee par une permutation aléatoire des chiffres qui lui manquent, de sorte que chaque ligne soit valide (permutation de 1..9) des le depart -- les conflits ne residuent plus que dans les colonnes et les blocs. Ensuite, a chaque pas, le solveur **echange (swap)** les valeurs de deux cases non-verrouillees prises dans une même ligne : ce move preserve la validite de la ligne, seuls les conflits de colonnes et de blocs peuvent changer. L'acceptation d'un move degradeur suit le critere de Metropolis (probabilite exp(-delta/T) qui decroit avec la \"temperature\" T). Le succes est obtenu quand le score (nombre de doublons sur les 9 colonnes et 9 blocs) tombe a 0.\n", "\n", "\n", - "> **Note de parite (graine RNG).** Le recuit simule est stochastique : la convergence depend de la sequence pseudo-aleatoire. Le twin Python resout le puzzle facile avec `seed=42` (981 itérations), car `random.seed(42)` produit une sequence qui converge tôt. Ce twin C# utilise `seed=51` : `System.Random(42)` produit une **sequence différente** qui reste bloquee dans un minimum local (score residual 2), tandis que `Random(51)` converge en ~1274 itérations. L'algorithme (init par permutation de ligne, swap intra-ligne, critere de Metropolis, refroidissement geometrique alpha=0.999) est **identique** au twin Python -- seule la sequence RNG differe, ce qui est intrinseque a l'ecart `System.Random` vs Mersenne Twister de Python. Sur 600 graines C# testees, ~3% convergent en <4000 itérations (ratio similaire a Python). C'est précisément le message pedagogique du Prong B (#3801) : une métaheuristique n'a **aucune garantie** de convergence." + "> **Note de parite (graine RNG).** Le recuit simule est stochastique : la convergence depend de la sequence pseudo-aléatoire. Le twin Python resout le puzzle facile avec `seed=42` (981 itérations), car `random.seed(42)` produit une sequence qui converge tôt. Ce twin C# utilise `seed=51` : `System.Random(42)` produit une **sequence différente** qui reste bloquee dans un minimum local (score residual 2), tandis que `Random(51)` converge en ~1274 itérations. L'algorithme (init par permutation de ligne, swap intra-ligne, critere de Metropolis, refroidissement geometrique alpha=0.999) est **identique** au twin Python -- seule la sequence RNG differe, ce qui est intrinseque a l'ecart `System.Random` vs Mersenne Twister de Python. Sur 600 graines C# testees, ~3% convergent en <4000 itérations (ratio similaire a Python). C'est précisément le message pedagogique du Prong B (#3801) : une métaheuristique n'a **aucune garantie** de convergence." ] }, { @@ -3197,7 +3197,7 @@ "source": [ "### exécution du benchmark etendu\n", "\n", - "Nous mesurons les **2 solveurs supplémentaires** -- Norvig + Forward Checking et le recuit simule -- avec le meme protocole statistique que le benchmark principal (5 grilles par difficulte, timeout cooperatif, censure). Les 4 solveurs coeur ne sont pas rejoues : leurs mesures ci-dessus restent valables." + "Nous mesurons les **2 solveurs supplémentaires** -- Norvig + Forward Checking et le recuit simule -- avec le même protocole statistique que le benchmark principal (5 grilles par difficulte, timeout cooperatif, censure). Les 4 solveurs coeur ne sont pas rejoues : leurs mesures ci-dessus restent valables." ] }, { @@ -3343,21 +3343,21 @@ "source": [ "### Analyse : le solveur Norvig + FC est-il competitif ?\n", "\n", - "**Reponse courte** : oui -- mais l'ecart avec le Norvig standard se lit dans les tableaux imprimes ci-dessus (benchmark principal pour Norvig, etendu pour Norvig + FC), en comparant des **medianes [p25-p75] obtenues sur le meme protocole** -- jamais deux temps ponctuels isoles.\n", + "**Reponse courte** : oui -- mais l'ecart avec le Norvig standard se lit dans les tableaux imprimes ci-dessus (benchmark principal pour Norvig, etendu pour Norvig + FC), en comparant des **medianes [p25-p75] obtenues sur le même protocole** -- jamais deux temps ponctuels isoles.\n", "\n", "**Comment lire la comparaison** :\n", "\n", "1. **Verifier les effectifs et taux d'abord**. Les deux solveurs completent l'ensemble (timeouts a 0) : les medianes sont donc comparables sans biais de censure -- c'est la condition que le protocole rend explicite.\n", "\n", - "2. **Performances quasi identiques a Norvig**. Sur ce corpus, Norvig + FC resout avec un nombre de coupes FC proche de zero : la propagation `Eliminate` deja presente dans Norvig detecte les domaines vides a la source, le forward check explicite ne coupe en pratique aucune branche additionnelle.\n", + "2. **Performances quasi identiques a Norvig**. Sur ce corpus, Norvig + FC resout avec un nombre de coupes FC proche de zero : la propagation `Eliminate` déjà presente dans Norvig detecte les domaines vides a la source, le forward check explicite ne coupe en pratique aucune branche additionnelle.\n", "\n", - "3. **Dans le bruit de mesure**. Les repetitions des runs rapides donnent l'echelle du bruit systeme : si l'ecart Norvig vs Norvig + FC est du meme ordre que ce spread, aucun gain ni surcharge du FC n'est demonstrable.\n", + "3. **Dans le bruit de mesure**. Les repetitions des runs rapides donnent l'echelle du bruit système : si l'ecart Norvig vs Norvig + FC est du même ordre que ce spread, aucun gain ni surcharge du FC n'est demonstrable.\n", "\n", - "4. **Ou le forward checking brille reellement**. Si on retirait la propagation puissante de Norvig (elimination + naked singles) et qu'on gardait uniquement un backtracking MRV + forward checking, l'impact du FC serait beaucoup plus visible : il servirait de principal mecanisme d'elagage. Ici, la propagation fait deja l'essentiel du travail.\n", + "4. **Ou le forward checking brille reellement**. Si on retirait la propagation puissante de Norvig (elimination + naked singles) et qu'on gardait uniquement un backtracking MRV + forward checking, l'impact du FC serait beaucoup plus visible : il servirait de principal mécanisme d'elagage. Ici, la propagation fait déjà l'essentiel du travail.\n", "\n", - "5. **Le recuit simule** : metaheuristique sans garantie -- ses timeouts censurees au denominateur sont une information (le voisinage par permutations de lignes explore mal l'espace des sudokus), pas un echec du protocole.\n", + "5. **Le recuit simule** : métaheuristique sans garantie -- ses timeouts censurees au denominateur sont une information (le voisinage par permutations de lignes explore mal l'espace des sudokus), pas un echec du protocole.\n", "\n", - "**Conclusion** : le forward checking est une **technique fondamentale** en CSP, mais son utilite depend du solveur dans lequel on l'integre. Sur un solveur deja fortement propage comme Norvig, il est redondant ; sur un backtracking naif, il apporte un gain enorme. C'est un bon exemple du principe **\"la somme des ameliorations n'est pas toujours additive\"** : certaines techniques se recouvrent." + "**Conclusion** : le forward checking est une **technique fondamentale** en CSP, mais son utilite depend du solveur dans lequel on l'integre. Sur un solveur déjà fortement propage comme Norvig, il est redondant ; sur un backtracking naif, il apporte un gain enorme. C'est un bon exemple du principe **\"la somme des ameliorations n'est pas toujours additive\"** : certaines techniques se recouvrent." ] }, { @@ -3726,7 +3726,7 @@ "\n", "Ce notebook a compare **4 solveurs Python** representatifs de paradigmes algorithmiques distincts pour la resolution du Sudoku.\n", "\n", - "### Concepts cles a retenir\n", + "### Concepts clés a retenir\n", "\n", "| Concept | Solveur(s) concerne(s) | Idee principale |\n", "|---------|----------------------|-----------------|\n", diff --git a/MyIA.AI.Notebooks/Sudoku/Sudoku-18-Comparison-Python.ipynb b/MyIA.AI.Notebooks/Sudoku/Sudoku-18-Comparison-Python.ipynb index 05c62e1006..015d4cd992 100644 --- a/MyIA.AI.Notebooks/Sudoku/Sudoku-18-Comparison-Python.ipynb +++ b/MyIA.AI.Notebooks/Sudoku/Sudoku-18-Comparison-Python.ipynb @@ -217,7 +217,7 @@ "\n", "| Méthode | Principe | Fiabilite | Notebook |\n", "|---------|----------|-----------|----------|\n", - "| **Reseau de neurones** | Apprentissage supervise | Approximation, necessite données | Sudoku-16 |\n", + "| **Réseau de neurones** | Apprentissage supervise | Approximation, necessite données | Sudoku-16 |\n", "\n", "### 2.5 Méthodes probabilistes\n", "\n", @@ -397,7 +397,7 @@ "| `clone` | Copie independante | Evite les interferences entre solveurs |\n", "| `is_valid_placement` | Valide un placement (ligne/colonne/bloc) | Utilisee par le backtracking |\n", "| `find_empty` | Trouve la première case vide | Parcours naive pour le backtracking simple |\n", - "| `count_empty` | Compte les cases vides | Metrique de difficulté |\n", + "| `count_empty` | Compte les cases vides | Métrique de difficulté |\n", "| `to_string` | Convertit en chaîne | Interface avec le solveur Norvig |\n", "\n", "**Grille de test** : 49 cases vides sur 81 (60% de la grille). C'est un puzzle de difficulté moyenne-facile qui servira de validation rapide pour chaque solveur.\n", @@ -512,12 +512,12 @@ "source": [ "### Interpretation : Solveur Backtracking simple\n", "\n", - "**Résultat** : Le backtracking simple resout le puzzle de test en 201 appels recursifs (temps en ms en sortie live de la cellule ci-dessus -- regle #9434, non fige en prose car machine-dependant).\n", + "**Résultat** : Le backtracking simple resout le puzzle de test en 201 appels recursifs (temps en ms en sortie live de la cellule ci-dessus -- règle #9434, non fige en prose car machine-dependant).\n", "\n", - "| Metrique | Valeur | Contexte |\n", + "| Métrique | Valeur | Contexte |\n", "|----------|--------|----------|\n", "| Appels recursifs | 201 | Nombre d'entrees dans `_backtrack` |\n", - "| Temps | (ms live, regle #9434) | Rapide pour ce puzzle facile |\n", + "| Temps | (ms live, règle #9434) | Rapide pour ce puzzle facile |\n", "| Résultat | Succes | Solution trouvee |\n", "\n", "**Analyse** :\n", @@ -779,12 +779,12 @@ "source": [ "### Interpretation : Solveur Backtracking avec MRV\n", "\n", - "**Résultat** : Le backtracking avec MRV resout le puzzle en 50 appels recursifs (temps en ms en sortie live -- regle #9434).\n", + "**Résultat** : Le backtracking avec MRV resout le puzzle en 50 appels recursifs (temps en ms en sortie live -- règle #9434).\n", "\n", - "| Metrique | Backtracking simple | BT + MRV | Amelioration |\n", + "| Métrique | Backtracking simple | BT + MRV | Amelioration |\n", "|----------|--------------------|---------|-------------|\n", "| Appels recursifs | 201 | 50 | **4x moins** |\n", - "| Temps | (ms live -- regle #9434) | (ms live) | Plus lent |\n", + "| Temps | (ms live -- règle #9434) | (ms live) | Plus lent |\n", "\n", "**Paradoxe apparent** : MRV fait moins d'appels mais prend plus de temps. Cela s'explique par le cout de l'heuristique :\n", "\n", @@ -980,12 +980,12 @@ "source": [ "### Interpretation : Solveur Norvig (propagation de contraintes)\n", "\n", - "**Résultat** : Norvig resout le puzzle en **1 appel récursif** (temps en ms en sortie live -- regle #9434).\n", + "**Résultat** : Norvig resout le puzzle en **1 appel récursif** (temps en ms en sortie live -- règle #9434).\n", "\n", - "| Metrique | Valeur | Observation |\n", + "| Métrique | Valeur | Observation |\n", "|----------|--------|-------------|\n", "| Appels recursifs | 1 | Aucune recherche nécessaire |\n", - "| Temps | (ms live, regle #9434) | Le plus rapide sur ce puzzle |\n", + "| Temps | (ms live, règle #9434) | Le plus rapide sur ce puzzle |\n", "\n", "**Pourquoi un seul appel ?**\n", "\n", @@ -1137,11 +1137,11 @@ "source": [ "### Interpretation : Solveur OR-Tools CP-SAT\n", "\n", - "**Résultat** : OR-Tools resout le puzzle avec succès (temps en ms en sortie live -- regle #9434).\n", + "**Résultat** : OR-Tools resout le puzzle avec succès (temps en ms en sortie live -- règle #9434).\n", "\n", - "| Metrique | Valeur | Observation |\n", + "| Métrique | Valeur | Observation |\n", "|----------|--------|-------------|\n", - "| Temps | (ms live, regle #9434) | Plus lent que Norvig sur ce puzzle (overhead de modelisation) |\n", + "| Temps | (ms live, règle #9434) | Plus lent que Norvig sur ce puzzle (overhead de modelisation) |\n", "| Appels | 1 | Le solveur gere tout en interne |\n", "\n", "**Analyse** :\n", @@ -1925,7 +1925,7 @@ "source": [ "### Visualisation : mediane par difficulte\n", "\n", - "Le graphique en barres groupees montre la **mediane** de resolution pour chaque solveur sur chaque niveau de difficulte, avec les barres d'erreur p25-p75. L'echelle symlog permet de comparer des ordres de grandeur tres differents ; une barre nulle annotee \"0/n TO\" signale une difficulte entierement censuree (timeouts), information en soi." + "Le graphique en barres groupees montre la **mediane** de resolution pour chaque solveur sur chaque niveau de difficulte, avec les barres d'erreur p25-p75. L'echelle symlog permet de comparer des ordres de grandeur très différents ; une barre nulle annotee \"0/n TO\" signale une difficulte entierement censuree (timeouts), information en soi." ] }, { @@ -2716,9 +2716,9 @@ "tags": [] }, "source": [ - "### Execution du benchmark etendu\n", + "### Exécution du benchmark etendu\n", "\n", - "Nous mesurons les **2 solveurs supplementaires** -- Norvig + Forward Checking et le recuit simule -- avec le meme protocole statistique que le benchmark principal (5 grilles par difficulte, timeout cooperatif, censure). Les 4 solveurs coeur ne sont pas rejoues : leurs mesures ci-dessus restent valables (deterministes ou comparees en mediane)." + "Nous mesurons les **2 solveurs supplementaires** -- Norvig + Forward Checking et le recuit simule -- avec le même protocole statistique que le benchmark principal (5 grilles par difficulte, timeout cooperatif, censure). Les 4 solveurs coeur ne sont pas rejoues : leurs mesures ci-dessus restent valables (déterministes ou comparees en mediane)." ] }, { @@ -2795,21 +2795,21 @@ "source": [ "### Analyse : le solveur Norvig + FC est-il competitif ?\n", "\n", - "**Reponse courte** : oui -- mais l'ecart avec le Norvig standard se lit dans les tableaux imprimes ci-dessus (benchmark principal pour Norvig, etendu pour Norvig + FC), en comparant des **medianes [p25-p75] obtenues sur le meme protocole** -- jamais deux temps ponctuels isoles.\n", + "**Reponse courte** : oui -- mais l'ecart avec le Norvig standard se lit dans les tableaux imprimes ci-dessus (benchmark principal pour Norvig, etendu pour Norvig + FC), en comparant des **medianes [p25-p75] obtenues sur le même protocole** -- jamais deux temps ponctuels isoles.\n", "\n", "**Comment lire la comparaison** :\n", "\n", "1. **Verifier les effectifs et taux d'abord**. Les deux solveurs completent l'ensemble (timeouts a 0) : les medianes sont donc compareables sans biais de censure -- c'est la condition que le protocole rend explicite.\n", "\n", - "2. **Performances quasi identiques a Norvig**. Sur ce corpus, Norvig + FC resout avec un nombre de coupes FC proche de zero : la propagation `_eliminate` deja presente dans Norvig detecte les domaines vides a la source, le forward check explicite ne coupe en pratique aucune branche additionnelle.\n", + "2. **Performances quasi identiques a Norvig**. Sur ce corpus, Norvig + FC resout avec un nombre de coupes FC proche de zero : la propagation `_eliminate` déjà presente dans Norvig detecte les domaines vides a la source, le forward check explicite ne coupe en pratique aucune branche additionnelle.\n", "\n", - "3. **Dans le bruit de mesure**. Les repetitions des runs rapides (protocol ci-dessus) donnent l'echelle du bruit systeme : si l'ecart Norvig vs Norvig + FC est du meme ordre que ce spread, aucun gain ni surcharge du FC n'est demonstrable. Le surcout theorique du FC (parcours des 81 cases a chaque descente recursive) est noye dans ce bruit.\n", + "3. **Dans le bruit de mesure**. Les repetitions des runs rapides (protocol ci-dessus) donnent l'echelle du bruit système : si l'ecart Norvig vs Norvig + FC est du même ordre que ce spread, aucun gain ni surcharge du FC n'est demonstrable. Le surcout théorique du FC (parcours des 81 cases a chaque descente récursive) est noye dans ce bruit.\n", "\n", - "4. **Ou le forward checking brille reellement**. Si on retirait la propagation puissante de Norvig (elimination + naked singles) et qu'on gardait uniquement un backtracking MRV + forward checking, l'impact du FC serait beaucoup plus visible : il servirait de principal mecanisme d'elagage. Ici, la propagation fait deja l'essentiel du travail.\n", + "4. **Ou le forward checking brille reellement**. Si on retirait la propagation puissante de Norvig (elimination + naked singles) et qu'on gardait uniquement un backtracking MRV + forward checking, l'impact du FC serait beaucoup plus visible : il servirait de principal mécanisme d'elagage. Ici, la propagation fait déjà l'essentiel du travail.\n", "\n", - "5. **Le recuit simule** : metaheuristique sans garantie -- ses timeouts censurees au denominateur sont une information (le voisinage par permutations de lignes explore mal l'espace des sudokus), pas un echec du protocole.\n", + "5. **Le recuit simule** : métaheuristique sans garantie -- ses timeouts censurees au denominateur sont une information (le voisinage par permutations de lignes explore mal l'espace des sudokus), pas un echec du protocole.\n", "\n", - "**Conclusion** : le forward checking est une **technique fondamentale** en CSP, mais son utilite depend du solveur dans lequel on l'integre. Sur un solveur deja fortement propage comme Norvig, il est redondant ; sur un backtracking naif, il apporte un gain enorme. C'est un bon exemple du principe **\"la somme des ameliorations n'est pas toujours additive\"** : certaines techniques se recouvrent." + "**Conclusion** : le forward checking est une **technique fondamentale** en CSP, mais son utilite depend du solveur dans lequel on l'integre. Sur un solveur déjà fortement propage comme Norvig, il est redondant ; sur un backtracking naif, il apporte un gain enorme. C'est un bon exemple du principe **\"la somme des ameliorations n'est pas toujours additive\"** : certaines techniques se recouvrent." ] }, { @@ -3212,7 +3212,7 @@ "\n", "Ce notebook a compare **4 solveurs Python** représentatifs de paradigmes algorithmiques distincts pour la résolution du Sudoku.\n", "\n", - "### Concepts cles a retenir\n", + "### Concepts clés a retenir\n", "\n", "| Concept | Solveur(s) concerne(s) | Idee principale |\n", "|---------|----------------------|-----------------|\n", diff --git a/scripts/notebook_tools/twin_pairs.d/sudoku-13-symbolicautomata.yaml b/scripts/notebook_tools/twin_pairs.d/sudoku-13-symbolicautomata.yaml index 570d516d2d..fa00290a1e 100644 --- a/scripts/notebook_tools/twin_pairs.d/sudoku-13-symbolicautomata.yaml +++ b/scripts/notebook_tools/twin_pairs.d/sudoku-13-symbolicautomata.yaml @@ -6,6 +6,7 @@ bridge_verdict: SOTA-OK bridge_verdict_reason: "Microsoft.Z3 (NuGet officiel, axe 1 du registre #3801) atteint la theorie des chaines et resout la **contrainte d'automate symbolique** via `str.in_re` / `re.++` / `re.*` / `str.to_re`. Annexe S10 du notebook C# (cellules 46-48) : constructeur d'automate symbolique inline (StringBuilder SMT-LIB 2.6) -> temoin mesure en ~133 ms (Z3 4.12.2.0). Le plafond SFAz3+Z3 'monstre regex tronque' (issue AutomataDotNet/Automata#6) reste une limite **academique et documentee** : elle vit dans `known_differences` et ne peut pas motiver un verdict de parite (les deux jumeaux sont frappes a l'identique, voir precedent GT-17 #10464 / GT-13 #10470). Readjudication de coherence 2026-08-25 (dispatch #10382, comment 5412568851, lane myia-po-2024:CoursIA) : le verdict RECOVERABLE-LOCAL contredisait sa propre raison -- l'annexe S10 exerce DEJA le pont Z3 str.in_re avec temoin mesure (~133 ms), reverifie firsthand ce jour (14 cellules Z3/str.in_re dans le twin C#, dont les cellules 0/1/17/18/21/23/26/29). Le pont est livre et execute : rien a recuperer, verdict SOTA-OK. Addendum 2026-08-29 (tranche BDD, lane myia-po-2025:CoursIA) : l'axe BDD est desormais couvert par le MEME moteur des deux cotes -- annexe S11 du notebook C#, pont pythonnet 3.1.0 -> CPython -> dd 0.6.0 epingle (axe 5 du registre #3801), miroir de la section 9 du jumeau Python (dd natif). Chiffres croises identiques dans les outputs committes (90 noeuds, 6 lignes valides, modele (2, 1, 3)) + contre-verification exhaustive des 64 lignes des deux cotes. Verdict SOTA-OK conforte." known_differences: + - "Re-baseline 2026-10-14 (hors-flotte:claude-session-16638, #16638) : restauration des accents de la prose markdown (tranche sudoku-b #16638, outil canonique restore_accents_canonical.py, invariance strip_accents a 0 finding), cote Python seul ; cote C# byte-identique a main. Aucune cellule de code, sortie ni execution_count touchee. Parite inchangee : attestation (le blob SHA se deplace), pas reparation. --update en DERNIERE operation (cf #8957)." - "2026-09-02 (grain hr-separateurs famille Sudoku, myia-po-2027:CoursIA) : conversion des separateurs markdown --- vers *** via fix_hr_separator.py (incident #11451 : un --- seul ouvre un bloc YAML Pandoc et casse quarto render) -- jumeau Python seul (1 separateur). Cellules markdown uniquement, aucune source de code ni output modifiee, pas de re-exec (C.2 exception markdown-only). Les blob et content SHAs deplaces dans l audit ci-dessus sont des artefacts de cette conversion markdown (le content_sha hashe le JSON canonique des cellules), pas une divergence pedagogique." - "Socle pedagogique commun : automates symboliques et resolution de Sudoku via Z3 (automates finis symboliques, representation symbolique des contraintes, liens avec SMT). Meme concept (automates symboliques + Z3 comme backend de decision), meme cas d'application (Sudoku). Les deux couvrent Z3, z3, symbolic, Solver." - "Divergence d'implementation : le C# (Microsoft.Z3 via NuGet + auto-suffisant en annexe S10, 19 cellules code apres #10459) utilise la theorie des chaines Z3 et la regle `re.++` / `re.*` / `re.range` / `str.to_re` pour la partie symbolique. Le Python (pyz3, 10 cellules code) utilise les bindings Z3 directement. Meme enseignement (automates symboliques + Z3), deux niveaux." diff --git a/scripts/notebook_tools/twin_pairs.d/sudoku-13-symbolicautomata/0024-2026-10-14-hors-flotte-claude-session-16638.yaml b/scripts/notebook_tools/twin_pairs.d/sudoku-13-symbolicautomata/0024-2026-10-14-hors-flotte-claude-session-16638.yaml new file mode 100644 index 0000000000..fdc3cffee4 --- /dev/null +++ b/scripts/notebook_tools/twin_pairs.d/sudoku-13-symbolicautomata/0024-2026-10-14-hors-flotte-claude-session-16638.yaml @@ -0,0 +1,6 @@ +date: '2026-10-14' +by: hors-flotte:claude-session-16638 +python_sha: 249d7cac9866af317566be18f3e2b7754f9abcec +csharp_sha: 866ad1947e6874d593b34127d3fd9e923c29f3ab +content_python_sha: 204045a0fe85a97e8f54741650cb2e2329cf43e2670e5bbe0353db191f05a834 +content_csharp_sha: bcd3cc1470232bfe95bbea1d7ebc06688ad1722f2d865f88adce3dd8f94d3822 diff --git a/scripts/notebook_tools/twin_pairs.d/sudoku-13-symbolicautomata/0025-2026-10-15-hors-flotte-claude-session-16638.yaml b/scripts/notebook_tools/twin_pairs.d/sudoku-13-symbolicautomata/0025-2026-10-15-hors-flotte-claude-session-16638.yaml new file mode 100644 index 0000000000..b8d2401516 --- /dev/null +++ b/scripts/notebook_tools/twin_pairs.d/sudoku-13-symbolicautomata/0025-2026-10-15-hors-flotte-claude-session-16638.yaml @@ -0,0 +1,6 @@ +date: '2026-10-15' +by: hors-flotte:claude-session-16638 +python_sha: ec5137ae76838280cd7782f8a05c9821c831c4ac +csharp_sha: 866ad1947e6874d593b34127d3fd9e923c29f3ab +content_python_sha: eba67240ffbe95d9fe256fcb21f714bdcaf6b4c022fc6d948d1b9abfb1203b33 +content_csharp_sha: bcd3cc1470232bfe95bbea1d7ebc06688ad1722f2d865f88adce3dd8f94d3822 diff --git a/scripts/notebook_tools/twin_pairs.d/sudoku-14-bdd.yaml b/scripts/notebook_tools/twin_pairs.d/sudoku-14-bdd.yaml index d7e338a7c1..f659697a35 100644 --- a/scripts/notebook_tools/twin_pairs.d/sudoku-14-bdd.yaml +++ b/scripts/notebook_tools/twin_pairs.d/sudoku-14-bdd.yaml @@ -6,6 +6,7 @@ bridge_verdict: SOTA-OK bridge_verdict_reason: "Solver-free by design : les deux jumeaux implementent les BDD/MDD (Binary/Multi-valued Decision Diagrams) from-scratch en pure stdlib. Python = `__future__/dataclasses/time/typing` uniquement (zero solveur externe, confirme par grep `import`/`from` = {`__future__`, `dataclasses`, `time`, `typing`}, aucune lib BDD tierce). C# = `System.Collections.Generic/System.Diagnostics/System.Linq` uniquement (zero solveur externe, confirme par grep `using` = {`System.Collections.Generic`, `System.Diagnostics`, `System.Linq`}, aucune lib BDD tierce). Verifie firsthand (c.235 audit 2026-08-12, myia-po-2023:CoursIA-2) : 33 cells Python / 40 cells C#, divergence d'implementation documentee dans known_differences (Python hand-roll, C# hand-roll avec idiomes differents). Pas de moteur SOTA a brancher : les BDD sont la demonstration (construction recursive de l'arbre de decisions, application des contraintes Sudoku comme noeuds BDD, evaluation par reduction). Verdict SOTA-OK : solver-free by design des deux cotes, aucune asymetrie de machinerie a corriger. parity_level `semantic` confirmee par audit (meme concept BDD, implementation differente)." known_differences: + - "Re-baseline 2026-10-14 (hors-flotte:claude-session-16638, #16638) : restauration des accents de la prose markdown (tranche sudoku-b #16638, outil canonique restore_accents_canonical.py, invariance strip_accents a 0 finding), cote Python seul ; cote C# byte-identique a main. Aucune cellule de code, sortie ni execution_count touchee. Parite inchangee : attestation (le blob SHA se deplace), pas reparation. --update en DERNIERE operation (cf #8957)." - "Re-baseline 2026-09-11 (myia-po-2023:CoursIA, #15446 / chore #15429) : suite de la normalisation str->list des cellules `source` (representation seule, aucun contenu pedagogique touche) l'attestation a ete refaite a l'ordinal 0012, au-dessus du 0011 venu de main (#15449, T8) qui portait l'etat pre-normalisation sous un ordinal superieur et masquait celle de cette PR — collision d'ordinal diagnostiquee firsthand par ai-01 sur #15446 ; l'ancien 0010 de cette PR, en collision avec le 0010-2026-09-08 de main, est retire. Verifie firsthand : le SHA canonique du carnet (toutes listes-de-chaines jointes, metadata de niveau carnet exclue) est IDENTIQUE base vs head, et les champs `text` des sorties sont inchanges ; seul le content_sha du registre bouge. Le garde #8057 demande une attestation de parite, pas une reparation." - "2026-09-02 (grain hr-separateurs famille Sudoku, myia-po-2027:CoursIA) : conversion des separateurs markdown --- vers *** via fix_hr_separator.py (incident #11451 : un --- seul ouvre un bloc YAML Pandoc et casse quarto render) -- jumeau C# seul (13 separateurs). Cellules markdown uniquement, aucune source de code ni output modifiee, pas de re-exec (C.2 exception markdown-only). Les blob et content SHAs deplaces dans l audit ci-dessus sont des artefacts de cette conversion markdown (le content_sha hashe le JSON canonique des cellules), pas une divergence pedagogique." - "Socle pedagogique commun : resolution du Sudoku par automates a decision binaire (BDD / MDD, Binary/Multi-valued Decision Diagrams), meme concept (codage booleen des contraintes, reduction canonique du graphe de decision, satisfaction via parcours). Le notebook Python declare explicitement etre le jumeau du C# (« Jumeau Python du notebook Sudoku-14-BDD-CSharp.ipynb »)." diff --git a/scripts/notebook_tools/twin_pairs.d/sudoku-14-bdd/0017-2026-10-14-hors-flotte-claude-session-16638.yaml b/scripts/notebook_tools/twin_pairs.d/sudoku-14-bdd/0017-2026-10-14-hors-flotte-claude-session-16638.yaml new file mode 100644 index 0000000000..9b522ac8fc --- /dev/null +++ b/scripts/notebook_tools/twin_pairs.d/sudoku-14-bdd/0017-2026-10-14-hors-flotte-claude-session-16638.yaml @@ -0,0 +1,6 @@ +date: '2026-10-14' +by: hors-flotte:claude-session-16638 +python_sha: 5c35b2f09c8aa9e35cbab224783cd1564ae65764 +csharp_sha: d7152c5b77dbeec95bc75b404634d186a4007abd +content_python_sha: 935a8b6c96cd4a24a31ce5e597519e808e75348803d9be8db121754cb1e57dbb +content_csharp_sha: 1a658a67c5d2eac5cd9f09dbe56496c4c6201dc84111696dbf19451dcc163d19 diff --git a/scripts/notebook_tools/twin_pairs.d/sudoku-15-infer.yaml b/scripts/notebook_tools/twin_pairs.d/sudoku-15-infer.yaml index db90d2daa0..36f2728c81 100644 --- a/scripts/notebook_tools/twin_pairs.d/sudoku-15-infer.yaml +++ b/scripts/notebook_tools/twin_pairs.d/sudoku-15-infer.yaml @@ -6,6 +6,7 @@ bridge_verdict: SOTA-OK bridge_verdict_reason: "Lib-vs-lib idiomatic-stack probabiliste : Python = NumPyro (SOTA Python probabilistic programming framework sur JAX, MCMC + inference variationnelle, stochastic). C# = Infer.NET (Microsoft Research legacy, SOTA .NET probabilistic programming framework, MCMC + expectation propagation + variational message passing, deterministic compilation). Les deux utilisent la SOTA PPL de leur stack respective. Pont cross-stack impossible : NumPyro est JAX-based (Python only, JAX compile XLA), Infer.NET est .NET only (compilation deterministe vers C#). Aucun bytecode commun bridgeable (pas de JPype, pas d'IKVM -- les deux PPL sont compiles dans leur stack respective). Verifie firsthand (c.235 audit 2026-08-12, myia-po-2023:CoursIA-2) : Python 34 cells / C# 47 cells, structure pedagogique symetrique (modele probabiliste Sudoku, observations, inference posterior). Asymetrie : Python = stochastic MCMC (echantillonnage NUTS), C# = deterministic variational message passing (EP/VMP). Les deux methodes sont SOTA dans leur stack, et l'objectif pedagogique (modeliser l'incertitude sur les valeurs Sudoku) est tenu. Verdict SOTA-OK : lib-vs-lib idiomatic-stack PPL, aucune asymetrie engine-mismatch a corriger." known_differences: + - "Re-baseline 2026-10-14 (hors-flotte:claude-session-16638, #16638) : restauration des accents de la prose markdown (tranche sudoku-b #16638, outil canonique restore_accents_canonical.py, invariance strip_accents a 0 finding), cote Python seul ; cote C# byte-identique a main. Aucune cellule de code, sortie ni execution_count touchee. Parite inchangee : attestation (le blob SHA se deplace), pas reparation. --update en DERNIERE operation (cf #8957)." - "2026-10-05 (PR #19252, myia-po-2024:CoursIA) : tranche A de #19240 -- reancrage markdown des titres et narrations (references a des marqueurs de processus supprimes, reancres sur le contenu reel du notebook). Portee : les DEUX cotes, 6 cellules markdown C# et 6 Python. Zero cellule code touchee, pas de re-exec (C.3) ; divergeance de forme seulement, le socle pedagogique commun et le bridge_verdict sont inchanges. Detail : les deux cotes touches a parts egales (6 C# / 6 Py)." - "Rebaseline 2026-09-07 : cote C# -- mission user degenerescence (PR #15010) : (1) ShowProgress=false pose sur chaque engine a la construction (cellule 5) + global (cellule 12) pour couper le flot des dots de progression Infer.NET -- 45 434 -> 3 805 lignes, 5 992 -> 108 objets output (jumeau Python = 31) ; (2) cellules 42/44 : tables en 9/8 displays mono-ligne -> 1 table HTML chacune ; (3) nouvelle section 10 : solveur v4 compile en DLL via Roslyn (sources extraites des .ipynb reels du depot, CompiledModels/SudokuV4Solver.dll commitee selon la convention de la serie) + benchmark top95 + grille la plus dure resolue affichee AVANT/APRES ; Exercices renumerotes ### 11. Re-exec complete kernel .net-csharp : 27 cellules code (26 + 1 nouvelle), 0 exec_null, 0 erreur. Arc pedagogique probabiliste intact (ancre Infer.NET conservee) ; la section 10 etend le contraste deterministe/probabiliste documente par la rebaseline 2026-08-24. Cote Python non modifie (byte-identique a main). Attestation = nouveau blob SHA csharp." - "Rebaseline 2026-08-24 : cote C# -- solveur v4 max-product hongrois reel ajoute (Kuhn-Munkres sur -log p, messages c2f extrinseques, damping 0.5, bruit log-uniforme aux restarts, seed=k/grille, PR #12769, issue #11925 : critere benchmark Medium hardest 9/11 ATTEINT contre 0/11 avant). Re-exec complete kernel .net-csharp : 26 cellules code, 0 exec_null, 0 erreur. Ancre de parite Infer.NET conservee (58 references) : le v4 est une strategie deterministe ADDITIONNELLE qui contraste avec l'inference probabiliste (Infer.NET), l'arc pedagogique probabiliste est intact. Cote Python non modifie (byte-identique a main). Attestation = nouveau blob SHA csharp." diff --git a/scripts/notebook_tools/twin_pairs.d/sudoku-15-infer/0030-2026-10-14-hors-flotte-claude-session-16638.yaml b/scripts/notebook_tools/twin_pairs.d/sudoku-15-infer/0030-2026-10-14-hors-flotte-claude-session-16638.yaml new file mode 100644 index 0000000000..a4658cbca5 --- /dev/null +++ b/scripts/notebook_tools/twin_pairs.d/sudoku-15-infer/0030-2026-10-14-hors-flotte-claude-session-16638.yaml @@ -0,0 +1,6 @@ +date: '2026-10-14' +by: hors-flotte:claude-session-16638 +python_sha: f3d25bbe720a9b2d71ada82c3345dc0fbae2f5d4 +csharp_sha: 2a824141a79d55ff55b1670ddb58432d1921e11c +content_python_sha: de2db4f9dcdd4096cbef2ac03340e1fe2bd33594a4307a0dda2d9a7e12abf4e5 +content_csharp_sha: b3f53f1bbb92ef5f94fa3a1eceb484217a940dee65c61179f56014e2a7989143 diff --git a/scripts/notebook_tools/twin_pairs.d/sudoku-18-comparison.yaml b/scripts/notebook_tools/twin_pairs.d/sudoku-18-comparison.yaml index b8cc364f22..eb24104ec3 100644 --- a/scripts/notebook_tools/twin_pairs.d/sudoku-18-comparison.yaml +++ b/scripts/notebook_tools/twin_pairs.d/sudoku-18-comparison.yaml @@ -6,6 +6,7 @@ bridge_verdict: SOTA-OK bridge_verdict_reason: "Lib-vs-lib meme moteur Google OR-Tools CP-SAT : Python = `ortools` PyPI package (CP-SAT via `from ortools.sat.python import cp_model`, 21 refs `ortools` runtime). C# = `Google.OrTools` NuGet package (CP-SAT via `Google.OrTools.Sat.CpModel`, 15 refs `ortools` + 5 `Google.OrTools` namespace). Meme solveur CP-SAT upstreams de Google Operations Research, accessible via les bindings officiels Python (.whl) et C# (.nupkg). Verifie firsthand (c.234 audit 2026-08-12, myia-po-2023:CoursIA-2) : 68 cells Python / 68 cells C#, structure symetrique (memes benchmarks, memes configurations, memes hard puzzles). Pont cross-stack impossible : CP-SAT est un moteur C++ natif, les deux bindings sont des wrappers SWIG officiels (cp_model.py = SWIG-generated, Google.OrTools.Sat.CpModel = SWIG-generated). Pas de bytecode Python ↔ C# bridgeable ; la parite est garantie par le fait que les deux utilisent la meme version du meme solveur upstream. Verdict SOTA-OK : OR-Tools CP-SAT est la SOTA CP-SAT solver pour les deux stacks, et la parite semantique est mecaniquement preservee tant que les deux versions PyPI/NuGet restent synchronisees (cf c.217 PR #10557 App-tranche-4 precedent qui a verifie 5 paires A-1/3/4/11/15 sur le meme pattern `ortools` ↔ `Google.OrTools`). parity_level `semantic` coherente : idiomes differents (Python dynamique vs C# statique) mais moteur commun." known_differences: + - "Re-baseline 2026-10-14 (hors-flotte:claude-session-16638, #16638) : restauration des accents de la prose markdown (tranche sudoku-b #16638, outil canonique restore_accents_canonical.py, invariance strip_accents a 0 finding), sur les deux jumeaux. Aucune cellule de code, sortie ni execution_count touchee. Parite inchangee : attestation (le blob SHA se deplace), pas reparation. --update en DERNIERE operation (cf #8957)." - "Rebaseline 2026-08-29 (#13045, PR #13069) : DEUX cotes deplaces. Cote Python = RE-EXECUTION reelle (papermill 2.7.0, 2026-08-29T10:51:00Z -> 10:55:06Z, 246,1 s, exception None, 25 cellules code, 0 execution_count nul, 0 erreur) apres reecriture du benchmark en protocole a mediane censuree ; les sorties committees sont celles de ce run. Cote C# = restauration d'une idee pedagogique (difficulte humaine vs difficulte algorithmique) perdue par la reecriture, plus la conversion de 3 separateurs decoratifs par le hook fix-hr-separator. Les DEUX cotes ont en outre recu la renumerotation zero-pad de #13357 (liens de navigation, cellules 1 et 4, reprise telle quelle depuis main). Parite structurelle inchangee (68 cellules par cote). Attestations = nouveaux blob SHAs des deux cotes." - "Rebaseline 2026-08-14 : DEUX cotes deplaces par drain wallclock #9434 / PR #10874 (remplacement des timings machine-dependants en ms par des ordres de grandeur dans 2 cellules markdown par cote). Parite semantique inchangee (cellules code byte-identiques, aucune sortie, aucun exec_count touche). Attestations = nouveaux blob SHAs des deux cotes." - "Rebaseline 2026-08-05 : cote Python deplace par de-hardcodage de la version numpy depuis le markdown (classe ENV #9434, edition markdown-only). Parite semantique inchangee (aucune cellule code, aucune sortie, aucun exec_count touche) ; cote C# non modifie. Attestation = nouveau blob SHA du cote Python." diff --git a/scripts/notebook_tools/twin_pairs.d/sudoku-18-comparison/0015-2026-10-14-hors-flotte-claude-session-16638.yaml b/scripts/notebook_tools/twin_pairs.d/sudoku-18-comparison/0015-2026-10-14-hors-flotte-claude-session-16638.yaml new file mode 100644 index 0000000000..c219eb630b --- /dev/null +++ b/scripts/notebook_tools/twin_pairs.d/sudoku-18-comparison/0015-2026-10-14-hors-flotte-claude-session-16638.yaml @@ -0,0 +1,6 @@ +date: '2026-10-14' +by: hors-flotte:claude-session-16638 +python_sha: 015d4cd99205b040263632e6ffb7b2bf74363ee4 +csharp_sha: 509cbc9132f586f766e740c8615867821d6fbadd +content_python_sha: 7c76b1fb577612b86624c770341b85d33e061993485caa346858d3600c3820cc +content_csharp_sha: 40569b7d9dc215fc66ff81c6105a5192ee523d745a4a8f49809293015fab0e08