Tartalomjegyzék
Bevezetés
A programok rövid története
A szoftverfejlesztés viszonylag új szakterület. A programozás ágazat kezdete megközelítőleg az 1950-es évekre rakható. Az ipari forradalmaknak köszönhetően ekkorra már fejlett gépek, elektronikus technológiák álltak a szakemberek rendelkezésére a számítógépek megépítéséhez, kezdődhetett a programnyelvek, szoftver tervezési folyamatok célzott, irányított létrehozása. A programozás bő fél évszázados múltja alatt ezek drasztikusan átalakultak, a hatékonyságok és komplexitásuk sokszorosára fejlődött, a folyamatok kiszámíthatóbbak, gördülékenyebbek lettek. Kezdetben csak 1-1 művelet sikeres, automatizált végrehajtása volt a cél, napjainkban azonban számos más dolog is fontos. Voltak programnyelvek, amik hibásan lettek megtervezve, használatuk túl bonyolult volt emberek számára, nehéz volt leírni bennük komplex rendszereket, feladatokat, nem alkalmazkodtak a fejlesztendő program struktúrájához. Ezekből sokat tanultunk, a tapasztalataink alapján újabb és újabb rendszereket fejlesztettünk ki. Manapság már óriási szoftvereket építünk, bonyolult algoritmusokat hozunk létre, számtalan mérnök foglalkozik egyszerre a feladattal, az elkészült programoktól pedig emberéletek függhetnek. Egyre rövidebb idő alatt, egyre nehezebb programot, egyre kevesebb pénzből kell fejlesztenünk, alkalmazkodva a kor elvárásának.
A klasszikus, elektronikus számítógépek azonban kezdenek csúcspontjukhoz jutni. Egy idő után már nem lehet gyorsaságukon fejleszteni, a technológia eléri határait, az algoritmusokat nem lehetséges tovább optimalizálni. Pedig rohamos igény lenne még a programok hatékonyságnövelése iránt, hiszen csak mostanában kezdenek igazán teret hódítani pl. a rengeteg számítást igénylő neurális hálózatok, vagy az egyre élethűbb kinézetű videójátékok, a tömérdek adat feldolgozása. Emiatt számtalan kutató cég foglalkozik azzal, hogy létre tudják hozni az elektronikus technológia utódját, a kvantummechanikára alapozó kvantumszámítógépet. Ezek az új gépek lényegesen más módszerekkel dolgoznak, elvi teljesítményük sokszorosa az elektronikus gépeknek.
A kvantum-programozás területe mostanában kezd megszületni. Napjainkban a kvantumszámítógép még fejlesztés alatt áll, messze vagyunk attól, hogy használatuk olyan széles körben elterjedt legyen, mint a mostani elektronikus személyi, vagy szerver oldali számítógépeké. Ennek ellenére egyre több és több kvantum programozási nyelv jelenik meg, számtalan olyan algoritmust megterveztek már, amit később kvantum-számítógépeken akarnak futtatni.
Igény a kvantum programokra
Mi értelme van kvantumprogramokat fejleszteni, ha még nem is igazán tudjuk min végrehajtani ezeket a programokat? A klasszikus programozás fejlődése során bebizonyosult, hogy sok elmélet hibás, és ezek a hibák csak elterjedt használatuk után derültek ki, rengeteg kárt okozva a fejlesztőknek és felhasználóknak egyaránt. Sok, korábban hatékonynak hitt algoritmushoz találtak annál sokkal gyorsabb, kevesebb memóriaigényű stb. változatot, biztonságosnak hitt protokollokban találtak támadható pontot. Mivel a kvantumszámítógépnek nagy jövőt jósolnak, tudhatjuk, hogy a közeljövőben valós igény lesz a kvantum-programokra. Annak érdekében, hogy minimalizáljuk a hibás elméletek és fejlesztési módszerek alkalmazását, vagy éppen felfedezzük, később mit tudunk még alkalmazni, a kvantumszámítógépekre szánt programok fejlesztése már most is elkezdődött. A sok évtizedekig tartó algoritmusok, protokollok fejlesztése és ellenőrzése már most is lehetséges. Szükséges, hogy találjunk olyan módszereket, amik leválthatják azokat az eljárásokat, amiket napjainkban használunk a klasszikus számítógépeknél, de egy kvantumszámítógépnek egyszerű lenne megkerülnie, hogy ha üzembe tudnak már helyezni nagyszámú kvantumszámítógépet, a szolgáltatások továbbra is működőképesek maradhassanak. Ilyen pl. a titkosított kommunikációra használt RSA algoritmus, ami az elektronikus számítógépeknél még kellő védelmet ad, de ha a kvantumszámítógépek elterjednek, már nem lehetne az interneten biztonságosan fizetni. Mivel azonban nem akarunk lemondani a biztonságos internetes fizetésről, más módszereket kell felkutatnunk, amik matematikailag bizonyítottan biztonságosak tudnak maradni a jövőre nézve is.
A klasszikus és kvantum programok jövője
A kvantum-számítógépek megjelenésével nem érdemes eltemetni az elektronikus számítógépeket. Várhatóan a két technológia nem lecseréli egymást, hanem együtt működnek tovább. Nem éri meg ugyanis minden feladatra a (most még) méregdrága csúcstechnológiát használni. Vegyünk például egy kézi számológépet. Igaz ugyan, hogy nem tud egy nagyon bonyolult, 100 sort elfoglaló egyenletet több millió tizedesjegy pontosságú eredményét kikalkulálni egy szempillantásnyi idő alatt, na de kinek lenne erre igénye? A grafikus kártyák teljesítménye és a monitor frissítési gyorsasága se teszi lehetővé (jelenleg), hogy másodpercenként több millió, teljesen élethű képkockát megjelenítsen egy program, azonban tudjuk, hogy az emberi szem nem is lenne képes értelmezni ezt a sok részletes információt kellő gyorsasággal. Egy táblázatos adminisztrátori program működésére aligha lenne hatással, ha azt kvantumszámítógépen futtatnánk. A kvantumprogramokat számításigényes (és ebből adódóan időigényes) feladatoknál éri meg használni.
Többnyire a kényelmes, emberek által jól értelmezhető programnyelveketben megírt feladatokat le kell fordítani egy, a gép, vagy az azon futó platform által közvetlenül, egyszerűen értelmezhető, optimalizált formára. Problémát jelent ugyanakkor, hogy még nem nagyon tudjuk, milyen lesz a kvantum-számítógépek interfésze, azaz, hogy hogyan lehet hozzáférni kívülről. Jelenleg 1-2 gyártó rendelkezik kísérleti kvantumszámítógéppel. Mint az várható minden felfedezés esetében, ebben a fázisban nem a kényelmes használatra koncentrálnak, hanem a működés elérésére. Így volt ez a klasszikus számítógépek esetében is: kezdetben minimális utasításkészletet támogattak a processzorok, de új igények jelentek meg, így kevésnek bizonyultak. Ma már számtalan utasításkészlet érhető el, ám kompatibilitási okok miatt az x86 architektúra mégis elterjedt maradt, a teljesítmény rovására. Remélhetőleg, a kvantum számítógép- és programnyelv tervezők tanulni fognak ebből az esetből, számolnak azzal, hogy a kísérletek után sok változásra kell felkészülniük. A mostani szimulátorok, és a jövőbeli kvantumszámítógépek interfészét össze kell egyeztetni minél inkább, hogy a már elkészített programok átvihetők legyenek.
Ha a kvantumszámítógép elérhető lesz, a kvantum programnyelvek nagy lendületet fognak kapni. Új fejlesztőkörnyezeteket hoznak létre, vagy ha lehetséges, beépítik a már meglévő rendszerekbe a kvantum programok készítéséhez szükséges eszközöket. Várhatóan lesznek próbálkozások arra, hogy egyes programnyelveket kiterjesszék a kvantum programok világára is, hogy a fejlesztők egységes nyelven tudjanak fejleszteni a kettő között, ne kelljen külön megtanulni a sok dologban hasonlító eljárásokat. A jelenlegi szimulátorokat leváltják majd a valós fordítóprogramok.
Kvantumprogramok jellemzői
Megjegyzés: A programok leírását, értelmezését lehetővé tevő nyelveket típusuk szerint különféle kategóriákba soroljuk, és emiatt eltérően is hívjuk őket (pl. a HTML jelölő, a Java programozási, a VHDL hardverleíró nyelv, az x86 pedig egy utasításkészlet), noha programokkal kapcsolatos területen használjuk fel őket. A továbbiakban a “kvantum programozási nyelv” főleg csak a kvantumszámítógépekkel és programokkal kapcsolatba hozható jellemzésre használt, nem pedig a nyelv céljának, típusának meghatározására.
Eltérések a klasszikus és kvantum programok között
A klasszikus programok felépítése néhány szempontból hasonlít a kvantum programokéra, más esetekben azonban gyökeres eltérések vannak köztük. Néhány ilyen eltérés (a teljesség igénye nélkül):
- A kvantumbiteken végrehajtott műveletek nem lehetnek tetszőlegesek. A kvamtum-számítástechnika 2. posztulátuma értelmében a változásokat unitér operátorokkal tudjuk leírni. Nem minden transzformáció rendelkezik azokkal a tulajdonságokkal, amik ehhez szükségesek. Jól mutatja ezt az ÉS kapu: ennek 2 be-, és 1 kimenete van, a műveletet nem tudjuk egyértelműen megfordítani. Habár az ÉS művelet értelmezhető a kvamtum programban is, ki kell terjeszteni, hogy teljesüljün rá a feltétel.
- A kvantumbiteknek nem határozható meg pontosan az értékük minden esetben. Klasszikus programoknál mindig tudhatjuk, hogy egy bit 0, vagy 1 értéket velet csak fel, a kvantumbit azonban másképpen működik. A tetszőleges állapotú kvantumbit egy pillanatban meghatározott valósínűséggel van egyik-másik állapotban. Néhány méréssel, vagy előzőtes műveletek alkalmazásával kinyerhetjük a pontos értéket, azonban nem mindig. Emiatt néha ismételni kell a műveleteket, vagy tippelni kell a végeredményt, vagy meg kell elégednünk a nem garantáltan jó válasszal.
- A mérések befolyásolják a mért adatot. Klasszikus programban nem feltételezzük, hogy egy regiszter tartalmának kiolvasásának külső hatása lenne (igazából lehetnek, pl. a gyorsítótárazás miatt, de ezek a kiolvasási művelet szempontjából láthatatlanok, nélkölüzhetőek). A kvantumprogramok készítésénél fel kell készülnünk arra, hogy az operátorok alkalmazása közben nem tudhatjuk pontosan a kvantumbitek értékét, mérés után pedig már nem tudjuk pontosan ugyan azt az értéket felhasználni.
- A kvantum-számítástechnikában léteznek összefonódott állapotok, ahol az egyik kvantumbit megmérése befolyásolja a másik kvantumbit értékét. Klasszikus programokban ha ilyesmit akarunk elérni, speciális adatszerkezetet kell létrehoznunk, és mauálisan kellene átállítanunk az adatok állapotát, hogy a következő kiolvasás eredményét befolyásolni tudjuk. A kvantumprogramokban mindez magától adódik - ami vagy jó nekünk, vagy nem.
- Kvantumbitek összekapcsolásával, és a Hadamard kapu alkalmazásával egy regiszterben több lehetséges értéket is eltárolhatunk, mint a neki megfelelő számú klasszikus regiszterben. Ezáltal jóval nagyobb tárkapacitáshoz férhetünk hozzá (már ha sikerül kellő számú kvantumbitet tárolonunk).
- A kvantumregiszter minden kvantumbitjén egyszerre végrehajthatóak átalaítások. Ezt nevezik kvantum-párhuzamosságnak. Ez nem egyenlő a párhuzamosítással, ami azt jelenti, hogy egymástól függetlenül több egység is ugyan azt végzi el. A kvantum-párhuzamosításnál egy adaton, egy egység, egyszerre hajtja végre ugyanazt a műveletet. Klasszikus számítógépeknél ilyenre nem igen van lehetőségünk, hiszen a CPU végső soron egyidőben csak egy műveletet tud végrehajtani.
- Jelenleg még nincs igazán szekvenciális kvantum programozás, pedig klasszikus programozásnál ez a legelterjedtebb módszer. Ez azért van, mert kvantumszámítógépet most még csak elemi alkatrészekből tudunk összerakni, így ezek célhardverek lesznek. Nincs általános célú feldolgozóegység kifejlesztve, ami tetszőleges operációt tudna végrehajtani az adaton egymás után. A kvantum hálózatok leírása pedig leginkább funkcionális nyelvekkel lehetséges.
- Klasszikus programoknál - ha betartjuk a típuskonverziókat - tetszőleges adatot lemásolhatunk, hiszen minden adat értékét pontosan ismerjük. Kvantumbiteknél nem így áll a helyzet: nem másolhatunk le tetszőleges kvantumbitet, csak ha ismerjük az állapotát, vagy egyértelműen meg tudjuk különböztetni őket. Ezt az elméletet figyelembe kell vennünk sokszor algoritmusok tervezésénél - néha jól jön, néha nem.
A felsorolt eltéréseknek számtalan további következménye is van, ami szintén eltérést eredményez. Ilyen pl. a kvantum teleportálás, ahol egy adatot úgy tudunk elküldeni másnak, hogy a valódi értékét ismernénk. A jelenlegi klasszikus számítógépek csak ismert biteket tudnak továbbítani a kábeleken keresztül.
Kvantum programozási nyelvek csoportosítása
Bár még jóval kevesebb nyelvet készítettem a kvantum programokhoz, mint a klasszikusokhoz, már most is elég sok kategóriát lefednek az elérhető nyelvek, így különféle területeken, különféle feladathoz lehet őket felhasználni. A programozási nyelvek csoportosíthatóak többek között a következők szerint is:
- Lehetnek alacsony vagy magas szintűek. Többnyire egy alacsony szintű nyelv szorosan kötődik a számítógéphez, vagy annak interfészéhez/utasításkészletéhez, a leírás elemi műveleteket tartalmaz, amit a számítógép akár közvetlenül is tudna értelmezni. Alacsony szintű leírásra alkalmas a QASM, és a Quil nyelv.
- Egy részük hardverleíró nyelv. Ezek a nyelvek azt fogalmazzák meg, milyen alkatrészekből/elemekből lehet felépíteni a hálózatot, hogyan kapcsolódnak egymáshoz az eszközök. A nyelv elemeinek konkrét fizikai jelentésük van. Ilyen pl. a QASM.
- A nyelv feldolgozásának eredménye alapján lehet szimulációs (mint pl. a Q# vagy libquantum esetében), gráfmodellt vagy hálózatképet megjelenítő (pl. Quipper, vagy csak simán emberek számára tájékoztató, pszeudokód-szerű.
- A nyelv belső felépítése szerint lehet egyszerű műveleteket leíró, kevés absztrakciót használó, mint a QCL, vagy pl. objektum-orientált (ilyen volt a Q language).
- Mintájuk alapján lehetnek pl. funkcionálisak vagy szekvenciálisak, kombináltak stb.
- Épülhetnek korábban már elkészített nyelvekre (pl. a Quipper egy kiegészítése a Haskell nyelvnek, a kvantum pszeudokód kiegészítése a hagyományos pszeudokódnak), vagy lehetnek teljesen újonnan felépítettek.
További csoportosítási szempontok átvehetőek a klasszikus programozási nyelvek esetéből, mint pl. erősen típusús nyelvek, natív vagy értelmezett nyelvek. Ezeknek a csoportoknak azonban még nem igazán van szerepük jelenleg.
Kvantum programozási nyelvek
Ebben a fejezetben néhány, egymástól eléggé eltérő kvantum programozással kapcsolatos nyelvet ismerhetünk meg. Az összehasonlíthatóság érdekében mindegyik nyelvnél találunk egy példát, ami a jól ismert Deutsch–Jozsa algoritmust mutatja be.
A feladat a következő: Adott egy függvény, f(x)
, amiről csak annyit tudunk, hogy néha egy konstans értéket rendel a bemenethez, máskor viszont úgy viselkedik, mint egy pénzfeldobás: az esetek felében a
, másik felében b
értéket rendel a bemenethez. Határozzuk meg, egy konkrét esetben f
melyik szabály szerint működik!
A feladat megoldható klasszikus programokkal is, azonban lépésszámra jóval nagyobb, mint amennyire a kvantumprogramoknak szüksége van. Egy lehetséges klasszikus megoldás, Java nyelven:
Kvantum pszeudokód
A pszeudokód nem tekinthető programozási nyelvnek, hiszen a célja pont az, hogy absztrakt módon, konkrét implementáció nélkül lehessen leírni vele az algoritmusokat. A pszeudokód elvben bármilyen másik programozási nyelvre átalakítható egyszerűen, majd annak felhasználásával futtatható. A pszeudókód célja, hogy az emberek számára könnyen értelmezhető, csak a lényeges dolgokra koncentrálva, nyelvfüggetlen leírást adhassunk különféle algoritmusokról.
A pszeudokódoknak többféle változata is van, kisebb-nagyobb eltérésekkel. Ezek többnyire a megértést nem akadályozzák, mert pl. csak másfajta jelölést használnak az értékadáshoz (let x be zero
, vagy x := 0
). A könnyebb kezelhetőség érdekében készült néhány ajánlás a pszeudokódok készítésére.
A hagyományos pszeudokódnak van kvantumos változata is. A felhasználási cél egyező: algoritmusok leírása implementációtól függetlenül, csak éppen már kvantumszámítógép meglétét feltételezve. A kvantum pszeudokód nem sokban különbözik a hagyományostól, mert bár sok új funkciót lehetséges kvantum programokkal elkészíteni, ezek többségének leírása a hagyományos formában is lehetséges (pl. az unitér operátorok hagyományos metódusokkal leírhatók).
A kvantum pszeudokódra is készült egy ajánlás. E. Knill készítette 1996-ban a kezdetleges ajánlást, azóta módosítás nem történt rajta. Ez a dokumentum nem tárgyalja a hagyományos pszeudokód elemeit, csak a kvantumprogramozással kapcsolatos dolgokkal egészíti ki azt. Az ajánlás egy része formai leírás. Fő elemei:
- Hagyományos és kvantum bitek, regiszterek megkülönböztetése: Minden, ami a “kvantum világban” történik, annak a leírását aláhúzással kell jelölni. Ha egy változó nevének nincs aláhúzása, az klasszikus adatot jelöl, ha van, az egy kvantumregisztert.
- Mérések, értékadások: Az aláhúzásos módszer alkalmas a kvantumregiszterek inicializálására, ahol az értékadás bal oldalán kvantumregiszter, jobb oldalán tetszőleges klasszikus érték található, illetve megmérésére, ahol pont fordított a felállás, egy hagyományos regiszterbe “kiírjuk” a kvantumregisztert.
- Unitér operátorok használata: A pszeudokódban lehetőségünk van megadni az operátorok mátrixos vagy más matematikai alakú leírását, majd erre hivatkozhatunk egy megszokott metódushívásként végrehajthatjuk a műveletet.
- Eljárások megfordítása: A kvantum pszeudokód egyszerű szintaktikát kínál arra a gyakran használt módszerre, amikor algoritmusokat fordítva hajtunk végre. Normál esetben az unitér operátorokat invertálnunk kell, és fordított sorrendben végrehajtani a műveleteket, azonban a kvantum pszeudokódban elegendő csak a művelet elé írni a
reverse
kulcsszót. - Kvantumregiszterek mérés nélkül átalakítása: Bizonyos esetekben a kvantumregiszter bizonyíthatóan klasszikus állapotba kerül a műveletek után. Ebben az esetben használhatjuk a kvantumregisztert klasszikus regiszterként a tövábbiakban, anélkül, hogy a nem megfordítható mérést el kellene végeznünk rajta. Erre való az
isClassical
kulcsszó. - Kvantumregiszterek eldobása: Előfordulhat, hogy egy kvantumregiszterre már nincs szükségünk a továbbiakban. Ahhoz, hogy a kvantumregiszter ne befolyásolja a későbbi műveleteket, jelezzük a
after dissipating
kifejezéssel, hogy a kvantumregisztert eldobtuk, alaphelyzetbe állítottuk. - Elágazások és ciklusok: Bár a kvantumprogramba klasszikus értelemben vett elágazást és ciklust csak akkor tudunk tenni, ha ismerjük (megmérjük) a regiszterek tartalmát, hogy össze tudjuk hasonlítani az értékeket, bizonyos unitér operátorok játszhatnak olyan szerepet, mint az elágazások, illetve az operátorok többszöri ismétlésével kaphatunk egy ciklust. A kvantum pszeudokód erre kínál szintaktikai lehetőséget:
if a then U(a)
,for i=A to i=B
. Ezek a kifejezések átalakíthatók lennének a neki megfelelő (de lehet kevésbé beszédesebb) unitér operátorokká.
A Deutsch–Jozsa algoritmus leírása kvantum pszeudokóddal
DeutschJozsa(n, f) Input: f egy konstans vagy kiegyensúlyozott függvény, n pedig az f függvény bemeneti kvantumregiszerének dimenziója (a qbit-ek száma). Output: Klasszikus igaz, ha f konstans, illetve hamis, ha kiegegysúlyozott. control 🠄 Initialize(0, n) C: A kvantumregiszterbe betöltünk n darab 0 fázisú qbitet. data 🠄 Initialize(1) state0 🠄 Merge(control, data) C: A state0 a két qregiszer összevont állapotát jelzi. state1 🠄 H⊗n+1(state0) C: Mindegyik qbiten alkalmazunk egy Hadamard kaput. state2 🠄 U-Controlled-CNOT(f, control, data) C: Az U-Controlled-CNOT egy olyan kaput jelöl, ami a CNOT kapuhoz hasonlóan működik, de a data ágon y ⊕ f(x) lesz a hatása. state3 🠄 H⊗n(state2)value 🠄 state3 C: Megmérjük a qregisztert, eredményül klasszikus állapotot kapunk. if value is -1 or 1 then result 🠄 true else result 🠄 false
Értékelés
- Előnyök: A kvantum psezudokód a legfontosabb dolgokra ad egységes jelölési lehetőséget, miközben kellő szabadságot ad az algoritmus leírásának testerszabására. Az emberek számára könnyen áttekinthetővé teszi az algoritmusok értelmezését, technikai részletek nélkül.
- Hátrányok: Mivel kevés dolog van szabályozva, sokszor keveredik LaTeX, vagy más matematikai képleteket leíró nyelvekkel, amiknek a kódolása nehezebb feladat lehet. Mivel sok elemre nincs egységes ajánlás, a pszeudokód leírásában sok komment található, ami rontja a leírás minőségét.
Quipper
A Quipper nyelvet 2013-tól kezdték el fejleszteni több ember közreműködésével. A Quipper tulajdonképpen Haskell könyvtárak és segédprogramok gyűjteménye, aminek felhasználásával készíthetünk Haskell nyelven írt kvantumprogramot. Számtalan kvantum programozással kapcsolatos műveletet, típust, eljárást biztosít a Quipper a fejlesztő számára, illetve sok, előre megírt algoritmus található benne. A Quipper képes szimulációra, a leírt kapuk/adatokról képeket készíteni. Ebben a fejezetben az utóbbival foglalkozunk csak.
A Haskell egy funkcionális programozási nyelv, ami azt jelenti, hogy a leírt műveletek nem egymás után, szekvenciálisan hajtódnak végre (mint pl. egy C vagy Java nyelvben), hanem jellemezhetjük a dolgokat, majd ennek a leírásnak segítségével, amint szükség van rá, a számítógép kikalkulálja az eredményt. A szekvenciális programozás esetében azt mondjuk meg a gépnek, hogy mit csináljon, funkcionális programozás esetében viszont csak azt, hogy hogyan tudja az eredményt megkapni amikor kell. Ez a két programozási módszer lényegesen eltér egymástól, nehéz a kettő közti váltás a fejlesztők számára. Néhány klasszikus számítógép támogatja CPU szinten a funkcionális végrehajtást, de többnyire a funkcionálisan leírt programok is speciális, szekvenciálisan végrehajtott programokká fordulnak számítógépeken.
Kvantumszámítógépek esetében viszont más a helyzet. A funkcionális nyelv alkalmazása, és a hálózati kép kimenet nem véletlen: jól mutatja, hogy a kvantum programok jelenleg eltérnek a klasszikus programoktól, amiknek többsége szekvenciálisan, előre nem látható műveleteket hajthat végre, a kvantum programok többsége viszont vezetékekkel összekapcsolt kapuk sorozatából áll (másként mondva operátorokat alkalmazunk egymás után), ennek a hálózatnak az elkészítése időfüggetlen. A kvantum programok hasonlítanak a klasszikus, elektronikus hardverekhez, az áramkörök leírására is funkcionális nyelvet szokás használni: két komponens közti kapcsolat leírásánál nem azt mondjuk meg, mit csináljon a program, hanem csak jellemezzük a kapcsolatukat, a végeredményként létrejött áramkör már magától tud működni megfelelően.
A Quipper programokat egy quipper
script futtatásával lehet lefordítani. Ez a script néhány beállítás hozzáadása után továbbítja a kódot a Haskell fordítójának. Eredményként egy futtatható állományt kapunk, ami pl. szimulációt, vagy képgenerálást végezhet el. Ha felhasználjuk a Preview
-t, akkor az Adobe Acrobat Reader-ben megnyílik a generált hálózat ábrája.
Ez a generált hálózati ábra a megszokott formában tartalmazza a kvantum hálózatot. A létrehozott qbiteket vezetékek reprezentálják. A qbiteken végrehajtott operációkat különféle szimbólumokkal, többnyire egy négyszög dobozzal jelölik. A négyszög azokat a vezetékeket érinti, amin végrehajtódik az operáció. Az ábrát balról jobbra kell értelmezni, az x tengely a végrehajtási sorrendet jelöli. Kezdetben az alapállapotoktól indulunk, majd az operátorokon keresztül eljutunk egy végállapotba, amikor is megmérjük a qbitet, és a mért adattal további műveleteket hajthatunk végre. A mérés utáni adatfolyamot dupla vonalas vezeték jelzi, itt az adat értéke klasszikus állapot, míg a kvantumbitek között egyszeres vonal található.
A Quipper lehetőséget ad a kép testreszabására pl. kommentek, feliratok elhelyezésével, elhelyezések módosításával. A hálózati elrendezés nagy része azonban generált pozíció szerint működik.
A programot előre megadott típusokból, emőre megadott műveletek felhasználásával írhatjuk meg Haskell nyelven, illetve tetszőlegesen kiegészíthetjük saját értékekkel, műveletekkel. A Hasekll ismerete után a Quipper elemeinek megértése nem okoz nehézséget. Az elemek listája megtalálható a hivatalos dokumentációban. Aki nem jártas a Haskell használatában, nem ismeri a funkcionális programozást, ajánlott a Learn You a Haskell for Great Good! című könyv átolvasása - már csak a humoros írásmód miatt is. A Haskell megtanulása talán nehézkes lehet, ugyanakkor használata sok dolgot megkönnyít.
A Deutsch–Jozsa algoritmus leírása Quipper nyelven
Megjegyzés: A példaprogram a Five Quantum Algorithms Using Quipper című rövid útmutatóból származik, annak egyszerűsített változata.
Ha futtatjuk a programot, és a kiegyensúlyozott típust választjuk, a következő ábrát generálja a Quipper:
Konstans típus esetén a kimenet:
Úgy tűnhet, hogy ez a program mégsem oldotta meg a Deutsch–Jozsa problémát. Ez részben igaz is, mert szimulációt nem hajtottunk végre, az eredmény nem lett kiértékelve. Azonban ne felejtsük el, hogy a programok futtattásának pillanatában a kérdéses függvénynek ismertnek kell lennie minden esetben, így a függvény típusától függően kétféle hálózat lehetséges a válasz kikalkulálásának időpontjában. A Quipper erről a kétféle változatról készített pillanatképeket. Ha a generált hálózat alapján építenénk egy mini-kvantumszámítógépet, és elindítanánk, a helyes választ kapnánk vissza. Természetesen lehetséges olyan hálózati leírást is generálni a Quipper-rel, ami általánosságban írja le a problémát megoldó hálózatot, de ha ezt akarnánk megvalósítani, a mini-kvantumszámítógép építése közben már egyik vagy másik variációt kell választanunk.
Értékelés
- Előnyök: Kisméretű hálózatok, vagy hálózatok részleteinek szemléltetésére ábrák sokkal alkalmasabbak, mint programkódok. Ránézésre is egyből meg tudjuk mondani, melyik kvantumbiten milyen műveleteket végzünk el. Mivel a Quipper a Haskell nyelvre épül, annak a nyelvnek minden elemeét felhasználhatjuk, illetve aki jártas már a Haskell programozásban, nem kell új színtaktikát megtanulnia.
- Hátrányok: A generált ábrák kezelése kissé nehézkes, ugyanis nem közvetlenül fájlba menti le a PDF dokumentumot, hanem külső programmal nyitja meg. Az ábrákon sokszor nem lehet részleteket feltünteni, mert néha a hálózat túl nagy méretű, ami miatt kicsi lesz az ábra, vagy túl sok, össze-vissza kapcsolt műveletet hajtunk végre, ami miatt áttekinthetetlen lesz (hasonlóan a bonyolult nyomtatott áramkörök terveihez).
Q#
A Q# nyelvet 2017 végén mutatta be a Microsoft, jelezve, hogy a cég a későbbiekben nagy figyelmet fog fordítani a kvantumprogramozásnak. A Microsoft Quantum Development Kit nagyban épít már korábban kifejlesztett és bevált technológiákra, mint pl. a C# nyelv, a Visual Studio fejlesztőkörnyezet. A Q# nyelv sok sajátosságot mutat más, főleg C# és F# nyelvekkel, ami könnyebbé teszi a szintaktika megértését, gyorsítva ezzel a fejlesztési folyamatot. Viszonylag gazdag elemekkel rendelkezik, a benne leírt algoritmusok könnyedén felismerhetők.
Jelenleg a Microsoft Quantum Development Kit, és azon belül a Q# nyelv egy Visual Studio kiegészítőként telepíthető. Ez egy kifejlett fejlesztőeszköz, amit a Microsoft már 1997 óta fejleszt, sok változáson ment keresztül. Eddigiekben főleg C++ és .NET fejlesztésre használták, de az eszköz számtalan más nyelvet képes kezelni.
Ez a kiegészítő még nem túl fejlett, ami nem meglepő, tekintve, hogy kb. fél éve jelent meg. A helyes működésre helyezték a legnagyobb hangsúlyt, az automatikus kiegészítés, hibák azonnali kijelzése, tippek megjelenítése - ahogy az ma már elvárható egy kompakt fejlesztőeszköztől - még csak kezdetlegesen érhető el. Várhatóan a közeljövőben ezt fejleszteni fogják, amint igény mutatkozik a Q# nyelv használata iránt, illetve az alap nyelvi elemeket sikerül hibátlanra, könnyen használhatóra alakítani.
A Microsoft kvantum fejlesztőcsomagjában a szimuláció és a kvantum program leírása élesen elkülönül. A szimuláció C# nyelven lehetséges - itt fel lehet használni a C# nyelv tetszőleges elemét, ami nagy szabadságot ad a fejlesztők számára, a tesztesetek lehetnek nagyon komplexek is, illetve könnyű a külvilággal kommunikálni (pl. megjeleníteni az eredményt). A két nyelv párhuzamos használata jól mutatja a :NET keretrendszer egyik fő jellemzőjét, mégpedig a nyelvfüggetlenséget: a különböző nyelvekben leírt dolgok egyező névtérben vannak, így elérhető az egyik a másikból fennakadás nélkül, a fordító elvégzi a szükséges konverziókat.
A Q#, és q C# illetve F# szintaktikái között sok hasonlósság figyelmhető meg. Sok elemet, módszert átvettek a korábbi nyelvekből - ilyen pl. az using
kulcsszó és a köré épülő minta: lefoglaljuk az erőforrást, végrehajtunk rajta tetszőleges műveletet, majd felszabadítjuk, vagy az F# nyelvben használt let
kulcsszó a módosíthatatlan változók esetében. Mégis a Microsoft fejlesztői törekedtek arra, hogy felismerhető legyen a különbség: a Q# nyelvben a típusoknak nagy kezdőbetűi vannak, a névtér meghatározása és kibontása kissé eltérű módon adható meg, az operátorok paraméterei eltérő helyen és sorrendben vannak, mint a hagyományos metódusoknál stb. Erre azért lehetett szükség, hogy a fejlesztők ránézésre meg tudják mondani, a két nyelv közül melyikben dolgoznak éppen, ugyanis sok hibát okozhat, ha összekevernék a nyelveket és azok elemeit, hiszen a C# nyelven elérhető, a .NET keretrendszerben megtalálható könyvtáraknak akár lehet, nincs is értelme egy kvantum programban, vagy teljesen máshogy kell a műveletet elvégezni.
A kvantum programokat egy .qs
kiterjesztésű fájlokban kell megírni Q# nyelven. Ebbe a fájlba több operációt és függvényt, típusokat és értékeket írhatunk le. A kvantum programnak van egy belépő, más nyelvekből main
-ként ismert pontja, ahol a bemeneti paramétereket várja, illetve visszatérési értéke megadja a kvantum program eredményét. Ezek tetszőleges értékeke lehetnek, így a klasszikus programból bármilyen adat átvihető a kvantum programba. Természetesen a kvantum programból nem vihető ki a klasszikus programba kvantumbit, csak azoknak mért eredményei.
A Q# típusrendszere klasszikus (pl. Int
, Bool
), és kvantum (Qubit
, Result
), és további segédtípusokat (pl. operációk, generikus, saját típusok) különböztet meg. A klasszikus típusok lehetővé teszik a két program közti kommunikációt, illetve az algoritmusok beállításait (pl. a qregiszter elemeinek számát megadhatjuk egy Int
típussal). A qregiszterek Qubit
tömbökből állnak. A qbiteket az operáció elején le kell foglalni, majd végén visszaállítani 0 fázisba, és elengedni őket. A foglalás és elengedés között tetszőleges transzformációkat, méréseket alkalmazhatunk a qbiteken. Számtalan, előre definiált segédoperáció érhető el a Microsoft.Quantum
névtér alatt, amiket felhasználva gyakori műveleteket gyorsan tudunk elvégezni. Ilyenek a gyakran használt általános unitér operátorok, illetve a kapuk több qbiten való végrehajtását lehetővé tevő ApplyToEach
függvény, vagy a hibakeresésre használható AssertQubit
művelet.
Ellentétben a hagyományos programozási nyelvekkel, a Q#-ban egy operációnak több “belseje” is lehet. Ugyanis ha az operációnak nincs visszatérési értéke, akkor megadhatjuk az adjoint (megfordított) és a controlled (irányított), illetve ezek ötvözésének viselkedését is. Többnyire a fordító elég okos ahhoz, hogy ezeket a viselkedéseket a rendes viselkedésből kikövetkeztesse (mivel a legtöbb alap kapu maga is unitér operátor, így megfordítható és irányítható), de ha mégse, vagy hatékonyságnövelés miatt szükséges, megadhatjuk mi is mindegyiket külön-külön.
A Q# kétféle típusú változókat különböztet meg:
- Mutable: Az ilyen változók deklarálása a
mutable
kulcsszóval lehetséges. A benne tárolt adat később megváltoztatható, aset
kulcsszó felhasználásával. Ilyen típusúnak érdemes választani pl. a mérési eredményeket tároló tömböt: elsőnek lefoglaljuk a tömböt, majd minden mérési eredményt beleírunk. - Immutable: Ezek a
let
kulcsszóval deklarálhatók. A későbbiekben nem rendelhető hozzájuk másik érték. Ilyen típusúnak érdemes választani a konstans paramétereket (mint pl. az algoritmusban használt qbitek száma), a köztes állapotokban qbitek azonosítására használt változókat (ebben az esetben a qbit értéke megváltozhat, de az, hogy az immutable változó melyik qbitre hivatkozik, az nem).
A mérések eredménye Result
típusú változóban tárolódik. Egy ilyen típusú változó értéke One
vagy Zero
lehet. Ezek az értékek nem 1 és 0 számokat jelölnek! Noha természetesen ha a mérési eredmény biztosan 1, akkor a változó One
-t fog tárolni, azonban ha a qbit mért együtthatója alapján az érték nem biztos, a program (az alkalmazott mérési operátornak megfelelően) dönti el, melyik klasszikus bitre alakítja át a kvantumbit értékét.
A Q# nyelv további elemei könnyen értelmezhetőek, ha már van ismeretünk más szekvenciális, objektum-orientált programozási nyelvekben. A teljes lista megtalálható a hivatalos dokumentációban.
Egy tipikus Q# nyelven leírt program felépítése:
- Felhasznált névterek megadása az
open
kulcsszóval. - Segéd- és főoperátorok deklarálása.
- Az operációkban lefoglaljuk a szükséges qbiteket.
- Végrehajtjuk a kívánt műveleteket.
- Ha kell, elvégezzük a méréseket a qbiteken.
- A mérési eredmény alapján kikalkuláljuk a kívánt eredményt, esetleg további műveleteket végzünk el.
- Alaphelyzetbe állítjuk a qbiteket.
- Átadjuk a klasszikus programnak a kvantum program eredményét.
A Deutsch–Jozsa algoritmus leírása Q# nyelvben és tesztelése C# nyelven
Megjegyzés: A példaprogram a hivatalos Q# repository-ből származik, annak egyszerűsített változata.
Tesztelésre használt szimuláció:
Az algoritmust leíró kvantum program:
Értékelés
- Előnyök: Nagyon kényelmes, hogy a szimuláció és a kvantum program leírása elkülönül. Főleg, mert így ha elérhetővé válik a kvantumszámítógép, lehetőség lesz a szimuláció egyszerű eltávolítására. A Q# színtaktikája könnyedén értelmezhető azok számára, akik dolgoztak már C# vagy hasonló nyelvekkel, ami gyorsítja a tanulást. Várhatóan a Microsoft sokáig fejleszteni fogja a nyelvet, mint ahogy teszi azt a C# esetében is, ami napjainkban talán a legmodernebb klasszikus programozási nyelvnek mondható. A Visual Studio használatával nagyon gyors és egyszerű a szimulációk lefuttatása, kényelmesen dolgozhatunk a már megszokott fejlesztőkörnyezetben.
- Hátrányok: A Microsoft Quantum Development Kit még csak fél éve jelent meg. Érezhető, hogy kezdeti fázisban van a fejlesztés. Bár működőképesek a programok, a fejlesztőeszköz, és a nyelvi elemek, elérhető segédoperációk használata kevésbé kifinomult, hosszú távon még sok fejlesztést igényelnek.
Összefoglalás
Mint látható, a klasszikus- és a kvantumprogramok között sok hasonlóság és eltérés található egyaránt. Jelenleg még nem léteznek igazi kvantum programok, többnyire csak szimulációval hajtják végre a leírt algoritmusokat, statisztikákat készítenek az eredményekről, vagy modelleket, hálózatokat készítenek hozzá. A kvantum programozási nyelvek egy része még fejlesztés alatt áll (vagy éppen abbamaradt), ám folyamatosan jönnek létre új nyelvek, és fejlesztőeszközök.
A kvantum programozási nyelvek nagy jövőnek néznek elé. Valamelyest követjük a klasszikus programozás életciklusát: legelsőnek a működőképes, egyszerű nyelvek jöttek létre (mint pl. a QCL), majd az új nyelvek már egyre több szempontot figyelembe vettek, felhasználtak bevált módszereket (mint pl. a Q# esetében). A kvantumszámítógép megjelenésével erőteljesebb fejlesztés várható ezen a területen.
A bemutatott nyelveken kívül számtalan másik is elérhető. Amiket megismerhettünk, azok lényegesen eltérnek egymástól, más esetekben érdemes őket használni. Ha absztrakt módon, főleg a matematikai jellemzőket kiemelve szeretnénk leírni algoritmusokat, használhatjuk a kvantum pszeudokódot. A Quipper-rel jól áttekinthető ábrákat hozhatunk létre, amik pl. tanításra felhasználhatóak. A Q# nyelv segítségével könnyen kezelhető kvantumszimulátorhoz férhetünk hozzá, amivel tesztelni is lehet az elméleti dolgokat. Igényeiknek megfelelően az interneten kereshetünk másféle nyelveket is.