Beispiel #1
0
 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
Beispiel #2
0
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
Beispiel #3
0
 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
Beispiel #4
0
 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
Beispiel #5
0
 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
Beispiel #6
0
 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
Beispiel #8
0
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")
Beispiel #9
0
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
Beispiel #10
0
def create_new_fnode_for_num(num):
    content = FNodeContent(11, (), long(num))
    node = FNode(content, 100000 + num)
    return node
Beispiel #11
0
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
Beispiel #12
0
def equation_to_inequation(Formula):
    NewContent = FNodeContent(16, Formula.args(), None)
    NewFormula = FNode(NewContent, -1)
    return NewFormula
Beispiel #13
0
def less_than_to_less(Formula):
    NewContent = FNodeContent(17, Formula.args(), None)
    NewFormula = FNode(NewContent, -1)
    return NewFormula