Skip to content

Commit

Permalink
more type massaging
Browse files Browse the repository at this point in the history
  • Loading branch information
ecpeterson committed Dec 17, 2019
1 parent 4d26012 commit 5df8964
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 39 deletions.
2 changes: 1 addition & 1 deletion pyquil/_parser/Quil.g4
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ modifier : CONTROLLED
// D. Gate Definitions

defGate : DEFGATE name (( LPAREN variable ( COMMA variable )* RPAREN ) | ( AS gatetype ))? COLON NEWLINE matrix ;
defGateAsPauli : DEFGATE name ( LPAREN ( variable ( COMMA variable )* )? RPAREN ) qubitVariable+ AS PAULISUM COLON NEWLINE pauliTerms ;
defGateAsPauli : DEFGATE name ( LPAREN variable ( COMMA variable )* RPAREN )? qubitVariable+ AS PAULISUM COLON NEWLINE pauliTerms ;

variable : PERCENTAGE IDENTIFIER ;
gatetype : MATRIX
Expand Down
39 changes: 19 additions & 20 deletions pyquil/_parser/gen3/QuilParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def serializedATN():
buf.write("\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\7\n\u00ca\n\n")
buf.write("\f\n\16\n\u00cd\13\n\3\n\3\n\3\n\3\n\5\n\u00d3\n\n\3\n")
buf.write("\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\7\13\u00df")
buf.write("\n\13\f\13\16\13\u00e2\13\13\5\13\u00e4\n\13\3\13\3\13")
buf.write("\n\13\f\13\16\13\u00e2\13\13\3\13\3\13\5\13\u00e6\n\13")
buf.write("\3\13\6\13\u00e9\n\13\r\13\16\13\u00ea\3\13\3\13\3\13")
buf.write("\3\13\3\13\3\13\3\f\3\f\3\f\3\r\3\r\3\16\3\16\3\16\7\16")
buf.write("\u00fb\n\16\f\16\16\16\u00fe\13\16\3\16\3\16\3\17\3\17")
Expand Down Expand Up @@ -126,12 +126,12 @@ def serializedATN():
buf.write("\3\2\2\2\u00d2\u00d0\3\2\2\2\u00d2\u00d3\3\2\2\2\u00d3")
buf.write("\u00d4\3\2\2\2\u00d4\u00d5\7F\2\2\u00d5\u00d6\7L\2\2\u00d6")
buf.write("\u00d7\5\32\16\2\u00d7\23\3\2\2\2\u00d8\u00d9\7\3\2\2")
buf.write("\u00d9\u00da\5\n\6\2\u00da\u00e3\7B\2\2\u00db\u00e0\5")
buf.write("\u00d9\u00e5\5\n\6\2\u00da\u00db\7B\2\2\u00db\u00e0\5")
buf.write("\26\f\2\u00dc\u00dd\7A\2\2\u00dd\u00df\5\26\f\2\u00de")
buf.write("\u00dc\3\2\2\2\u00df\u00e2\3\2\2\2\u00e0\u00de\3\2\2\2")
buf.write("\u00e0\u00e1\3\2\2\2\u00e1\u00e4\3\2\2\2\u00e2\u00e0\3")
buf.write("\2\2\2\u00e3\u00db\3\2\2\2\u00e3\u00e4\3\2\2\2\u00e4\u00e5")
buf.write("\3\2\2\2\u00e5\u00e6\7C\2\2\u00e6\u00e8\3\2\2\2\u00e7")
buf.write("\u00e0\u00e1\3\2\2\2\u00e1\u00e3\3\2\2\2\u00e2\u00e0\3")
buf.write("\2\2\2\u00e3\u00e4\7C\2\2\u00e4\u00e6\3\2\2\2\u00e5\u00da")
buf.write("\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e6\u00e8\3\2\2\2\u00e7")
buf.write("\u00e9\5$\23\2\u00e8\u00e7\3\2\2\2\u00e9\u00ea\3\2\2\2")
buf.write("\u00ea\u00e8\3\2\2\2\u00ea\u00eb\3\2\2\2\u00eb\u00ec\3")
buf.write("\2\2\2\u00ec\u00ed\7\23\2\2\u00ed\u00ee\7\26\2\2\u00ee")
Expand Down Expand Up @@ -262,7 +262,7 @@ def serializedATN():
buf.write("\u021dm\3\2\2\2\u021e\u021f\5p9\2\u021f\u0220\7.\2\2\u0220")
buf.write("o\3\2\2\2\u0221\u0222\t\f\2\2\u0222q\3\2\2\2\64sx}\u0083")
buf.write("\u008c\u00a0\u00a5\u00af\u00b4\u00b9\u00cb\u00d2\u00e0")
buf.write("\u00e3\u00ea\u00fc\u0107\u010f\u011c\u0126\u012b\u0130")
buf.write("\u00e5\u00ea\u00fc\u0107\u010f\u011c\u0126\u012b\u0130")
buf.write("\u013b\u0144\u0149\u014e\u0153\u0157\u015d\u0165\u016e")
buf.write("\u0172\u0177\u018e\u0198\u019f\u01a2\u01b0\u01b6\u01bc")
buf.write("\u01c2\u01d6\u01dd\u01e9\u01ed\u0201\u020c\u020e\u0216")
Expand Down Expand Up @@ -1291,6 +1291,13 @@ def pauliTerms(self):
def LPAREN(self):
return self.getToken(QuilParser.LPAREN, 0)

def variable(self, i:int=None):
if i is None:
return self.getTypedRuleContexts(QuilParser.VariableContext)
else:
return self.getTypedRuleContext(QuilParser.VariableContext,i)


def RPAREN(self):
return self.getToken(QuilParser.RPAREN, 0)

Expand All @@ -1301,13 +1308,6 @@ def qubitVariable(self, i:int=None):
return self.getTypedRuleContext(QuilParser.QubitVariableContext,i)


def variable(self, i:int=None):
if i is None:
return self.getTypedRuleContexts(QuilParser.VariableContext)
else:
return self.getTypedRuleContext(QuilParser.VariableContext,i)


def COMMA(self, i:int=None):
if i is None:
return self.getTokens(QuilParser.COMMA)
Expand Down Expand Up @@ -1339,13 +1339,12 @@ def defGateAsPauli(self):
self.match(QuilParser.DEFGATE)
self.state = 215
self.name()

self.state = 216
self.match(QuilParser.LPAREN)
self.state = 225
self.state = 227
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==QuilParser.PERCENTAGE:
if _la==QuilParser.LPAREN:
self.state = 216
self.match(QuilParser.LPAREN)
self.state = 217
self.variable()
self.state = 222
Expand All @@ -1360,10 +1359,10 @@ def defGateAsPauli(self):
self._errHandler.sync(self)
_la = self._input.LA(1)

self.state = 225
self.match(QuilParser.RPAREN)


self.state = 227
self.match(QuilParser.RPAREN)
self.state = 230
self._errHandler.sync(self)
_la = self._input.LA(1)
Expand Down
30 changes: 16 additions & 14 deletions pyquil/paulis.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@

from typing import Callable, Dict, FrozenSet, Iterable, Iterator, List, Optional, Sequence, Tuple, Union

from pyquil.quilatom import QubitPlaceholder, FormalArgument, Expression
from pyquil.quilatom import QubitPlaceholder, FormalArgument, Expression, ExpressionDesignator

from .quil import Program
from .gates import H, RZ, RX, CNOT, X, PHASE, QUANTUM_GATES
from numbers import Number
from collections import OrderedDict
import warnings

PauliCoefficientDesignator = Union[int, float, complex, Expression]
PauliTargetDesignator = Union[int, FormalArgument]
PauliDesignator = Union['PauliTerm', 'PauliSum']

Expand Down Expand Up @@ -74,7 +73,7 @@ class PauliTerm(object):
"""A term is a product of Pauli operators operating on different qubits.
"""

def __init__(self, op: str, index: PauliTargetDesignator, coefficient: PauliCoefficientDesignator = 1.0):
def __init__(self, op: str, index: PauliTargetDesignator, coefficient: ExpressionDesignator = 1.0):
""" Create a new Pauli Term with a Pauli operator at a particular index and a leading
coefficient.
Expand All @@ -90,6 +89,9 @@ def __init__(self, op: str, index: PauliTargetDesignator, coefficient: PauliCoef
if not _valid_qubit(index):
raise ValueError(f"{index} is not a valid qubit")
self._ops[index] = op

self.coefficient: Union[complex, Expression]

if isinstance(coefficient, Number):
self.coefficient = complex(coefficient)
else:
Expand Down Expand Up @@ -208,7 +210,7 @@ def _multiply_factor(self, factor: str, index: int) -> 'PauliTerm':

return new_term

def __mul__(self, term: Union[PauliDesignator, PauliCoefficientDesignator]) -> PauliDesignator:
def __mul__(self, term: Union[PauliDesignator, ExpressionDesignator]) -> PauliDesignator:
"""Multiplies this Pauli Term with another PauliTerm, PauliSum, or number according to the
Pauli algebra rules.
Expand All @@ -229,7 +231,7 @@ def __mul__(self, term: Union[PauliDesignator, PauliCoefficientDesignator]) -> P

return term_with_coeff(new_term, new_term.coefficient * new_coeff)

def __rmul__(self, other: PauliCoefficientDesignator) -> 'PauliTerm':
def __rmul__(self, other: ExpressionDesignator) -> 'PauliTerm':
"""Multiplies this PauliTerm with another object, probably a number.
:param other: A number or PauliTerm to multiply by
Expand Down Expand Up @@ -258,7 +260,7 @@ def __pow__(self, power: int) -> 'PauliTerm':
result *= self
return result

def __add__(self, other: Union[PauliDesignator, PauliCoefficientDesignator]) -> 'PauliSum':
def __add__(self, other: Union[PauliDesignator, ExpressionDesignator]) -> 'PauliSum':
"""Adds this PauliTerm with another one.
:param other: A PauliTerm object, a PauliSum object, or a Number
Expand All @@ -273,7 +275,7 @@ def __add__(self, other: Union[PauliDesignator, PauliCoefficientDesignator]) ->
new_sum = PauliSum([self, other])
return new_sum.simplify()

def __radd__(self, other: PauliCoefficientDesignator) -> 'PauliTerm':
def __radd__(self, other: ExpressionDesignator) -> 'PauliTerm':
"""Adds this PauliTerm with a Number.
:param other: A Number
Expand Down Expand Up @@ -487,7 +489,7 @@ def sZ(q: int) -> PauliTerm:
return PauliTerm("Z", q)


def term_with_coeff(term: PauliTerm, coeff: PauliCoefficientDesignator) -> PauliTerm:
def term_with_coeff(term: PauliTerm, coeff: ExpressionDesignator) -> PauliTerm:
"""
Change the coefficient of a PauliTerm.
Expand Down Expand Up @@ -560,7 +562,7 @@ def __getitem__(self, item: int) -> PauliTerm:
def __iter__(self) -> Iterator[PauliTerm]:
return self.terms.__iter__()

def __mul__(self, other: Union[PauliDesignator, PauliCoefficientDesignator]) -> 'PauliSum':
def __mul__(self, other: Union[PauliDesignator, ExpressionDesignator]) -> 'PauliSum':
"""
Multiplies together this PauliSum with PauliSum, PauliTerm or Number objects. The new term
is then simplified according to the Pauli Algebra rules.
Expand All @@ -580,7 +582,7 @@ def __mul__(self, other: Union[PauliDesignator, PauliCoefficientDesignator]) ->
new_sum = PauliSum(new_terms)
return new_sum.simplify()

def __rmul__(self, other: PauliCoefficientDesignator) -> 'PauliSum':
def __rmul__(self, other: ExpressionDesignator) -> 'PauliSum':
"""
Multiples together this PauliSum with PauliSum, PauliTerm or Number objects. The new term
is then simplified according to the Pauli Algebra rules.
Expand Down Expand Up @@ -620,7 +622,7 @@ def __pow__(self, power: int) -> 'PauliSum':
result *= self
return result

def __add__(self, other: Union[PauliDesignator, PauliCoefficientDesignator]) -> 'PauliSum':
def __add__(self, other: Union[PauliDesignator, ExpressionDesignator]) -> 'PauliSum':
"""
Adds together this PauliSum with PauliSum, PauliTerm or Number objects. The new term
is then simplified according to the Pauli Algebra rules.
Expand All @@ -638,7 +640,7 @@ def __add__(self, other: Union[PauliDesignator, PauliCoefficientDesignator]) ->
new_sum = PauliSum(new_terms)
return new_sum.simplify()

def __radd__(self, other: PauliCoefficientDesignator) -> 'PauliSum':
def __radd__(self, other: ExpressionDesignator) -> 'PauliSum':
"""
Adds together this PauliSum with a Number object. The new term
is then simplified according to the Pauli Algebra rules.
Expand All @@ -650,7 +652,7 @@ def __radd__(self, other: PauliCoefficientDesignator) -> 'PauliSum':
assert isinstance(other, Number)
return self + other

def __sub__(self, other: Union[PauliDesignator, PauliCoefficientDesignator]) -> 'PauliSum':
def __sub__(self, other: Union[PauliDesignator, ExpressionDesignator]) -> 'PauliSum':
"""
Finds the difference of this PauliSum with PauliSum, PauliTerm or Number objects. The new
term is then simplified according to the Pauli Algebra rules.
Expand All @@ -661,7 +663,7 @@ def __sub__(self, other: Union[PauliDesignator, PauliCoefficientDesignator]) ->
"""
return self + -1. * other

def __rsub__(self, other: Union[PauliDesignator, PauliCoefficientDesignator]) -> 'PauliSum':
def __rsub__(self, other: Union[PauliDesignator, ExpressionDesignator]) -> 'PauliSum':
"""
Finds the different of this PauliSum with PauliSum, PauliTerm or Number objects. The new
term is then simplified according to the Pauli Algebra rules.
Expand Down
19 changes: 15 additions & 4 deletions pyquil/quilbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import collections
import numpy as np
from typing import (Any, Callable, ClassVar, Container, Dict, Iterable, List, Optional, Set, Tuple,
Union)
Union, TYPE_CHECKING)
from warnings import warn

from pyquil.quilatom import (Expression, ExpressionDesignator, Label, LabelPlaceholder,
Expand All @@ -28,6 +28,10 @@
format_parameter, unpack_qubit)


if TYPE_CHECKING:
from pyquil.paulis import PauliSum


class AbstractInstruction(object):
"""
Abstract class for representing single instructions.
Expand Down Expand Up @@ -419,7 +423,11 @@ class DefGateByPaulis(DefGate):
"""

# actually, body is of type PauliSum, but circular imports are no good
def __init__(self, gate_name: str, parameters: list, arguments: list, body): # type: ignore
def __init__(self,
gate_name: str,
parameters: List[ParameterDesignator],
arguments: List[QubitDesignator],
body: 'PauliSum'):
if not isinstance(gate_name, str):
raise TypeError("Gate name must be a string")

Expand All @@ -432,10 +440,13 @@ def __init__(self, gate_name: str, parameters: list, arguments: list, body): #
self.body = body

def out(self) -> str:
out = f"DEFGATE {self.name}({', '.join(map(str, self.parameters))}) " # type: ignore
out = f"DEFGATE {self.name}"
if self.parameters is not None:
out += f"({', '.join(map(str, self.parameters))}) "
out += f"{' '.join(map(str, self.arguments))} AS PAULI-SUM:\n"
for term in self.body:
args, word = zip(*term._ops.items())
args = term._ops.keys()
word = term._ops.values()
out += f" {''.join(word)}({term.coefficient}) " + " ".join(map(str, args)) + "\n"
return out

Expand Down

0 comments on commit 5df8964

Please sign in to comment.