Поделиться через


Операции и функции

Как описано более подробно в описании типа данных кубита, квантовые вычисления выполняются в виде побочных эффектов операций, которые изначально поддерживаются на целевом квантовом процессоре. Это, на самом деле, единственные побочные эффекты в Q#. Так как все типы неизменяемы, побочные эффекты не влияют на значение, которое явно представлено в Q#. Таким образом, если реализация определенного вызываемого объекта не напрямую или косвенно вызывает какие-либо из этих встроенных операций, его выполнение всегда создает одинаковые выходные данные, учитывая те же входные данные.

Q# позволяет явно разделить такие чисто детерминированные вычисления на функции . Так как набор собственных поддерживаемых инструкций не является фиксированным и встроенным в сам язык, а довольно полностью настраиваемым и выраженным как библиотека Q#, детерминизм гарантируется, требуя, чтобы функции могли вызывать только другие функции и не могут вызывать какие-либо операции. Кроме того, собственные инструкции, которые не детерминированы, т. е. они влияют на квантовое состояние, представляются как операции. С этими двумя ограничениями функции можно оценить сразу после того, как их входное значение известно, и, в принципе, никогда не нужно оценивать более одного раза для одного и того же входного значения.

Q# поэтому различает два типа вызываемых : операции и функции. Все вызываемые методы принимают один аргумент (потенциально значение кортежа) в качестве входных данных и создают одно значение (кортеж) в качестве выходных данных. Синтаксически тип операции выражается как <TIn> => <TOut> is <Char>, где <TIn> необходимо заменить типом аргумента, <TOut> необходимо заменить типом возвращаемого значения, а <Char> заменить <Char> характеристиками операции . Если не нужно указывать характеристики, синтаксис упрощает <TIn> => <TOut>. Аналогичным образом типы функций выражаются как <TIn> -> <TOut>.

Помимо этой гарантии детерминизма, существует мало различий между операциями и функциями. Оба являются значениями первого класса, которые можно передавать свободно; их можно использовать в качестве возвращаемых значений или аргументов для других вызываемых элементов, как показано в следующем примере:

function Pow<'T>(op : 'T => Unit, pow : Int) : 'T => Unit {
    return PowImpl(op, pow, _);
}

Оба экземпляра можно создать на основе определения типо-параметризованного определения, например, параметризованной типа Pow функции Pow типа, и их можно частично применять, как показано в инструкции return в примере.

Характеристики операций

Помимо сведений о входном и выходном типе, тип операции содержит сведения о характеристиках операции. Эти сведения, например, описывают, какие воронки поддерживаются операцией. Кроме того, внутреннее представление также содержит сведения, относящиеся к оптимизации, которые выводится компилятором.

Характеристики операции — это набор предопределенных и встроенных меток. Они выражаются в виде специального выражения, которое является частью сигнатуры типа. Выражение состоит из одного из предопределенных наборов меток или сочетания выражений характеристик с помощью поддерживаемого двоичного оператора.

Существует два предопределенных набора, Adj и Ctl.

  • Adj — это набор, содержащий одну метку, указывающую на то, что операция связана, то есть она поддерживает Adjoint functor, а примененное квантовое преобразование может быть "отменено", то есть может быть инвертировано.
  • Ctl — это набор, содержащий одну метку, указывающую, что операция управляется, то есть она поддерживает Controlled functor и его выполнение может быть обусловлено состоянием других кубитов.

Два оператора, поддерживаемые в рамках выражений характеристик, представляют собой набор + объединения и *заданного пересечения. В EBNF (расширенная форма Backus–Naur)

    predefined = "Adj" | "Ctl";
    characteristics = predefined 
        | "(", characteristics, ")" 
        | characteristics ("+"|"*") characteristics;

Как ожидается, * имеет более высокий приоритет, чем +, и оба являются левыми ассоциативными. Тип унитарной операции, например, выражается как <TIn> => <TOut> is Adj + Ctl, где <TIn> следует заменить типом аргумента операции и <TOut> заменен типом возвращаемого значения.

Примечание.

Указание характеристик операции в этой форме имеет два основных преимущества; для одной из них новые метки могут быть представлены без экспоненциально многих ключевых слов языка для всех сочетаний меток. Кроме того, использование выражений для указания характеристик операции также поддерживает параметризацию по характеристикам операций в будущем.