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))
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()
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()
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()
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()
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