示例#1
0
文件: coi.py 项目: yuex1994/CoSA
    def _build_var_deps(self, hts):

        if self.var_deps is not None:
            return

        self.var_deps = {}

        ftrans = hts.single_ftrans()
        for var, cond_assign_list in ftrans.items():
            for refvar in self._free_variables(var):
                if refvar not in self.var_deps:
                    self.var_deps[refvar] = []

                for cass in cond_assign_list:
                    self.var_deps[refvar] += list(self._free_variables(
                        cass[0]))
                    self.var_deps[refvar] += list(self._free_variables(
                        cass[1]))

        trans = list(
            conjunctive_partition(hts.single_trans(include_ftrans=False)))
        invar = list(
            conjunctive_partition(hts.single_invar(include_ftrans=False)))
        init = list(conjunctive_partition(hts.single_init()))

        for ts_formula in [invar, trans, init]:
            for f in ts_formula:
                fv = self._free_variables(f)
                for v in fv:
                    if v not in self.var_deps:
                        self.var_deps[v] = []
                    self.var_deps[v] += list(fv)
                    self.var_deps[v] = [
                        x for x in set(self.var_deps[v]) if x != v
                    ]
示例#2
0
def analyse_unsat(Formulas):
    conj = conjunctive_partition(Formulas)
    ucore = get_unsat_core(conj)
    print("Unsat core:")
    for f in ucore:
        print(f.serialize())
    return ucore
示例#3
0
    def _add_assertion(self, solver, formula, comment=None):
        if not self.config.skip_solving:
            solver.solver.add_assertion(formula)

        if Logger.level(3):
            buf = cStringIO()
            printer = SmtPrinter(buf)
            printer.printer(formula)
            print(buf.getvalue() + "\n")

        if solver.trace_file is not None:
            if comment:
                self._write_smt2_comment(solver, "%s: START" % comment)

            formula_fv = get_free_variables(formula)

            for v in formula_fv:
                if v in solver.smt2vars:
                    continue

                if v.symbol_type() == BOOL:
                    self._write_smt2_log(
                        solver, "(declare-fun %s () Bool)" % (v.symbol_name()))
                elif v.symbol_type().is_array_type():
                    st = v.symbol_type()
                    assert st.index_type.is_bv_type(), "Expecting BV indices"
                    assert st.elem_type.is_bv_type(), "Expecting BV elements"
                    self._write_smt2_log(
                        solver,
                        "(declare-fun %s () (Array (_ BitVec %s) (_ BitVec %s)))"
                        % (v.symbol_name(), st.index_type.width,
                           st.elem_type.width))
                elif v.symbol_type().is_bv_type():
                    self._write_smt2_log(
                        solver, "(declare-fun %s () (_ BitVec %s))" %
                        (v.symbol_name(), v.symbol_type().width))
                else:
                    Logger.error("Unhandled type in smt2 translation")

            self._write_smt2_log(solver, "")

            for v in formula_fv:
                solver.smt2vars.add(v)

            if formula.is_and():
                for f in conjunctive_partition(formula):
                    buf = cStringIO()
                    printer = SmtPrinter(buf)
                    printer.printer(f)
                    self._write_smt2_log(solver,
                                         "(assert %s)" % buf.getvalue())
            else:
                buf = cStringIO()
                printer = SmtPrinter(buf)
                printer.printer(formula)
                self._write_smt2_log(solver, "(assert %s)" % buf.getvalue())

            if comment:
                self._write_smt2_comment(solver, "%s: END" % comment)
示例#4
0
 def test_conj_partitioning(self):
     for (f, _, _, logic) in get_example_formulae():
         if get_env().factory.has_solvers(logic=logic):
             conjuncts = list(conjunctive_partition(f))
             try:
                 ok = is_valid(Iff(f, And(conjuncts)), logic=logic)
             except SolverReturnedUnknownResultError:
                 ok = not logic.quantifier_free
             self.assertTrue(ok)
示例#5
0
 def test_conj_partitioning(self):
     for (f, _, _, logic) in get_example_formulae():
         if self.env.factory.has_solvers(logic=logic):
             conjuncts = list(conjunctive_partition(f))
             try:
                 ok = is_valid(Iff(f, And(conjuncts)), logic=logic)
             except SolverReturnedUnknownResultError:
                 ok = not logic.quantifier_free
             self.assertTrue(ok)
示例#6
0
    def unsat_core(self):

        res = self.solver.solve()

        if not res:
            print('Assertions:', self.fml)
            conj = conjunctive_partition(self.fml)
            ucore = get_unsat_core(conj)
            print("UNSAT-Core size '%d'" % len(ucore))
        for f in ucore:
            print(f.serialize())
示例#7
0
def get_model_or_print_ucore(formula):
    m = s.get_model(formula)
    if not m:
        print('unsat')
        from pysmt.rewritings import conjunctive_partition
        conj = conjunctive_partition(s.And(formula))
        ucore = s.get_unsat_core(conj)
        print("UNSAT-Core size '%d'" % len(ucore))
        for f in ucore:
            print(f.serialize())
        return
    return m
示例#8
0
    def __print_single_ts(self, ts):

        has_comment = len(ts.comment) > 0

        if has_comment:
            lenstr = len(ts.comment) + 3

            self.write("\n%s\n" % ("-" * lenstr))
            self.write("# %s\n" % ts.comment)
            self.write("%s\n" % ("-" * lenstr))

        sections = [("VAR", [x for x in ts.vars if x not in list(ts.state_vars)+list(ts.input_vars)+list(ts.output_vars)]),\
                    ("STATE", ts.state_vars),\
                    ("INPUT", ts.input_vars),\
                    ("OUTPUT", ts.output_vars)]

        for (sname, vars) in sections:
            if len(vars) > 0: self.write("%s\n" % sname)
            for var in vars:
                sname = self.names(var.symbol_name())
                if var.symbol_type() == BOOL:
                    self.write("%s : Bool;\n" % (sname))
                else:
                    self.write("%s : BV(%s);\n" %
                               (sname, var.symbol_type().width))
            self.write("\n")

        sections = [((ts.init), "INIT"), ((ts.invar), "INVAR"),
                    ((ts.trans), "TRANS")]

        for (formula, keyword) in sections:
            if formula not in [TRUE(), FALSE()]:
                self.write("%s\n" % keyword)
                cp = list(conjunctive_partition(formula))
                if self.simplify:
                    cp = self._simplify_cp(cp)

                for i in range(len(cp)):
                    f = simplify(cp[i])
                    if f == TRUE():
                        continue
                    self.printer(f)
                    self.write(";\n")
                    if f == FALSE():
                        break
                self.write("\n")

        if has_comment:
            self.write("\n%s\n" % ("-" * lenstr))
示例#9
0
    def _simplify_cp(self, cp):
        random.shuffle(cp)
        newcp = []
        last = False
        step = 3
        for i in range(0, len(cp) - (step - 1), step):
            if i == len(cp) - step:
                last = True
            formula = simplify(And([cp[i + j] for j in range(step)]))
            newcp += list(conjunctive_partition(formula))

        if not last:
            for i in range(-1, -step, -1):
                newcp.append(cp[i])
        return newcp
示例#10
0
    def __print_single_hts(self, hts, printed_vars):

        has_comment = len(hts.comment) > 0

        if has_comment:
            lenstr = len(hts.comment) + 3

            self.write("\n%s\n" % ("-" * lenstr))
            self.write("-- %s\n" % hts.comment)
            self.write("%s\n" % ("-" * lenstr))

        locvars = [v for v in hts.vars if v not in printed_vars]

        for v in hts.vars:
            printed_vars.add(v)

        if locvars: self.write("\nVAR\n")
        for var in locvars:
            sname = self.names(var.symbol_name())
            if var.symbol_type() == BOOL:
                self.write("%s : boolean;\n" % (sname))
            else:
                self.write("%s : word[%s];\n" %
                           (sname, var.symbol_type().width))

        sections = [((hts.init), "INIT"), ((hts.invar), "INVAR"),
                    ((hts.trans), "TRANS")]

        for (formula, keyword) in sections:
            if formula not in [TRUE(), FALSE()]:
                self.write("\n%s\n" % keyword)
                cp = list(conjunctive_partition(formula))
                for i in range(len(cp)):
                    f = simplify(cp[i])
                    self.printer(f)
                    if i < len(cp) - 1:
                        self.write(" &\n")
                self.write(";\n")

        if has_comment:
            self.write("\n%s\n" % ("-" * lenstr))

        return printed_vars
示例#11
0
    def __print_single_ts(self, ts, printed_vars):

        has_comment = len(ts.comment) > 0

        if has_comment:
            lenstr = len(ts.comment) + 3

            self.write("\n%s\n" % ("-" * lenstr))
            self.write("-- %s\n" % ts.comment)
            self.write("%s\n" % ("-" * lenstr))

        locvars = [v for v in ts.vars if v not in printed_vars]

        for v in ts.vars:
            printed_vars.add(v)

        if locvars: self.write("\nVAR\n")
        for var in locvars:
            self.write("{} : {};\n".format(var.symbol_name(),
                                           to_smv_type(var.get_type())))

        sections = [((ts.init), "INIT"), ((ts.invar), "INVAR"),
                    ((ts.trans), "TRANS")]

        for (formula, keyword) in sections:
            if formula not in [TRUE(), FALSE()]:
                self.write("\n%s\n" % keyword)
                cp = list(conjunctive_partition(formula))
                for i in range(len(cp)):
                    f = simplify(cp[i])
                    self.printer(f)
                    if i < len(cp) - 1:
                        self.write(" &\n")
                self.write(";\n")

        if has_comment:
            self.write("\n%s\n" % ("-" * lenstr))

        return printed_vars
示例#12
0
    print("UNSAT")
    # We first check whether the constraints on the domain and problem
    # are satisfiable in isolation.
    assert is_sat(facts)
    assert is_sat(domain)
    assert is_unsat(problem)

    # In isolation they are both fine, rules from both are probably
    # interacting.
    #
    # The problem is given by a nesting of And().
    # conjunctive_partition can be used to obtain a "flat"
    # structure, i.e., a list of conjuncts.
    #
    from pysmt.rewritings import conjunctive_partition
    conj = conjunctive_partition(problem)
    ucore = get_unsat_core(conj)
    print("UNSAT-Core size '%d'" % len(ucore))
    for f in ucore:
        print(f.serialize())

    # The exact version of the UNSAT-Core depends on the solver in
    # use.  Nevertheless, this represents a starting point for your
    # debugging.  A possible way to approach the result is to look for
    # clauses of size 1 (i.e., unit clauses). In the facts list there
    # are only 2 facts:
    #   2_drink_milk
    #   0_nat_norwegian
    #
    # The clause ("1_color_blue" <-> "0_nat_norwegian")
    # Implies that "1_color_blue"
示例#13
0
print("Generate model")
model = get_model(facts_domain, solver_name=args.solver)

#print model
if model is None:
    print("UNSAT")
    print("Please verify that the student fields are correct.")
    # In isolation they are both fine, rules from both are probably
    # interacting.
    #
    # The problem is given by a nesting of And().
    # conjunctive_partition can be used to obtain a "flat"
    # structure, i.e., a list of conjuncts.
    #
    from pysmt.rewritings import conjunctive_partition
    conj = conjunctive_partition(facts_domain)
    ucore = get_unsat_core(conj)
    print("UNSAT-Core size '%d'" % len(ucore))
    for f in ucore:
        print(f.serialize())
else:
    f1_classes = []
    s1_classes = []
    f2_classes = []
    s2_classes = []
    f3_classes = []
    s3_classes = []
    f4_classes = []
    s4_classes = []
    for x in model:
        if x[1]._content.payload == 1:
示例#14
0
    print("UNSAT")
    # We first check whether the constraints on the domain and problem
    # are satisfiable in isolation.
    assert is_sat(facts)
    assert is_sat(domain)
    assert is_unsat(problem)

    # In isolation they are both fine, rules from both are probably
    # interacting.
    #
    # The problem is given by a nesting of And().
    # conjunctive_partition can be used to obtain a "flat"
    # structure, i.e., a list of conjuncts.
    #
    from pysmt.rewritings import conjunctive_partition
    conj = conjunctive_partition(problem)
    ucore = get_unsat_core(conj)
    print("UNSAT-Core size '%d'" % len(ucore))
    for f in ucore:
        print(f.serialize())

    # The exact version of the UNSAT-Core depends on the solver in
    # use.  Nevertheless, this represents a starting point for your
    # debugging.  A possible way to approach the result is to look for
    # clauses of size 1 (i.e., unit clauses). In the facts list there
    # are only 2 facts:
    #   2_drink_milk
    #   0_nat_norwegian
    #
    # The clause ("1_color_blue" <-> "0_nat_norwegian")
    # Implies that "1_color_blue"
示例#15
0
文件: coi.py 项目: yuex1994/CoSA
    def compute(self, hts, prop):
        Logger.log("Building COI", 1)

        self._build_var_deps(hts)

        coi_vars = set(self._free_variables(prop))

        if (len(coi_vars) < 1) or (self.var_deps == {}):
            return hts

        if hts.assumptions is not None:
            for assumption in hts.assumptions:
                for v in self._free_variables(assumption):
                    coi_vars.add(v)

        if hts.lemmas is not None:
            for lemma in hts.lemmas:
                for v in self._free_variables(lemma):
                    coi_vars.add(v)

        coits = TS("COI")

        coi_vars = list(coi_vars)
        i = 0
        visited = set([])
        while i < len(coi_vars):
            var = coi_vars[i]
            if (var in visited) or (var not in self.var_deps):
                i += 1
                continue

            coi_vars = coi_vars[:i + 1] + list(
                self.var_deps[var]) + coi_vars[i + 1:]

            visited.add(var)
            i += 1

        coi_vars = frozenset(coi_vars)

        trans = list(
            conjunctive_partition(hts.single_trans(include_ftrans=True)))
        invar = list(
            conjunctive_partition(hts.single_invar(include_ftrans=True)))
        init = list(conjunctive_partition(hts.single_init()))

        coits.trans = [
            f for f in trans
            if self._intersect(coi_vars, self._free_variables(f))
        ]
        coits.invar = [
            f for f in invar
            if self._intersect(coi_vars, self._free_variables(f))
        ]
        coits.init = [
            f for f in init
            if self._intersect(coi_vars, self._free_variables(f))
        ]

        Logger.log("COI statistics:", 1)
        Logger.log("  Vars:  %s -> %s" % (len(hts.vars), len(coi_vars)), 1)
        Logger.log("  Init:  %s -> %s" % (len(init), len(coits.init)), 1)
        Logger.log("  Invar: %s -> %s" % (len(invar), len(coits.invar)), 1)
        Logger.log("  Trans: %s -> %s" % (len(trans), len(coits.trans)), 1)

        coits.trans = And(coits.trans)
        coits.invar = And(coits.invar)
        coits.init = And(coits.init)

        coits.vars = set([])
        for bf in [init, invar, trans]:
            for f in bf:
                for v in self._free_variables(f):
                    coits.vars.add(v)

        coits.input_vars = set([v for v in coi_vars if v in hts.input_vars])
        coits.output_vars = set([v for v in coi_vars if v in hts.output_vars])
        coits.state_vars = set([v for v in coi_vars if v in hts.state_vars])

        new_hts = HTS("COI")
        new_hts.add_ts(coits)

        if self.save_model:
            printer = HTSPrintersFactory.printer_by_name("STS")
            with open("/tmp/coi_model.ssts", "w") as f:
                f.write(printer.print_hts(new_hts, []))

        return new_hts
示例#16
0
    def __print_single_ts(self, ts, ftrans=False):

        has_comment = len(ts.comment) > 0
        
        if has_comment:
            lenstr = len(ts.comment)+3

            self.write("\n%s\n"%("-"*lenstr))
            self.write("# %s\n"%ts.comment)
            self.write("%s\n"%("-"*lenstr))

        sections = [("INPUT", ts.input_vars),\
                    ("OUTPUT", ts.output_vars),\
                    ("STATE", ts.state_vars),\
                    ("VAR", [x for x in ts.vars if x not in list(ts.state_vars)+list(ts.input_vars)+list(ts.output_vars)])]

        for (sname, vars) in sections:
            if len(vars) > 0: self.write("%s\n"%sname)
            varsort = sort_system_variables(vars)
            for var in varsort:
                sname = self.names(var.symbol_name())
                if var.symbol_type() == BOOL:
                    self.write("%s : Bool;\n"%(sname))
                else:
                    self.write("%s : BV(%s);\n"%(sname, var.symbol_type().width))
            self.write("\n")

        sections = [((ts.init),"INIT"), ((ts.invar),"INVAR"), ((ts.trans),"TRANS")]

        for (formula, keyword) in sections:
            if formula not in [TRUE(), FALSE()]:
                self.write("%s\n"%keyword)
                cp = list(conjunctive_partition(formula))
                if self.simplify:
                    cp = self._simplify_cp(cp)

                cp = [x for x in cp if x.is_equals()]+[x for x in cp if not x.is_equals()]
                for i in range(len(cp)):
                    f = cp[i]
                    if self.simplify:
                        f = simplify(f)
                    if f == TRUE():
                        continue
                    self.printer(f)
                    self.write(";\n")
                    if f == FALSE():
                        break
                self.write("\n")

        if ftrans:
            if ts.ftrans is not None:
                self.write("FUNC\n")
                for var, var_ass in ts.ftrans.items():
                    self.printer(var)
                    self.write(" :=")
                    for cond, value in var_ass:
                        self.write(" {")
                        self.printer(cond)
                        self.write(", ")
                        self.printer(value)
                        self.write("}")
                    self.write(";\n")
                
        if has_comment:
            self.write("\n%s\n"%("-"*lenstr))
示例#17
0
    def parametric_safety(self,
                          prop,
                          k_max,
                          k_min,
                          parameters,
                          monotonic=True,
                          at_most=-1):
        if len(parameters) == 0:
            Logger.error("Parameters size cannot be 0")

        lemmas = self.hts.lemmas
        self._init_at_time(self.hts.vars, k_max)

        monotonic = True

        # if monotonic:
        #     for p in parameters:
        #         self.set_preferred((p, False))

        self.region = FALSE()

        generalize = lambda model, t: self._get_param_assignments(
            model, t, parameters, monotonic)

        if at_most == -1:
            cardinality = len(parameters)
        else:
            cardinality = at_most

        prev_cs_count = 0

        prove = self.config.prove

        step = 5
        same_res_counter = 0
        k = step
        end = False
        has_next = TS.has_next(prop)

        # Strategy selection
        increase_k = False

        if cardinality == -2:
            (t, status) = self.solve_safety_inc_fwd(self.hts,
                                                    prop,
                                                    k_max,
                                                    k_min,
                                                    all_vars=False,
                                                    generalize=generalize)
        else:
            sn = SortingNetwork.sorting_network(parameters)

            if increase_k:
                # Approach with incremental increase of bmc k
                while k < k_max + 1:
                    for at in range(cardinality):
                        Logger.msg("[%d,%d]" % ((at + 1), k), 0,
                                   not (Logger.level(1)))

                        sn_k = sn[at + 1] if at + 1 < len(sn) else FALSE()
                        bound_constr = Or(sn_k, self.region)
                        bound_constr = bound_constr if not has_next else Or(
                            bound_constr, TS.to_next(bound_constr))

                        self.config.prove = False
                        (t, status) = self.solve_safety_inc_bwd(
                            self.hts,
                            Or(prop, bound_constr),
                            k,
                            generalize=generalize)

                        if (prev_cs_count == self.cs_count):
                            same_res_counter += 1
                        else:
                            same_res_counter = 0

                        prev_cs_count = self.cs_count

                        if (prove == True) and ((same_res_counter > 1) or
                                                (at == cardinality - 1)):
                            Logger.msg("[>%d,%d]" % ((at + 1), k), 0,
                                       not (Logger.level(1)))

                            if (at_most > -1) and (at_most < cardinality):
                                sn_k = sn[at_most - 1]
                            else:
                                sn_k = FALSE()
                            bound_constr = Or(sn_k, self.region)
                            bound_constr = bound_constr if not has_next else Or(
                                bound_constr, TS.to_next(bound_constr))

                            self.config.prove = True
                            (t, status) = self.solve_safety(
                                self.hts, Or(prop, bound_constr), k,
                                max(k_min, k - step))

                            if status == True:
                                end = True
                                break

                        if (same_res_counter > 2) and (k < k_max):
                            break

                    if end:
                        break
                    k += step
            else:
                # Approach with fixed bmc k
                for at in range(cardinality):
                    Logger.msg("[%d]" % ((at + 1)), 0, not (Logger.level(1)))

                    sn_k = sn[at + 1] if at + 1 < len(sn) else FALSE()
                    bound_constr = Or(sn_k, self.region)
                    bound_constr = bound_constr if not has_next else Or(
                        bound_constr, TS.to_next(bound_constr))

                    self.config.prove = False
                    (t, status) = self.solve_safety_inc_bwd(
                        self.hts,
                        Or(prop, bound_constr),
                        k_max,
                        generalize=generalize)

                    if simplify(self.region) == TRUE():
                        break

                    if (prev_cs_count == self.cs_count):
                        same_res_counter += 1
                    else:
                        same_res_counter = 0

                    prev_cs_count = self.cs_count

                    if (prove == True) and ((same_res_counter > 1) or
                                            (at == cardinality - 1)):
                        Logger.msg("[>%d]" % ((at + 1)), 0,
                                   not (Logger.level(1)))

                        if (at_most > -1) and (at_most < cardinality):
                            sn_k = sn[at_most - 1]
                        else:
                            sn_k = FALSE()
                        bound_constr = Or(sn_k, self.region)
                        bound_constr = bound_constr if not has_next else Or(
                            bound_constr, TS.to_next(bound_constr))

                        self.config.prove = True
                        (t,
                         status) = self.solve_safety(self.hts,
                                                     Or(prop, bound_constr),
                                                     k_max, k_min)
                        if status == True:
                            break

        traces = None
        if (self.models is not None) and (simplify(self.region)
                                          not in [TRUE(), FALSE()]):
            traces = []
            for (model, time) in self.models:
                model = self._remap_model(self.hts.vars, model, time)
                trace = self.generate_trace(model, time,
                                            get_free_variables(prop))
                traces.append(trace)

        region = []
        dass = {}

        # Sorting result by size
        for ass in list(disjunctive_partition(self.region)):
            cp = list(conjunctive_partition(ass))
            size = len(cp)
            if size not in dass:
                dass[size] = []
            dass[size].append(ass)

        indexes = list(dass.keys())
        indexes.sort()
        for size in indexes:
            region += dass[size]

        if status == True:
            return (VerificationStatus.TRUE, traces, region)
        elif status is not None:
            return (VerificationStatus.FALSE, traces, region)
        else:
            return (VerificationStatus.UNK, traces, region)