Specializációdeklarációk
A hívható deklarációkról szóló szakaszban leírtak szerint jelenleg nincs ok a függvények specializációinak explicit deklarálására. Ez a témakör a műveletekre vonatkozik, és ismerteti, hogyan deklarálhatja az egyes funktorok támogatásához szükséges specializációkat.
A kvantum-számítástechnikában meglehetősen gyakori probléma egy adott átalakítás mellékjelének megkövetelése. Számos kvantum-algoritmusnak szüksége van egy műveletre és annak mellékelésére is a számítások elvégzéséhez.
Q# olyan szimbolikus számításokat alkalmaz, amelyek automatikusan létrehozhatják a megfelelő mellékes implementációt egy adott test implementációhoz. Ez a generáció még olyan implementációk esetében is lehetséges, amelyek szabadon keverik a klasszikus és kvantumszámításokat. Vannak azonban bizonyos korlátozások, amelyek ebben az esetben érvényesek. Az automatikus létrehozás például teljesítménybeli okokból nem támogatott, ha az implementáció mutable változókat használ. Ezenkívül a testen belüli minden egyes művelet létrehozza a megfelelő mellékjelet, hogy támogassa magát a Adjoint
funktort.
Bár a több qubites esetben nem lehet könnyen visszavonni a méréseket, a mérések kombinálhatók úgy, hogy az alkalmazott átalakítás egységes legyen. Ebben az esetben ez azt jelenti, hogy bár a test megvalósítása olyan méréseket tartalmaz, amelyek önmagukban nem támogatják a Adjoint
funktort, a test teljes egészében szomszédos. A mellék implementáció automatikus létrehozása azonban ebben az esetben sikertelen lesz. Ezért manuálisan is meg lehet adni az implementációt.
A fordító automatikusan optimalizált implementációkat hoz létre a gyakori mintákhoz, például a konjugációkhoz.
Mindazonáltal egy explicit specializáció kívánatos lehet egy optimalizáltabb implementáció kézi meghatározásához. Egy implementációt és tetszőleges számú implementációt explicit módon meg lehet adni.
Megjegyzés
A fordító nem ellenőrzi egy ilyen manuálisan megadott implementáció helyességét.
A következő példában egy művelet SWAP
deklarációja , amely két qubit állapotát cseréli le, és q2
explicit specializációt deklarál q1
a szomszédos verzióra és annak szabályozott verziójára. Bár a és így a felhasználó által definiált implementációk Adjoint SWAP
Controlled SWAP
, a fordítónak továbbra is létre kell hoznia az implementációt mindkét funktor kombinációjához (Controlled Adjoint SWAP
ami ugyanaz, mint Adjoint Controlled SWAP
).
operation SWAP (q1 : Qubit, q2 : Qubit) : Unit
is Adj + Ctl {
body ... {
CNOT(q1, q2);
CNOT(q2, q1);
CNOT(q1, q2);
}
adjoint ... {
SWAP(q1, q2);
}
controlled (cs, ...) {
CNOT(q1, q2);
Controlled CNOT(cs, (q2, q1));
CNOT(q1, q2);
}
}
Automatikus létrehozási irányelvek
Egy adott specializáció létrehozásának meghatározásakor a fordító rangsorolja a felhasználó által definiált implementációkat. Ez azt jelenti, hogy ha egy mellékint specializáció felhasználó által definiált, és egy szabályozott specializáció automatikusan jön létre, akkor az irányított mellékint specializáció a felhasználó által definiált melléknév alapján jön létre, és fordítva. Ebben az esetben mindkét specializáció felhasználó által definiált. Mivel a mellékint-implementáció automatikus létrehozása további korlátozás alá esik, az irányított mellékint specializáció alapértelmezés szerint a mellékint specializáció explicit módon meghatározott implementációjának szabályozott specializációját hozza létre.
Az implementáció esetében SWAP
a jobb megoldás az ellenőrzött specializáció szomszédossága, hogy elkerülje az első és az utolsó CNOT
végrehajtásának szükségtelen konfigurálását a vezérlő qubitek állapotában.
Ha explicit deklarációt ad hozzá az ellenőrzött mellékhálózati verzióhoz, amely megfelelő generációs direktívát határoz meg, kényszeríti a fordítót arra, hogy a szabályozott mellékint specializációt az ellenőrzött verzió manuálisan megadott implementációja alapján hozza létre. A fordító által létrehozandó specializáció ilyen explicit deklarációja
controlled adjoint invert;
és be van szúrva a deklarációba.SWAP
Másrészt a sor beszúrása
controlled adjoint distribute;
kényszeríti a fordítót a specializáció létrehozására a definiált (vagy létrehozott) mellékspecializáció alapján. További részletekért tekintse meg ezt a részleges specializációs következtetési javaslatot.
A művelethez SWAP
van egy jobb lehetőség.
SWAP
önbőség, azaz saját inverz; a melléknév definiált implementációja csupán a törzsét SWAP
hívja meg. Ezt az irányelvvel fejezheti ki
adjoint self;
A szomszédos specializáció ilyen módon történő deklarálása biztosítja, hogy a fordító által automatikusan beszúrt szabályozott mellékint specializáció csak az ellenőrzött specializációt hívja meg.
A következő generációs irányelvek léteznek és érvényesek:
Specializáció | Irányelv(ek) |
---|---|
body Specializáció: |
- |
adjoint Specializáció: |
self , invert |
controlled Specializáció: |
distribute |
controlled adjoint Specializáció: |
self , invert , distribute |
Az, hogy az összes generációs irányelv érvényes egy ellenőrzött mellékint specializációra, nem véletlen; Mindaddig, amíg a funktorok ingáznak, a funktorok kombinációjára vonatkozó specializáció megvalósítására vonatkozó érvényes generációs irányelvek halmaza mindig az érvényes generátorok halmazának egyesítése mindegyikhez.
A korábban felsorolt irányelveken kívül az irányelv auto
minden specializációra érvényes, kivéve body
azokat, amelyek azt jelzik, hogy a fordítónak automatikusan megfelelő generációs irányelvet kell választania.
A nyilatkozat
operation DoNothing() : Unit {
body ... { }
adjoint auto;
controlled auto;
controlled adjoint auto;
}
egyenértékű a
operation DoNothing() : Unit
is Adj + Ctl { }
A példában szereplő széljegyzet is Adj + Ctl
meghatározza a művelet jellemzőit, amelyek az adott művelet által támogatott funktorokkal kapcsolatos információkat tartalmazzák.
Bár az olvashatóság kedvéért javasoljuk, hogy minden műveletet a jellemzőinek teljes leírásával jegyzeteljön, a fordító automatikusan beszúrja vagy befejezi a jegyzetet az explicit módon deklarált specializációk alapján. Ezzel szemben a fordító olyan specializációkat is létrehoz, amelyek nem lettek explicit módon deklarálva, de a jegyzetekkel ellátott jellemzők alapján létezniük kell. Azt mondjuk, hogy a megadott jegyzet implicit módon deklarálta ezeket a specializációkat. A fordító automatikusan létrehozza a szükséges specializációkat, ha tudja, kiválasztja a megfelelő direktívát. Q# így támogatja mind a műveleti jellemzők, mind a meglévő specializációk következtetését (részleges) széljegyzetek és explicit módon meghatározott specializációk alapján.
Bizonyos értelemben a specializációk hasonlóak az azonos hívható egyéni túlterhelésekhez, azzal a kikötéssel, hogy bizonyos korlátozások vonatkoznak a deklarálható túlterhelésekre.