예제 #1
0
    def sample(block: Block, sample_count: int) -> SamplingResult:

        samples = cast(List[dict], [])
        metrics = cast(dict, {'sample_metrics': []})

        overall_start = time()

        # Build the full CNF for this block
        cnf = build_cnf(block)

        metrics['solver_call_count'] = 0
        for _ in range(sample_count):
            sample_metrics = cast(dict, {})
            t_start = time()
            samples.append(
                GuidedSamplingStrategy.__generate_sample(
                    block, cnf, sample_metrics))
            sample_metrics['time'] = time() - t_start
            metrics['sample_metrics'].append(sample_metrics)
            metrics['solver_call_count'] += sample_metrics['solver_call_count']

        metrics['time'] = time() - overall_start
        GuidedSamplingStrategy.__compute_additional_metrics(metrics)

        return SamplingResult(samples, metrics)
def test_uniform_combinatoric_is_always_valid(filename):

    failures = []
    contents = None
    with open(filename, 'r') as f:
        contents = f.read()
        exec(contents, globals(), locals())

    if 'block' not in vars():
        pytest.fail(
            "File did not produce a variable named 'block', aborting. file={}".
            format(filename))

    # Build the CNF for this block
    build_cnf_result = build_cnf(vars()['block'])

    # Build the sampler
    enumerator = UCSolutionEnumerator(vars()['block'])

    # Generate some samples, make sure they're all SAT.
    sample_count = min(enumerator.solution_count(), 200)
    print("Checking that UC samples are SAT for {}, sample count={}".format(
        filename, sample_count))
    for s in range(sample_count):
        sample = enumerator.generate_solution_variables()
        if not cnf_is_satisfiable(build_cnf_result +
                                  CNF(cnf_to_json([And(sample)]))):
            failures.append("Found UNSAT solution! Solution={} File={}".format(
                sample, filename))

    if failures:
        pytest.fail(
            '{} failures occurred in SAT checks for UC sampler: {}'.format(
                len(failures), failures))
예제 #3
0
def __generate_cnf(block: Block) -> str:
    """Converts a :class:`.Block` into a CNF formula and renders that CNF
    formula in the Unigen-specific DIMACS format.

    :param block:
        A description of a CNF formula as a :class:`.Block`.

    :returns:
        The given :class:`.Block` rendered as a Unigen-specific
        DIMACS-formatted string.
    """
    cnf = build_cnf(block)
    return cnf.as_unigen_string()
예제 #4
0
def test_correct_solution_count_with_congruence_factor_and_constrained_exactly_cnf(design=[color, text, mix, con_factor]):
    crossing = [[color, text], [text, mix]]
    constraints = [exactly_k_in_a_row(2, con_factor)]

    block  = multiple_cross_block(design, crossing, constraints)
    cnf = build_cnf(block)

    # with open(path_to_cnf_files+'/test_correct_solution_count_with_congruence_factor_and_constrained_exactly.cnf', 'w') as f:
    #     f.write(cnf.as_unigen_string())
    with open(path_to_cnf_files+'/test_correct_solution_count_with_congruence_factor_and_constrained_exactly.cnf', 'r') as f:
        old_cnf = f.read()

    assert old_cnf == cnf.as_unigen_string()
예제 #5
0
def test_correct_solution_count_with_repeated_color_factor_and_no_repetition_allowed_cnf(design=[color, text, mix, repeated_color_factor]):
    crossing = [[color, text], [mix, text]]
    constraints = [exclude(repeated_color_factor, get_level_from_name(repeated_color_factor, "yes"))]

    block  = multiple_cross_block(design, crossing, constraints)
    cnf = build_cnf(block)

    # with open(path_to_cnf_files+'/test_correct_solution_count_with_repeated_color_factor_and_no_repetition_allowed.cnf', 'w') as f:
    #     f.write(cnf.as_unigen_string())
    with open(path_to_cnf_files+'/test_correct_solution_count_with_repeated_color_factor_and_no_repetition_allowed.cnf', 'r') as f:
        old_cnf = f.read()

    assert old_cnf == cnf.as_unigen_string()
예제 #6
0
def test_is_cnf_still_sat_should_respond_correctly():

    # Build the CNF on the server.
    cnf_result = build_cnf(block)

    # with open(path_to_cnf_files+'/test_is_cnf_still_sat_should_respond_correctly.cnf', 'w') as f:
    #     f.write(cnf_result.as_unigen_string())
    with open(
            path_to_cnf_files +
            '/test_is_cnf_still_sat_should_respond_correctly.cnf', 'r') as f:
        old_cnf = f.read()

    assert old_cnf == cnf_result.as_unigen_string()

    assert is_cnf_still_sat(block, [And([1, 3])])

    assert not is_cnf_still_sat(block, [And([7, 8])])
    assert not is_cnf_still_sat(block, [And([1, 7, 13])])
def test_correct_solution_count_when_bookends_must_not_match_each_other_cnf(
        design=[color, text, congruent_bookend]):
    crossing = [color, text]

    # Require both bookends to be incongruent with each other.
    constraints = [at_most_k_in_a_row(1, congruent_bookend)]

    block = fully_cross_block(design, crossing, constraints)
    cnf = build_cnf(block)

    # with open(path_to_cnf_files+'/test_correct_solution_count_when_bookends_must_not_match_each_other.cnf', 'w') as f:
    #     f.write(cnf.as_unigen_string())
    with open(
            path_to_cnf_files +
            '/test_correct_solution_count_when_bookends_must_not_match_each_other.cnf',
            'r') as f:
        old_cnf = f.read()

    assert old_cnf == cnf.as_unigen_string()
예제 #8
0
def test_correct_solution_count_when_transition_in_crossing_and_constrained_cnf(
        design=[direction, color, repeated_color_factor]):
    crossing = [direction, repeated_color_factor]
    constraints = [
        at_most_k_in_a_row(1, (color, get_level_from_name(color, "red")))
    ]

    block = fully_cross_block(design, crossing, constraints)
    cnf = build_cnf(block)

    # with open(path_to_cnf_files+'/test_correct_solution_count_when_transition_in_crossing_and_constrained.cnf', 'w') as f:
    #     f.write(cnf.as_unigen_string())
    with open(
            path_to_cnf_files +
            '/test_correct_solution_count_when_transition_in_crossing_and_constrained.cnf',
            'r') as f:
        old_cnf = f.read()

    assert old_cnf == cnf.as_unigen_string()
def test_correct_solution_count_with_override_flag_and_multiple_trials_excluded_cnf(
):
    # With this constraint, there should only be ONE allowed crossing, and therefore one solution.
    constraints = [
        exclude(stimulus_configuration,
                get_level_from_name(stimulus_configuration, "legal"))
    ]
    block = fully_cross_block(design,
                              crossing,
                              constraints,
                              require_complete_crossing=False)
    cnf = build_cnf(block)

    # with open(path_to_cnf_files+'/test_correct_solution_count_with_override_flag_and_multiple_trials_excluded.cnf', 'w') as f:
    #     f.write(cnf.as_unigen_string())
    with open(
            path_to_cnf_files +
            '/test_correct_solution_count_with_override_flag_and_multiple_trials_excluded.cnf',
            'r') as f:
        old_cnf = f.read()

    assert old_cnf == cnf.as_unigen_string()  # FIXME