{ "version": "1.0", "gate_descriptions": { "h": {"short": "Hadamard — crée une superposition égale", "effect_on_zero": "Transforme |0⟩ en (|0⟩+|1⟩)/√2", "effect_on_one": "Transforme |1⟩ en (|0⟩-|1⟩)/√2"}, "x": {"short": "Pauli-X — NOT quantique", "effect_on_zero": "Transforme |0⟩ en |1⟩", "effect_on_one": "Transforme |1⟩ en |0⟩"}, "y": {"short": "Pauli-Y — rotation π autour de Y", "effect_on_zero": "Transforme |0⟩ en i|1⟩", "effect_on_one": "Transforme |1⟩ en -i|0⟩"}, "z": {"short": "Pauli-Z — flip de phase", "effect_on_zero": "Laisse |0⟩ inchangé", "effect_on_one": "Transforme |1⟩ en -|1⟩"}, "s": {"short": "Phase S — rotation π/2 autour de Z", "effect_on_zero": "Laisse |0⟩ inchangé", "effect_on_one": "Transforme |1⟩ en i|1⟩"}, "sdg": {"short": "S† — rotation -π/2 autour de Z (inverse de S)", "effect_on_zero": "Laisse |0⟩ inchangé", "effect_on_one": "Transforme |1⟩ en -i|1⟩"}, "t": {"short": "Phase T — rotation π/4 autour de Z", "effect_on_zero": "Laisse |0⟩ inchangé", "effect_on_one": "Transforme |1⟩ en e^(iπ/4)|1⟩"}, "tdg": {"short": "T† — rotation -π/4 autour de Z (inverse de T)", "effect_on_zero": "Laisse |0⟩ inchangé", "effect_on_one": "Transforme |1⟩ en e^(-iπ/4)|1⟩"}, "cx": {"short": "CNOT — flip la cible si le contrôle est |1⟩", "effect_on_zero": "Si contrôle=|0⟩, ne fait rien à la cible"}, "cz": {"short": "CZ — flip de phase sur la cible si contrôle=|1⟩"}, "swap": {"short": "SWAP — échange l'état de deux qubits"}, "ccx": {"short": "Toffoli — flip la cible si les deux contrôles sont |1⟩"}, "rx": {"short": "Rotation autour de l'axe X d'un angle θ"}, "ry": {"short": "Rotation autour de l'axe Y d'un angle θ"}, "rz": {"short": "Rotation autour de l'axe Z d'un angle θ"} }, "modules": [ { "id": 1, "title": "Le qubit", "lessons": [ { "id": 1, "title": "États |0⟩ et |1⟩", "concept": "Un qubit peut être dans l'état |0⟩ ou |1⟩, exactement comme un bit classique — mais aussi dans une superposition des deux. Sans rien faire, il part de |0⟩. La porte X (NOT quantique) bascule |0⟩ en |1⟩.", "example_circuit": "OPENQASM 3.0;\ninclude \"stdgates.inc\";\nqubit[1] q;\nbit[1] c;\nx q[0];\nc = measure q;", "what_to_observe": "Lance run_circuit avec 100 shots. Tu devrais voir uniquement '1' dans les counts.", "exercises": [ { "id": "1-1-a", "prompt": "Écris un circuit OpenQASM 3.0 avec 1 qubit qui produit toujours '1' quand on le mesure. Utilise la porte X.", "hint": "La porte X s'applique avec 'x q[0];' avant la mesure.", "criteria": { "required_outcomes": [{"bitstring": "1", "min_ratio": 0.99}], "forbidden_outcomes": ["0"] }, "feedback_pass": "Parfait ! La porte X bascule |0⟩ en |1⟩.", "feedback_fail": "Ton circuit ne produit pas toujours '1'." }, { "id": "1-1-b", "prompt": "Écris un circuit avec 1 qubit sans aucune porte, juste la mesure.", "hint": "Un qubit non touché part de |0⟩.", "criteria": { "required_outcomes": [{"bitstring": "0", "min_ratio": 0.99}], "forbidden_outcomes": ["1"] }, "feedback_pass": "Sans aucune porte, le qubit reste dans |0⟩.", "feedback_fail": "Ton circuit produit des '1' alors qu'il ne devrait pas." } ] } ] }, { "id": 2, "title": "Superposition", "lessons": [ { "id": 1, "title": "La porte Hadamard et l'état |+⟩", "concept": "La porte H (Hadamard) transforme |0⟩ en une superposition égale de |0⟩ et |1⟩. Quand tu mesures, tu obtiens 0 ou 1 avec 50% de probabilité chacun — pas parce que c'est aléatoire au sens classique, mais parce que la mesure fait 'choisir' le qubit.", "example_circuit": "OPENQASM 3.0;\ninclude \"stdgates.inc\";\nqubit[1] q;\nbit[1] c;\nh q[0];\nc = measure q;", "what_to_observe": "Lance run_circuit avec 1000 shots. Tu devrais voir ~500 '0' et ~500 '1'. Relance plusieurs fois : la distribution change légèrement à chaque fois.", "exercises": [ { "id": "2-1-a", "prompt": "Écris un circuit qui met un qubit en superposition parfaite (50/50) et le mesure.", "hint": "La porte H est la seule dont tu as besoin.", "criteria": { "required_outcomes": [ {"bitstring": "0", "min_ratio": 0.4}, {"bitstring": "1", "min_ratio": 0.4} ], "forbidden_outcomes": [] }, "feedback_pass": "Parfait ! La porte H crée bien une superposition équilibrée.", "feedback_fail": "Tu dois voir à la fois des '0' et des '1' en quantités comparables." }, { "id": "2-1-b", "prompt": "Applique H deux fois de suite sur le même qubit. Quel est le résultat à la mesure ?", "hint": "H est son propre inverse : H·H = Identité.", "criteria": { "required_outcomes": [{"bitstring": "0", "min_ratio": 0.99}], "forbidden_outcomes": ["1"] }, "feedback_pass": "Excellent ! H·H = Identité : appliquer Hadamard deux fois ramène au point de départ.", "feedback_fail": "Deux portes H d'affilée doivent ramener à |0⟩ avec certitude." }, { "id": "2-1-c", "prompt": "Pars de |1⟩ (utilise X d'abord), puis applique H. Que vois-tu ?", "hint": "H|1⟩ = (|0⟩-|1⟩)/√2 = |−⟩. La mesure donne toujours 50/50.", "criteria": { "required_outcomes": [ {"bitstring": "0", "min_ratio": 0.4}, {"bitstring": "1", "min_ratio": 0.4} ], "forbidden_outcomes": [] }, "feedback_pass": "Bien vu ! H|1⟩ donne aussi 50/50 — la différence (|−⟩ vs |+⟩) est dans la phase.", "feedback_fail": "Tu devrais voir ~50/50. Utilise X puis H." } ] } ] }, { "id": 3, "title": "Interférence et phase", "lessons": [ { "id": 1, "title": "La phase quantique et l'interférence", "concept": "La phase d'un état quantique est invisible à la mesure directe, mais deux états en superposition peuvent interférer : leurs amplitudes s'additionnent ou s'annulent. C'est le moteur de l'avantage quantique.", "example_circuit": "OPENQASM 3.0;\ninclude \"stdgates.inc\";\nqubit[1] q;\nbit[1] c;\nh q[0];\nz q[0];\nh q[0];\nc = measure q;", "what_to_observe": "Ce circuit (H·Z·H) donne toujours '1'. Compare avec un simple X.", "exercises": [ { "id": "3-1-a", "prompt": "Vérifie que H·Z·H = X. Écris le circuit H·Z·H et mesure.", "hint": "Applique h, puis z, puis h, puis mesure.", "criteria": { "required_outcomes": [{"bitstring": "1", "min_ratio": 0.99}], "forbidden_outcomes": ["0"] }, "feedback_pass": "Parfait ! H·Z·H = X — l'interférence transforme un flip de phase en flip de bit.", "feedback_fail": "Assure-toi d'appliquer h, z, h dans cet ordre." }, { "id": "3-1-b", "prompt": "Applique H, puis Rz(π), puis H. Que vois-tu ?", "hint": "rz(pi) q[0]; — la constante pi est disponible.", "criteria": { "required_outcomes": [{"bitstring": "1", "min_ratio": 0.99}], "forbidden_outcomes": ["0"] }, "feedback_pass": "Exact ! Rz(π) est équivalent à Z (à une phase globale près).", "feedback_fail": "Vérifie ta syntaxe pour rz(pi) q[0];" }, { "id": "3-1-c", "prompt": "Crée un circuit H·S·H et mesure. Que devient la distribution ?", "hint": "S introduit une phase de 90° qui modifie l'interférence.", "criteria": { "required_outcomes": [ {"bitstring": "0", "min_ratio": 0.2}, {"bitstring": "1", "min_ratio": 0.2} ], "forbidden_outcomes": [] }, "feedback_pass": "Bien joué ! H·S·H produit une superposition non triviale.", "feedback_fail": "Tu dois voir les deux outcomes. Applique h, s, h dans cet ordre." } ] } ] }, { "id": 4, "title": "2 qubits et intrication", "lessons": [ { "id": 1, "title": "Le circuit de Bell et l'intrication", "concept": "Deux qubits peuvent être 'intriqués' : mesurer l'un détermine instantanément le résultat de l'autre. L'état de Bell est le prototype de l'intrication.", "example_circuit": "OPENQASM 3.0;\ninclude \"stdgates.inc\";\nqubit[2] q;\nbit[2] c;\nh q[0];\ncx q[0], q[1];\nc = measure q;", "what_to_observe": "Lance avec 1000 shots. Tu dois voir uniquement '00' et '11' en quantités égales — jamais '01' ou '10'.", "exercises": [ { "id": "4-1-a", "prompt": "Crée un état de Bell entre 2 qubits : la mesure doit donner uniquement '00' ou '11'.", "hint": "H sur q[0], puis CX q[0]→q[1].", "criteria": { "required_outcomes": [ {"bitstring": "00", "min_ratio": 0.4}, {"bitstring": "11", "min_ratio": 0.4} ], "forbidden_outcomes": ["01", "10"] }, "feedback_pass": "Excellent ! Tu as créé l'état de Bell.", "feedback_fail": "Tu dois voir uniquement '00' et '11'. Utilise H q[0] puis CX q[0],q[1]." }, { "id": "4-1-b", "prompt": "CNOT sans superposition : pars de |00⟩ et applique CX. Que vois-tu ?", "hint": "Sans H, q[0] reste |0⟩.", "criteria": { "required_outcomes": [{"bitstring": "00", "min_ratio": 0.99}], "forbidden_outcomes": ["01", "10", "11"] }, "feedback_pass": "Correct ! CNOT avec contrôle=|0⟩ ne change rien.", "feedback_fail": "Tu dois obtenir '00' systématiquement." }, { "id": "4-1-c", "prompt": "Prépare q[0]=|1⟩ avec X, puis applique CX. Que voit-on sur q[1] ?", "hint": "CNOT flip la cible quand le contrôle est |1⟩.", "criteria": { "required_outcomes": [{"bitstring": "11", "min_ratio": 0.99}], "forbidden_outcomes": ["00", "01", "10"] }, "feedback_pass": "Parfait ! |10⟩ devient |11⟩ après CX.", "feedback_fail": "Avec q[0]=|1⟩, le CNOT doit flipper q[1]." } ] } ] }, { "id": 5, "title": "Circuits multi-qubits", "lessons": [ { "id": 1, "title": "GHZ, Toffoli et superposition uniforme", "concept": "On peut intriqué N qubits en même temps. L'état GHZ généralise Bell à 3+ qubits. La porte Toffoli (CCX) est un AND quantique réversible.", "example_circuit": "OPENQASM 3.0;\ninclude \"stdgates.inc\";\nqubit[3] q;\nbit[3] c;\nh q[0];\ncx q[0], q[1];\ncx q[0], q[2];\nc = measure q;", "what_to_observe": "Avec 3 qubits GHZ, tu dois voir uniquement '000' et '111'.", "exercises": [ { "id": "5-1-a", "prompt": "Crée l'état GHZ à 3 qubits.", "hint": "H sur q[0], puis CX q[0]→q[1], puis CX q[0]→q[2].", "criteria": { "required_outcomes": [ {"bitstring": "000", "min_ratio": 0.4}, {"bitstring": "111", "min_ratio": 0.4} ], "forbidden_outcomes": ["001", "010", "011", "100", "101", "110"] }, "feedback_pass": "Bravo ! L'état GHZ à 3 qubits est créé.", "feedback_fail": "L'état GHZ doit produire uniquement '000' et '111'." }, { "id": "5-1-b", "prompt": "Toffoli : prépare q[0]=|1⟩ et q[1]=|1⟩, puis applique CCX.", "hint": "CCX flip q[2] seulement si q[0] ET q[1] sont à |1⟩.", "criteria": { "required_outcomes": [{"bitstring": "111", "min_ratio": 0.99}], "forbidden_outcomes": ["000", "001", "010", "011", "100", "101", "110"] }, "feedback_pass": "Toffoli est un AND quantique : il flip q[2] seulement si q[0]=q[1]=|1⟩.", "feedback_fail": "Utilise x q[0]; x q[1]; ccx q[0],q[1],q[2];" }, { "id": "5-1-c", "prompt": "Crée une superposition uniforme de tous les états à 2 qubits (~25% chacun).", "hint": "Applique H sur chaque qubit indépendamment.", "criteria": { "required_outcomes": [ {"bitstring": "00", "min_ratio": 0.15}, {"bitstring": "01", "min_ratio": 0.15}, {"bitstring": "10", "min_ratio": 0.15}, {"bitstring": "11", "min_ratio": 0.15} ], "forbidden_outcomes": [] }, "feedback_pass": "Avec H sur chaque qubit tu explores 4 états simultanément.", "feedback_fail": "Tu dois voir les 4 états chacun avec ~25%." } ] } ] }, { "id": 6, "title": "Premiers algorithmes quantiques", "lessons": [ { "id": 1, "title": "Bernstein-Vazirani et phase kickback", "concept": "L'algorithme de Bernstein-Vazirani retrouve une chaîne secrète en un seul appel à l'oracle. Le phase kickback est le mécanisme central : faire 'remonter' une phase d'un qubit cible vers un qubit de contrôle en superposition.", "example_circuit": "OPENQASM 3.0;\ninclude \"stdgates.inc\";\nqubit[2] q;\nbit[2] c;\nx q[1];\nh q[0];\nh q[1];\ncx q[0], q[1];\nh q[0];\nc = measure q;", "what_to_observe": "Bernstein-Vazirani pour s='1' : le bit q[0] (à droite) vaut toujours 1 (bitstrings '01' ou '11', jamais '00' ni '10').", "exercises": [ { "id": "6-1-a", "prompt": "Bernstein-Vazirani pour s='1' : prépare l'ancilla en |−⟩ (X+H), mets q[0] en superposition (H), applique CX q[0]→q[1] (oracle pour s=1), puis H sur q[0]. Mesure les deux qubits avec bit[2] c; c = measure q;.", "hint": "X q[1]; H q[1]; H q[0]; CX q[0],q[1]; H q[0]; puis c = measure q;. Le bit de droite (q[0]) doit toujours valoir 1.", "criteria": { "required_outcomes": [ {"bitstring": "01", "min_ratio": 0.4}, {"bitstring": "11", "min_ratio": 0.4} ], "forbidden_outcomes": ["00", "10"] }, "feedback_pass": "Excellent ! BV retrouve s='1' en un seul appel à l'oracle : q[0] (bit de droite) vaut toujours 1.", "feedback_fail": "Le bit q[0] (à droite) doit toujours valoir 1. Tu devrais ne voir que '01' et '11'." }, { "id": "6-1-b", "prompt": "Phase kickback : prépare q[1] en |1⟩ (X), mets q[0] en superposition (H), applique CZ q[0],q[1]. Puis H q[0]. Mesure les deux qubits avec bit[2] c; c = measure q;.", "hint": "Le CZ avec q[1]=|1⟩ ajoute une phase -1 quand q[0]=|1⟩ — la phase remonte sur q[0]. État final |11⟩.", "criteria": { "required_outcomes": [{"bitstring": "11", "min_ratio": 0.99}], "forbidden_outcomes": ["00", "01", "10"] }, "feedback_pass": "Parfait ! La phase de q[1] s'est 'kickback' sur q[0]. État final |11⟩, c'est la clé des algorithmes quantiques.", "feedback_fail": "Tu dois obtenir uniquement '11'. Vérifie : x q[1]; h q[0]; cz q[0],q[1]; h q[0]; c = measure q;." } ] } ] }, { "id": 7, "title": "Algorithme de Grover", "lessons": [ { "id": 1, "title": "Recherche quantique : amplification d'amplitude", "concept": "L'algorithme de Grover retrouve un élément marqué dans N éléments en O(√N) appels — quadratiquement plus rapide que la recherche classique. Il utilise un oracle de phase + un opérateur de diffusion.", "example_circuit": "OPENQASM 3.0;\ninclude \"stdgates.inc\";\nqubit[2] q;\nbit[2] c;\nh q[0];\nh q[1];\ncz q[0], q[1];\nh q[0];\nh q[1];\nx q[0];\nx q[1];\ncz q[0], q[1];\nx q[0];\nx q[1];\nh q[0];\nh q[1];\nc = measure q;", "what_to_observe": "Grover sur 2 qubits avec marqueur '11' produit '11' avec ~100% après 1 itération.", "exercises": [ { "id": "7-1-a", "prompt": "Implémente Grover sur 2 qubits pour trouver l'état marqué '11'. 1 itération suffit.", "hint": "H H | CZ (oracle) | H H X X CZ X X H H (diffuseur).", "criteria": { "required_outcomes": [{"bitstring": "11", "min_ratio": 0.85}], "forbidden_outcomes": [] }, "feedback_pass": "Magnifique ! Grover trouve '11' en une itération avec haute probabilité.", "feedback_fail": "L'état '11' doit dominer (>85%). Vérifie oracle et diffuseur." }, { "id": "7-1-b", "prompt": "Grover pour l'état '00'. Oracle = X X CZ X X.", "hint": "X q[0]; X q[1]; CZ q[0],q[1]; X q[0]; X q[1]; puis diffuseur.", "criteria": { "required_outcomes": [{"bitstring": "00", "min_ratio": 0.85}], "forbidden_outcomes": [] }, "feedback_pass": "Excellent ! En changeant l'oracle, Grover trouve n'importe quel état marqué.", "feedback_fail": "L'état '00' doit dominer (>85%). Ton oracle doit marquer '00'." } ] } ] } ] }