import proveit
theory = proveit.Theory() # the theorem's theory
from proveit import a, b, m, x, N, defaults
from proveit.logic import InSet
from proveit.numbers import two, Div, Floor, LessEq, ModAbs, Mult, Real, subtract
from proveit.numbers.modular import mod_abs_of_difference_bound, mod_abs_scaled
from proveit.numbers.rounding import floor_x_le_x
from proveit.physics.quantum.QPE import (
_best_floor_def, _n_in_natural_pos, _phase,
_phase_in_interval, _t_in_natural_pos, _two_pow_t,
_two_pow_t__minus_one, _two_pow_t_minus_one_is_nat_pos)
%proving _precision_guarantee_lemma_02
defaults.assumptions = _precision_guarantee_lemma_02.conditions
# for convenience
_thm_expr = _precision_guarantee_lemma_02.instance_expr
Import some basic local assumptions and local definitions
# some basic assumptions and definitions
display(_t_in_natural_pos)
display(_n_in_natural_pos)
display(_phase_in_interval)
display(_best_floor_def)
It is useful generally to establish that $2^{t}\varphi \ge \lfloor 2^{t}\varphi\rfloor$ (this is then used implicitly in some auto_simplification further below) (might be nice to convert this to a method of some sort in the Floor class?):
floor_x_le_x
_x_sub = Mult(_two_pow_t, _phase)
floor_int_phase_bound = floor_x_le_x.instantiate({x: _x_sub}).reversed()
We gradually transform the assumed condition $|m-b|_{\text{mod}\;2^t} \le 2^{t-1}-1$ into the desired condition $|\frac{m}{2^{t}}-1|_{\text{mod}\;1} \le 2^{-n}$:
condition_01 = _precision_guarantee_lemma_02.condition.operands[1].prove()
condition_02 = (
condition_01.inner_expr().lhs.value.operands[1].
operand.substitute(_best_floor_def))
mod_abs_of_difference_bound
Then for later auto-simplification to work well, we want to establish that $|\lfloor 2^{t}\varphi\rfloor - 2^{t}\varphi| \le 2^{t}/2$
div_mult_id = Div(_two_pow_t, two).cancelation(two)
The _two_pow_t_minus_one_is_nat_pos
theorem, imported at the top, also lets us know that $\vdash 2^{t-1}\in\mathbb{N}$.
from proveit.numbers.rounding import real_minus_floor_interval
real_minus_floor_interval
from proveit import x
from proveit.numbers import two, Exp
from proveit.physics.quantum.QPE import _t
_x_sub = Mult(Exp(two, _t), _phase)
real_minus_floor = real_minus_floor_interval.instantiate({x: _x_sub})
from proveit.numbers import zero, one, Abs, IntervalCO
real_minus_floor_abs = InSet(Abs(real_minus_floor.element), IntervalCO(zero, one)).prove()
real_minus_floor_abs.inner_expr().element.reverse_difference(auto_simplify=False)
Notice in the result of the following instantiation the ModAbs that would have appeared on the lhs with respect to $2^{t}$ has been automatically simplified to a non-modular (and non-absolute-value) expression:
_a_sub, _b_sub, _N_sub = (
subtract(m, Mult(_two_pow_t, _phase)),
subtract(m, Floor(Mult(_two_pow_t, _phase))),
_two_pow_t)
condition_03 = mod_abs_of_difference_bound.instantiate(
{a: _a_sub, b: _b_sub, N: _N_sub}).inner_expr().lhs.dividend.commute(0,1)
condition_04 = condition_03.inner_expr().lhs.commute(0, 1).with_styles(direction='normal')
But we also know from our work above that $2^{t}\varphi - \lfloor 2^{t}\varphi \rfloor < 1$, so Prove-It can now give us the following:
condition_05 = LessEq(condition_04.lhs, one).prove()
And then we rearrange a bit:
condition_06 = condition_05.left_add_both_sides(condition_05.lhs.operands[1].operand)
From an earlier condition, we can derive a bound on the rhs of condition_06
above:
condition_07 = condition_02.right_add_both_sides(one)
Then apply transitivity to obtain the following:
condition_08 = condition_06.apply_transitivity(condition_07)
We want to transform the $\text{mod}\;2^{t}$ on the lhs to the $\text{mod}\;1$ that we want in the eventual desired expression.
We can utilize the following theorem and subsequent instantiation to do that:
mod_abs_scaled
from proveit import a, b, c
_a_sub, _b_sub, _c_sub = _two_pow_t, _thm_expr.lhs.operands[0], one
condition_equality_01 = mod_abs_scaled.instantiate({a: _a_sub, b: _b_sub, c: _c_sub})
# clean up rhs side by distributing that factor of 2^t
condition_equality_02 = condition_equality_01.inner_expr().rhs.operands[0].distribute(1)
Now we utilize that result, substituting the lhs for the rhs in our previous result:
condition_09 = condition_equality_02.sub_left_side_into(condition_08)
We can then divide both sides by the factor $2^{t}$ and simplify, and we are done:
condition_10 = condition_09.divide_both_sides(_two_pow_t)
%qed