Example #1
0
def compose(*expressions, assumptions=USE_DEFAULTS):
    '''
    Returns [A and B and ...], the And operator applied to the collection of given arguments,
    derived from each separately.
    '''
    from proveit._core_.expression.composite import composite_expression
    expressions = composite_expression(expressions)
    if expressions.num_entries() == 0:
        from proveit.logic.booleans.conjunction import \
            empty_conjunction
        return empty_conjunction
    if expressions.is_double():
        from . import and_if_both
        return and_if_both.instantiate({
            A: expressions[0],
            B: expressions[1]
        },
                                       assumptions=assumptions)
    else:
        from . import and_if_all
        _m = expressions.num_elements(assumptions)
        return and_if_all.instantiate({
            m: _m,
            A: expressions
        },
                                      assumptions=assumptions)
Example #2
0
def compose(*expressions, **defaults_config):
    '''
    Returns [A and B and ...], the And operator applied to the
    collection of given arguments, derived from each separately.
    '''
    from proveit._core_.expression.composite import (ExprRange,
                                                     composite_expression)
    expressions = composite_expression(expressions)
    if expressions.num_entries() == 0:
        from proveit.logic.booleans.conjunction import \
            empty_conjunction
        return empty_conjunction
    if expressions.is_double():
        from . import and_if_both
        return and_if_both.instantiate({
            A: expressions[0],
            B: expressions[1]
        },
                                       auto_simplify=False)
    elif expressions.contains_range():
        # If there are ranges, prove these portions separately
        # (grouped together) and then disassociate.
        new_expressions = []
        to_expand = []
        # Group the ExprRanges and record their entry indices.
        for _k, entry in enumerate(expressions):
            if isinstance(entry, ExprRange):
                new_expressions.append(And(entry))
                to_expand.append(_k)
            else:
                new_expressions.append(entry)
        # Prove the composition with ExprRanges grouped:
        composed = compose(*new_expressions)
        # Disassociate each ExprRange in reverse order so we don't
        # have to update indices.
        for _idx in reversed(to_expand):
            composed = composed.disassociate(_idx)
        return composed
    else:
        from . import and_if_all
        _m = expressions.num_elements()
        return and_if_all.instantiate({
            m: _m,
            A: expressions
        },
                                      auto_simplify=False)
Example #3
0
 def __init__(self, var, index_or_indices, *, styles=None):
     '''
     Initialize an IndexedVar to represent the given 'var' being indexed
     via 'index_or_indices'.  The 'var' must be a Variable.
     '''
     from proveit._core_.expression.composite import composite_expression
     if not isinstance(var, Variable):
         raise TypeError("'var' being indexed should be a Variable "
                         "or IndexedVar itself; got %s" % str(var))
     self.indices = composite_expression(index_or_indices)
     if is_single(self.indices):
         # has a single index
         self.index = self.indices[0]
         self.index_or_indices = self.index
     else:
         self.index_or_indices = self.indices
     Function.__init__(self, var, self.index_or_indices, styles=styles)
     self.var = var
Example #4
0
 def _formatted_operation(format_type,
                          operator_or_operators,
                          operands,
                          *,
                          wrap_positions,
                          justification,
                          implicit_first_operator=True,
                          **kwargs):
     from proveit import ExprRange, ExprTuple, composite_expression
     if (isinstance(operator_or_operators, Expression)
             and not isinstance(operator_or_operators, ExprTuple)):
         # Single operator case.
         operator = operator_or_operators
         if isinstance(operands, ExprTuple):
             # An ExprTuple of operands.
             # Different formatting when there is 0 or 1 element, unless
             # it is an ExprRange.
             if operands.num_entries() < 2:
                 if operands.num_entries() == 0 or not isinstance(
                         operands[0], ExprRange):
                     if format_type == 'string':
                         return (
                             '[' + operator.string(fence=True) + '](' +
                             operands.string(fence=False, sub_fence=False) +
                             ')')
                     else:
                         return (
                             r'\left[' + operator.latex(fence=True) +
                             r'\right]\left(' +
                             operands.latex(fence=False, sub_fence=False) +
                             r'\right)')
                     raise ValueError("Unexpected format_type: " +
                                      str(format_type))
             fence = kwargs.get('fence', False)
             sub_fence = kwargs.get('sub_fence', True)
             do_wrapping = len(wrap_positions) > 0
             formatted_str = ''
             formatted_str += operands.formatted(
                 format_type,
                 fence=fence,
                 sub_fence=sub_fence,
                 operator_or_operators=operator,
                 implicit_first_operator=implicit_first_operator,
                 wrap_positions=wrap_positions,
                 justification=justification)
             return formatted_str
         else:
             # The operands ExprTuple are being represented by a Variable
             # (or Operation) equating to an ExprTuple.  We will format this
             # similarly as when we have 1 element except we drop the
             # round parantheses.  For example, [+]a, where a represents
             # the ExprTuple of operands for the '+' operation.
             if format_type == 'string':
                 return '[' + operator.string(
                     fence=True) + ']' + operands.string(fence=False,
                                                         sub_fence=False)
             else:
                 return (r'\left[' + operator.latex(fence=True) +
                         r'\right]' +
                         operands.latex(fence=False, sub_fence=False))
     else:
         operators = operator_or_operators
         operands = composite_expression(operands)
         # Multiple operator case.
         # Different formatting when there is 0 or 1 element, unless it is
         # an ExprRange
         if operands.num_entries() < 2:
             if operands.num_entries() == 0 or not isinstance(
                     operands[0], ExprRange):
                 raise OperationError(
                     "No defaut formatting with multiple operators and zero operands"
                 )
         fence = kwargs['fence'] if 'fence' in kwargs else False
         sub_fence = kwargs['sub_fence'] if 'sub_fence' in kwargs else True
         do_wrapping = len(wrap_positions) > 0
         formatted_str = ''
         if fence:
             formatted_str = '(' if format_type == 'string' else r'\left('
         if do_wrapping and format_type == 'latex':
             formatted_str += r'\begin{array}{%s} ' % justification[0]
         formatted_str += operands.formatted(
             format_type,
             fence=False,
             sub_fence=sub_fence,
             operator_or_operators=operators,
             implicit_first_operator=implicit_first_operator,
             wrap_positions=wrap_positions)
         if do_wrapping and format_type == 'latex':
             formatted_str += r' \end{array}'
         if fence:
             formatted_str += ')' if format_type == 'string' else r'\right)'
         return formatted_str
Example #5
0
    def __init__(self,
                 operator,
                 operand_or_operands=None,
                 *,
                 operands=None,
                 styles):
        '''
        Create an operation with the given operator and operands.
        The operator must be a Label (a Variable or a Literal).
        If a composite expression is provided as the 
        'operand_or_operands' it is taken to be the 'operands' of the
        Operation; otherwise the 'operands' will be the the provided
        Expression wrapped as a single entry in an ExprTuple.
        When there is a single operand that is not an ExprRange, there
        will be an 'operand' attribute as well as 'operands' as an 
        ExprTuple containing the one operand.
        '''
        from proveit._core_.expression.composite import (
            composite_expression, single_or_composite_expression, Composite,
            ExprTuple, NamedExprs)
        from proveit._core_.expression.lambda_expr import Lambda
        from .indexed_var import IndexedVar
        if self.__class__ == Operation:
            raise TypeError("Do not create an object of type Operation; "
                            "use a derived class (e.g., Function) instead.")
        self.operator = operator
        if (operand_or_operands == None) == (operands == None):
            if operands == None:
                raise ValueError(
                    "Must supply either 'operand_or_operands' or 'operands' "
                    "when constructing an Operation")
            else:
                raise ValueError(
                    "Must supply 'operand_or_operands' or 'operands' but not "
                    "both when constructing an Operation")
        if operands is not None:
            if not isinstance(operands, Expression):
                operands = composite_expression(operands)
            self.operands = operands
        else:
            orig_operand_or_operands = operand_or_operands
            operand_or_operands = single_or_composite_expression(
                operand_or_operands, do_singular_reduction=True)
            if isinstance(operand_or_operands, Composite):
                # a composite of multiple operands
                self.operands = operand_or_operands
            else:
                if isinstance(orig_operand_or_operands, Composite):
                    self.operands = orig_operand_or_operands
                else:
                    self.operands = ExprTuple(operand_or_operands)

        def raise_bad_operator_type(operator):
            raise TypeError("An operator may not be an explicit Lambda map "
                            "like %s; this is necessary to avoid a Curry's "
                            "paradox." % str(operator))

        if isinstance(self.operator, Lambda):
            raise_bad_operator_type(self.operator)
        if (isinstance(self.operands, ExprTuple)
                and self.operands.is_single()):
            # This is a single operand.
            self.operand = self.operands[0]
        sub_exprs = (self.operator, self.operands)
        if isinstance(self, IndexedVar):
            core_type = 'IndexedVar'
        else:
            core_type = 'Operation'
        if isinstance(self.operands, NamedExprs):
            # Make attributes to make the keys of the NamedExprs
            # operands.
            for key in self.operands.keys():
                setattr(self, key, self.operands[key])
        Expression.__init__(self, [core_type], sub_exprs, styles=styles)