import proveit
theory = proveit.Theory() # the theorem's theory
from proveit.logic import Equals
from proveit.numbers import two, Add, Exp, frac, Mult, Neg
from proveit.physics.quantum.QPE import (
_e_value_ge_two, _eps, _eps_in_interval, _n,
_n_in_natural_pos, _t, _t_in_natural_pos, _t_req )
%proving _precision_guarantee_lemma_01
display(_eps_in_interval)
display(_t_req)
display(_e_value_ge_two)
from proveit.numbers import one, greater_eq, subtract
_t_minus_n_lb_01 = greater_eq(subtract(_t, _n), _t_req.rhs.operands[1]).prove()
# follow up here with a Ceil method to perform this and next step
from proveit.numbers.rounding import ceil_x_ge_x
ceil_x_ge_x
from proveit import x
_x_sub = _t_minus_n_lb_01.rhs.operand
_t_minus_n_lb_02 = ceil_x_ge_x.instantiate({x: _x_sub})
_t_minus_n_lb_03 = _t_minus_n_lb_01.apply_transitivity(_t_minus_n_lb_02)
bound_03 = _precision_guarantee_lemma_01.lhs.deduce_bound(_t_minus_n_lb_03)
Now we perform some algebraic manipulation of that lower bound, trying to rewrite the lower bound in the form
$1 - \epsilon(\frac{f(\epsilon)}{g(\epsilon)})$. The steps are labeled as sub-scripts of bound_03
because we're not deriving a new bound, just processing the bound we already have.
bound_03_01 = bound_03.inner_expr().rhs.operands[1].operand.denominator.distribute(1)
bound_03_02 = (
bound_03_01.inner_expr().rhs.operands[2].operand.denominator.
operands[0].substitute(Exp(two, two)))
bound_03_03 = (
bound_03_02.inner_expr().rhs.operands[2].operand.denominator.
common_power_extract(exp_factor=two))
bound_03_04 = (
bound_03_03.inner_expr().rhs.operands[2].operand.denominator.
base.distribute(1))
temp_multiplier = bound_03_04.rhs.operands[1].operand.denominator
bound_03_05 = bound_03_04.inner_expr().rhs.operands[1].operand.top_and_bottom_multiply(temp_multiplier)
with Add.temporary_simplification_directives() as tmp_directives:
tmp_directives.combine_like_denoms = True
bound_03_06 = bound_03_05.inner_expr().rhs.associate(1,2)
bound_03_07 = bound_03_06.inner_expr().rhs.operands[1].operand.simplify()
bound_03_08 = (bound_03_07.inner_expr().rhs.operands[1].
operand.top_and_bottom_multiply(Exp(_eps, two)))
bound_03_09 = bound_03_08.inner_expr().rhs.operands[1].operand.factor(_eps)
bound_03_10 = bound_03_09.inner_expr().rhs.operands[1].operand.operands[1].numerator.distribute(1)
bound_03_11 = bound_03_10.inner_expr().rhs.operands[1].operand.operands[1].denominator.common_power_extract(exp_factor=2)
bound_03_12 = bound_03_11.inner_expr().rhs.operands[1].operand.operands[1].denominator.base.distribute(1)
Now we focus on the fraction in the rhs of that bound, showing that the fraction is in fact positive and less than 1. Some of this section can eventually be replaced with a more general Add.factorization() case for the factoring of polynomial-like Add expressions.
from proveit.numbers import zero, four, greater
bound_04 = greater(Add(Mult(four, _eps), one), zero).prove()
bound_05 = greater(Mult(_eps, Add(Mult(four, _eps), one)), zero).prove()
bound_05_01 = bound_05.inner_expr().lhs.distribute(1)
from proveit.numbers import three
bound_06 = greater(Add(Mult(four, Exp(_eps, two)), Mult(four, _eps), one),
Add(Mult(three, _eps), one)).prove()
equality_01 = (
Mult(Add(Mult(two, _eps), one), Add(Mult(two, _eps), one)).
simplification().reversed())
equality_02 = equality_01.inner_expr().rhs.distribute(1)
equality_03 = equality_02.inner_expr().rhs.operands[0].distribute(1)
bound_07 = bound_06.inner_expr().lhs.substitute(equality_03.lhs)
bound_08 = bound_07.divide_both_sides(bound_07.lhs)
Now we can feed that bound above into the deduce_bound() method to find a bound on the earlier-derived bound $1 - \epsilon(\frac{f(\epsilon)}{g(\epsilon)})$
bound_09 = bound_03_12.rhs.deduce_bound(bound_08.reversed())
%qed