logo

Expression of type Equals

from the theory of proveit.physics.quantum.QPE

In [1]:
import proveit
# Automation is not needed when building an expression:
proveit.defaults.automation = False # This will speed things up.
proveit.defaults.inline_pngs = False # Makes files smaller.
%load_expr # Load the stored expression as 'stored_expr'
# import Expression classes needed to build the expression
from proveit import ExprRange, U, Variable, VertExprArray, eps, m, n, s, t
from proveit.core_expr_types import Len
from proveit.linear_algebra import MatrixMult, ScalarMult, Unitary
from proveit.logic import Equals, Forall, InSet
from proveit.numbers import Add, Ceil, Exp, Interval, IntervalCO, IntervalOC, LessEq, Log, Mod, ModAbs, Mult, NaturalPos, Neg, Real, Round, e, four, frac, greater, greater_eq, i, one, pi, subtract, three, two, zero
from proveit.physics.quantum import I, NumKet, Z, ket_plus, normalized_var_ket_u, var_ket_u
from proveit.physics.quantum.QPE import QPE, phase, s_ket_domain, two_pow_s, two_pow_t
from proveit.physics.quantum.circuits import Gate, Input, Measure, MultiQubitElem, Output, Qcircuit
from proveit.statistics import Prob, ProbOfAll
In [2]:
# build up the expression from sub-expressions
sub_expr1 = Variable("_a", latex_format = r"{_{-}a}")
sub_expr2 = [s, t]
sub_expr3 = [U]
sub_expr4 = [var_ket_u]
sub_expr5 = [phase]
sub_expr6 = Add(t, one)
sub_expr7 = Add(t, s)
sub_expr8 = Interval(one, t)
sub_expr9 = Interval(sub_expr6, sub_expr7)
sub_expr10 = Mult(two_pow_t, phase)
sub_expr11 = Unitary(two_pow_s)
sub_expr12 = InSet(phase, IntervalCO(zero, one))
sub_expr13 = [ExprRange(sub_expr1, Measure(basis = Z), one, t), ExprRange(sub_expr1, Gate(operation = I).with_implicit_representation(), one, s)]
sub_expr14 = MultiQubitElem(element = Gate(operation = QPE(U, t), part = sub_expr1), targets = Interval(one, sub_expr7))
sub_expr15 = Interval(zero, subtract(two_pow_t, one))
sub_expr16 = ExprRange(sub_expr1, MultiQubitElem(element = Output(state = var_ket_u, part = sub_expr1), targets = sub_expr9), one, s)
sub_expr17 = Equals(MatrixMult(U, var_ket_u), ScalarMult(Exp(e, Mult(two, pi, i, phase)), var_ket_u))
sub_expr18 = [ExprRange(sub_expr1, Input(state = ket_plus), one, t), ExprRange(sub_expr1, MultiQubitElem(element = Input(state = var_ket_u, part = sub_expr1), targets = sub_expr9), one, s)]
sub_expr19 = [ExprRange(sub_expr1, sub_expr14, one, t), ExprRange(sub_expr1, sub_expr14, sub_expr6, sub_expr7)]
expr = Equals(Len(operands = [Forall(instance_param_or_params = sub_expr2, instance_expr = Forall(instance_param_or_params = sub_expr3, instance_expr = Forall(instance_param_or_params = sub_expr4, instance_expr = Forall(instance_param_or_params = sub_expr5, instance_expr = Equals(Prob(Qcircuit(vert_expr_array = VertExprArray(sub_expr18, sub_expr19, sub_expr13, [ExprRange(sub_expr1, MultiQubitElem(element = Output(state = NumKet(sub_expr10, t), part = sub_expr1), targets = sub_expr8), one, t), sub_expr16]))), one), domain = Real, conditions = [InSet(sub_expr10, sub_expr15), sub_expr17]).with_wrapping(), domain = s_ket_domain, condition = normalized_var_ket_u).with_wrapping(), domain = sub_expr11).with_wrapping(), domain = NaturalPos).with_wrapping(), Forall(instance_param_or_params = sub_expr2, instance_expr = Forall(instance_param_or_params = sub_expr3, instance_expr = Forall(instance_param_or_params = sub_expr4, instance_expr = Forall(instance_param_or_params = sub_expr5, instance_expr = greater(Prob(Qcircuit(vert_expr_array = VertExprArray(sub_expr18, sub_expr19, sub_expr13, [ExprRange(sub_expr1, MultiQubitElem(element = Output(state = NumKet(Mod(Round(sub_expr10), two_pow_t), t), part = sub_expr1), targets = sub_expr8), one, t), sub_expr16]))), frac(four, Exp(pi, two))), domain = Real, conditions = [sub_expr12, sub_expr17]).with_wrapping(), domain = s_ket_domain, condition = normalized_var_ket_u).with_wrapping(), domain = sub_expr11).with_wrapping(), domain = NaturalPos).with_wrapping(), Forall(instance_param_or_params = [eps], instance_expr = Forall(instance_param_or_params = [s, n], instance_expr = Forall(instance_param_or_params = [U, var_ket_u, phase], instance_expr = Forall(instance_param_or_params = [t], instance_expr = greater_eq(ProbOfAll(instance_param_or_params = [m], instance_element = Qcircuit(vert_expr_array = VertExprArray(sub_expr18, sub_expr19, sub_expr13, [ExprRange(sub_expr1, MultiQubitElem(element = Output(state = NumKet(m, t), part = sub_expr1), targets = sub_expr8), one, t), sub_expr16])), domain = sub_expr15, condition = LessEq(ModAbs(subtract(frac(m, two_pow_t), phase), one), Exp(two, Neg(n)))).with_wrapping(), subtract(one, eps)), domain = NaturalPos, condition = greater_eq(t, Add(n, Ceil(Log(two, Add(two, frac(one, Mult(two, eps)))))))).with_wrapping(), domains = [sub_expr11, s_ket_domain, Real], conditions = [sub_expr12, normalized_var_ket_u, sub_expr17]).with_wrapping(), domain = NaturalPos, condition = greater_eq(n, two)).with_wrapping(), domain = IntervalOC(zero, one)).with_wrapping()]), Len(operands = [ExprRange(sub_expr1, sub_expr1, one, three)]))
expr:
In [3]:
# check that the built expression is the same as the stored expression
assert expr == stored_expr
assert expr._style_id == stored_expr._style_id
print("Passed sanity check: expr matches stored_expr")
Passed sanity check: expr matches stored_expr
In [4]:
# Show the LaTeX representation of the expression for convenience if you need it.
print(stored_expr.latex())
|\left(\begin{array}{l}\forall_{s, t \in \mathbb{N}^+}~\\
\left[\begin{array}{l}\forall_{U \in \textrm{U}\left(2^{s}\right)}~\\
\left[\begin{array}{l}\forall_{\lvert u \rangle \in \mathbb{C}^{2^{s}}~|~\left \|\lvert u \rangle\right \| = 1}~\\
\left[\begin{array}{l}\forall_{\varphi \in \mathbb{R}~|~\left(2^{t} \cdot \varphi\right) \in \{0~\ldotp \ldotp~2^{t} - 1\}, \left(U \thinspace \lvert u \rangle\right) = \left(\mathsf{e}^{2 \cdot \pi \cdot \mathsf{i} \cdot \varphi} \cdot \lvert u \rangle\right)}~\\
\left(\textrm{Pr}\left(\begin{array}{c} \Qcircuit@C=1em @R=.7em{
\qin{\lvert + \rangle} & \multigate{4}{\textrm{QPE}\left(U, t\right)} & \meter & \multiqout{3}{\lvert 2^{t} \cdot \varphi \rangle_{t}} \\
\qin{\lvert + \rangle} & \ghost{\textrm{QPE}\left(U, t\right)} & \meter & \ghostqout{\lvert 2^{t} \cdot \varphi \rangle_{t}} \\
\qin{\begin{array}{c}:\\ \left(t - 3\right) \times \\:\end{array}} & \ghost{\textrm{QPE}\left(U, t\right)} & \measure{\begin{array}{c}:\\ \left(t - 3\right) \times \\:\end{array}} \qw & \ghostqout{\lvert 2^{t} \cdot \varphi \rangle_{t}} \\
\qin{\lvert + \rangle} & \ghost{\textrm{QPE}\left(U, t\right)} & \meter & \ghostqout{\lvert 2^{t} \cdot \varphi \rangle_{t}} \\
\qin{\lvert u \rangle} & \ghost{\textrm{QPE}\left(U, t\right)} & { /^{s} } \qw & \qout{\lvert u \rangle}
} \end{array}\right) = 1\right)\end{array}\right]\end{array}\right]\end{array}\right]\end{array}, \begin{array}{l}\forall_{s, t \in \mathbb{N}^+}~\\
\left[\begin{array}{l}\forall_{U \in \textrm{U}\left(2^{s}\right)}~\\
\left[\begin{array}{l}\forall_{\lvert u \rangle \in \mathbb{C}^{2^{s}}~|~\left \|\lvert u \rangle\right \| = 1}~\\
\left[\begin{array}{l}\forall_{\varphi \in \mathbb{R}~|~\varphi \in \left[0,1\right), \left(U \thinspace \lvert u \rangle\right) = \left(\mathsf{e}^{2 \cdot \pi \cdot \mathsf{i} \cdot \varphi} \cdot \lvert u \rangle\right)}~\\
\left(\textrm{Pr}\left(\begin{array}{c} \Qcircuit@C=1em @R=.7em{
\qin{\lvert + \rangle} & \multigate{4}{\textrm{QPE}\left(U, t\right)} & \meter & \multiqout{3}{\lvert round\left(2^{t} \cdot \varphi\right) ~\textup{mod}~ 2^{t} \rangle_{t}} \\
\qin{\lvert + \rangle} & \ghost{\textrm{QPE}\left(U, t\right)} & \meter & \ghostqout{\lvert round\left(2^{t} \cdot \varphi\right) ~\textup{mod}~ 2^{t} \rangle_{t}} \\
\qin{\begin{array}{c}:\\ \left(t - 3\right) \times \\:\end{array}} & \ghost{\textrm{QPE}\left(U, t\right)} & \measure{\begin{array}{c}:\\ \left(t - 3\right) \times \\:\end{array}} \qw & \ghostqout{\lvert round\left(2^{t} \cdot \varphi\right) ~\textup{mod}~ 2^{t} \rangle_{t}} \\
\qin{\lvert + \rangle} & \ghost{\textrm{QPE}\left(U, t\right)} & \meter & \ghostqout{\lvert round\left(2^{t} \cdot \varphi\right) ~\textup{mod}~ 2^{t} \rangle_{t}} \\
\qin{\lvert u \rangle} & \ghost{\textrm{QPE}\left(U, t\right)} & { /^{s} } \qw & \qout{\lvert u \rangle}
} \end{array}\right) > \frac{4}{\pi^{2}}\right)\end{array}\right]\end{array}\right]\end{array}\right]\end{array}, \begin{array}{l}\forall_{\epsilon \in \left(0,1\right]}~\\
\left[\begin{array}{l}\forall_{s, n \in \mathbb{N}^+~|~n \geq 2}~\\
\left[\begin{array}{l}\forall_{U \in \textrm{U}\left(2^{s}\right), \lvert u \rangle \in \mathbb{C}^{2^{s}}, \varphi \in \mathbb{R}~|~\varphi \in \left[0,1\right), \left \|\lvert u \rangle\right \| = 1, \left(U \thinspace \lvert u \rangle\right) = \left(\mathsf{e}^{2 \cdot \pi \cdot \mathsf{i} \cdot \varphi} \cdot \lvert u \rangle\right)}~\\
\left[\begin{array}{l}\forall_{t \in \mathbb{N}^+~|~t \geq \left(n + \left\lceil \textrm{log}_2\left(2 + \frac{1}{2 \cdot \epsilon}\right)\right\rceil\right)}~\\
\left(\left[\begin{array}{l}\textrm{Prob}_{m \in \{0~\ldotp \ldotp~2^{t} - 1\}~|~\left|\frac{m}{2^{t}} - \varphi\right|_{\textup{mod}\thinspace 1} \leq 2^{-n}}~\\
\left(\begin{array}{c} \Qcircuit@C=1em @R=.7em{
\qin{\lvert + \rangle} & \multigate{4}{\textrm{QPE}\left(U, t\right)} & \meter & \multiqout{3}{\lvert m \rangle_{t}} \\
\qin{\lvert + \rangle} & \ghost{\textrm{QPE}\left(U, t\right)} & \meter & \ghostqout{\lvert m \rangle_{t}} \\
\qin{\begin{array}{c}:\\ \left(t - 3\right) \times \\:\end{array}} & \ghost{\textrm{QPE}\left(U, t\right)} & \measure{\begin{array}{c}:\\ \left(t - 3\right) \times \\:\end{array}} \qw & \ghostqout{\lvert m \rangle_{t}} \\
\qin{\lvert + \rangle} & \ghost{\textrm{QPE}\left(U, t\right)} & \meter & \ghostqout{\lvert m \rangle_{t}} \\
\qin{\lvert u \rangle} & \ghost{\textrm{QPE}\left(U, t\right)} & { /^{s} } \qw & \qout{\lvert u \rangle}
} \end{array}\right)\end{array}\right] \geq \left(1 - \epsilon\right)\right)\end{array}\right]\end{array}\right]\end{array}\right]\end{array}\right)| = |\left(1, 2, \ldots, 3\right)|
In [5]:
stored_expr.style_options()
namedescriptiondefaultcurrent valuerelated methods
operation'infix' or 'function' style formattinginfixinfix
wrap_positionsposition(s) at which wrapping is to occur; '2 n - 1' is after the nth operand, '2 n' is after the nth operation.()()('with_wrapping_at', 'with_wrap_before_operator', 'with_wrap_after_operator', 'without_wrapping', 'wrap_positions')
justificationif any wrap positions are set, justify to the 'left', 'center', or 'right'centercenter('with_justification',)
directionDirection of the relation (normal or reversed)normalnormal('with_direction_reversed', 'is_reversed')
In [6]:
# display the expression information
stored_expr.expr_info()
 core typesub-expressionsexpression
0Operationoperator: 130
operands: 1
1ExprTuple2, 3
2Operationoperator: 5
operands: 4
3Operationoperator: 5
operands: 6
4ExprTuple7, 8, 9
5Literal
6ExprTuple10
7Operationoperator: 72
operand: 16
8Operationoperator: 72
operand: 17
9Operationoperator: 72
operand: 18
10ExprRangelambda_map: 14
start_index: 314
end_index: 15
11ExprTuple16
12ExprTuple17
13ExprTuple18
14Lambdaparameter: 292
body: 292
15Literal
16Lambdaparameters: 20
body: 19
17Lambdaparameters: 20
body: 21
18Lambdaparameter: 310
body: 22
19Conditionalvalue: 23
condition: 25
20ExprTuple315, 326
21Conditionalvalue: 24
condition: 25
22Conditionalvalue: 26
condition: 27
23Operationoperator: 72
operand: 33
24Operationoperator: 72
operand: 34
25Operationoperator: 174
operands: 30
26Operationoperator: 72
operand: 35
27Operationoperator: 200
operands: 32
28ExprTuple33
29ExprTuple34
30ExprTuple54, 119
31ExprTuple35
32ExprTuple310, 36
33Lambdaparameter: 312
body: 37
34Lambdaparameter: 312
body: 39
35Lambdaparameters: 40
body: 41
36Operationoperator: 42
operands: 154
37Conditionalvalue: 43
condition: 78
38ExprTuple312
39Conditionalvalue: 44
condition: 78
40ExprTuple315, 285
41Conditionalvalue: 45
condition: 46
42Literal
43Operationoperator: 72
operand: 51
44Operationoperator: 72
operand: 52
45Operationoperator: 72
operand: 53
46Operationoperator: 174
operands: 50
47ExprTuple51
48ExprTuple52
49ExprTuple53
50ExprTuple54, 55, 56
51Lambdaparameter: 291
body: 57
52Lambdaparameter: 291
body: 58
53Lambdaparameters: 59
body: 60
54Operationoperator: 200
operands: 61
55Operationoperator: 200
operands: 62
56Operationoperator: 202
operands: 63
57Conditionalvalue: 64
condition: 66
58Conditionalvalue: 65
condition: 66
59ExprTuple312, 291, 322
60Conditionalvalue: 67
condition: 68
61ExprTuple315, 148
62ExprTuple285, 148
63ExprTuple325, 285
64Operationoperator: 72
operand: 75
65Operationoperator: 72
operand: 76
66Operationoperator: 174
operands: 71
67Operationoperator: 72
operand: 77
68Operationoperator: 174
operands: 74
69ExprTuple75
70ExprTuple76
71ExprTuple79, 80
72Literal
73ExprTuple77
74ExprTuple78, 79, 114, 115, 80, 116
75Lambdaparameter: 322
body: 81
76Lambdaparameter: 322
body: 82
77Lambdaparameter: 326
body: 84
78Operationoperator: 200
operands: 85
79Operationoperator: 200
operands: 86
80Operationoperator: 130
operands: 87
81Conditionalvalue: 88
condition: 89
82Conditionalvalue: 90
condition: 91
83ExprTuple326
84Conditionalvalue: 92
condition: 93
85ExprTuple312, 94
86ExprTuple291, 95
87ExprTuple96, 314
88Operationoperator: 130
operands: 97
89Operationoperator: 174
operands: 98
90Operationoperator: 99
operands: 100
91Operationoperator: 174
operands: 101
92Operationoperator: 202
operands: 102
93Operationoperator: 174
operands: 103
94Operationoperator: 104
operand: 122
95Operationoperator: 106
operands: 107
96Operationoperator: 108
operand: 291
97ExprTuple110, 314
98ExprTuple114, 111, 116
99Literal
100ExprTuple112, 113
101ExprTuple114, 115, 116
102ExprTuple117, 118
103ExprTuple119, 120
104Literal
105ExprTuple122
106Literal
107ExprTuple121, 122
108Literal
109ExprTuple291
110Operationoperator: 126
operand: 138
111Operationoperator: 200
operands: 124
112Operationoperator: 296
operands: 125
113Operationoperator: 126
operand: 141
114Operationoperator: 200
operands: 128
115Operationoperator: 200
operands: 129
116Operationoperator: 130
operands: 131
117Operationoperator: 308
operands: 132
118Operationoperator: 133
operand: 147
119Operationoperator: 200
operands: 135
120Operationoperator: 202
operands: 136
121Literal
122Operationoperator: 323
operands: 137
123ExprTuple138
124ExprTuple318, 217
125ExprTuple139, 140
126Literal
127ExprTuple141
128ExprTuple322, 142
129ExprTuple322, 143
130Literal
131ExprTuple144, 145
132ExprTuple314, 146
133Literal
134ExprTuple147
135ExprTuple326, 148
136ExprTuple149, 326
137ExprTuple325, 315
138Operationoperator: 172
operands: 150
139Literal
140Operationoperator: 323
operands: 151
141Operationoperator: 172
operands: 152
142Literal
143Operationoperator: 153
operands: 154
144Operationoperator: 155
operands: 156
145Operationoperator: 157
operands: 158
146Operationoperator: 298
operand: 310
147Lambdaparameter: 313
body: 161
148Literal
149Operationoperator: 308
operands: 162
150ExprTuple182, 183, 184, 163
151ExprTuple208, 325
152ExprTuple182, 183, 184, 164
153Literal
154ExprTuple247, 314
155Literal
156ExprTuple312, 291
157Literal
158ExprTuple165, 291
159ExprTuple310
160ExprTuple313
161Conditionalvalue: 166
condition: 167
162ExprTuple285, 168
163ExprTuple169, 199
164ExprTuple170, 199
165Operationoperator: 323
operands: 171
166Operationoperator: 172
operands: 173
167Operationoperator: 174
operands: 175
168Operationoperator: 176
operand: 188
169ExprRangelambda_map: 178
start_index: 314
end_index: 326
170ExprRangelambda_map: 179
start_index: 314
end_index: 326
171ExprTuple180, 181
172Literal
173ExprTuple182, 183, 184, 185
174Literal
175ExprTuple186, 187
176Literal
177ExprTuple188
178Lambdaparameter: 292
body: 189
179Lambdaparameter: 292
body: 190
180Literal
181Operationoperator: 319
operands: 191
182ExprTuple192, 193
183ExprTuple194, 195
184ExprTuple196, 197
185ExprTuple198, 199
186Operationoperator: 200
operands: 201
187Operationoperator: 202
operands: 203
188Operationoperator: 204
operands: 205
189Operationoperator: 245
operands: 206
190Operationoperator: 245
operands: 207
191ExprTuple325, 208, 209, 322
192ExprRangelambda_map: 210
start_index: 314
end_index: 326
193ExprRangelambda_map: 211
start_index: 314
end_index: 315
194ExprRangelambda_map: 212
start_index: 314
end_index: 326
195ExprRangelambda_map: 212
start_index: 293
end_index: 294
196ExprRangelambda_map: 213
start_index: 314
end_index: 326
197ExprRangelambda_map: 214
start_index: 314
end_index: 315
198ExprRangelambda_map: 215
start_index: 314
end_index: 326
199ExprRangelambda_map: 216
start_index: 314
end_index: 315
200Literal
201ExprTuple313, 217
202Literal
203ExprTuple218, 219
204Literal
205ExprTuple325, 220
206NamedExprselement: 221
targets: 261
207NamedExprselement: 222
targets: 261
208Literal
209Literal
210Lambdaparameter: 292
body: 223
211Lambdaparameter: 292
body: 224
212Lambdaparameter: 292
body: 225
213Lambdaparameter: 292
body: 226
214Lambdaparameter: 292
body: 227
215Lambdaparameter: 292
body: 228
216Lambdaparameter: 292
body: 230
217Operationoperator: 280
operands: 231
218Operationoperator: 232
operands: 233
219Operationoperator: 323
operands: 234
220Operationoperator: 308
operands: 235
221Operationoperator: 278
operands: 236
222Operationoperator: 278
operands: 237
223Operationoperator: 272
operands: 238
224Operationoperator: 245
operands: 239
225Operationoperator: 245
operands: 240
226Operationoperator: 241
operands: 242
227Operationoperator: 273
operands: 243
228Operationoperator: 245
operands: 244
229ExprTuple292
230Operationoperator: 245
operands: 246
231ExprTuple247, 248
232Literal
233ExprTuple249, 314
234ExprTuple325, 250
235ExprTuple325, 251
236NamedExprsstate: 252
part: 292
237NamedExprsstate: 253
part: 292
238NamedExprsstate: 254
239NamedExprselement: 255
targets: 263
240NamedExprselement: 256
targets: 257
241Literal
242NamedExprsbasis: 258
243NamedExprsoperation: 259
244NamedExprselement: 260
targets: 261
245Literal
246NamedExprselement: 262
targets: 263
247Literal
248Operationoperator: 308
operands: 264
249Operationoperator: 308
operands: 265
250Operationoperator: 298
operand: 285
251Operationoperator: 296
operands: 267
252Operationoperator: 305
operands: 268
253Operationoperator: 305
operands: 269
254Operationoperator: 270
operand: 288
255Operationoperator: 272
operands: 279
256Operationoperator: 273
operands: 274
257Operationoperator: 280
operands: 275
258Literal
259Literal
260Operationoperator: 278
operands: 276
261Operationoperator: 280
operands: 277
262Operationoperator: 278
operands: 279
263Operationoperator: 280
operands: 281
264ExprTuple321, 282
265ExprTuple283, 284
266ExprTuple285
267ExprTuple314, 286
268ExprTuple318, 326
269ExprTuple287, 326
270Literal
271ExprTuple288
272Literal
273Literal
274NamedExprsoperation: 289
part: 292
275ExprTuple314, 294
276NamedExprsstate: 290
part: 292
277ExprTuple314, 326
278Literal
279NamedExprsstate: 291
part: 292
280Literal
281ExprTuple293, 294
282Operationoperator: 298
operand: 314
283Operationoperator: 296
operands: 297
284Operationoperator: 298
operand: 322
285Variable
286Operationoperator: 319
operands: 300
287Operationoperator: 301
operands: 302
288Literal
289Operationoperator: 303
operands: 304
290Operationoperator: 305
operands: 306
291Variable
292Variable
293Operationoperator: 308
operands: 307
294Operationoperator: 308
operands: 309
295ExprTuple314
296Literal
297ExprTuple313, 321
298Literal
299ExprTuple322
300ExprTuple325, 310
301Literal
302ExprTuple311, 321
303Literal
304ExprTuple312, 326
305Literal
306ExprTuple313, 326
307ExprTuple326, 314
308Literal
309ExprTuple326, 315
310Variable
311Operationoperator: 316
operand: 318
312Variable
313Variable
314Literal
315Variable
316Literal
317ExprTuple318
318Operationoperator: 319
operands: 320
319Literal
320ExprTuple321, 322
321Operationoperator: 323
operands: 324
322Variable
323Literal
324ExprTuple325, 326
325Literal
326Variable