def coverability(petrinet, init, targets): if q_coverable(petrinet, init, targets) is False: return False # System init_config = omega_marking(init) target_configs = {m for _, m in targets} system = (petrinet, init_config, target_configs) # Pruning solver, variables = build_cpn_solver(petrinet, init, targets=None, domain="N") _, _, target_vars = variables def q_pruning(markings): def pred(m): return not check_q_coverability_z3(solver, target_vars, {m}) pruned = {x for x in markings if pred(x)} for x in pruned: solver.add(z3.Or([target_vars[p] < x[p] for p in range(len(x))])) return pruned # New candidates def smallest_markings(markings): sorted_markings = sorted(markings, key=lambda m: m.sum_norm()) return set(sorted_markings[:int(10 + 0.2 * len(markings))]) return backward_coverability(system, q_pruning, smallest_markings)
def non_coverable(petrinet, init, targets): MAX_TARGETS_SINGLE_TEST = 10 if len(targets) <= MAX_TARGETS_SINGLE_TEST: if check_cpn_coverability(petrinet, init, targets) == False: return True else: solver, _ = build_cpn_solver(petrinet, init, targets, domain='N') if solver.check() == z3.unsat: return True return False
def coverability(petrinet, init, targets, prune=False, max_iter=None): # Verify if non coverable in CPN first if prune and non_coverable(petrinet, init, targets): return False # Otherwise, proceed with backward coverability def smallest_elems(x): return set(sorted(x, key=sum_norm)[:int(10 + 0.2 * len(x))]) solver, variables = build_cpn_solver(petrinet, init, targets=None, domain='N') _, _, target_vars = variables def coverable(markings): return check_cpn_coverability_z3(solver, target_vars, markings) init_marking = _omega_marking(init) basis = {tuple(constraint_vector(m)) for m in targets} precomputed = {} covered = False num_iter = 0 while not covered: if max_iter is not None and num_iter >= max_iter: return None # Unknown result else: num_iter += 1 # Compute prebasis prebasis = pre_upward(petrinet, basis, precomputed) # Coverability pruning pruned = {x for x in prebasis if prune and not coverable([x])} prebasis.difference_update(pruned) for x in pruned: solver.add(z3.Or([target_vars[p] < x[p] for p in range(len(x))])) # Continue? if len(prebasis) == 0: break else: prebasis = smallest_elems(prebasis) merge_upward(basis, prebasis) covered = in_upward(init_marking, basis) return covered
def comparable_coverability(petrinet, init, targets, prune=False, max_iter=None): global total_check_time global total_build_time global UUcomp global nbcomp global error # Verify if non coverable in CPN first if prune and non_coverable(petrinet, init, targets): print "non_coverable in Q" print "result find with non_coverable" return False # Otherwise, proceed with backward coverability def smallest_elems(x): return set(sorted(x, key=sum_norm)[:int(10 + 0.2 * len(x))]) solverQ, variables = build_cpn_solver(petrinet, init, targets=None, domain='N') transitions = get_transitions(petrinet) solverL,_ = build_limit_solver(transitions,init) _, _, target_vars = variables def comparaison_coverable(markings): global glitch global UUcomp global nbcomp global error nbcomp += 1 #print solverQ #print solverL resQ = check_cpn_coverability_z3(solverQ, target_vars, markings) resL = check_limit_coverability_z3(solverL, markings) if resQ and resL == False: print "qcover solver say cover and limit solver say not cover" print "impossible" print "error" #print markings error +=1 print exit(1) if resQ == False and resL: glitch +=1 return resQ init_marking = _omega_marking(init) basis = {tuple(constraint_vector(m)) for m in targets} precomputed = {} covered = in_upward(init_marking, basis) num_iter = 0 while not covered: if max_iter is not None and num_iter >= max_iter: return None # Unknown result else: num_iter += 1 # Compute prebasis print "step :",num_iter prebasis = pre_upward(petrinet, basis, precomputed) # Coverability pruning nbover = glitch pruned = {x for x in prebasis if prune and not comparaison_coverable([x])} print "nb over ", glitch-nbover print "prebasis size : ", len(prebasis) print "size of pruned :", len(pruned) prebasis.difference_update(pruned) for x in pruned: solverQ.add(z3.Or([target_vars[p] < x[p] for p in range(len(x))])) # Continue? if len(prebasis) == 0: break else: prebasis = smallest_elems(prebasis) merge_upward(basis, prebasis) covered = in_upward(init_marking, basis) print print "total build time :", total_build_time print "total check time :", total_check_time print "glitch: ", glitch print "error", error print "comparison", nbcomp return covered