Megosztás a következőn keresztül:


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 SWAPdeklarációja , amely két qubit állapotát cseréli le, és q2explicit 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 SWAPControlled 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 SWAPami 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 SWAPvan 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 SWAPhí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 bodyazokat, 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.