Ejemplo n.º 1
0
    def test_single_variable_solver_handles_distribution(self):
        equation = Parser.parse_equation('p * -25 + (1 - p) * 5 = 0')
        result = Solver.single_variable(equation,
                                        'p',
                                        print_out=True,
                                        max_iterations=20)

        verify(str(result), self.reporter)
Ejemplo n.º 2
0
    def test_single_variable_solver_handles_same_variable(self):

        equation = Parser.parse_equation('x + x = 3')
        result = Solver.single_variable(equation,
                                        'x',
                                        print_out=True,
                                        max_iterations=5)

        self.assertEqual(str(result), 'x = 1.5')
Ejemplo n.º 3
0
    def test_single_variable_solver_handles_same_variable_complex(self):

        equation = Parser.parse_equation('2*x - 7 = 4*x + 5')
        result = Solver.single_variable(equation,
                                        'x',
                                        print_out=True,
                                        max_iterations=20)

        self.assertEqual(str(result), 'x = -6.0')
Ejemplo n.º 4
0
    def test_single_variable_solver_evaluates(self):

        equation = Parser.parse_equation('0 = 0.5*a + 3*4')
        result = Solver.single_variable(equation,
                                        'a',
                                        print_out=True,
                                        max_iterations=5)

        verify(str(result), self.reporter)
Ejemplo n.º 5
0
    def test_all_equation_substitutions_addition_by_same(self):

        equation = Parser.parse_equation('3.0 = (x)+(x)')

        substitution = ExpressionSubstitution(Parser.parse_expression('a + a'),
                                              Parser.parse_expression('2*a'))

        transformation = Transformation.apply_all_substitution_transformations(
            substitution)

        result = transformation.apply(equation)

        verify(str(result), self.reporter)
Ejemplo n.º 6
0
    def test_all_equation_substitutions_simple(self):

        equation = Parser.parse_equation('y = (x)-(x)')

        substitution = ExpressionSubstitution(Parser.parse_expression('a - a'),
                                              Parser.parse_expression('0'))

        transformation = Transformation.apply_all_substitution_transformations(
            substitution)

        result = transformation.apply(equation)

        verify(str(result), self.reporter)
Ejemplo n.º 7
0
def solve_equation(input):
    assert type(input) == str

    if Parser.is_equation(input):
        equation = Parser.parse_equation(input)
        variables = equation.get_variables()
        if len(variables) != 1:
            raise InputException(
                'Equation should have exactly 1 variable but instead has {}: {}'
                .format(str(len(variables)), variables))
        result = Solver.single_variable(equation, variables[0])
    else:
        expression = Parser.parse_expression(input)
        variables = expression.get_variables()
        if len(variables) != 0:
            raise InputException(
                'Expression should have no variables but instead has the following: {}'
                .format(variables))
        result = expression.evaluate()

    print(result)
Ejemplo n.º 8
0
    def test_single_variable_solver_simple(self):

        equation = Parser.parse_equation('y*0.5 - 2*x = 9')
        result = Solver.single_variable(equation, 'y', print_out=True)

        verify(str(result), self.reporter)
Ejemplo n.º 9
0
    def test_single_variable_solver_flip(self):

        equation = Parser.parse_equation('-3.1415 = p')
        result = Solver.single_variable(equation, 'p')

        verify(str(result), self.reporter)
Ejemplo n.º 10
0
    def single_variable(equation,
                        variable,
                        print_out=False,
                        max_iterations=1000):
        assert isinstance(equation, Equation)
        if type(variable) == str:
            variable = Variable(variable)
        assert isinstance(variable, Variable)
        assert type(print_out) == bool
        assert type(max_iterations) == int
        assert variable.symbol in equation.get_variables()

        expected_result = Operation(variable)
        condition = lambda x: (
            (Operation.areEqual(x.lhs, expected_result) and variable.symbol not in x.rhs.get_variables())\
            or x is None
        )

        distributions = [
            ExpressionSubstitution(Parser.parse_expression('a * (b + c)'),
                                   Parser.parse_expression('a * b + a * c')),
            ExpressionSubstitution(Parser.parse_expression('(a + b) * c'),
                                   Parser.parse_expression('a * c + b * c')),
            ExpressionSubstitution(Parser.parse_expression('(a + b) / c'),
                                   Parser.parse_expression('a / c + b / c')),
            ExpressionSubstitution(Parser.parse_expression('a * (b - c)'),
                                   Parser.parse_expression('a * b - a * c')),
            ExpressionSubstitution(Parser.parse_expression('(a - b) * c'),
                                   Parser.parse_expression('a * c - b * c')),
            ExpressionSubstitution(Parser.parse_expression('(a - b) / c'),
                                   Parser.parse_expression('a / c - b / c')),
        ]

        distributions = [
            Transformation.apply_all_substitution_transformations(x)
            for x in distributions
        ]
        distribute = SolverStep(
            Transformation.each_transformation(distributions, False))

        pre_solve = SolverStep(
            Transformation.collect_like_terms_transformation())

        equation = distribute.execute_step(equation)
        equation = pre_solve.execute_step(equation)

        branches = [equation]
        executed_branches = set()
        iterations = 0

        no_regrets_transformations = [
            Transformation.apply_all_substitution_transformations(x)\
            for x in Solver.no_regrets_substitutions
        ]

        solve_step = SolverStep(Transformation.evaluation_transformation(),
                                terminate_on_repeat=True)
        solve_step_2 = SolverStep(
            Transformation.each_transformation(no_regrets_transformations,
                                               False))
        solve_step_3 = SolverStep(Transformation.flip_transformation(variable))
        solve_step_4 = SolverStep.cancellations()

        solve_step.next_step = solve_step_2
        solve_step_2.next_step = solve_step_3
        solve_step_3.next_step = solve_step_4
        solve_step_4.next_step = solve_step

        while iterations < max_iterations:

            if len(branches) == 0:
                raise SolverException('Exhausted possible transformations.')

            branch = branches[0]
            branches = branches[1:]

            if print_out:
                print('Executing branch: {}'.format(str(branch)))
            result = solve_step.execute_until(branch,
                                              condition,
                                              print_out=print_out)
            if condition(result):
                final_execute_step = SolverStep(
                    Transformation.evaluation_transformation())
                return final_execute_step.execute_step(result)
            else:

                executed_branches.add(str(branch))
                executed_branches.add(
                    str(result))  # Executed already since steps terminated

                new_branches = dict()
                # We don't care about the outputs of flips or cancellations
                new_branch_strings = solve_step_3.previous_inputs - executed_branches
                for string in new_branch_strings:
                    new_branches[string] = Parser.parse_equation(string)
                solve_step.clear_history()
                solve_step_2.clear_history()
                solve_step_3.clear_history()
                solve_step_4.clear_history()

                for substitution in Solver.substitutions:
                    left_substitution_result = [
                        x[1]
                        for x in substitution.get_all_substitutions(branch.lhs)
                    ]
                    right_substitution_result = [
                        x[1]
                        for x in substitution.get_all_substitutions(branch.rhs)
                    ]

                    equations = [
                        Equation(x, branch.rhs)
                        for x in left_substitution_result
                    ]
                    equations += [
                        Equation(branch.lhs, x)
                        for x in right_substitution_result
                    ]

                    pairs = [(str(x), x) for x in equations
                             if str(x) not in executed_branches]

                    for k, v in pairs:
                        new_branches[k] = v

                if print_out:
                    print("New branches from {}:\n{}\n".format(
                        str(branch), '\n'.join(new_branches.keys())))
                branches += new_branches.values()
                branches.sort(key=lambda x: len(str(x)))
            iterations += 1

        raise SolverException(
            'Could not solve equation for a single variable.  Final result: {}'
            .format(str(equation)))