def pre_upward(petrinet, markings, precomputed=None, prune=True): pre_matrix, post_matrix = petrinet num_places, num_transitions = pre_matrix.shape basis = set() for m in markings: if precomputed is not None and m in precomputed: to_merge = { pre_m for pre_m in precomputed[m] if not in_upward(pre_m, markings) } merge_upward(basis, to_merge) continue else: precomputed[m] = set() for t in range(num_transitions): pre_m = [0] * num_places for p in range(num_places): pre, post = int(pre_matrix[p, t]), int(post_matrix[p, t]) pre_m[p] = max(pre, m[p] + pre - post) pre_m = tuple(pre_m) if precomputed is not None: update_upward(precomputed[m], pre_m) if not prune or not in_upward(pre_m, markings): update_upward(basis, pre_m) return basis
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 = 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 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 pre_upward_for_one_element(petrinet,element,transitions,basis): pre_matrix, post_matrix = petrinet num_places, num_transitions = pre_matrix.shape res = [] for t in range(num_transitions): pre_m = [0] * num_places for p in range(num_places): pre, post = int(pre_matrix[p, t]), int(post_matrix[p, t]) pre_m[p] = max(pre, element[p] + pre - post) pre_m = tuple(pre_m) if not in_upward(pre_m,basis): #print "pre_m",pre_m res.append(pre_m) return res
def limit_coverability(petrinet, init, targets, prune=False, max_iter=None): # use state equation # add by GLS # Verify if non coverable in CPN first transitions = get_transitions(petrinet) if prune and limit_non_coverable(transitions, init, targets): 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))]) solver,target_vars = build_limit_solver(transitions,init) def limit_coverable(markings): return check_limit_coverability_z3(solver, markings) 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 #time_before = time.time() prebasis = pre_upward(petrinet, basis, precomputed) #time_after = time.time() #print "time pre upward :", time_after - time_before # Coverability pruning #time_before = time.time() pruned = {x for x in prebasis if prune and not limit_coverable([x])} nbpruned = len(pruned) #time_after = time.time() #print "time to prune:", time_after - time_before prebasis.difference_update(pruned) # Continue? if len(prebasis) == 0: break else: prebasis = smallest_elems(prebasis) merge_upward(basis, prebasis) covered = in_upward(init_marking, basis) #print "numbers",num_iter,len(prebasis)+nbpruned,nbpruned #print "total build time :", total_build_time #print "total check time :", total_check_time #print "numbers",num_iter,len(prebasis)+nbpruned,nbpruned return covered
def is_already_seen(basis,element): #print "already seen ? basis:",basis return in_upward(element,basis)
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