コード例 #1
0
    def test_evaluate_where_possible_simple(self):
        two_plus_two = Operation(OperationType.PLUS(),
                                 [Variable(2.0), Variable(2.0)])
        expression = Operation(OperationType.DIVIDE(),
                               [Variable('x'), two_plus_two])

        verify(str(expression.evaluate_where_possible()), self.reporter)
コード例 #2
0
    def test_complex_operation(self):

        two = Operation(OperationType.POSITIVE(), [Variable(2)])
        negative_x = Operation(OperationType.NEGATIVE(), [Variable('x')])
        op = Operation(OperationType.TIMES(), [two, negative_x])

        verify(str(op), self.reporter)
コード例 #3
0
    def test_evaluation_simple(self):

        two_plus_two = Operation(OperationType.PLUS(),
                                 [Variable(2.0), Variable(2.0)])
        two_plus_two_divided_by_four = Operation(
            OperationType.DIVIDE(), [two_plus_two, Variable(4)])

        self.assertTrue(two_plus_two_divided_by_four.is_evaluatable())
        self.assertAlmostEqual(two_plus_two_divided_by_four.evaluate(), 1)
コード例 #4
0
    def test_evaluation_trivial(self):

        two = Operation(OperationType.POSITIVE(), [Variable('2')])

        self.assertTrue(two.is_evaluatable())
        self.assertAlmostEqual(two.evaluate(), 2)

        x = Operation(OperationType.POSITIVE(), [Variable('x')])
        self.assertFalse(x.is_evaluatable())
コード例 #5
0
    def test_equation(self):

        two = Operation(OperationType.POSITIVE(), [Variable(2)])
        negative_x = Operation(OperationType.NEGATIVE(), [Variable('x')])
        lhs = Operation(OperationType.TIMES(), [two, negative_x])

        rhs = Variable(3.1415)

        eq = Equation(lhs, rhs)

        verify(str(eq), self.reporter)
コード例 #6
0
    def test_equation_cancellation(self):

        lhs = Parser(Tokenizer.tokenize('x * 4')).parse()
        rhs = Parser(Tokenizer.tokenize('y')).parse()
        equation = Equation(lhs, rhs)

        multiplication_cancellation = EquationCancellation(
            OperationType.TIMES(), OperationType.DIVIDE())

        self.assertTrue(multiplication_cancellation.is_applicable_to(equation))
        result = multiplication_cancellation.apply(equation)
        verify(str(result), self.reporter)
コード例 #7
0
    def test_equation_cancellation_is_applicable(self):

        lhs = Parser(Tokenizer.tokenize('x + 4')).parse()
        rhs = Parser(Tokenizer.tokenize('y')).parse()
        equation = Equation(lhs, rhs)

        addition_cancellation = EquationCancellation(OperationType.PLUS(),
                                                     OperationType.MINUS())

        self.assertTrue(addition_cancellation.is_applicable_to(equation))
        flipped = equation.flip()
        self.assertFalse(addition_cancellation.is_applicable_to(flipped))
コード例 #8
0
    def test_equation_cancellation_with_negative(self):

        lhs = Parser(Tokenizer.tokenize('x + -4')).parse()
        rhs = Parser(Tokenizer.tokenize('y')).parse()
        equation = Equation(lhs, rhs)

        addition_cancellation = EquationCancellation(OperationType.PLUS(),
                                                     OperationType.MINUS())

        self.assertTrue(addition_cancellation.is_applicable_to(equation))
        result = addition_cancellation.apply(equation)
        verify(str(result), self.reporter)
コード例 #9
0
    def __init__(self, token):
        assert isinstance(token, Token)

        if token.token_type in self.token_map.keys():
            self._operation_type = self.token_map[token.token_type]
        else:
            self._operation_type = OperationType.VARIABLE(token.value)
コード例 #10
0
class InfixParselet:

    token_map = {
        TokenType.PLUS: OperationType.PLUS(),
        TokenType.MINUS: OperationType.MINUS(),
        TokenType.TIMES: OperationType.TIMES(),
        TokenType.DIVIDES: OperationType.DIVIDE(),
        TokenType.EXPONENTIATES: OperationType.EXPONENTIATE()
    }

    # Enforce order of operations
    # If precedence <= max_priority, parser will parse only the next substatement
    # If priority > max_priority, parser will parse everything to the right
    precedence_map = {
        TokenType.EXPONENTIATES: 3,
        TokenType.TIMES: 2,
        TokenType.DIVIDES: 2,
        TokenType.PLUS: 1,
        TokenType.MINUS: 1
    }

    def __init__(self, token):
        assert isinstance(token, Token)
        assert token.token_type in self.token_map.keys()

        self._operation_type = self.token_map[token.token_type]
        self.precedence = self.precedence_map[token.token_type]

    def parse(self, parser, left):
        assert isinstance(parser, Parser)
        assert isinstance(left, Operation)

        right = parser.parse(self.precedence)

        return Operation(self._operation_type, [left, right])

    @staticmethod
    def get_next_precedence(parser):
        assert isinstance(parser, Parser)

        token = parser.peek()
        if token.token_type in InfixParselet.precedence_map.keys():
            return InfixParselet.precedence_map[token.token_type]
        else:
            return 0
コード例 #11
0
    def cancellations():
        cancels = [
            EquationCancellation(OperationType.PLUS(), OperationType.MINUS()),
            EquationCancellation(OperationType.MINUS(), OperationType.PLUS()),
            EquationCancellation(OperationType.TIMES(),
                                 OperationType.DIVIDE()),
            EquationCancellation(OperationType.DIVIDE(), OperationType.TIMES())
        ]

        transformations = [x.as_transformation() for x in cancels]

        return SolverStep(transformations)
コード例 #12
0
class PrefixParselet:

    token_map = {
        TokenType.PLUS : OperationType.POSITIVE(),
        TokenType.MINUS : OperationType.NEGATIVE()
    }

    def __init__(self, token):
        assert isinstance(token, Token)

        if token.token_type in self.token_map.keys():
            self._operation_type = self.token_map[token.token_type]
        else:
            self._operation_type = OperationType.VARIABLE(token.value)

    def parse(self, parser):
        assert isinstance(parser, Parser)

        if self._operation_type in self.token_map.values():
            right = parser.parse(precedence=10) # All prefixes should be evaluated before infixes
            return Operation(self._operation_type, [right])
        else:
            return Operation(self._operation_type)
コード例 #13
0
    def transform(self, expression, pattern=None):
        assert isinstance(expression, Operation)
        if pattern is None:
            assert isinstance(pattern, SubstitutionPattern)

        for k in pattern.keys():
            if type(pattern[k]) == str:
                pattern[k] = Operation(OperationType.VARIABLE(pattern[k]))

        substituted_start = self.try_transform(expression, pattern)

        substituted_end = self._substitute(self._end, pattern)

        return substituted_end
コード例 #14
0
 def apply_function(equation):
     if equation.lhs.operation_type.arity == 0:
         equation = equation.flip()
     if (equation.rhs.operation_type.arity
             == 0) and (equation.rhs.operation_type.symbol == '0'):
         homogenized = equation.lhs
     else:
         homogenized = Operation(OperationType.MINUS(),
                                 [equation.lhs, equation.rhs])
     collected = CollectedTerms.try_parse_expression(homogenized)
     if collected is None:
         return equation
     collected = collected.as_expression
     return Equation(collected, Operation(Variable(0)))
コード例 #15
0
    def test_evaluate_where_possible_complex(self):
        two_plus_two = Operation(OperationType.PLUS(),
                                 [Variable(2.0), Variable(2.0)])
        two_plus_two_divided_by_four = Operation(
            OperationType.DIVIDE(), [two_plus_two, Variable(4)])
        three_minus_x = Operation(OperationType.MINUS(),
                                  [Variable(3.0), Variable('x')])
        seven_plus_five = Operation(OperationType.PLUS(),
                                    [Variable(7), Variable(5)])
        three_minus_x_over_seven_plus_five = Operation(
            OperationType.DIVIDE(), [three_minus_x, seven_plus_five])
        expression = Operation(
            OperationType.TIMES(),
            [two_plus_two_divided_by_four, three_minus_x_over_seven_plus_five])

        verify(str(expression.evaluate_where_possible()), self.reporter)
コード例 #16
0
    def test_complex_single_solution_solve(self):

        lhs = Parser(Tokenizer.tokenize('x * 4 - 18')).parse()
        rhs = Parser(Tokenizer.tokenize('2')).parse()
        equation = Equation(lhs, rhs)

        cancellations = [
            EquationCancellation(OperationType.PLUS(), OperationType.MINUS()),
            EquationCancellation(OperationType.MINUS(), OperationType.PLUS()),
            EquationCancellation(OperationType.TIMES(),
                                 OperationType.DIVIDE()),
            EquationCancellation(OperationType.DIVIDE(), OperationType.TIMES())
        ]

        transformations = list(
            map(lambda x: x.as_transformation(), cancellations))

        step = SolverStep(transformations)
        step.next_step = step

        condition = lambda x: str(x.lhs) == 'x'

        result = step.execute_until(equation, condition)
        verify(str(result), self.reporter)
コード例 #17
0
    def test_simple_operation(self):

        simple_op = Operation(OperationType.PLUS(), [Variable(2), Variable(2)])
        verify(str(simple_op), self.reporter)