# Path: matchpy/utils.py
# T = TypeVar('T')
# def fixed_integer_vector_iter(max_vector: Tuple[int, ...], vector_sum: int) -> Iterator[Tuple[int, ...]]:
# def weak_composition_iter(n: int, num_parts: int) -> Iterator[Tuple[int, ...]]:
# def optional_iter(remaining, count):
# def _make_variable_generator_factory(value, total, variables: List[VariableWithCount]):
#     def _factory(subst):
# def _commutative_single_variable_partiton_iter(values: 'Multiset[T]',
#                                                variable: VariableWithCount) -> Iterator[Dict[str, 'Multiset[T]']]:
# def commutative_sequence_variable_partition_iter(values: Multiset, variables: List[VariableWithCount]
#                                                 ) -> Iterator[Dict[str, Multiset]]:
#     def __init__(self, lines):
#     def visit(self, node):
#     def visit_Lambda(self, node):
#     def generic_visit(self, node):
# def get_short_lambda_source(lambda_func: LambdaType) -> Optional[str]:
# def extended_euclid(a: int, b: int) -> Tuple[int, int, int]:
# def base_solution_linear(a: int, b: int, c: int) -> Iterator[Tuple[int, int]]:
# def solve_linear_diop(total: int, *coeffs: int) -> Iterator[Tuple[int, ...]]:
# def generator_chain(initial_data: T, *factories: Callable[[T], Iterator[T]]) -> Iterator[T]:
#     def __init__(self, getter, slot=None):
#     def __get__(self, obj, cls):
# def slot_cached_property(slot):
#     def _wrapper(getter):
# class LambdaNodeVisitor(ast.NodeVisitor):
# class cached_property(property):


import itertools
import os
import hypothesis.strategies as st
import pytest
from hypothesis import assume, example, given, settings
from multiset import Multiset
from matchpy.utils import (
    VariableWithCount, base_solution_linear, cached_property, commutative_sequence_variable_partition_iter,
    extended_euclid, fixed_integer_vector_iter, get_short_lambda_source, weak_composition_iter, slot_cached_property,
    solve_linear_diop
)
                total_solutions_approx *= c / coeff
        assume(total_solutions_approx <= 100)

    @given(st.lists(st.integers(min_value=1, max_value=100), max_size=5), st.integers(min_value=0, max_value=100))
    @example([1, 2, 2], 4)
    def test_correctness(self, coeffs, c):
        self._limit_possible_solution_count(coeffs, c)
        for solution in solve_linear_diop(c, *coeffs):
            assert len(solution) == len(coeffs), "Solution size differs from coefficient count"
            result = sum(c * x for c, x in zip(coeffs, solution))
            for x in solution:
                assert x >= 0
            assert result == c, "Invalid solution {!r}".format(solution)

    @given(st.lists(st.integers(min_value=1, max_value=100), max_size=5), st.integers(min_value=0, max_value=100))
    @example([1, 2, 2], 4)
    @settings(deadline=400)
    def test_completeness(self, coeffs, c):
        self._limit_possible_solution_count(coeffs, c)
        solutions = set(solve_linear_diop(c, *coeffs))
        values = [range(c // x) for x in coeffs]
        for solution2 in itertools.product(*values):
            result = sum(c * x for c, x in zip(coeffs, solution2))
            if result == c:
                assert solution2 in solutions, "Missing solution {!r}".format(solution2)

    @given(st.lists(st.integers(min_value=1, max_value=100), max_size=5), st.integers(min_value=0, max_value=100))
    @example([1, 2, 2], 4)
    def test_uniqueness(self, coeffs, c):
        self._limit_possible_solution_count(coeffs, c)

# Path: matchpy/utils.py
# T = TypeVar('T')
# def fixed_integer_vector_iter(max_vector: Tuple[int, ...], vector_sum: int) -> Iterator[Tuple[int, ...]]:
# def weak_composition_iter(n: int, num_parts: int) -> Iterator[Tuple[int, ...]]:
# def optional_iter(remaining, count):
# def _make_variable_generator_factory(value, total, variables: List[VariableWithCount]):
#     def _factory(subst):
# def _commutative_single_variable_partiton_iter(values: 'Multiset[T]',
#                                                variable: VariableWithCount) -> Iterator[Dict[str, 'Multiset[T]']]:
# def commutative_sequence_variable_partition_iter(values: Multiset, variables: List[VariableWithCount]
#                                                 ) -> Iterator[Dict[str, Multiset]]:
#     def __init__(self, lines):
#     def visit(self, node):
#     def visit_Lambda(self, node):
#     def generic_visit(self, node):
# def get_short_lambda_source(lambda_func: LambdaType) -> Optional[str]:
# def extended_euclid(a: int, b: int) -> Tuple[int, int, int]:
# def base_solution_linear(a: int, b: int, c: int) -> Iterator[Tuple[int, int]]:
# def solve_linear_diop(total: int, *coeffs: int) -> Iterator[Tuple[int, ...]]:
# def generator_chain(initial_data: T, *factories: Callable[[T], Iterator[T]]) -> Iterator[T]:
#     def __init__(self, getter, slot=None):
#     def __get__(self, obj, cls):
# def slot_cached_property(slot):
#     def _wrapper(getter):
# class LambdaNodeVisitor(ast.NodeVisitor):
# class cached_property(property):


# Path: tests/test_utils.py
import itertools
import os
import hypothesis.strategies as st
import pytest
from hypothesis import assume, example, given, settings
from multiset import Multiset
from matchpy.utils import (
    VariableWithCount, base_solution_linear, cached_property, commutative_sequence_variable_partition_iter,
    extended_euclid, fixed_integer_vector_iter, get_short_lambda_source, weak_composition_iter, slot_cached_property,
    solve_linear_diop
)

                total_solutions_approx *= c / coeff
        assume(total_solutions_approx <= 100)

    @given(st.lists(st.integers(min_value=1, max_value=100), max_size=5), st.integers(min_value=0, max_value=100))
    @example([1, 2, 2], 4)
    def test_correctness(self, coeffs, c):
        self._limit_possible_solution_count(coeffs, c)
        for solution in solve_linear_diop(c, *coeffs):
            assert len(solution) == len(coeffs), "Solution size differs from coefficient count"
            result = sum(c * x for c, x in zip(coeffs, solution))
            for x in solution:
                assert x >= 0
            assert result == c, "Invalid solution {!r}".format(solution)

    @given(st.lists(st.integers(min_value=1, max_value=100), max_size=5), st.integers(min_value=0, max_value=100))
    @example([1, 2, 2], 4)
    @settings(deadline=400)
    def test_completeness(self, coeffs, c):
        self._limit_possible_solution_count(coeffs, c)
        solutions = set(solve_linear_diop(c, *coeffs))
        values = [range(c // x) for x in coeffs]
        for solution2 in itertools.product(*values):
            result = sum(c * x for c, x in zip(coeffs, solution2))
            if result == c:
                assert solution2 in solutions, "Missing solution {!r}".format(solution2)

    @given(st.lists(st.integers(min_value=1, max_value=100), max_size=5), st.integers(min_value=0, max_value=100))
    @example([1, 2, 2], 4)
    def test_uniqueness(self, coeffs, c):
        self._limit_possible_solution_count(coeffs, c)

        solutions = list(solve_linear_diop(c, *coeffs))