def test_decoder_basic_1(self): sat_problem = SATProblem() Encoder.encode_basic_clause(self.tbn_problem, sat_problem) Encoder.increment_min_representatives(self.tbn_problem, sat_problem) sat_problem.solve() polymers = Decoder.decode_boolean_values(self.tbn_problem, sat_problem) self.assertEqual(len(polymers), 1)
def test_encode_each_site_binds_at_most_once(self): sat_problem = SATProblem() Encoder.encode_each_site_binds_at_most_once(self.tbn_problem, sat_problem) self.assertEqual(len(sat_problem.each_site_binds_at_most_once_clauses), 38) self.assertEqual(len(sat_problem.pair_to_id), 28)
def test_constraints_encoder_monomer_together(self): constraint_input = ["TOGETHER output extra"] tbn_problem = parse_input_lines(self.monomer_input, constraint_input) sat_problem = SATProblem() Encoder.encode_basic_clause(tbn_problem, sat_problem) self.assertEqual(len(sat_problem.constraint_clauses), 1) self.assertEqual(len(sat_problem.constraint_clauses[0]), 1)
def test_constraints_encoder_monomer_notfree(self): constraint_input = ["NOTFREE output"] tbn_problem = parse_input_lines(self.monomer_input, constraint_input) sat_problem = SATProblem() Encoder.encode_basic_clause(tbn_problem, sat_problem) self.assertEqual(len(sat_problem.constraint_clauses), 1) self.assertEqual(len(sat_problem.constraint_clauses[0]), 8)
def test_constraints_encoder_bsite_notanypaired(self): constraint_input = ["NOTANYPAIRED s1"] tbn_problem = parse_input_lines(self.monomer_input, constraint_input) sat_problem = SATProblem() Encoder.encode_basic_clause(tbn_problem, sat_problem) num_complement = tbn_problem.site_type_to_sitelist_map.get( "c").get_normal_site_count() self.assertEqual(len(sat_problem.constraint_clauses), num_complement)
def test_basic(self): tbn_file = open("../input/classic.txt", 'rt') tbn_problem = parse_input_lines(tbn_file.readlines(), []) tbn_file.close() sat_problem = SATProblem() Encoder.encode_basic_clause(tbn_problem, sat_problem) while sat_problem.success: Encoder.increment_min_representatives(tbn_problem, sat_problem) sat_problem.solve() self.assertEqual(sat_problem.min_reps, 4)
def test_encode_bind_representatives(self): sat_problem = SATProblem() Encoder.encode_each_site_binds_at_most_once(self.tbn_problem, sat_problem) Encoder.encode_limiting_site_binds(self.tbn_problem, sat_problem) Encoder.encode_pair_implies_bind(self.tbn_problem, sat_problem) Encoder.encode_bind_transitive(self.tbn_problem, sat_problem) Encoder.encode_bind_representatives(self.tbn_problem, sat_problem) self.assertEqual(len(sat_problem.rep_to_id), self.tbn_problem.monomer_count) self.assertEqual(len(sat_problem.bind_representatives_clauses), 36)
def test_constraints_encoder_bsite_paired(self): constraint_input = ["PAIRED s1 s2"] tbn_problem = parse_input_lines(self.monomer_input, constraint_input) sat_problem = SATProblem() Encoder.encode_basic_clause(tbn_problem, sat_problem) self.assertEqual(len(sat_problem.constraint_clauses), 1) self.assertEqual(len(sat_problem.constraint_clauses[0]), 1) pair_id = sat_problem.constraint_clauses[0][0] pair = sat_problem.id_to_pair.get(pair_id) self.assertEqual(pair.site1.name, "s1") self.assertEqual(pair.site2.name, "s2")
def test_encode_limiting_site_binds(self): sat_problem = SATProblem() Encoder.encode_each_site_binds_at_most_once(self.tbn_problem, sat_problem) Encoder.encode_limiting_site_binds(self.tbn_problem, sat_problem) self.assertEqual(len(sat_problem.pair_to_id), 28) self.assertEqual(len(sat_problem.limited_site_binds_clauses), 10) self.assertTrue([1, 2] in sat_problem.limited_site_binds_clauses) self.assertTrue([3, 4, 5] in sat_problem.limited_site_binds_clauses) self.assertTrue([9, 10, 11] in sat_problem.limited_site_binds_clauses) self.assertTrue([12, 13, 14] in sat_problem.limited_site_binds_clauses) self.assertTrue([15, 16, 17] in sat_problem.limited_site_binds_clauses) self.assertTrue([18, 19, 20] in sat_problem.limited_site_binds_clauses) self.assertTrue([21, 22, 23] in sat_problem.limited_site_binds_clauses) self.assertTrue([24, 25, 26] in sat_problem.limited_site_binds_clauses) self.assertTrue([27, 28] in sat_problem.limited_site_binds_clauses)
def test_encode_bind_transitive(self): sat_problem = SATProblem() Encoder.encode_each_site_binds_at_most_once(self.tbn_problem, sat_problem) Encoder.encode_limiting_site_binds(self.tbn_problem, sat_problem) Encoder.encode_pair_implies_bind(self.tbn_problem, sat_problem) Encoder.encode_bind_transitive(self.tbn_problem, sat_problem) self.assertEqual(len(sat_problem.bind_to_id), 36) self.assertEqual(len(sat_problem.bind_transitive_clauses), 252)
def test_encode_pair_implies_bind(self): sat_problem = SATProblem() Encoder.encode_each_site_binds_at_most_once(self.tbn_problem, sat_problem) Encoder.encode_limiting_site_binds(self.tbn_problem, sat_problem) Encoder.encode_pair_implies_bind(self.tbn_problem, sat_problem) self.assertEqual(len(sat_problem.bind_to_id), 14) # Same number as number of pairs! self.assertEqual(len(sat_problem.pair_implies_bind_clauses), len(sat_problem.pair_to_id))
def test_encoder_reset_clauses(self): sat_problem = SATProblem() Encoder.encode_basic_clause(self.tbn_problem, sat_problem) Encoder.increment_min_representatives(self.tbn_problem, sat_problem) Encoder.increment_min_representatives(self.tbn_problem, sat_problem) self.assertEqual(sat_problem.min_reps, 2) sat_problem.reset_clauses() self.assertEqual(sat_problem.min_reps, 0) self.assertEqual( len(sat_problem.increment_min_representatives_clauses), 0)
def test_increment_min_representatives(self): sat_problem = SATProblem() Encoder.encode_basic_clause(self.tbn_problem, sat_problem) self.assertEqual(sat_problem.min_reps, 0) Encoder.increment_min_representatives(self.tbn_problem, sat_problem) self.assertEqual(sat_problem.min_reps, 1) self.assertEqual( len(sat_problem.increment_min_representatives_clauses), 10) Encoder.increment_min_representatives(self.tbn_problem, sat_problem) self.assertEqual(sat_problem.min_reps, 2) self.assertEqual( len(sat_problem.increment_min_representatives_clauses), 28) Encoder.increment_min_representatives(self.tbn_problem, sat_problem) self.assertEqual(sat_problem.min_reps, 3) self.assertEqual( len(sat_problem.increment_min_representatives_clauses), 45)
def get_stable_config(tbn_lines, constr_lines, gen_count, init_k, celery_task=None): # parse the input to encode it into BindingSite/Monomer classes t0 = time.time() # Celery Task is flag to indicate if a call is made from library or from a celery broker worker API if celery_task is not None: if celery_task.is_aborted(): raise EarlyTerminationException(0, 0) celery_task.update_state(state="PROGRESS", meta={ 'status': "Progress", 'count': 0, 'k': 0 }) tbn_problem = parse_input_lines(tbn_lines, constr_lines) tbn_problem.gen_count = gen_count tbn_problem.init_k = init_k configs = [] # encode problem to SAT solver compatible problem sat_problem = SATProblem() Encoder.encode_basic_clause(tbn_problem, sat_problem) print() print("[1] COMPUTING ORIGINAL STABLE CONFIGURATION:") # Increment solver to minimum polymers before computing while sat_problem.min_reps < tbn_problem.init_k: Encoder.increment_min_representatives(tbn_problem, sat_problem) original_num_reps = 0 # solve the problem (SAT solver) while sat_problem.success: if celery_task is not None: if celery_task.is_aborted(): raise EarlyTerminationException(1, sat_problem.min_reps) celery_task.update_state(state="PROGRESS", meta={ 'status': "Progress", 'count': 1, 'k': sat_problem.min_reps }) else: print("... Checking for k =", sat_problem.min_reps, "polymers") sat_problem.solve(False) if (sat_problem.success): original_num_reps = sat_problem.min_reps Encoder.increment_min_representatives(tbn_problem, sat_problem) if original_num_reps > 0: if celery_task is None: print("Found an original stable configuration with [", original_num_reps, "] polymers.\n") else: if celery_task is None: print("Could not find original stable configuration with [", tbn_problem.init_k, "] polymers.\n") # Printing execution time print("\nCompleted in", time.time() - t0, "seconds.\n") raise MinPolymersExceedEntropyException(tbn_problem.init_k) # Decode the problem into polymers and print results polymers = Decoder.decode_boolean_values(tbn_problem, sat_problem) if celery_task is None: for index, polymer in enumerate(polymers): print("\t" + "Polymer number", index + 1) for monomer in polymer.monomer_list: print("\t\t" + str(monomer)) print() # SOLVING WITH CONSTRAINTS if len(tbn_problem.constraints) != 0: configs = get_stable_configs_using_constraints(tbn_problem, sat_problem, original_num_reps, celery_task) # SOLVING WITHOUT CONSTRAINTS else: # Add original configuration solution to result list configs.append(polymers) # Generate additional unique solutions if tbn_problem.gen_count > 1: additional_configs = get_stable_configs_using_constraints( tbn_problem, sat_problem, original_num_reps, celery_task) # Add results to existing solution list configs.extend(additional_configs) # Printing execution time if celery_task is None: print("\nCompleted in", time.time() - t0, "seconds.\n") return configs, original_num_reps
def get_stable_configs_using_constraints(tbn_problem, sat_problem, original_num_reps, celery_task=None): counter = 0 # For just generating new solutions w/o constraints, need to encode original solution if len(tbn_problem.constraints) == 0: Encoder.encode_unique_solution(tbn_problem, sat_problem) counter = 1 #Set counter = 1 since we include the original solution # Print constraints out for readability elif celery_task is None: #Only need to print if using CLI print() print("COMPUTING WITH FOLLOWING CONSTRAINTS:") for constr in tbn_problem.constraints: print("\t" + str(constr)) print() configs = [] # Generate multiple unique solutions while counter < tbn_problem.gen_count: sat_problem.reset_clauses() print("[" + str(counter + 1) + "] COMPUTING STABLE CONFIGURATION WITH ADDITIONAL CONSTRAINTS:") # Increment solver to minimum polymers before computing while sat_problem.min_reps < tbn_problem.init_k: Encoder.increment_min_representatives(tbn_problem, sat_problem) modified_num_reps = 0 # solve the problem again (SAT solver) while sat_problem.success: if celery_task is not None: if celery_task.is_aborted(): raise EarlyTerminationException(counter + 1, sat_problem.min_reps) celery_task.update_state(state="PROGRESS", meta={ 'status': "Progress", 'count': counter + 1, 'k': sat_problem.min_reps }) else: print("... Checking for k =", sat_problem.min_reps, "polymers") sat_problem.solve(True) if (sat_problem.success): modified_num_reps = sat_problem.min_reps Encoder.increment_min_representatives(tbn_problem, sat_problem) if modified_num_reps > 0: if celery_task is None: print("Found a constrained stable configuration with [", modified_num_reps, "] polymers.\n") print("Entropy is [", original_num_reps - modified_num_reps, "] away from stable configuration:\n") else: print("Unsatisfiable\n") break # Decode the problem into polymers polymers = Decoder.decode_boolean_values(tbn_problem, sat_problem) configs.append(polymers) if celery_task is None: for index, polymer in enumerate(polymers): print("\t" + "Polymer number", index + 1) for monomer in polymer.monomer_list: print("\t\t" + str(monomer)) print() # Encode a new unique solution Encoder.encode_unique_solution(tbn_problem, sat_problem) counter += 1 return configs
def test_constraints_encoder_monomer_free(self): sat_problem = SATProblem() Encoder.encode_basic_clause(self.tbn_problem, sat_problem) self.assertEqual(len(sat_problem.constraint_clauses), 8) for clause in sat_problem.constraint_clauses: self.assertEqual(len(clause), 1)