Beispiel #1
0
 def create_disjuntive(cls, scc):
     fancy = {}
     nodes = scc.get_nodes()
     gvs = scc.get_info("global_vars")
     Nvars = int(len(gvs) / 2)
     vs = gvs[:Nvars]
     for node in nodes:
         ors = {}
         for tr in scc.get_edges(source=node):
             tname = tr["name"]
             lvs = tr["local_vars"]
             cs = tr["polyhedron"].project(vs).get_constraints()
             cs_nd = []
             if len(lvs) > 0:
                 cs_nd = tr["polyhedron"].project(lvs).get_constraints()
             if len(cs) == 0:
                 cs = Expression(0) == Expression(0)
             elif len(cs) == 1:
                 cs = cs[0]
             else:
                 cs = And(cs)
             if len(cs_nd) == 0:
                 cs_nd = Expression(0) == Expression(0)
             elif len(cs_nd) == 1:
                 cs_nd = cs_nd[0]
             else:
                 cs_nd = And(cs_nd)
             ors[tname] = [cs, cs_nd]
         fancy[node] = ors
     return fancy
Beispiel #2
0
 def get_conjuntive(self,
                    node,
                    tr=None,
                    only_deterministic=False,
                    vs=None,
                    pvs=None):
     rename = not (vs is None and pvs is None)
     if only_deterministic:
         return self.phi[node][0].renamed(
             vs, pvs) if rename else self.phi[node][0]
     else:
         return And(self.phi[node][0].renamed(vs, pvs),
                    self.phi[node][1]) if rename else And(
                        self.phi[node][0], self.phi[node][1])
Beispiel #3
0
 def get_disjuntive(self, node, tr=None, only_deterministic=False, vs=None, pvs=None):
     rename = not (vs is None and pvs is None)
     if tr is None:
         trs = list(self.phi[node].keys())
     else:
         trs = [tr]
     mphi = []
     for k in trs:
         cs = []
         if not only_deterministic:
             cs = [self.phi[node][k][1]]
         if rename:
             cs += [self.phi[node][k][0].renamed(vs, pvs)]
         else:
             cs += [self.phi[node][k][0]]
         if len(cs) == 1:
             mphi.append(cs[0])
         else:
             mphi.append(And(cs))
     if len(mphi) == 0:
         return Expression(0) >= Expression(1)
     if len(mphi) == 1:
         return mphi[0]
     else:
         return Or(mphi)
Beispiel #4
0
    def generatePoints_rays(self, s, vs, all_vars, others=[], tags=None):
        from lpi import C_Polyhedron
        cons = And(s.get_constraints(tags=tags))
        from ppl import Variable
        poly = C_Polyhedron(cons, variables=vs)
        gene = poly.get_generators()
        g_points = [g for g in gene if g.is_point()]
        g_lines = [g for g in gene if g.is_line()]
        g_rays = [g for g in gene if g.is_ray()]
        rs = []
        ps = []
        for l in g_lines:
            item = {}
            item2 = {}
            for i in range(len(vs)):
                item[vs[i]] = int(l.coefficient(Variable(i)))
                item2[vs[i]] = -int(l.coefficient(Variable(i)))
            rs.append(item)
            rs.append(item2)
        for r in g_rays:
            item = {}
            for i in range(len(vs)):
                item[vs[i]] = int(r.coefficient(Variable(i)))
            rs.append(item)
        for p in g_points:
            item = {}
            for i in range(len(vs)):
                item[vs[i]] = int(p.coefficient(Variable(i)))
            ps.append((item, int(p.divisor())))

        def combine(p, rays, coeffs, vs, incr):
            point = {v: p[v] for v in vs}
            for i in range(len(coeffs)):
                for v in vs:
                    point[v] += coeffs[i] * rays[i][v]
            if coeffs[incr] < 10:
                yield from combine(
                    p, rays, coeffs[:i] + [coeffs[i] + 1] + coeffs[i + 1:], vs,
                    incr)
            elif incr < len(coeffs):
                yield from combine(p, rays, coeffs, vs, incr + 1)
            yield point

        points = []
        for p, d in ps:
            points.append({v: (p[v] / d) for v in vs})
            for r in rs:
                for k in range(1, 100):
                    points.append({v: ((p[v] + k * r[v]) / d) for v in vs})
        return points
        points = []
        for p, d in ps:
            points += list(combine(p, rs, [0 for __ in rs], vs, 0))
        print(points, "\n", gene)
        return points
Beispiel #5
0
 def generatePoints_lp(self, s, vs, all_vars, others=[], tags=None):
     from lpi import C_Polyhedron
     cons = And(s.get_constraints(tags=tags))
     cons_dnf = cons.to_DNF()
     ps = []
     queue = [[c for c in cs if c.is_linear()] for cs in cons_dnf]
     count = 0
     while len(ps) < self.sampling["N"] and len(queue) > 0:
         if count == 10:
             raise ValueError()
         cs = queue.pop()
         poly = C_Polyhedron(constraints=cs, variables=all_vars)
         if poly.is_empty():
             continue
         m, __ = poly.get_point()
         p = []
         exp = []
         for v in vs:
             if v not in m or m[v] is None:
                 pi = 0.0
             else:
                 pi = m[v]
                 exp.append(
                     Expression(v) > Expression(pi) +
                     self.sampling["threshold"])
                 exp.append(
                     Expression(v) < Expression(pi) -
                     self.sampling["threshold"])
             p.append(pi)
         if p not in ps and p not in others:
             ps.append(p)
         else:
             count += 1
         if len(ps) == self.sampling["N"]:
             break
         for e in exp:
             queue.append(list(cs) + [e])
     return ps
Beispiel #6
0
def set_fancy_props_neg(cfg, scc):
    fancy = {}
    nodes = scc.get_nodes()
    gvs = cfg.get_info("global_vars")
    Nvars = int(len(gvs) / 2)
    vs = gvs[:Nvars]
    for node in nodes:
        ors = []
        for tr in cfg.get_edges(source=node):
            if tr["target"] in nodes:
                continue
            cs = tr["polyhedron"].project(vs).get_constraints()
            if len(cs) == 0:
                continue
            if len(cs) == 1:
                ors.append(cs[0])
            else:
                ors.append(And(cs))
        if len(ors) == 0:
            fancy[node] = Or(Expression(0) == Expression(0))
        else:
            fancy[node] = Or([o.negate() for o in ors])
    OM.printf("exit conditions: \n", fancy, "\n ===========================")
    scc.set_nodes_info(fancy, "exit_props")
Beispiel #7
0
    def run(cls, scc, config):
        OM.printif(1, "--> with " + cls.NAME)
        mround = lambda x: round(x, 4)
        global_vars = scc.get_info("global_vars")
        Nvars = int(len(global_vars) / 2)
        vs = global_vars[:Nvars]
        pvs = global_vars[Nvars:]
        conf = MLConf(**config)
        phi = conf.create_phi(scc)
        OM.printif(1, "initial phi", phi)
        max_tries = 10
        trs = {t["name"]: t for t in scc.get_edges()}
        tr_queue = list(trs.keys())
        tr_tries = {n: max_tries for n in tr_queue}
        skiped = []
        itis = TerminationResult.UNKNOWN
        while tr_queue:
            tname = tr_queue.pop(0)
            if tr_tries[tname] == 0:
                OM.printif(1, "TOO MANY TRIES with tr: ", tname)
                skiped.append(tname)
                continue
            t = trs[tname]
            source = t["source"]
            target = t["target"]
            srcphi = phi.get(source, tname)
            s = Solver()
            s.add(srcphi, name="_phi")
            if not s.is_sat(["_phi"]):
                continue
            OM.printif(0, "Analyzing transition: ", tname)
            lvs = t["local_vars"]
            all_vars = global_vars + lvs
            s.add(t["polyhedron"].get_constraints(), name="_tr")
            if len(lvs) > 0:
                s.add(And([c for c in t["polyhedron"].get_constraints()
                           ]).negate(),
                      name="_no_tr")
            s.add(phi.get(target, vs=vs, pvs=pvs, only_deterministic=True),
                  name="_good")  # phi[ti[target]]
            s.add(phi.get(target, vs=vs, pvs=pvs,
                          only_deterministic=True).negate(),
                  name="_bad")  # not phi[ti[target]]
            goods = s.is_sat(["_phi", "_tr", "_good"])
            bads = s.is_sat([
                "_phi", "_tr", "_bad"
            ]) or (len(lvs) > 0 and s.is_sat(["_phi", "_no_tr"]))
            modified = False
            mixed = False
            bad_points = []
            while goods and bads:
                if tr_tries[tname] == 0:
                    OM.printif(1, "TOO MANY TRIES with tr: ", tname)
                    skiped.append(tname)
                    mixed = True
                    break
                tr_tries[tname] -= 1
                new_bad_points, good_points = conf.getPoints(s,
                                                             vs,
                                                             lvs,
                                                             all_vars,
                                                             others=bad_points)
                bad_points += new_bad_points
                OM.printif(2, "bad:", bad_points)
                OM.printif(2, "good:", good_points)
                if len(bad_points) == 0 or len(good_points) == 0:
                    mixed = True
                    modified = True
                    OM.printif(
                        1, "WARNING: Couldn't generate points of both groups.")
                    break
                new_phi = conf.split(bad_points, good_points, vs)
                if new_phi is None:
                    modified = True
                    mixed = True
                    OM.printif(1, "WARNING: Couldn't find a line")
                    break
                else:
                    new_phi.aproximate_coeffs(max_coeff=1e10, max_dec=10)
                    OM.printif(1, "split found:", new_phi.toString(str, str))
                    s.add(new_phi, name="_phi")
                    modified = True
                    phi.append(source, tname, new_phi)
                goods = s.is_sat(["_phi", "_tr", "_good"])
                bads = s.is_sat(["_phi", "_tr", "_bad"])
            if modified:
                for k in trs:
                    if trs[k]["target"] == source and trs[k][
                            "name"] not in tr_queue:
                        if trs[k]["name"] == tname and mixed:
                            continue
                        tr_queue.append(trs[k]["name"])
            if mixed:
                OM.printf("removing transition: {}".format(tname))
                scc.remove_edge(t["source"], t["target"], t["name"])
                phi.remove(source, tname)
            elif not bads:
                OM.printif(1, "{}: bads (terminating) are UNSAT".format(tname))
            elif not goods:
                OM.printf(
                    "{}: bads (terminating) are SAT, but goods (non-terminating) are UNSAT"
                    .format(tname))
                OM.printf("removing transition: {}".format(tname))
                scc.remove_edge(t["source"], t["target"], t["name"])
                phi.remove(source, tname)

        nonterminate = False
        for sub_scc in scc.get_scc():
            if len(sub_scc.get_edges()) == 0:
                continue
            sub_nont = True
            for t in sub_scc.get_edges():
                source = t["source"]
                target = t["target"]
                tname = t["name"]
                OM.printif(1, "Checking transition: ", tname)
                srcphi = phi.get(source, tname)
                s = Solver()
                s.add(srcphi, name="_phi")
                lvs = t["local_vars"]
                all_vars = global_vars + t["local_vars"]
                s.add(t["polyhedron"].get_constraints(), name="_tr")
                s.add(phi.get(target, vs=vs, pvs=pvs, only_deterministic=True),
                      name="_good")  # phi[ti[target]]
                s.add(phi.get(target, vs=vs, pvs=pvs,
                              only_deterministic=True).negate(),
                      name="_bad")  # not phi[ti[target]]
                goods = s.is_sat(["_phi", "_tr", "_good"])
                bads = s.is_sat(["_phi", "_tr", "_bad"])
                OM.printif(1, "goods: {}, bads: {}".format(goods, bads))
                if not goods or bads:
                    sub_nont = False
                    break
            if sub_nont:
                nonterminate = True
                for node in sub_scc.get_nodes():
                    OM.printif(2, "\t {} :".format(node))
                    for t in sub_scc.get_edges(source=node):
                        tname = t["name"]
                        OM.printif(
                            2, "\t\t {} : {}".format(
                                tname,
                                phi.get(node, tname).toString(str,
                                                              str,
                                                              and_symb="AND",
                                                              or_symb="OR")))
                        OM.printif(
                            3, "\t\t {}(rounded) : {}".format(
                                tname,
                                phi.get(node, tname).toString(str,
                                                              mround,
                                                              and_symb="AND",
                                                              or_symb="OR")))
                break
        if len(skiped) > 0:
            OM.printf(
                "some transitions ({}) where ignored after {} iterations.".
                format(skiped, max_tries))

        if nonterminate:
            itis = TerminationResult.NONTERMINATE
            OM.printf("phi props: {")
            for node in scc.get_nodes():
                OM.printf("\t {} :".format(node))
                for edge in scc.get_edges(source=node):
                    tname = edge["name"]
                    OM.printf("\t\t {} : {}".format(
                        tname,
                        phi.get(node, tname).toString(str,
                                                      str,
                                                      and_symb="AND",
                                                      or_symb="OR")))
                    OM.printif(
                        2, "\t\t {}(rounded) : {}".format(
                            tname,
                            phi.get(node, tname).toString(str,
                                                          mround,
                                                          and_symb="AND",
                                                          or_symb="OR")))
            OM.printf("}")
        OM.printf("Answer: {}".format(itis))
        max_iterations_needed = max_tries - min(
            [tr_tries[k] for k in tr_tries])
        OM.printf("Iterations: {}".format(max_iterations_needed))
        OM.printif(1, "Graph:")
        for e in scc.get_edges():
            OM.printif(1, e["name"], ":", e["source"], "-->", e["target"])

        response = Result()
        response.set_response(status=itis)
        return response
Beispiel #8
0
 def append_conjuntive(self, node, tr, value, deterministic=True):
     idx = 0 if deterministic else 1
     self.phi[node][idx] = And([value, self.phi[node][idx]])
Beispiel #9
0
 def append_disjuntive(self, node, tr, value, deterministic=True):
     if self.phi[node][tr] is None:
         return
     idx = 0 if deterministic else 1
     self.phi[node][tr][idx] = And([value, self.phi[node][tr][idx]])
Beispiel #10
0
 def set_conjuntive(self, node, tr, value, deterministic=True):
     idx = 0 if deterministic else 1
     self.phi[node][idx] = And(value)