コード例 #1
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)
コード例 #2
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)
コード例 #3
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)
コード例 #4
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)
コード例 #5
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)
コード例 #6
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)
コード例 #7
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