def cpy_tree(self, root, subs, to_sub): if root == None: return None, [] elif root.is_symbol(): to_sub = [] res = FNode( FNodeContent( root._content.node_type, (), (root._content.payload[0], root._content.payload[1])), self.node_num) if root in subs: to_sub = [res] self.node_num += 1 return res, to_sub else: childrens = [] to_sub = [] for node in root._content.args: cpy, sub = self.cpy_tree(node, subs, []) childrens.append(cpy) to_sub.extend(sub) node_id = self.node_num self.node_num += 1 content = FNodeContent(root._content.node_type, tuple(childrens), [None]) res = FNode(content, node_id) return res, to_sub
def mul_nums_and_fnodes(nums, nodes): temp = [] for index, n in enumerate(nums): temp.append(mul_num_and_fnode(n, nodes[index])) content = FNodeContent(13, tuple(temp), None) result = FNode(content, 300000 + nums[0]) return result
def create_node(self, node_type, args, payload=None): content = FNodeContent(node_type, args, payload) if content in self.formulae: return self.formulae[content] else: n = FNode(content) self.formulae[content] = n self._do_type_check(n) return n
def create_node(self, node_type, args, payload=None): content = FNodeContent(node_type, args, payload, self.init_data()) if content in self.formulae: return self.formulae[content] else: n = FNode(content, self._next_free_id) self._next_free_id += 1 self.formulae[content] = n self._do_type_check(n) return n
def split_left_and_right(self, formula): L = list(formula.args()) formula_type = formula.node_type() if len(L) == 2: L.append(formula_type) else: length = len(L) c = FNodeContent(formula_type, tuple(L[1:]), None) newNode = FNode(c, -1) L = L[:1] L.append(newNode) L.append(formula_type) return L
def change_tree(self, root, sub, sub_dict): if root == None: return None elif root.is_symbol(): if root._node_id in sub_dict: if sub_dict[root._node_id] == 1: for key in sub: if key.symbol_name() == root.symbol_name(): return sub[key] return root else: childrens = [] for node in root._content.args: cpy = self.change_tree(node, sub, sub_dict) childrens.append(cpy) node_id = root._node_id content = FNodeContent(root._content.node_type, tuple(childrens), [None]) res = FNode(content, node_id) return res
def super_bad_function(): sb = FNode(FNodeContent(node_type=AND, args=(self.p, self.p), payload=None), -1) return sb
def test(): f = open("./benchmark/test4.smt2") Str = f.read() parser = SmtLibParser() script = parser.get_script(cStringIO(Str)) target_formula = script.get_last_formula() formulas_arith = list(target_formula.get_atoms()) equations = [] inequations = [] # split formulas into equations and inequations. for x in formulas_arith: if is_equation(x): equations.append(x.simplify()) else: inequations.append(x.simplify()) print0(equations, inequations) # find all let sentences (it seems that all the lets have been substituted by original terms) # lets = script.filter_by_command_name("let") # if len(lets) == 0: # print("no lets") # else: # print("lets") # for l in lets: # print(l) #From now on, start step 2. #Construct a new question according to left inequations. new_question = reduce(And, inequations) if not is_sat(new_question): print("Unsat") analyse_unsat(new_question) return False else: #turn all <= into < new_formulas = [] for x in inequations: new_formulas.append(less_than_to_less(x)) print("*" * 25, "new_formulas", "*" * 25) print(new_formulas) #Construct a new question according to left inequations(new). new_questionLQ = reduce(And, new_formulas) if is_sat(new_questionLQ): #call spass and return pass else: unsat_core = analyse_unsat(new_questionLQ) for x in unsat_core: equations.append(inequation_to_equation(x).simplify()) inequations.remove(find_same_formula(inequations, x)) print0(equations, inequations) #From now on, start step 3 if equations != []: for e in equations: e.simplify() variable_list = list(find_all_variables(equations)) equations_coefficient = extract_coefficient_in_formulas( equations, variable_list) print("variable list is:\n %s" % (variable_list)) print("coefficient matrix is:\n%s" % (equations_coefficient)) # start smithify. coefficient_matrix = smith_nf.Matrix(equations_coefficient) right_matrix = extract_right_side_of_formulas(equations) print(type(coefficient_matrix.matrix[:][0])) coefficient_matrix.smithify() print("smith normal form is:\n%s" % (coefficient_matrix.matrix)) print("matrix U is\n%s" % (coefficient_matrix.U)) print("matrix V is\n%s" % (coefficient_matrix.V)) print("right side is:\n%s" % (right_matrix)) U_mul_right = np.dot(coefficient_matrix.U, right_matrix) print("U * right =\n%s" % (U_mul_right)) # if the rank of the smithify matrix is n, then we just want first n elements of the u_mul_tight. trancate_index = np.linalg.matrix_rank(coefficient_matrix.matrix) U_mul_right_m = U_mul_right[:][:trancate_index] print("After truncation, U * right = \n%s" % (U_mul_right_m)) variable_num = len(variable_list) new_variables_list = [] for i in range(len(coefficient_matrix.V[0]) - trancate_index): new_variables_list.append(create_new_variable(i)) transform_equations_dict = {} for i in range(len(coefficient_matrix.V)): temp0 = np.dot(coefficient_matrix.V[i][:trancate_index], U_mul_right_m) temp0_node = create_new_fnode_for_num(temp0) nums_list = coefficient_matrix.V[i][trancate_index:] temp1 = mul_nums_and_fnodes(nums_list, new_variables_list) #print("temp1 is: %s" % (temp1)) content = FNodeContent(13, (temp0_node, temp1), None) temp2 = FNode(content, 400000 + i) #print("temp2 is: %s" % (temp2.simplify())) transform_equations_dict[variable_list[i]] = temp2.simplify() print("the transform dictionary is:\n%s" % (transform_equations_dict)) print(transform_equations_dict[variable_list[0]]) print("new variables list is:") print(new_variables_list) #return transform_equations_dict #print(transform_equations_dict[variable_list[0].serialize()]) else: # if there is no equation, solve the question by spass pass #From now on ,start step 4. new_inequations = [] for f in inequations: new_inequations.append( f.substitute(transform_equations_dict).simplify()) print("new inequations is:\n%s" % (new_inequations)) #print(new_inequations[0].args()[0]) #From now on, start step 5. #Transform equations are stored in a dictionary called transform_equations_dict, and applying this transform, we turn inequations into new_inequations. #In step 6, we need to construct a new script variable for this question, and return the transform dictionary and the new question. #Also, we need to declare the new variable in script new_parser = SmtLibParser() new_script = new_parser.get_script(cStringIO(Str)) new_assert_command = SmtLibCommand(smtcmd.ASSERT, [And(new_inequations)]) #print("new command is:") #print(type(new_command.args)) for index, cmd in enumerate(script.commands): if cmd.name == smtcmd.ASSERT: new_script.commands[index] = new_assert_command if cmd.name == smtcmd.DECLARE_FUN: last_declare_fun = index for i in range(0, len(new_variables_list)): temp_new_declare_command = SmtLibCommand(smtcmd.DECLARE_FUN, [new_variables_list[i]]) new_script.commands.insert(last_declare_fun + i + 1, temp_new_declare_command) print("new script's content is:") print(new_script.commands) new_script.to_file("./benchmark/new_test4.smt2")
def mul_num_and_fnode(num, node): node0 = create_new_fnode_for_num(num) content = FNodeContent(15, (node0, node), None) result = FNode(content, 200000 + num) return result
def create_new_fnode_for_num(num): content = FNodeContent(11, (), long(num)) node = FNode(content, 100000 + num) return node
def create_new_variable(variable_index): variable_name = "new_variable" + str(variable_index) content = FNodeContent(SYMBOL, (), (variable_name, INT)) node = FNode(content, 10000 + variable_index) return node
def equation_to_inequation(Formula): NewContent = FNodeContent(16, Formula.args(), None) NewFormula = FNode(NewContent, -1) return NewFormula
def less_than_to_less(Formula): NewContent = FNodeContent(17, Formula.args(), None) NewFormula = FNode(NewContent, -1) return NewFormula