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
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])
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)
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
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
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")
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
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]])
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]])
def set_conjuntive(self, node, tr, value, deterministic=True): idx = 0 if deterministic else 1 self.phi[node][idx] = And(value)