def proccess_sat_file(filename, sat, solver): start_time = time.time() result = "{} || solver {} ".format(filename, solver) formula = CNF(from_file="./InstanciasSAT/" + filename) clauses = formula.clauses[:] nv = formula.nv original_time = time.time() original_solution = solve_clauses(clauses, solver) result += "|| original: {} || Tiempo: {:.10f} segundos ".format(original_solution, time.time() - original_time) clauses, nv = sat_to_3_sat(clauses, nv) if sat > 3: x_sat = 3 while x_sat < sat: clauses, nv = reduce_to_x_sat(clauses, nv) x_sat += 1 x_sat_time = time.time() x_sat_solution = solve_clauses(clauses, solver) result += "|| {}-SAT: {} || Tiempo: {:.10f} segundos ".format(sat, x_sat_solution, time.time() - x_sat_time) formula.clauses = clauses formula.nv = nv formula.to_file("./X-SAT/" + filename) result += "|| Tiempo total: {:.10f} segundos".format(time.time() - start_time) print(result)
def test_unigen_generate_dataset_small_formula(self): cnf_file = '/tmp/test_small.cnf' f = CNF(from_clauses=[[1, 2, 3], [4]]) ''' the formula above has 7 positive samples: positives = { (1, 2, 3, 4), (1, 2, -3, 4), (1, -2, 3, 4), (1, -2, -3, 4), (-1, 2, 3, 4), (-1, 2, -3, 4), (-1, -2, 3, 4), } ''' f.to_file(cnf_file) sampler = mlbf.positives.UnigenSampler() # a formula with very few solutions will return an empty dataset data = sampler.sample(cnf_file, 50) self.assertEqual(0, len(data)) # deletes the temp file used to store the formula os.unlink(cnf_file)
class MockupCall: """ Fakes a subprocess.call routine """ def __init__(self): pass def set_desired_formula(self, clauses, output_file): self.formula = CNF(from_clauses=clauses) self.output_file = output_file def call(self, *args): """ Writes the pre-set formula to the pre-set output file :return: """ self.formula.to_file(self.output_file)
def consistencyCheck(AC, solver, difficulty): if solver == "Sat4j": f = tempfile.NamedTemporaryFile() cnf = CNF() for clause in AC: #AC es conjunto de conjuntos # print(clause[1]) cnf.append(clause[1]) #añadimos la constraint cnf.to_file(f.name) starttime = time.time() out = os.popen("java -jar org.sat4j.core.jar " + f.name).read() f.close() reqtime = time.time() - starttime time.sleep(reqtime * difficulty) if "UNSATISFIABLE" in out: # print("===> AC: " + str(AC) + " - False") return False else: # print("===> AC: " + str(AC) + " - True") return True elif solver == "Glucose3": g = Glucose3() for clause in AC: #AC es conjunto de conjuntos g.add_clause(clause[1]) #añadimos la constraint starttime = time.time() sol = g.solve() reqtime = time.time() - starttime time.sleep(reqtime * difficulty) return sol elif solver == "Choco4": f = tempfile.NamedTemporaryFile() cnf = CNF() for clause in AC: #AC es conjunto de conjuntos cnf.append(clause[1]) #añadimos la constraint cnf.to_file(f.name) starttime = time.time() out = os.popen("java -jar choco4solver.jar " + f.name).read() f.close() reqtime = time.time() - starttime time.sleep(reqtime * difficulty) if "UNSATISFIABLE" in out: return False else: return True else: raise ValueError("Solver not defined")
def test_negative_simple(self): cnf_file = '/tmp/simple_negative.cnf' f = CNF(from_clauses=[[-1, 2], [3]]) expected_negatives = { # set of tuples, contains all unsat assignments for the formula (1, -2, 3), (-1, -2, -3), (-1, 2, -3), (1, -2, -3), (1, 2, -3) } f.to_file(cnf_file) negatives = mlbf.negatives.uniformly_negative_samples( cnf_file, 5) # 5 is the max number of negatives self.assertEqual(5, len(negatives)) # checks if all negatives are unique: transform into set and see if the length did not reduce neg_set = set(tuple(neg) for neg in negatives) self.assertEqual(5, len(neg_set)) # checks if the returned set of negatives is correct self.assertEqual(expected_negatives, neg_set) os.unlink(cnf_file)
def read_cnf_and_reduce(x): ACTUAL_DIRECTORY = getcwd() # Get the current directory path (../SAT/Reductor) PARENT_DIRECTORY = sep.join(ACTUAL_DIRECTORY.split(sep)[1:-1]) # Get the parent directory (../SAT) PARENT_DIRECTORY = join(sep, PARENT_DIRECTORY) # Apeend SO separator to access the folder SAT_instances_directory = join(PARENT_DIRECTORY, "InstanciasSAT") # Joins the parent directory with InstanciasSAT to get into (../SAT/instanciasSAT) X_SAT_directory = join(PARENT_DIRECTORY, "X-SAT") # Joins the parent directory with InstanciasSAT to get into (../SAT/X-SAT) _, _, SAT_instances = next(walk(SAT_instances_directory)) print("REDUCIENDO INSTANCIAS A %s-SAT . . ." % x) for SAT_instance in SAT_instances: with open(join(SAT_instances_directory, SAT_instance), 'r') as fp: sat_instance = CNF(from_fp=fp) # Leemos el archivo .cnf para obtener el problema en un formato manejable sat_instance_reduced = CNF() # Creamos una instancia de la clase CNF donde se almacenaran las clausulas reducidas sat_instance_reduced = reduce(x, sat_instance) # Llamamos a la funcion "reduce", la cual reduce la instancia que le pasemos sat_instance_reduced.to_file(join(X_SAT_directory, SAT_instance[:-4] + '_reduced.cnf')) # Escribimos un nuevo archivo .cnf con la instancia reducida print("INSTANCIAS REDUCIDAS A %s-SAT." % x)
def test_negative_max_attempts(self): cnf_file = '/tmp/test_max_attempts.cnf' f = CNF(from_clauses=[[-1, 2], [3]]) expected_negatives = { # set of tuples, contains all unsat assignments for the formula (1, -2, 3), (-1, -2, -3), (-1, 2, -3), (1, -2, -3), (1, 2, -3) } f.to_file(cnf_file) # 5 is the max number of negatives, with 20 it will reach max attempts negatives = mlbf.negatives.uniformly_negative_samples( cnf_file, 20, max_attempts=200000) self.assertEqual(5, len(negatives)) # checks if all negatives are unique: transform into set and see if the length did not reduce neg_set = set(tuple(neg) for neg in negatives) self.assertEqual(5, len(neg_set)) # checks if the returned set of negatives is correct self.assertEqual(expected_negatives, neg_set) # removes the temporary file os.unlink(cnf_file)
def sat_to_dimacs_format(SATANSWERS): sat_answers = SATANSWERS nombre = "sat_dimacs_format_" answers_dimacs = [] sat_cnf = CNF() ACTUAL_DIRECTORY = getcwd( ) # Get the current directory path (../SAT/Reductor) PARENT_DIRECTORY = sep.join( ACTUAL_DIRECTORY.split(sep)[1:-1]) # Get the parent directory (../SAT) PARENT_DIRECTORY = join( sep, PARENT_DIRECTORY) # Apeend SO separator to access the folder X_SAT_directory = join(PARENT_DIRECTORY, "X-SAT") for index, answer in enumerate(SATANSWERS): num_archivo = str(index) nombre_res = nombre + num_archivo answer.pop(-1) for clause in answer: for index, variable in enumerate(clause): clause[index] = int(variable) sat_cnf.append(clause) sat_cnf.to_file(join(X_SAT_directory, nombre_res + ".cnf")) sat_cnf = CNF() return answers_dimacs
def save_to(self, outfile): """ Save the encoding into a file with a given name. """ if outfile.endswith('.txt'): outfile = outfile[:-3] + 'cnf' formula = CNF() # comments formula.comments = [ 'c features: {0}'.format(', '.join(self.feats)), 'c classes: {0}'.format(self.nofcl) ] for clid in self.enc: formula.comments += [ 'c clid starts: {0} {1}'.format(clid, len(formula.clauses)) ] for leaf in self.enc[clid].leaves: formula.comments += ['c leaf: {0} {1} {2}'.format(clid, *leaf)] formula.clauses.extend(self.enc[clid].formula.clauses) for f in self.xgb.extended_feature_names_as_array_strings: if f in self.intvs: c = 'c i {0}: '.format(f) c += ', '.join([ '"{0}" <-> "{1}"'.format(u, v) for u, v in zip(self.intvs[f], self.ivars[f]) ]) else: c = 'c i {0}: none'.format(f) formula.comments.append(c) formula.to_file(outfile)
def cnf(username, password, N, show_all): # Function to create clauses def atLeastOneQueen(propositions, cnf): # A11 V A12 V ... V A1N # Add clauses to the CNF object cnf.append(propositions) def atMostOneQueen(propositions, cnf): # -A11 V -A12 # -Aij V -Aik for every j<k for k in range(len(propositions)): for j in range(k): temp = [] temp.append(-propositions[j]) temp.append(-propositions[k]) # Add clauses to the CNF object cnf.append(temp) # Get the size of the board # N = input() N = int(N) # Created an object of class CNF cnf = CNF() # Initial variable solutions = [] board = [[(j + (i * N) + 1) for j in range(N)] for i in range(N)] # Every Row and Column for i in range(N): propositions_row = [] propositions_col = [] for j in range(N): propositions_row.append(board[i][j]) propositions_col.append(board[j][i]) # At least one queen on every row atLeastOneQueen(propositions_row, cnf) # At least one queen on every column atMostOneQueen(propositions_row, cnf) # At least one queen on every column atLeastOneQueen(propositions_col, cnf) # At most one queen on every column atMostOneQueen(propositions_col, cnf) # Every Diagonal for i in [0, N - 1]: for j in range(N): propositions1 = [] propositions2 = [] for i_ in range(N): for j_ in range(N): if i == N - 1 and j == 0: pass elif i == N - 1 and j == N - 1: pass else: if i == i_ and j == j_: propositions1.append(board[i_][j_]) propositions2.append(board[i_][j_]) elif i - j == i_ - j_: propositions1.append(board[i_][j_]) elif i + j == i_ + j_: propositions2.append(board[i_][j_]) # At most one queen on every diagonal in the first direction \ atMostOneQueen(propositions1, cnf) # At most one queen on every diagonal in the second direction / atMostOneQueen(propositions2, cnf) # Connect to the SSH client client = paramiko.SSHClient() # add to known hosts client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) connect = 1 while (connect): try: client.connect(hostname="willow.cs.ttu.edu", username=username, password=password, banner_timeout=2000) ftp_client = client.open_sftp() connect = 0 except: print("[1] Cannot connect to the SSH Server") # Close connection client.close() connect = connect + 5 time.sleep(connect) # Find all posible solutions while (True): while (connect): try: client.connect(hostname="willow.cs.ttu.edu", username=username, password=password, banner_timeout=2000) ftp_client = client.open_sftp() connect = 0 except: print("[2] Cannot connect to the SSH Server") # Close connection client.close() connect = connect + 5 time.sleep(connect) try: # Write CNF file cnf.to_file('input.cnf') path = str(pathlib.Path().absolute()) + '/input.cnf' ftp_client.put(path, 'input.cnf') # Read output.txt file stdin, stdout, stderr = client.exec_command( "./MiniSat_v1.14_linux input.cnf output.txt") # stdout.read().decode() err = stderr.read().decode() if err: print(err) ftp_client.get('output.txt', 'output.txt') f = open('output.txt', 'r') if f.readline() == "SAT\n": line = f.readline() while line: line = line.rstrip() # strip trailing spaces and newline # process the line t = line.split() clause = [] neg_clause = [] for i in t: if int(i) == 0: break clause.append(int(i)) neg_clause.append(-int(i)) solutions.append(clause) cnf.append(neg_clause) line = f.readline() f.close() else: f.close() break if show_all == False: break except: print("[3] Connect Error") # Close connection ftp_client.close() client.close() connect = connect + 5 # Close connection ftp_client.close() client.close() # Print solutions print(len(solutions)) # clear file if os.path.exists("input.cnf"): os.remove("input.cnf") else: print("The input.cnf file does not exist.") if os.path.exists("output.txt"): os.remove("output.txt") else: print("The output.txt file does not exist.") # Return solutions return (solutions)
def test_unigen_generate_dataset(self): cnf_file = '/tmp/test.cnf' f = CNF(from_clauses=[[1, 2, 3, 4], [5, 6]]) # the formula above has 45 positive & 19 negative samples # positives enumerated below (with Glucose3) positives = {(1, -2, -3, -4, 5, -6), (1, 2, -3, -4, 5, -6), (1, 2, 3, -4, 5, -6), (1, 2, 3, 4, 5, -6), (1, 2, 3, 4, 5, 6), (-1, 2, 3, 4, 5, 6), (-1, -2, 3, 4, 5, 6), (-1, -2, -3, 4, 5, 6), (-1, -2, 3, -4, 5, 6), (-1, -2, 3, -4, -5, 6), (-1, -2, 3, -4, 5, -6), (1, -2, 3, -4, 5, -6), (-1, 2, 3, -4, 5, -6), (-1, 2, -3, -4, 5, -6), (-1, 2, -3, 4, 5, -6), (-1, 2, -3, 4, 5, 6), (-1, 2, -3, -4, 5, 6), (1, 2, -3, -4, 5, 6), (1, -2, -3, -4, 5, 6), (1, -2, 3, -4, 5, 6), (1, -2, 3, -4, -5, 6), (1, -2, 3, 4, 5, 6), (1, -2, 3, 4, -5, 6), (1, -2, -3, 4, 5, 6), (1, -2, -3, 4, -5, 6), (1, -2, -3, -4, -5, 6), (1, 2, -3, -4, -5, 6), (1, 2, 3, -4, 5, 6), (1, 2, 3, -4, -5, 6), (1, 2, 3, 4, -5, 6), (1, 2, -3, 4, 5, 6), (1, 2, -3, 4, -5, 6), (-1, 2, -3, 4, -5, 6), (-1, 2, -3, -4, -5, 6), (-1, 2, 3, -4, 5, 6), (-1, 2, 3, -4, -5, 6), (-1, 2, 3, 4, -5, 6), (-1, -2, 3, 4, -5, 6), (-1, -2, -3, 4, -5, 6), (1, 2, -3, 4, 5, -6), (1, -2, -3, 4, 5, -6), (-1, -2, -3, 4, 5, -6), (-1, -2, 3, 4, 5, -6), (-1, 2, 3, 4, 5, -6), (1, -2, 3, 4, 5, -6)} # negatives enumerated below (by hand) negatives = { (-1, -2, -3, -4, -5, -6), # negate first clause (-1, -2, -3, -4, -5, 6), (-1, -2, -3, -4, 5, -6), (-1, -2, -3, -4, 5, 6), (-1, -2, -3, 4, -5, -6), # negate 2nd clause, 4th lit up (-1, -2, 3, -4, -5, -6), # negate 2nd clause, 3rd lit up (-1, -2, 3, 4, -5, -6), # ... (-1, 2, -3, -4, -5, -6), # negate 2nd clause, 2nd lit up (-1, 2, -3, 4, -5, -6), # ... (-1, 2, 3, -4, -5, -6), # ... (-1, 2, 3, 4, -5, -6), # ... (1, -2, -3, -4, -5, -6), (1, -2, -3, 4, -5, -6), # negate 2nd clause, 1st lit up (1, -2, 3, -4, -5, -6), (1, -2, 3, 4, -5, -6), (1, 2, -3, -4, -5, -6), (1, 2, -3, 4, -5, -6), (1, 2, 3, -4, -5, -6), (1, 2, 3, 4, -5, -6), } f.to_file(cnf_file) sampler = mlbf.positives.UnigenSampler() sampled_positives = sampler.sample(cnf_file, 500) sampled_negatives = mlbf.negatives.uniformly_negative_samples( cnf_file, 500) data_x, data_y = dataset.get_xy_data( dataset.prepare_dataset(sampled_positives, sampled_negatives)) # I expect the dataset to contain all 64 possible assignments self.assertEqual(64, len(data_x)) self.assertEqual(64, len(data_y)) # create a new dataset with data_x and y appended column-wise df = data_x.copy() df['y'] = data_y # convert expected to 0/1 instead of n/-n binary_pos = { # +[1] because each one is a positive example tuple([0 if lit < 0 else 1 for lit in assignment] + [1]) for assignment in positives } binary_neg = { # +[0] because each one is a positive example tuple([0 if lit < 0 else 1 for lit in assignment] + [0]) for assignment in negatives } # creates a set out of the dataset and compare it with the expected one dataset_set = set([tuple(row) for row in df.values]) self.assertEqual(binary_pos.union(binary_neg), dataset_set) # deletes the temp file used to store the formula os.unlink(cnf_file)
k=int(len(S)/2) S1=S[0:k] S2=S[k:len(S)] A1=diag(S2,S1,Diff(AC,S2)) A2=diag(A1,S2,Diff(AC,A1)) return A1 + A2 def Diff(li1, li2): li_dif = [i for i in li1 + li2 if i not in li1 or i not in li2] return li_dif #model=sys.argv[1] #requirements=sys.argv[2] #outFile=sys.argv[3] #model="./cnf/aircraft_fm.xml.cnf" #requirements="./cnf/aircraft_fm.xml.cnf_conf/1" requirements="../QX-Benchmark/cnf/betty/5000_30_0/16-50-4.prod" model="../QX-Benchmark/cnf/betty/5000_30_0.cnf" outFile="./out.txt" modelCNF = CNF(from_file=model) requirementsCNF = CNF(from_file=requirements) result= fmdiag(requirementsCNF.clauses, modelCNF.clauses + requirementsCNF.clauses) resCNF= CNF() for c in result: resCNF.append(c) resCNF.to_file(outFile) print(count)