We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Sympy Division by Integer in Exponent or Radians throws and error
**Description of the issue**
When using sympy to define a circuit, a ValueError exception might be thrown by NumPy
(ValueError: Integers to negative integer powers are not allowed.)

This happens when there is some division in the exponent by some integer and an attempt to resolve the parameters of the gate/circuit is made.

A simple example of this issue is given below.

**How to reproduce the issue**

```

import cirq
import sympy

Rx_gate = cirq.rx(rads=sympy.Symbol('a')/sympy.Symbol('b'))
cirq.resolve_parameters(Rx_gate,{'a':1, 'b':2})

```

<details>

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-101-ef0861896379> in <module>
----> 1 cirq.resolve_parameters(Rx_1,{'a':a, 'b':b, 't':t, 'm':m})

~/anaconda3/envs/quantum/lib/python3.8/site-packages/cirq/protocols/resolve_parameters.py in resolve_parameters(val, param_resolver, recursive)
    182         result = NotImplemented
    183     else:
--> 184         result = getter(param_resolver, recursive)
    185 
    186     if result is not NotImplemented:

~/anaconda3/envs/quantum/lib/python3.8/site-packages/cirq/ops/eigen_gate.py in _resolve_parameters_(self, resolver, recursive)
    354 
    355     def _resolve_parameters_(self, resolver: 'cirq.ParamResolver', recursive: bool) -> 'EigenGate':
--> 356         return self._with_exponent(exponent=resolver.value_of(self._exponent, recursive))
    357 
    358     def _equal_up_to_global_phase_(self, other, atol):

~/anaconda3/envs/quantum/lib/python3.8/site-packages/cirq/study/resolver.py in value_of(self, value, recursive)
    141             product = self.value_of(value.args[0], recursive)
    142             for factor in value.args[1:]:
--> 143                 product *= self.value_of(factor, recursive)
    144             return product
    145         if isinstance(value, sympy.Pow) and len(value.args) == 2:

~/anaconda3/envs/quantum/lib/python3.8/site-packages/cirq/study/resolver.py in value_of(self, value, recursive)
    144             return product
    145         if isinstance(value, sympy.Pow) and len(value.args) == 2:
--> 146             return np.power(
    147                 self.value_of(value.args[0], recursive), self.value_of(value.args[1], recursive)
    148             )

ValueError: Integers to negative integer powers are not allowed.


</details>

**Cirq version**
0.11.1



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cirq-core/cirq/study/resolver.py`
Content:
```
1 # Copyright 2018 The Cirq Developers
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     https://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 """Resolves ParameterValues to assigned values."""
16 import numbers
17 from typing import Any, Dict, Iterator, Optional, TYPE_CHECKING, Union, cast
18 
19 import numpy as np
20 import sympy
21 from sympy.core import numbers as sympy_numbers
22 from cirq._compat import proper_repr
23 from cirq._doc import document
24 
25 if TYPE_CHECKING:
26     import cirq
27 
28 
29 ParamDictType = Dict['cirq.TParamKey', 'cirq.TParamVal']
30 document(ParamDictType, """Dictionary from symbols to values.""")  # type: ignore
31 
32 ParamResolverOrSimilarType = Union['cirq.ParamResolver', ParamDictType, None]
33 document(
34     ParamResolverOrSimilarType,  # type: ignore
35     """Something that can be used to turn parameters into values.""",
36 )
37 
38 # Used to mark values that are being resolved recursively to detect loops.
39 _RecursionFlag = object()
40 
41 
42 class ParamResolver:
43     """Resolves parameters to actual values.
44 
45     A parameter is a variable whose value has not been determined.
46     A ParamResolver is an object that can be used to assign values for these
47     variables.
48 
49     ParamResolvers are hashable; their param_dict must not be mutated.
50 
51     Attributes:
52         param_dict: A dictionary from the ParameterValue key (str) to its
53             assigned value.
54     """
55 
56     def __new__(cls, param_dict: 'cirq.ParamResolverOrSimilarType' = None):
57         if isinstance(param_dict, ParamResolver):
58             return param_dict
59         return super().__new__(cls)
60 
61     def __init__(self, param_dict: 'cirq.ParamResolverOrSimilarType' = None) -> None:
62         if hasattr(self, 'param_dict'):
63             return  # Already initialized. Got wrapped as part of the __new__.
64 
65         self._param_hash: Optional[int] = None
66         self.param_dict = cast(ParamDictType, {} if param_dict is None else param_dict)
67         self._deep_eval_map: ParamDictType = {}
68 
69     def value_of(
70         self, value: Union['cirq.TParamKey', float], recursive: bool = True
71     ) -> 'cirq.TParamVal':
72         """Attempt to resolve a parameter to its assigned value.
73 
74         Floats are returned without modification.  Strings are resolved via
75         the parameter dictionary with exact match only.  Otherwise, strings
76         are considered to be sympy.Symbols with the name as the input string.
77 
78         A sympy.Symbol is first checked for exact match in the parameter
79         dictionary. Otherwise, it is treated as a sympy.Basic.
80 
81         A sympy.Basic is resolved using sympy substitution.
82 
83         Note that passing a formula to this resolver can be slow due to the
84         underlying sympy library.  For circuits relying on quick performance,
85         it is recommended that all formulas are flattened before-hand using
86         cirq.flatten or other means so that formula resolution is avoided.
87         If unable to resolve a sympy.Symbol, returns it unchanged.
88         If unable to resolve a name, returns a sympy.Symbol with that name.
89 
90         Args:
91             value: The parameter to try to resolve.
92             recursive: Whether to recursively evaluate formulas.
93 
94         Returns:
95             The value of the parameter as resolved by this resolver.
96 
97         Raises:
98             RecursionError: If the ParamResolver detects a loop in recursive
99                 resolution.
100         """
101 
102         # Input is a pass through type, no resolution needed: return early
103         v = _resolve_value(value)
104         if v is not NotImplemented:
105             return v
106 
107         # Handles 2 cases:
108         # Input is a string and maps to a number in the dictionary
109         # Input is a symbol and maps to a number in the dictionary
110         # In both cases, return it directly.
111         if value in self.param_dict:
112             param_value = self.param_dict[value]
113             v = _resolve_value(param_value)
114             if v is not NotImplemented:
115                 return v
116 
117         # Input is a string and is not in the dictionary.
118         # Treat it as a symbol instead.
119         if isinstance(value, str):
120             # If the string is in the param_dict as a value, return it.
121             # Otherwise, try using the symbol instead.
122             return self.value_of(sympy.Symbol(value), recursive)
123 
124         # Input is a symbol (sympy.Symbol('a')) and its string maps to a number
125         # in the dictionary ({'a': 1.0}).  Return it.
126         if isinstance(value, sympy.Symbol) and value.name in self.param_dict:
127             param_value = self.param_dict[value.name]
128             v = _resolve_value(param_value)
129             if v is not NotImplemented:
130                 return v
131 
132         # The following resolves common sympy expressions
133         # If sympy did its job and wasn't slower than molasses,
134         # we wouldn't need the following block.
135         if isinstance(value, sympy.Add):
136             summation = self.value_of(value.args[0], recursive)
137             for addend in value.args[1:]:
138                 summation += self.value_of(addend, recursive)
139             return summation
140         if isinstance(value, sympy.Mul):
141             product = self.value_of(value.args[0], recursive)
142             for factor in value.args[1:]:
143                 product *= self.value_of(factor, recursive)
144             return product
145         if isinstance(value, sympy.Pow) and len(value.args) == 2:
146             return np.power(
147                 self.value_of(value.args[0], recursive), self.value_of(value.args[1], recursive)
148             )
149 
150         if not isinstance(value, sympy.Basic):
151             # No known way to resolve this variable, return unchanged.
152             return value
153 
154         # Input is either a sympy formula or the dictionary maps to a
155         # formula.  Use sympy to resolve the value.
156         # Note that sympy.subs() is slow, so we want to avoid this and
157         # only use it for cases that require complicated resolution.
158         if not recursive:
159             # Resolves one step at a time. For example:
160             # a.subs({a: b, b: c}) == b
161             v = value.subs(self.param_dict, simultaneous=True)
162             if v.free_symbols:
163                 return v
164             elif sympy.im(v):
165                 return complex(v)
166             else:
167                 return float(v)
168 
169         # Recursive parameter resolution. We can safely assume that value is a
170         # single symbol, since combinations are handled earlier in the method.
171         if value in self._deep_eval_map:
172             v = self._deep_eval_map[value]
173             if v is not _RecursionFlag:
174                 return v
175             raise RecursionError('Evaluation of {value} indirectly contains itself.')
176 
177         # There isn't a full evaluation for 'value' yet. Until it's ready,
178         # map value to None to identify loops in component evaluation.
179         self._deep_eval_map[value] = _RecursionFlag
180 
181         v = self.value_of(value, recursive=False)
182         if v == value:
183             self._deep_eval_map[value] = v
184         else:
185             self._deep_eval_map[value] = self.value_of(v, recursive)
186         return self._deep_eval_map[value]
187 
188     def _resolve_parameters_(self, resolver: 'ParamResolver', recursive: bool) -> 'ParamResolver':
189         new_dict = {k: k for k in resolver}
190         new_dict.update({k: self.value_of(k, recursive) for k in self})
191         new_dict.update({k: resolver.value_of(v, recursive) for k, v in new_dict.items()})
192         if recursive and self.param_dict:
193             new_resolver = ParamResolver(new_dict)
194             # Resolve down to single-step mappings.
195             return ParamResolver()._resolve_parameters_(new_resolver, recursive=True)
196         return ParamResolver(new_dict)
197 
198     def __iter__(self) -> Iterator[Union[str, sympy.Symbol]]:
199         return iter(self.param_dict)
200 
201     def __bool__(self) -> bool:
202         return bool(self.param_dict)
203 
204     def __getitem__(self, key: Union[sympy.Basic, float, str]) -> 'cirq.TParamVal':
205         return self.value_of(key)
206 
207     def __hash__(self) -> int:
208         if self._param_hash is None:
209             self._param_hash = hash(frozenset(self.param_dict.items()))
210         return self._param_hash
211 
212     def __eq__(self, other):
213         if not isinstance(other, ParamResolver):
214             return NotImplemented
215         return self.param_dict == other.param_dict
216 
217     def __ne__(self, other):
218         return not self == other
219 
220     def __repr__(self) -> str:
221         param_dict_repr = (
222             '{'
223             + ', '.join([f'{proper_repr(k)}: {proper_repr(v)}' for k, v in self.param_dict.items()])
224             + '}'
225         )
226         return f'cirq.ParamResolver({param_dict_repr})'
227 
228     def _json_dict_(self) -> Dict[str, Any]:
229         return {
230             'cirq_type': self.__class__.__name__,
231             # JSON requires mappings to have keys of basic types.
232             'param_dict': list(self.param_dict.items()),
233         }
234 
235     @classmethod
236     def _from_json_dict_(cls, param_dict, **kwargs):
237         return cls(dict(param_dict))
238 
239 
240 def _resolve_value(val: Any) -> Any:
241     if isinstance(val, numbers.Number) and not isinstance(val, sympy.Basic):
242         return val
243     if isinstance(val, sympy_numbers.IntegerConstant):
244         return val.p
245     if isinstance(val, sympy_numbers.RationalConstant):
246         return val.p / val.q
247     if val == sympy.pi:
248         return np.pi
249 
250     getter = getattr(val, '_resolved_value_', None)
251     result = NotImplemented if getter is None else getter()
252     return result
253
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/cirq-core/cirq/study/resolver.py b/cirq-core/cirq/study/resolver.py
--- a/cirq-core/cirq/study/resolver.py
+++ b/cirq-core/cirq/study/resolver.py
@@ -143,9 +143,11 @@
                 product *= self.value_of(factor, recursive)
             return product
         if isinstance(value, sympy.Pow) and len(value.args) == 2:
-            return np.power(
-                self.value_of(value.args[0], recursive), self.value_of(value.args[1], recursive)
-            )
+            base = self.value_of(value.args[0], recursive)
+            exponent = self.value_of(value.args[1], recursive)
+            if isinstance(base, numbers.Number):
+                return np.float_power(base, exponent)
+            return np.power(base, exponent)
 
         if not isinstance(value, sympy.Basic):
             # No known way to resolve this variable, return unchanged.

{"golden_diff": "diff --git a/cirq-core/cirq/study/resolver.py b/cirq-core/cirq/study/resolver.py\n--- a/cirq-core/cirq/study/resolver.py\n+++ b/cirq-core/cirq/study/resolver.py\n@@ -143,9 +143,11 @@\n                 product *= self.value_of(factor, recursive)\n             return product\n         if isinstance(value, sympy.Pow) and len(value.args) == 2:\n-            return np.power(\n-                self.value_of(value.args[0], recursive), self.value_of(value.args[1], recursive)\n-            )\n+            base = self.value_of(value.args[0], recursive)\n+            exponent = self.value_of(value.args[1], recursive)\n+            if isinstance(base, numbers.Number):\n+                return np.float_power(base, exponent)\n+            return np.power(base, exponent)\n \n         if not isinstance(value, sympy.Basic):\n             # No known way to resolve this variable, return unchanged.\n", "issue": "Sympy Division by Integer in Exponent or Radians throws and error\n**Description of the issue**\r\nWhen using sympy to define a circuit, a ValueError exception might be thrown by NumPy\r\n(ValueError: Integers to negative integer powers are not allowed.)\r\n\r\nThis happens when there is some division in the exponent by some integer and an attempt to resolve the parameters of the gate/circuit is made.\r\n\r\nA simple example of this issue is given below.\r\n\r\n**How to reproduce the issue**\r\n\r\n```\r\n\r\nimport cirq\r\nimport sympy\r\n\r\nRx_gate = cirq.rx(rads=sympy.Symbol('a')/sympy.Symbol('b'))\r\ncirq.resolve_parameters(Rx_gate,{'a':1, 'b':2})\r\n\r\n```\r\n\r\n<details>\r\n\r\n---------------------------------------------------------------------------\r\nValueError                                Traceback (most recent call last)\r\n<ipython-input-101-ef0861896379> in <module>\r\n----> 1 cirq.resolve_parameters(Rx_1,{'a':a, 'b':b, 't':t, 'm':m})\r\n\r\n~/anaconda3/envs/quantum/lib/python3.8/site-packages/cirq/protocols/resolve_parameters.py in resolve_parameters(val, param_resolver, recursive)\r\n    182         result = NotImplemented\r\n    183     else:\r\n--> 184         result = getter(param_resolver, recursive)\r\n    185 \r\n    186     if result is not NotImplemented:\r\n\r\n~/anaconda3/envs/quantum/lib/python3.8/site-packages/cirq/ops/eigen_gate.py in _resolve_parameters_(self, resolver, recursive)\r\n    354 \r\n    355     def _resolve_parameters_(self, resolver: 'cirq.ParamResolver', recursive: bool) -> 'EigenGate':\r\n--> 356         return self._with_exponent(exponent=resolver.value_of(self._exponent, recursive))\r\n    357 \r\n    358     def _equal_up_to_global_phase_(self, other, atol):\r\n\r\n~/anaconda3/envs/quantum/lib/python3.8/site-packages/cirq/study/resolver.py in value_of(self, value, recursive)\r\n    141             product = self.value_of(value.args[0], recursive)\r\n    142             for factor in value.args[1:]:\r\n--> 143                 product *= self.value_of(factor, recursive)\r\n    144             return product\r\n    145         if isinstance(value, sympy.Pow) and len(value.args) == 2:\r\n\r\n~/anaconda3/envs/quantum/lib/python3.8/site-packages/cirq/study/resolver.py in value_of(self, value, recursive)\r\n    144             return product\r\n    145         if isinstance(value, sympy.Pow) and len(value.args) == 2:\r\n--> 146             return np.power(\r\n    147                 self.value_of(value.args[0], recursive), self.value_of(value.args[1], recursive)\r\n    148             )\r\n\r\nValueError: Integers to negative integer powers are not allowed.\r\n\r\n\r\n</details>\r\n\r\n**Cirq version**\r\n0.11.1\r\n\r\n\n", "before_files": [{"content": "# Copyright 2018 The Cirq Developers\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Resolves ParameterValues to assigned values.\"\"\"\nimport numbers\nfrom typing import Any, Dict, Iterator, Optional, TYPE_CHECKING, Union, cast\n\nimport numpy as np\nimport sympy\nfrom sympy.core import numbers as sympy_numbers\nfrom cirq._compat import proper_repr\nfrom cirq._doc import document\n\nif TYPE_CHECKING:\n    import cirq\n\n\nParamDictType = Dict['cirq.TParamKey', 'cirq.TParamVal']\ndocument(ParamDictType, \"\"\"Dictionary from symbols to values.\"\"\")  # type: ignore\n\nParamResolverOrSimilarType = Union['cirq.ParamResolver', ParamDictType, None]\ndocument(\n    ParamResolverOrSimilarType,  # type: ignore\n    \"\"\"Something that can be used to turn parameters into values.\"\"\",\n)\n\n# Used to mark values that are being resolved recursively to detect loops.\n_RecursionFlag = object()\n\n\nclass ParamResolver:\n    \"\"\"Resolves parameters to actual values.\n\n    A parameter is a variable whose value has not been determined.\n    A ParamResolver is an object that can be used to assign values for these\n    variables.\n\n    ParamResolvers are hashable; their param_dict must not be mutated.\n\n    Attributes:\n        param_dict: A dictionary from the ParameterValue key (str) to its\n            assigned value.\n    \"\"\"\n\n    def __new__(cls, param_dict: 'cirq.ParamResolverOrSimilarType' = None):\n        if isinstance(param_dict, ParamResolver):\n            return param_dict\n        return super().__new__(cls)\n\n    def __init__(self, param_dict: 'cirq.ParamResolverOrSimilarType' = None) -> None:\n        if hasattr(self, 'param_dict'):\n            return  # Already initialized. Got wrapped as part of the __new__.\n\n        self._param_hash: Optional[int] = None\n        self.param_dict = cast(ParamDictType, {} if param_dict is None else param_dict)\n        self._deep_eval_map: ParamDictType = {}\n\n    def value_of(\n        self, value: Union['cirq.TParamKey', float], recursive: bool = True\n    ) -> 'cirq.TParamVal':\n        \"\"\"Attempt to resolve a parameter to its assigned value.\n\n        Floats are returned without modification.  Strings are resolved via\n        the parameter dictionary with exact match only.  Otherwise, strings\n        are considered to be sympy.Symbols with the name as the input string.\n\n        A sympy.Symbol is first checked for exact match in the parameter\n        dictionary. Otherwise, it is treated as a sympy.Basic.\n\n        A sympy.Basic is resolved using sympy substitution.\n\n        Note that passing a formula to this resolver can be slow due to the\n        underlying sympy library.  For circuits relying on quick performance,\n        it is recommended that all formulas are flattened before-hand using\n        cirq.flatten or other means so that formula resolution is avoided.\n        If unable to resolve a sympy.Symbol, returns it unchanged.\n        If unable to resolve a name, returns a sympy.Symbol with that name.\n\n        Args:\n            value: The parameter to try to resolve.\n            recursive: Whether to recursively evaluate formulas.\n\n        Returns:\n            The value of the parameter as resolved by this resolver.\n\n        Raises:\n            RecursionError: If the ParamResolver detects a loop in recursive\n                resolution.\n        \"\"\"\n\n        # Input is a pass through type, no resolution needed: return early\n        v = _resolve_value(value)\n        if v is not NotImplemented:\n            return v\n\n        # Handles 2 cases:\n        # Input is a string and maps to a number in the dictionary\n        # Input is a symbol and maps to a number in the dictionary\n        # In both cases, return it directly.\n        if value in self.param_dict:\n            param_value = self.param_dict[value]\n            v = _resolve_value(param_value)\n            if v is not NotImplemented:\n                return v\n\n        # Input is a string and is not in the dictionary.\n        # Treat it as a symbol instead.\n        if isinstance(value, str):\n            # If the string is in the param_dict as a value, return it.\n            # Otherwise, try using the symbol instead.\n            return self.value_of(sympy.Symbol(value), recursive)\n\n        # Input is a symbol (sympy.Symbol('a')) and its string maps to a number\n        # in the dictionary ({'a': 1.0}).  Return it.\n        if isinstance(value, sympy.Symbol) and value.name in self.param_dict:\n            param_value = self.param_dict[value.name]\n            v = _resolve_value(param_value)\n            if v is not NotImplemented:\n                return v\n\n        # The following resolves common sympy expressions\n        # If sympy did its job and wasn't slower than molasses,\n        # we wouldn't need the following block.\n        if isinstance(value, sympy.Add):\n            summation = self.value_of(value.args[0], recursive)\n            for addend in value.args[1:]:\n                summation += self.value_of(addend, recursive)\n            return summation\n        if isinstance(value, sympy.Mul):\n            product = self.value_of(value.args[0], recursive)\n            for factor in value.args[1:]:\n                product *= self.value_of(factor, recursive)\n            return product\n        if isinstance(value, sympy.Pow) and len(value.args) == 2:\n            return np.power(\n                self.value_of(value.args[0], recursive), self.value_of(value.args[1], recursive)\n            )\n\n        if not isinstance(value, sympy.Basic):\n            # No known way to resolve this variable, return unchanged.\n            return value\n\n        # Input is either a sympy formula or the dictionary maps to a\n        # formula.  Use sympy to resolve the value.\n        # Note that sympy.subs() is slow, so we want to avoid this and\n        # only use it for cases that require complicated resolution.\n        if not recursive:\n            # Resolves one step at a time. For example:\n            # a.subs({a: b, b: c}) == b\n            v = value.subs(self.param_dict, simultaneous=True)\n            if v.free_symbols:\n                return v\n            elif sympy.im(v):\n                return complex(v)\n            else:\n                return float(v)\n\n        # Recursive parameter resolution. We can safely assume that value is a\n        # single symbol, since combinations are handled earlier in the method.\n        if value in self._deep_eval_map:\n            v = self._deep_eval_map[value]\n            if v is not _RecursionFlag:\n                return v\n            raise RecursionError('Evaluation of {value} indirectly contains itself.')\n\n        # There isn't a full evaluation for 'value' yet. Until it's ready,\n        # map value to None to identify loops in component evaluation.\n        self._deep_eval_map[value] = _RecursionFlag\n\n        v = self.value_of(value, recursive=False)\n        if v == value:\n            self._deep_eval_map[value] = v\n        else:\n            self._deep_eval_map[value] = self.value_of(v, recursive)\n        return self._deep_eval_map[value]\n\n    def _resolve_parameters_(self, resolver: 'ParamResolver', recursive: bool) -> 'ParamResolver':\n        new_dict = {k: k for k in resolver}\n        new_dict.update({k: self.value_of(k, recursive) for k in self})\n        new_dict.update({k: resolver.value_of(v, recursive) for k, v in new_dict.items()})\n        if recursive and self.param_dict:\n            new_resolver = ParamResolver(new_dict)\n            # Resolve down to single-step mappings.\n            return ParamResolver()._resolve_parameters_(new_resolver, recursive=True)\n        return ParamResolver(new_dict)\n\n    def __iter__(self) -> Iterator[Union[str, sympy.Symbol]]:\n        return iter(self.param_dict)\n\n    def __bool__(self) -> bool:\n        return bool(self.param_dict)\n\n    def __getitem__(self, key: Union[sympy.Basic, float, str]) -> 'cirq.TParamVal':\n        return self.value_of(key)\n\n    def __hash__(self) -> int:\n        if self._param_hash is None:\n            self._param_hash = hash(frozenset(self.param_dict.items()))\n        return self._param_hash\n\n    def __eq__(self, other):\n        if not isinstance(other, ParamResolver):\n            return NotImplemented\n        return self.param_dict == other.param_dict\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __repr__(self) -> str:\n        param_dict_repr = (\n            '{'\n            + ', '.join([f'{proper_repr(k)}: {proper_repr(v)}' for k, v in self.param_dict.items()])\n            + '}'\n        )\n        return f'cirq.ParamResolver({param_dict_repr})'\n\n    def _json_dict_(self) -> Dict[str, Any]:\n        return {\n            'cirq_type': self.__class__.__name__,\n            # JSON requires mappings to have keys of basic types.\n            'param_dict': list(self.param_dict.items()),\n        }\n\n    @classmethod\n    def _from_json_dict_(cls, param_dict, **kwargs):\n        return cls(dict(param_dict))\n\n\ndef _resolve_value(val: Any) -> Any:\n    if isinstance(val, numbers.Number) and not isinstance(val, sympy.Basic):\n        return val\n    if isinstance(val, sympy_numbers.IntegerConstant):\n        return val.p\n    if isinstance(val, sympy_numbers.RationalConstant):\n        return val.p / val.q\n    if val == sympy.pi:\n        return np.pi\n\n    getter = getattr(val, '_resolved_value_', None)\n    result = NotImplemented if getter is None else getter()\n    return result\n", "path": "cirq-core/cirq/study/resolver.py"}], "after_files": [{"content": "# Copyright 2018 The Cirq Developers\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Resolves ParameterValues to assigned values.\"\"\"\nimport numbers\nfrom typing import Any, Dict, Iterator, Optional, TYPE_CHECKING, Union, cast\n\nimport numpy as np\nimport sympy\nfrom sympy.core import numbers as sympy_numbers\nfrom cirq._compat import proper_repr\nfrom cirq._doc import document\n\nif TYPE_CHECKING:\n    import cirq\n\n\nParamDictType = Dict['cirq.TParamKey', 'cirq.TParamVal']\ndocument(ParamDictType, \"\"\"Dictionary from symbols to values.\"\"\")  # type: ignore\n\nParamResolverOrSimilarType = Union['cirq.ParamResolver', ParamDictType, None]\ndocument(\n    ParamResolverOrSimilarType,  # type: ignore\n    \"\"\"Something that can be used to turn parameters into values.\"\"\",\n)\n\n# Used to mark values that are being resolved recursively to detect loops.\n_RecursionFlag = object()\n\n\nclass ParamResolver:\n    \"\"\"Resolves parameters to actual values.\n\n    A parameter is a variable whose value has not been determined.\n    A ParamResolver is an object that can be used to assign values for these\n    variables.\n\n    ParamResolvers are hashable; their param_dict must not be mutated.\n\n    Attributes:\n        param_dict: A dictionary from the ParameterValue key (str) to its\n            assigned value.\n    \"\"\"\n\n    def __new__(cls, param_dict: 'cirq.ParamResolverOrSimilarType' = None):\n        if isinstance(param_dict, ParamResolver):\n            return param_dict\n        return super().__new__(cls)\n\n    def __init__(self, param_dict: 'cirq.ParamResolverOrSimilarType' = None) -> None:\n        if hasattr(self, 'param_dict'):\n            return  # Already initialized. Got wrapped as part of the __new__.\n\n        self._param_hash: Optional[int] = None\n        self.param_dict = cast(ParamDictType, {} if param_dict is None else param_dict)\n        self._deep_eval_map: ParamDictType = {}\n\n    def value_of(\n        self, value: Union['cirq.TParamKey', float], recursive: bool = True\n    ) -> 'cirq.TParamVal':\n        \"\"\"Attempt to resolve a parameter to its assigned value.\n\n        Floats are returned without modification.  Strings are resolved via\n        the parameter dictionary with exact match only.  Otherwise, strings\n        are considered to be sympy.Symbols with the name as the input string.\n\n        A sympy.Symbol is first checked for exact match in the parameter\n        dictionary. Otherwise, it is treated as a sympy.Basic.\n\n        A sympy.Basic is resolved using sympy substitution.\n\n        Note that passing a formula to this resolver can be slow due to the\n        underlying sympy library.  For circuits relying on quick performance,\n        it is recommended that all formulas are flattened before-hand using\n        cirq.flatten or other means so that formula resolution is avoided.\n        If unable to resolve a sympy.Symbol, returns it unchanged.\n        If unable to resolve a name, returns a sympy.Symbol with that name.\n\n        Args:\n            value: The parameter to try to resolve.\n            recursive: Whether to recursively evaluate formulas.\n\n        Returns:\n            The value of the parameter as resolved by this resolver.\n\n        Raises:\n            RecursionError: If the ParamResolver detects a loop in recursive\n                resolution.\n        \"\"\"\n\n        # Input is a pass through type, no resolution needed: return early\n        v = _resolve_value(value)\n        if v is not NotImplemented:\n            return v\n\n        # Handles 2 cases:\n        # Input is a string and maps to a number in the dictionary\n        # Input is a symbol and maps to a number in the dictionary\n        # In both cases, return it directly.\n        if value in self.param_dict:\n            param_value = self.param_dict[value]\n            v = _resolve_value(param_value)\n            if v is not NotImplemented:\n                return v\n\n        # Input is a string and is not in the dictionary.\n        # Treat it as a symbol instead.\n        if isinstance(value, str):\n            # If the string is in the param_dict as a value, return it.\n            # Otherwise, try using the symbol instead.\n            return self.value_of(sympy.Symbol(value), recursive)\n\n        # Input is a symbol (sympy.Symbol('a')) and its string maps to a number\n        # in the dictionary ({'a': 1.0}).  Return it.\n        if isinstance(value, sympy.Symbol) and value.name in self.param_dict:\n            param_value = self.param_dict[value.name]\n            v = _resolve_value(param_value)\n            if v is not NotImplemented:\n                return v\n\n        # The following resolves common sympy expressions\n        # If sympy did its job and wasn't slower than molasses,\n        # we wouldn't need the following block.\n        if isinstance(value, sympy.Add):\n            summation = self.value_of(value.args[0], recursive)\n            for addend in value.args[1:]:\n                summation += self.value_of(addend, recursive)\n            return summation\n        if isinstance(value, sympy.Mul):\n            product = self.value_of(value.args[0], recursive)\n            for factor in value.args[1:]:\n                product *= self.value_of(factor, recursive)\n            return product\n        if isinstance(value, sympy.Pow) and len(value.args) == 2:\n            base = self.value_of(value.args[0], recursive)\n            exponent = self.value_of(value.args[1], recursive)\n            if isinstance(base, numbers.Number):\n                return np.float_power(base, exponent)\n            return np.power(base, exponent)\n\n        if not isinstance(value, sympy.Basic):\n            # No known way to resolve this variable, return unchanged.\n            return value\n\n        # Input is either a sympy formula or the dictionary maps to a\n        # formula.  Use sympy to resolve the value.\n        # Note that sympy.subs() is slow, so we want to avoid this and\n        # only use it for cases that require complicated resolution.\n        if not recursive:\n            # Resolves one step at a time. For example:\n            # a.subs({a: b, b: c}) == b\n            v = value.subs(self.param_dict, simultaneous=True)\n            if v.free_symbols:\n                return v\n            elif sympy.im(v):\n                return complex(v)\n            else:\n                return float(v)\n\n        # Recursive parameter resolution. We can safely assume that value is a\n        # single symbol, since combinations are handled earlier in the method.\n        if value in self._deep_eval_map:\n            v = self._deep_eval_map[value]\n            if v is not _RecursionFlag:\n                return v\n            raise RecursionError('Evaluation of {value} indirectly contains itself.')\n\n        # There isn't a full evaluation for 'value' yet. Until it's ready,\n        # map value to None to identify loops in component evaluation.\n        self._deep_eval_map[value] = _RecursionFlag\n\n        v = self.value_of(value, recursive=False)\n        if v == value:\n            self._deep_eval_map[value] = v\n        else:\n            self._deep_eval_map[value] = self.value_of(v, recursive)\n        return self._deep_eval_map[value]\n\n    def _resolve_parameters_(self, resolver: 'ParamResolver', recursive: bool) -> 'ParamResolver':\n        new_dict = {k: k for k in resolver}\n        new_dict.update({k: self.value_of(k, recursive) for k in self})\n        new_dict.update({k: resolver.value_of(v, recursive) for k, v in new_dict.items()})\n        if recursive and self.param_dict:\n            new_resolver = ParamResolver(new_dict)\n            # Resolve down to single-step mappings.\n            return ParamResolver()._resolve_parameters_(new_resolver, recursive=True)\n        return ParamResolver(new_dict)\n\n    def __iter__(self) -> Iterator[Union[str, sympy.Symbol]]:\n        return iter(self.param_dict)\n\n    def __bool__(self) -> bool:\n        return bool(self.param_dict)\n\n    def __getitem__(self, key: Union[sympy.Basic, float, str]) -> 'cirq.TParamVal':\n        return self.value_of(key)\n\n    def __hash__(self) -> int:\n        if self._param_hash is None:\n            self._param_hash = hash(frozenset(self.param_dict.items()))\n        return self._param_hash\n\n    def __eq__(self, other):\n        if not isinstance(other, ParamResolver):\n            return NotImplemented\n        return self.param_dict == other.param_dict\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __repr__(self) -> str:\n        param_dict_repr = (\n            '{'\n            + ', '.join([f'{proper_repr(k)}: {proper_repr(v)}' for k, v in self.param_dict.items()])\n            + '}'\n        )\n        return f'cirq.ParamResolver({param_dict_repr})'\n\n    def _json_dict_(self) -> Dict[str, Any]:\n        return {\n            'cirq_type': self.__class__.__name__,\n            # JSON requires mappings to have keys of basic types.\n            'param_dict': list(self.param_dict.items()),\n        }\n\n    @classmethod\n    def _from_json_dict_(cls, param_dict, **kwargs):\n        return cls(dict(param_dict))\n\n\ndef _resolve_value(val: Any) -> Any:\n    if isinstance(val, numbers.Number) and not isinstance(val, sympy.Basic):\n        return val\n    if isinstance(val, sympy_numbers.IntegerConstant):\n        return val.p\n    if isinstance(val, sympy_numbers.RationalConstant):\n        return val.p / val.q\n    if val == sympy.pi:\n        return np.pi\n\n    getter = getattr(val, '_resolved_value_', None)\n    result = NotImplemented if getter is None else getter()\n    return result\n", "path": "cirq-core/cirq/study/resolver.py"}]}