Пример #1
0
 def shallow_simplification(self, *, must_evaluate=False,
                            **defaults_config):
     '''
     Simplify via inner product linearity:
     <a x, y> = a <x, y>
     <x, y> = <x, a y>
     <x + y, z> = <x, z> + <y, z>
     <x, y + z> = <x, y> + <x, z>
     '''
     from proveit.linear_algebra import VecSpaces, ScalarMult, VecAdd
     from proveit.linear_algebra.inner_products import (
             inner_prod_scalar_mult_left, inner_prod_scalar_mult_right,
             inner_prod_vec_add_left, inner_prod_vec_add_right)
     _u, _v = self.operands
     try:
         vec_space = VecSpaces.common_known_vec_space((_u, _v))
     except UnsatisfiedPrerequisites:
         # No known common vectors space for the operands, so
         # we have no specific shallow_simplication we can do here.
         return Operation.shallow_simplification(
                 self, must_evaluate=must_evaluate)
     field = VecSpaces.known_field(vec_space)
     simp = None
     if isinstance(_u, ScalarMult):
         simp = inner_prod_scalar_mult_left.instantiate(
                 {K:field, H:vec_space, a:_u.scalar, x:_u.scaled, y:_v})
     if isinstance(_v, ScalarMult):
         simp = inner_prod_scalar_mult_right.instantiate(
                 {K:field, H:vec_space, a:_v.scalar, x:_u, y:_v.scaled})
     if isinstance(_u, VecAdd):
         simp = inner_prod_vec_add_left.instantiate(
                 {K:field, H:vec_space, x:_u.terms[0], y:_u.terms[1], z:_v})
     if isinstance(_v, VecAdd):
         simp = inner_prod_vec_add_right.instantiate(
                 {K:field, H:vec_space, x:_u, y:_v.terms[0], z:_v.terms[1]})
     if simp is None:
         return Operation.shallow_simplification(
                 self, must_evaluate=must_evaluate)
     if must_evaluate and not is_irreducible_value(simp.rhs):
         return simp.inner_expr().rhs.evaluate()
     return simp
Пример #2
0
    def deduce_in_vec_space(self, vec_space=None, *, field, **defaults_config):
        '''
        Prove that this linear combination of vectors is in a vector
        space.  The vector space may be specified or inferred via known
        memberships.  A field for the vector space must be specified.
        '''
        from proveit.linear_algebra import ScalarMult

        terms = self.terms
        if vec_space is None:
            vec_space = VecSpaces.common_known_vec_space(terms, field=field)
        field = VecSpaces.known_field(vec_space)
        all_scaled = all((isinstance(term, ScalarMult) or (
            isinstance(term, ExprRange) and isinstance(term.body, ScalarMult)))
                         for term in terms)
        if all_scaled:
            # Use a linear combination theorem since everything
            # is scaled.
            from proveit.linear_algebra.scalar_multiplication import (
                binary_lin_comb_closure, lin_comb_closure)
            if terms.is_double():
                # Special linear combination binary case
                _a, _b = terms[0].scalar, terms[1].scalar
                _x, _y = terms[0].scaled, terms[1].scaled
                return binary_lin_comb_closure.instantiate({
                    K: field,
                    V: vec_space,
                    a: _a,
                    b: _b,
                    x: _x,
                    y: _y
                })
            else:
                # General linear combination case
                _a = []
                _x = []
                for term in terms:
                    if isinstance(term, ExprRange):
                        _a.append(
                            ExprRange(term.parameter, term.body.scalar,
                                      term.true_start_index,
                                      term.true_end_index))
                        _x.append(
                            ExprRange(term.parameter, term.body.scaled,
                                      term.true_start_index,
                                      term.true_end_index))
                    else:
                        _a.append(term.scalar)
                        _x.append(term.scaled)
                _n = terms.num_elements()
                return lin_comb_closure.instantiate({
                    n: _n,
                    K: field,
                    V: vec_space,
                    a: _a,
                    x: _x
                })
        else:
            # Use a vector addition closure theorem.
            from . import binary_closure, closure
            if terms.is_double():
                # Special binary case
                return binary_closure.instantiate({
                    K: field,
                    V: vec_space,
                    x: terms[0],
                    y: terms[1]
                })
            else:
                # General case
                _n = terms.num_elements()
                return closure.instantiate({
                    n: _n,
                    K: field,
                    V: vec_space,
                    x: terms
                })