Exemplo n.º 1
0
    def chord_length_simplification(self, **defaults_config):
        '''
        |r exp(i a) - r exp(i b)| = 2 r sin(|a - b|/2)   or
        |x exp(i a) - x exp(i b)| = 2 |x| sin(|a - b|/2)
        simplification given a, b in Real and either r in RealNonNeg
        or x in Real (depending upon what is known).
        '''
        from proveit.numbers import (one, two, Add, Neg, subtract, Div,
                                     complex_polar_coordinates)
        from proveit.trigonometry import (complex_unit_circle_chord_length,
                                          complex_circle_chord_length)

        def raise_not_valid_form():
            raise ValueError(
                "Complex circle coord length is only applicable to "
                "expressions of the form |r exp(i a) - r exp(i b)| "
                "or obviously equivalent. "
                "%s does not qualify." % self)

        if not (isinstance(self.operand, Add)
                and self.operand.operands.is_double()):
            raise_not_valid_form()

        replacements = set()
        term1 = self.operand.terms[0]
        term2 = self.operand.terms[1]
        if isinstance(term2, Neg):
            term2 = term2.operand
        else:
            term2 = Neg(term2)
            replacements.add(
                Neg(term2).double_neg_simplification(preserve_all=True))
        _r1, _theta1 = complex_polar_coordinates(term1,
                                                 reductions=replacements)
        _r2, _theta2 = complex_polar_coordinates(term2,
                                                 reductions=replacements)
        if _r1 == _r2:
            if _r1 == one:
                return complex_unit_circle_chord_length.instantiate(
                    {
                        a: _theta1,
                        b: _theta2
                    }, replacements=replacements)
            else:
                return complex_circle_chord_length.instantiate(
                    {
                        r: _r1,
                        a: _theta1,
                        b: _theta2
                    },
                    replacements=replacements)
        raise_not_valid_form()
Exemplo n.º 2
0
def num(x):
    from proveit.numbers import Neg
    if x < 0:
        return Neg(num(abs(x)))
    if isinstance(x, int):
        if x < 10:
            if x == 0:
                return zero
            elif x == 1:
                return one
            elif x == 2:
                return two
            elif x == 3:
                return three
            elif x == 4:
                return four
            elif x == 5:
                return five
            elif x == 6:
                return six
            elif x == 7:
                return seven
            elif x == 8:
                return eight
            elif x == 9:
                return nine
        else:
            return DecimalSequence(*[num(int(digit)) for digit in str(x)])
    else:
        assert False, 'num not implemented for anything except integers currently. plans to take in strings or floats with specified precision'
Exemplo n.º 3
0
def multi_elem_entries(element_from_part,
                       start_qubit_idx,
                       end_qubit_idx,
                       *part_start_and_ends,
                       check_part_index_span=True):
    '''
    Yield consecutive vertical entries for MultiQubitElem to 
    represent all parts of a multi-qubit operation in a quantum circuit
    involving all qubits from 'start_qubit_idx' to 'end_qubit_idx.
    There will be an entry for each "part" start/end pair of indices.
    In total, these must start from one, be consecutive, and cover the 
    range from the 'start_qubit_idx' to the 'end_qubit_idx.
    The element_from_part function must return an element corresponding
    to a given 'part'.
    '''
    targets = Interval(start_qubit_idx, end_qubit_idx)
    multi_qubit_gate_from_part = (
        lambda part: MultiQubitElem(element_from_part(part), targets))
    part = one
    if len(part_start_and_ends) == 0:
        raise ValueError("Must specify one or more 'part' start and end "
                         "indices, starting from one and covering the range "
                         "from %s to %s" % (start_qubit_idx, end_qubit_idx))
    for part_start, part_end in part_start_and_ends:
        #try:
        #    Equals(part, part_start).prove()
        #except ProofFailure:
        if part != part_start:
            raise ValueError("Part indices must be provably consecutive "
                             "starting from 1: %s ≠ %s" % (part_start, part))
        if part_start == part_end:  # just a single element
            yield multi_qubit_gate_from_part(part)
        else:
            param = safe_dummy_var()
            yield ExprRange(param, multi_qubit_gate_from_part(param),
                            part_start, part_end)
        part = Add(part_end, one).quick_simplified()
    if not check_part_index_span:
        lhs = Add(part_end, num(-1)).quick_simplified()
        rhs = Add(end_qubit_idx, Neg(start_qubit_idx)).quick_simplified()
        try:
            try:
                lhs = lhs.simplified()
            except:
                pass
            try:
                rhs = rhs.simplified()
            except:
                pass
            Equals(lhs, rhs).prove()
        except ProofFailure:
            raise ValueError("Part indices must span the range of the "
                             "multi qubit operation: %s ≠ %s" % (lhs, rhs))
Exemplo n.º 4
0
 def deduce_in_interval(self, **defaults_config):
     '''
     Bound the interval of the Sin function evaluation depending
     upon what is known about the angle.
     '''
     from . import (sine_interval, sine_nonneg_interval, sine_pos_interval,
                    sine_nonpos_interval, sine_neg_interval)
     from proveit.numbers import (zero, pi, Less, LessEq, Neg)
     _theta = self.angle
     deduce_number_set(_theta)
     if (Less(zero, _theta).proven() and Less(_theta, pi).proven()):
         return sine_pos_interval.instantiate({theta: _theta})
     elif (LessEq(zero, _theta).proven() and LessEq(_theta, pi).proven()):
         return sine_nonneg_interval.instantiate({theta: _theta})
     elif (Less(Neg(pi), _theta).proven() and Less(_theta, zero).proven()):
         return sine_neg_interval.instantiate({theta: _theta})
     elif (Less(Neg(pi), _theta).proven() and Less(_theta, zero).proven()):
         return sine_neg_interval.instantiate({theta: _theta})
     elif (LessEq(Neg(pi), _theta).proven()
           and LessEq(_theta, zero).proven()):
         return sine_nonpos_interval.instantiate({theta: _theta})
     else:
         # Without knowing more, we can only bound it by +/-1.
         return sine_interval.instantiate({theta: _theta})
Exemplo n.º 5
0
add_one_left_in_exp = Forall([a, b],
                             Equals(Exp(a, Add(one, b)), Mult(a, Exp(a, b))),
                             domain=Complex,
                             conditions=[NotEquals(a, zero)])
add_one_left_in_exp

add_one_left_in_exp_rev = Forall([a, b],
                                 Equals(Mult(a, Exp(a, b)),
                                        Exp(a, Add(one, b))),
                                 domain=Complex,
                                 conditions=[NotEquals(a, zero)])
add_one_left_in_exp_rev

diff_in_exp = Forall([a, b, c],
                     Equals(Exp(a, Sub(b, c)), Mult(Exp(a, b), Exp(a,
                                                                   Neg(c)))),
                     domain=Complex,
                     conditions=[NotEquals(a, zero)])
diff_in_exp

diff_in_exp_rev = Forall([a, b, c],
                         Equals(Mult(Exp(a, b), Exp(a, Neg(c))),
                                Exp(a, Sub(b, c))),
                         domain=Complex,
                         conditions=[NotEquals(a, zero)])
diff_in_exp_rev

diff_frac_in_exp = Forall([a, b, c, d],
                          Equals(Exp(a, Sub(b, frac(c, d))),
                                 Mult(Exp(a, b), Exp(a, frac(Neg(c), d)))),
                          domain=Complex,
Exemplo n.º 6
0
    def do_reduced_simplification(self, assumptions=USE_DEFAULTS):
        '''
        For the case Abs(x) where the operand x is already known to
        be or assumed to be a non-negative real, derive and return
        this Abs expression equated with the operand itself:
        |- Abs(x) = x. For the case where x is already known or assumed
        to be a negative real, return the Abs expression equated with
        the negative of the operand: |- Abs(x) = -x.
        Assumptions may be necessary to deduce necessary conditions for
        the simplification.
        '''
        from proveit.numbers import greater, greater_eq, Mult, Neg
        from proveit.numbers import (zero, Natural, NaturalPos, RealNeg,
                                     RealNonNeg, RealPos)
        # among other things, convert any assumptions=None
        # to assumptions=() (thus averting len(None) errors)
        assumptions = defaults.checked_assumptions(assumptions)

        #-- -------------------------------------------------------- --#
        #-- Case (1): Abs(x) where entire operand x is known or      --#
        #--           assumed to be non-negative Real.               --#
        #-- -------------------------------------------------------- --#
        if InSet(self.operand, RealNonNeg).proven(assumptions=assumptions):
            # Entire operand is known to be or assumed to be a
            # non-negative real, so we can return Abs(x) = x
            return self.abs_elimination(operand_type='non-negative',
                                        assumptions=assumptions)

        #-- -------------------------------------------------------- --#
        #-- Case (2): Abs(x) where entire operand x is known or      --#
        #--           assumed to be a negative Real.                 --#
        #-- -------------------------------------------------------- --#
        if InSet(self.operand, RealNeg).proven(assumptions=assumptions):
            # Entire operand is known to be or assumed to be a
            # negative real, so we can return Abs(x) = -x
            return self.abs_elimination(operand_type='negative',
                                        assumptions=assumptions)

        #-- -------------------------------------------------------- --#
        # -- Case (3): Abs(x) where entire operand x is not yet known --*
        #--           to be a non-negative Real, but can easily be   --#
        #--           proven to be a non-negative Real because it is --#
        # --           (a) known or assumed to be ≥ 0 or
        #--           (b) known or assumed to be in a subset of the  --#
        #--               non-negative Real numbers, or              --#
        #--           (c) the addition or product of operands, all   --#
        #--               of which are known or assumed to be non-   --#
        # --               negative real numbers. TBA!
        #-- -------------------------------------------------------- --#
        if (greater(self.operand, zero).proven(assumptions=assumptions)
                and not greater_eq(self.operand,
                                   zero).proven(assumptions=assumptions)):
            greater_eq(self.operand, zero).prove(assumptions=assumptions)
            # and then it will get picked up in the next if() below

        if greater_eq(self.operand, zero).proven(assumptions=assumptions):
            from proveit.numbers.number_sets.real_numbers import (
                in_real_non_neg_if_greater_eq_zero)
            in_real_non_neg_if_greater_eq_zero.instantiate(
                {a: self.operand}, assumptions=assumptions)
            return self.abs_elimination(operand_type='non-negative',
                                        assumptions=assumptions)

        if self.operand in InSet.known_memberships.keys():
            for kt in InSet.known_memberships[self.operand]:
                if kt.is_sufficient(assumptions):
                    if is_equal_to_or_subset_eq_of(
                            kt.expr.operands[1],
                            equal_sets=[RealNonNeg, RealPos],
                            subset_eq_sets=[Natural, NaturalPos, RealPos],
                            assumptions=assumptions):

                        InSet(self.operand,
                              RealNonNeg).prove(assumptions=assumptions)
                        return self.abs_elimination(
                            operand_type='non-negative',
                            assumptions=assumptions)

        if isinstance(self.operand, Add) or isinstance(self.operand, Mult):
            count_of_known_memberships = 0
            count_of_known_relevant_memberships = 0
            for op in self.operand.operands:
                if op in InSet.known_memberships.keys():
                    count_of_known_memberships += 1
            if (count_of_known_memberships ==
                    self.operand.operands.num_entries()):
                for op in self.operand.operands:
                    op_temp_known_memberships = InSet.known_memberships[op]
                    for kt in op_temp_known_memberships:
                        if (kt.is_sufficient(assumptions)
                                and is_equal_to_or_subset_eq_of(
                                    kt.expr.operands[1],
                                    equal_sets=[RealNonNeg, RealPos],
                                    subset_eq_sets=[
                                        Natural, NaturalPos, RealPos,
                                        RealNonNeg
                                    ],
                                    assumptions=assumptions)):

                            count_of_known_relevant_memberships += 1
                            break

                if (count_of_known_relevant_memberships ==
                        self.operand.operands.num_entries()):
                    # Prove that the sum or product is in
                    # RealNonNeg and then instantiate abs_elimination.
                    for op in self.operand.operands:
                        InSet(op, RealNonNeg).prove(assumptions=assumptions)
                    return self.abs_elimination(assumptions=assumptions)

        #-- -------------------------------------------------------- --#
        #-- Case (4): Abs(x) where operand x can easily be proven    --#
        #--           to be a negative Real number because -x is     --#
        #--           known to be in a subset of the positive Real   --#
        #--           numbers.                                       --#
        #-- -------------------------------------------------------- --#
        negated_op = None
        if isinstance(self.operand, Neg):
            negated_op = self.operand.operand
        else:
            negated_op = Neg(self.operand)
        negated_op_simp = negated_op.simplification(
            assumptions=assumptions).rhs

        if negated_op_simp in InSet.known_memberships.keys():
            from proveit.numbers.number_sets.real_numbers import (
                neg_is_real_neg_if_pos_is_real_pos)
            for kt in InSet.known_memberships[negated_op_simp]:
                if kt.is_sufficient(assumptions):
                    if is_equal_to_or_subset_eq_of(
                            kt.expr.operands[1],
                            equal_sets=[RealNonNeg, RealPos],
                            subset_sets=[NaturalPos, RealPos],
                            subset_eq_sets=[NaturalPos, RealPos],
                            assumptions=assumptions):

                        InSet(negated_op_simp,
                              RealPos).prove(assumptions=assumptions)
                        neg_is_real_neg_if_pos_is_real_pos.instantiate(
                            {a: negated_op_simp}, assumptions=assumptions)
                        return self.abs_elimination(operand_type='negative',
                                                    assumptions=assumptions)

        # for updating our equivalence claim(s) for the
        # remaining possibilities
        from proveit import TransRelUpdater
        eq = TransRelUpdater(self, assumptions)
        return eq.relation
Exemplo n.º 7
0
            a,
            zero)])
abs_not_eq_zero

# transferred by wdc 3/11/2020
abs_elim = Forall(x, Equals(Abs(x), x),
                  domain=RealPos)
abs_elim

# transferred by wdc 3/11/2020
abs_ineq = Forall(
    (x, y), Iff(
        LessThanEquals(
            Abs(x), y), And(
                LessThanEquals(
                    Neg(y), x), LessThanEquals(
                        x, y))), domain=Real, conditions=[
                            GreaterThanEquals(
                                y, zero)])
abs_ineq

# transferred by wdc 3/11/2020
triangle_inequality = Forall([a, b], LessThanEquals(
    Abs(Add(a, b)), Add(Abs(a), Abs(b))), domain=Complex)
triangle_inequality

# transferred by wdc 3/11/2020
abs_prod = Forall(x_etc,
                  Equals(Abs(Mult(x_etc)),
                         Mult(Etcetera(Abs(x_multi)))),
                  domain=Complex)
Exemplo n.º 8
0
m_ = Literal(pkg, 'm')

# phase_m: Random variable for the phase result of the quantum phase estimation.
#          phase_m = m / 2^t
phase_m_ = Literal(pkg, 'phase_m', {LATEX: r'\varphi_m'})

# b: The "best" outcome of m such that phase_m is as close as possible to
# phase.
b_ = Literal(pkg, 'b')

# 2^t
two_pow_t = Exp(two, t_)

# 2^{t-1}
two_pow_t_minus_one = Exp(two, Sub(t_, one))

# amplitude of output register as indexted
alpha_ = Literal(pkg, 'alpha', {STRING: 'alpha', LATEX: r'\alpha'})
alpha_l = SubIndexed(alpha_, l)
abs_alpha_l = Abs(alpha_l)
alpha_l_sqrd = Exp(Abs(alpha_l), two)

# delta: difference between the phase and the best phase_m
delta_ = Literal(pkg, 'delta', {LATEX: r'\delta'})

full_domain = Interval(Add(Neg(Exp(two, Sub(t_, one))), one),
                       Exp(two, Sub(t_, one)))
neg_domain = Interval(Add(Neg(two_pow_t_minus_one), one), Neg(Add(eps, one)))
pos_domain = Interval(Add(eps, one), two_pow_t_minus_one)
eps_domain = Interval(one, Sub(two_pow_t_minus_one, two))
Exemplo n.º 9
0
begin_axioms(locals())

# Define the set of Natural as, essentially, the minimum set that contains zero and all of its successors;
# that is, n is in Natural iff n is in all sets that contain zero and all
# successors.
naturals_def = Forall(
    n,
    Equals(
        InSet(n, Natural),
        Forall(
            S,
            Implies(
                And(InSet(zero, S), Forall(x, InSet(Add(x, one), S),
                                           domain=S)), InSet(n, S)))))

# Define the length of an ExpressionList inductively.
expr_list_length_def = And(
    Equals(Len(), zero),
    Forall((x_multi, y), Equals(Len(x_etc, y), Add(Len(x_etc), one))))

naturals_pos_def = Forall(n,
                          Iff(InSet(n, NaturalPos), GreaterThanEquals(n, one)),
                          domain=Natural)
naturals_pos_def

integers_def = Equals(Integer,
                      Union(Natural, SetOfAll(n, Neg(n), domain=Natural)))

end_axioms(locals(), __package__)
Exemplo n.º 10
0
def complex_polar_coordinates(expr,
                              *,
                              radius_must_be_nonneg=True,
                              nonneg_radius_preferred=True,
                              do_include_unit_length_reduction=True,
                              reductions=None):
    '''
    Given an expression, expr, of the complex number polar form,
        r * exp(i * theta),
    or something obviously equivalent to this, where r and theta are 
    Real (and r is preferably RealNonNeg) under the given assumptions, 
    return
        (r, theta)
    as a tuple pair. If defaults.automation=False, the r and theta must
    already be known to be RealNonNeg and Real respectively. If
    defaults.automation=True, we may attempt to prove these through 
    automation.
    
    If radius_must_be_nonneg and nonneg_radius_preferred are False, 
    we won't worry about ensuring that r is non-negative (so the result
    can be ambiguous).  If radius_must_be_nonneg is True, a ValueError
    will be raised if we can't convert to a form where r is known to be
    non-negative.
    
    If expr is not exactly in this complex number polar form and
    'reductions' is provided as a set, add to the 'reductions' set
    an equation that equates the exact form on the left with the
    original form on the right.  This may be useful to use as
    'reductions' in instantiations of theorems that employ the
    complex number polar form so it may perform proper reductions
    to the desired form.  For example, if expr=5 is provided,
    the added reduction will be
        5 * exp(i * 0) = 5.
    
    If do_include_unit_length_reduction is True,  we will included
    reductions so that it will reduce from the unit length
    form as well.  For example, if expr=1 is provided, the added
    reductions will be
        exp(i * 0) = 1
        1 * 1 = 1.
    This also works in a way that cascades when reducing from the
    general polar form:
        1 * exp(i * 0) = 1 * 1 = 1
    
    Raise ValueError if the expr is not obviously equivalent to a
    complex number polar form.

    Also see unit_length_complex_polar_angle.
    '''
    from . import complex_polar_negation, complex_polar_radius_negation
    from proveit.logic import InSet, Equals
    from proveit.numbers import deduce_in_number_set, deduce_number_set
    from proveit.numbers import zero, one, e, i, pi
    from proveit.numbers import Real, RealNonPos, RealNonNeg, Complex
    from proveit.numbers import Add, LessEq, Neg, Mult, Exp
    orig_expr = expr
    automation = defaults.automation
    simplify = defaults.auto_simplify
    if reductions is None: reductions = set()

    def add_reduction(reduction, _radius, _theta):
        '''
        Add the given reduction.  First check that its left and
        rights sides are as expected: the left should be the polar
        form and the right should be the original expression.
        '''
        polar_form = Mult(_radius, Exp(e, Mult(i, _theta)))
        assert (isinstance(reduction, Judgment)
                and isinstance(reduction.expr, Equals)
                and reduction.lhs == polar_form and reduction.rhs
                == orig_expr), ("Reduction, %s, not a judgement "
                                "for %s = %s" %
                                (reduction, polar_form, orig_expr))
        if do_include_unit_length_reduction and _radius == one:
            # As a unit length complex number, let's include the
            # reduction from the unit length form in case a unit length
            # formula is applied (cover the bases).
            # The 'automation' allowed here is negligible (assuming
            # we have already proven appropriate set membership by this
            # point).
            reductions.add(reduction.inner_expr().lhs.eliminate_one(
                0, automation=True))
            # But prepare for a multi-stage reduction:
            # 1 * exp[i * theta] = 1 * orig_expr = orig_expr
            reductions.add(
                Mult(one, orig_expr).one_elimination(0, automation=True))
        elif reduction.lhs != reduction.rhs:
            reductions.add(reduction)

    def raise_not_valid_form(extra_msg=None):
        if extra_msg is None: extra_msg = ""
        raise ValueError("%s not in a form that is obviously "
                         "reducible from an r * exp(i*theta) form. %s" %
                         (orig_expr, extra_msg))

    if (isinstance(expr, Exp)
            or (isinstance(expr, Neg) and isinstance(expr.operand, Exp))):
        # exp(i * theta) reduced from 1 * exp(i * theta).
        # or exp(i * (theta + pi)) reduced from -exp(i * theta).
        inner_reductions = set()
        _theta = unit_length_complex_polar_angle(expr,
                                                 reductions=inner_reductions)
        deduce_in_number_set(_theta, Complex)
        deduce_in_number_set(Mult(i, _theta), Complex)
        deduce_in_number_set(Exp(e, Mult(i, _theta)), Complex)
        _r = one
        expr = Mult(_r, Exp(e, Mult(i, _theta)))
        # reduction: 1*exp(i * theta) = exp(i * theta)
        reduction = expr.one_elimination(0, preserve_all=True)
        # reduction: 1*exp(i * theta) = orig_expr
        if len(inner_reductions) > 0:
            reduction = reduction.inner_expr().rhs.substitute(
                inner_reductions.pop().rhs, preserve_all=True)
        # Add the reduction and return the coordinates.
        add_reduction(reduction, _r, _theta)
        return (_r, _theta)
    elif isinstance(expr, Neg):
        # expr = -(r*exp(i*theta0)) = r*exp(i*(theta0 + pi))
        inner_reductions = set()
        # obtain the theta of the negated expression.
        _r, _theta0 = complex_polar_coordinates(
            expr.operand,
            radius_must_be_nonneg=radius_must_be_nonneg,
            nonneg_radius_preferred=nonneg_radius_preferred,
            reductions=inner_reductions)
        # theta = theta0 + pi
        _theta = Add(_theta0, pi)
        if defaults.auto_simplify:
            # simplify theta
            theta_simplification = _theta.simplification()
            inner_reductions.add(theta_simplification)
            _theta = theta_simplification.rhs
        deduce_in_number_set(_theta, Complex)
        deduce_in_number_set(Mult(i, _theta), Complex)
        deduce_in_number_set(Exp(e, Mult(i, _theta)), Complex)
        # reduction: r*exp(i*theta) = orig_expr [via -(r*exp(i*theta0))]
        reduction = complex_polar_negation.instantiate(
            {
                r: _r,
                theta: _theta0
            },
            replacements=inner_reductions,
            auto_simplify=False)
        # Add the reduction and return the coordinates.
        add_reduction(reduction, _r, _theta)
        return (_r, _theta)

    # Search for an exponentiation factor with base of 'e' and an
    # imaginary number in the exponent.
    complex_exp_factor_idx = None
    if isinstance(expr, Mult):
        i_factor_idx = None
        for idx, factor in enumerate(expr.factors):
            if isinstance(factor, Exp) and factor.base == e:
                # exp(x) type factor; check for imaginary number in
                # exponent.
                contains_imaginary_factor = False
                sub_expr = factor.exponent
                if isinstance(sub_expr, Neg):
                    sub_expr = sub_expr.operand
                if isinstance(sub_expr, Mult):
                    if i in sub_expr.operands.entries:
                        contains_imaginary_factor = True
                else:
                    contains_imaginary_factor = (sub_expr == i)
                if contains_imaginary_factor:
                    # Found imaginary number in an exponent.
                    if ((complex_exp_factor_idx is not None)
                            or (i_factor_idx is not None)):
                        # We already have an imaginary number in
                        # an exponent.  We can only have one.
                        raise_not_valid_form()
                    complex_exp_factor_idx = idx
                    deduce_in_number_set(sub_expr, Complex)
    if complex_exp_factor_idx is None:
        # No exp(i theta) factor.  Let's multiply by exp(i * 0).
        exp_i0 = Exp(e, Mult(i, zero))
        expr = Mult(expr, exp_i0)
        inner_reductions = set()
        _r, _theta = complex_polar_coordinates(
            expr,
            radius_must_be_nonneg=radius_must_be_nonneg,
            nonneg_radius_preferred=nonneg_radius_preferred,
            do_include_unit_length_reduction=False,
            reductions=inner_reductions)
        assert _theta == zero
        deduce_in_number_set(exp_i0, Complex)
        # reduction: r * exp(i * theta) = orig_expr * exp(i * 0)
        if len(inner_reductions) > 0:
            reduction = inner_reductions.pop()
        else:
            reduction = Equals(expr, expr).conclude_via_reflexivity()
        # reduction: r * exp(i * theta) = orig_expr
        reduction = reduction.inner_expr().rhs.simplify(
            preserve_expr=orig_expr)
        add_reduction(reduction, _r, _theta)
        return (_r, _theta)

    # expr in ... * exp(... * i * ...) * ... form
    # Obtain the theta from exp(... * i * ...) = exp[i * theta0].
    inner_reductions = set()
    _theta0 = unit_length_complex_polar_angle(
        expr.factors[complex_exp_factor_idx], reductions=inner_reductions)
    expr = Mult(*expr.factors.entries[:complex_exp_factor_idx],
                Exp(e, Mult(i, _theta0)),
                *expr.factors.entries[complex_exp_factor_idx + 1:])
    # reduction: ... * expr[i * theta0] * ... = orig_expr
    if len(inner_reductions) > 0:
        reduction = expr.inner_expr().operands[1].substitution(
            inner_reductions.pop().rhs, preserve_all=True)
    else:
        reduction = Equals(expr, expr).conclude_via_reflexivity()
    if not expr.operands.is_double() or complex_exp_factor_idx != 1:
        # Pull the exp(i*theta) type factor to the right.
        # reduction: r0 * exp(i * theta0) = orig_expr
        for factor in expr.factors:
            # Deduce the factors are complex numbers ahead of time
            # in case automation is disabled.
            deduce_in_number_set(factor, Complex)
        reduction = reduction.inner_expr().lhs.factor(complex_exp_factor_idx,
                                                      pull='right',
                                                      group_remainder=True,
                                                      preserve_all=True)
        expr = reduction.lhs
    # expr: r0 * exp(i * theta0)
    assert expr.operands.is_double() and isinstance(expr.operands[1], Exp)
    # Check that r0 is real and that we know it's relation with zero.
    _r0 = expr.operands[0]
    _r0_ns = deduce_number_set(_r0).domain
    if Real.includes(_r0_ns):
        InSet(_r0, Real).prove()
    else:
        raise_not_valid_form("%s not known to be real." % _r0)
    is_known_nonneg = RealNonNeg.includes(_r0_ns)
    is_known_nonpos = RealNonPos.includes(_r0_ns)
    if radius_must_be_nonneg:
        # We must know the relationship between r0 and 0 so we
        # can ensure r is non-negative.
        if not nonneg_radius_preferred:
            ValueError("nonneg_radius_preferred must be True if "
                       "radius_must_be_nonneg is True.")
        if not (is_known_nonneg or is_known_nonpos):
            raise_not_valid_form("Relation of %s to 0 is unknown and "
                                 "radius_must_be_nonneg is True." % _r0)
    if nonneg_radius_preferred and is_known_nonpos:
        # r0 <= 0, so we must negate it and add pi to the angle.
        inner_reductions = {reduction}
        # theta: theta + pi
        _theta = Add(_theta0, pi)
        if simplify:
            # simplify theta
            theta_simplification = _theta.simplification()
            inner_reductions.add(theta_simplification)
            _theta = theta_simplification.rhs
        # r: -r0
        _r = Neg(_r0)
        if simplify:
            # simplify radius
            radius_simplification = _r.simplification()
            inner_reductions.add(radius_simplification)
            _r = radius_simplification.rhs
        # reduction: r*exp(i*theta) = orig_expr [via r0*exp(i*theta0))]
        reduction = complex_polar_radius_negation.instantiate(
            {
                r: _r0,
                theta: _theta0
            },
            replacements=inner_reductions,
            auto_simplify=False)
    else:
        _r, _theta = _r0, _theta0
    # Add the reduction and return the coordinates.
    add_reduction(reduction, _r, _theta)
    return (_r, _theta)
Exemplo n.º 11
0
def exp_neg_2pi_i_on_two_pow_t(*exp_factors):
    from proveit.physics.quantum.QPE import _two_pow_t
    return exp(Neg(frac(Mult(*((two, pi, i) + exp_factors)), _two_pow_t)))
Exemplo n.º 12
0
from proveit import Etcetera
from proveit.logic import Forall, InSet, Equals, NotEquals
from proveit.numbers import Neg, Integer, Real, Complex, Add, Sub, Mult, LessThan, GreaterThan
from proveit.common import a, b, x, y, x_etc, x_multi
from proveit.numbers.common import zero
from proveit import begin_theorems, end_theorems

begin_theorems(locals())

neg_int_closure = Forall(a, InSet(Neg(a), Integer), domain=Integer)
neg_int_closure

neg_real_closure = Forall(a, InSet(Neg(a), Real), domain=Real)
neg_real_closure

neg_complex_closure = Forall(a, InSet(Neg(a), Complex), domain=Complex)
neg_complex_closure

negated_positive_is_negative = Forall(a,
                                      LessThan(Neg(a), zero),
                                      domain=Real,
                                      conditions=[GreaterThan(a, zero)])
negated_positive_is_negative

negated_negative_is_positive = Forall(a,
                                      GreaterThan(Neg(a), zero),
                                      domain=Real,
                                      conditions=[LessThan(a, zero)])
negated_negative_is_positive

neg_not_eq_zero = Forall(a,
Exemplo n.º 13
0
subtract_real_closure = Forall([a, b], InSet(Sub(a, b), Real), domain=Real)
subtract_real_closure

subtract_one_in_nats = Forall(a,
                              InSet(Sub(a, one), Natural),
                              domain=NaturalPos)
subtract_one_in_nats

diff_not_eq_zero = Forall((a, b),
                          NotEquals(Sub(a, b), zero),
                          domain=Complex,
                          conditions=[NotEquals(a, b)])
diff_not_eq_zero

subtract_as_add_neg = Forall([x, y],
                             Equals(Sub(x, y), Add(x, Neg(y))),
                             domain=Complex)
subtract_as_add_neg

add_neg_as_subtract = Forall([x, y],
                             Equals(Add(x, Neg(y)), Sub(x, y)),
                             domain=Complex)
add_neg_as_subtract

absorb_terms_into_subtraction = Forall([w_etc, x, y, z_etc],
                                       Equals(Add(w_etc, Sub(x, y), z_etc),
                                              Sub(Add(w_etc, x, z_etc), y)),
                                       domain=Complex)
absorb_terms_into_subtraction

subtract_cancel_elim_sums = Forall([x, y, z],
Exemplo n.º 14
0
greater_than_add_right

greater_than_add_left = Forall([a, b, c],
                               GreaterThan(Add(c, a), Add(c, b)),
                               domain=Real,
                               conditions=[GreaterThan(a, b)])
greater_than_add_left

greater_than_subtract = Forall([a, b, c],
                               GreaterThan(Sub(a, c), Sub(b, c)),
                               domain=Real,
                               conditions=[GreaterThan(a, b)])
greater_than_subtract

negated_less_than = Forall([a, b],
                           GreaterThan(Neg(a), Neg(b)),
                           domain=Real,
                           conditions=[LessThan(a, b)])
negated_less_than

negated_less_than_equals = Forall([a, b],
                                  GreaterThanEquals(Neg(a), Neg(b)),
                                  domain=Real,
                                  conditions=[LessThanEquals(a, b)])
negated_less_than_equals

negated_greater_than = Forall([a, b],
                              LessThan(Neg(a), Neg(b)),
                              domain=Real,
                              conditions=[GreaterThan(a, b)])
negated_greater_than