def generate_basic_traces(folder_name, trace_count, duration):

    viol_formula = 'x0 < 5'

    stn_viol = STL.SyntaxTreeNode()
    stn_viol.initialize_node(viol_formula.split(), 0)

    tc = 0
    while tc < trace_count:
        f_signal_name = folder_name + "test_" + str(tc)
        f_label_name = f_signal_name + "_label"
        f_s = open(f_signal_name, 'w')
        f_l = open(f_label_name, 'w')

        time = 0
        x = [
            random.randint(5, 7)
        ]  # this line is to be uncommented if initial x is wanted to be randomized.
        #x = [0]
        while time <= duration:
            u = [random.choice([-2, 1, 2])]
            f_s.write(
                "%s %s %s\n" %
                (str(time), " ".join([str(x[0])]), " ".join([str(u[0])])))
            stn_viol.compute_qv(STL.DataPoint(value=x + u, time=time))
            qual = 1 if stn_viol.qv < 0 else 0
            f_l.write("%s %s\n" % (str(time), str(qual)))
            x, _ = basic_example_step_function(x, u)

            time += 1

        f_s.close()
        f_l.close()
        print("Done with generate basic traces, trace no" + str(tc))
        tc += 1
def parameter_search_for_formula(formula, parameter_domains_for_formula, folder_name, trace_count, signal_file_base,
                                 process_count, return_type, past_results=[]):
  parameter_list = list(parameter_domains_for_formula.keys())
  parameter_domain = [parameter_domains_for_formula[pa] for pa in parameter_list]

  prefix_formula = STL.infix_to_prefix(formula)

  best_v, params, time_passed = grid_search.grid_search(formula=prefix_formula, parameter_list=parameter_list,
                                                        parameter_domain=parameter_domain, folder_name=folder_name,
                                                        signal_file_base=signal_file_base, trace_count=trace_count,
                                                        signal_file_rest='', process_count=process_count,
                                                        return_type=return_type, past_results=past_results)

  #result_file = folder_name + "".join(formula.split()) + ".mat"
  #_ = plot.convert_save_results(parameter_list, parameter_domain, all_results, result_file, formula,
  #                                                  time_passed, trace_count, process_count, best_v, params)

  formula_n = formula
  if params == None:
    print( "There are no best parameters for the formula: " + formula )
  else:
    for p, v in zip(parameter_list, params):
      formula_n = formula_n.replace(p, str(v))
    print("With valuation " + str(best_v) + " ,best parameters form " + formula_n + " ,with prefix form: " +
          STL.infix_to_prefix(formula_n) + " ,in time: " + str(time_passed))
  return stl_constants.FormulaValuation(formula=formula_n, valuation=best_v)
예제 #3
0
def label_test_file(test_file_name, label_file_name, viol_formula, duration):
    # THIS DOES NOT WORK. I WILL FIX IT LATER!
    f_s = open(test_file_name, 'r')
    lines = f_s.readlines()
    f_l = open(label_file_name, 'w')

    time = 0

    # Initialize the checker:
    stn_viol = STL.SyntaxTreeNode()
    stn_viol.initialize_node(viol_formula.split(), 0)

    while time <= duration:
        # Store the values to the file:
        kk = [float(f) for f in lines[time].split()[1:6]
              ] + [int(i) for i in lines[time].split()[6:]]
        stn_viol.compute_qv(
            STL.DataPoint(value=[float(f) for f in lines[time].split()[1:6]] +
                          [int(i) for i in lines[time].split()[6:]],
                          time=time))
        qual = 1 if stn_viol.qv > 0 else 0
        f_l.write("%s %s\n" % (str(time), str(qual)))

        time += 1

    f_s.close()
    f_l.close()
    print("Done!")
예제 #4
0
def controller_traffic_data(viol_formula, folder_name, trace_count, duration,
                            pc, cause_formula):
    """

    Args:
        cause_formula: formula got from cause_mining_traffic_data (in prefix form)

    Returns: nothing

    """
    #traffic_file = "test_data/traffic_data/l5_system"
    #traffic_file_no_soln = "test_data/traffic_data/l5_system_no_soln"
    #traffic_file_no_soln2 = "test_data/traffic_data/l5_system_no_soln2"
    traffic_file_no_soln3 = "test_data/traffic_data/l5_system_no_soln3"
    link_dict, intersection_dict = read_input.load_from_annotated_file(
        traffic_file_no_soln3)
    tn = network.Network(link_dict, intersection_dict, scale=5)

    uk_count = tn.get_intersection_count()
    xk_initialized = np.zeros(tn.get_link_count())
    tn.initialize_links(xk_initialized, 0.1)

    viol_formula_prefix = STL.infix_to_prefix(viol_formula)
    sg.controller(folder_name=folder_name,
                  name='test',
                  trace_count=trace_count,
                  duration=duration,
                  viol_formula=viol_formula_prefix,
                  cause_formula=cause_formula,
                  step_function=tn.step,
                  xk_initialized=xk_initialized,
                  uk_domain=[0, 1],
                  uk_count=uk_count,
                  num_to_let=True)
def cause_mining_print_detailed_result(infix_formula, folder_name, signal_file_base, trace_count, signal_file_rest):
    """
        Written as a function to see how "good" a formula is, mainly to help us debug.
        This function prints the false positive, false negative, true positive, true negative, precision,
        recall and various f scores of the infix formula given as an input.
    """

    prefix_formula = STL.infix_to_prefix(infix_formula)
    fp_fn_tp_tn = evaluator.evaluate_signals(formula=prefix_formula, folder_name=folder_name,
                                             signal_file_base=signal_file_base, trace_count=trace_count,
                                             signal_file_rest=signal_file_rest, return_type=stl_constants.__DETAILED)

    print(infix_formula)
    fp = str(fp_fn_tp_tn[0])
    fn = str(fp_fn_tp_tn[1])
    tp = str(fp_fn_tp_tn[2])
    tn = str(fp_fn_tp_tn[3])
    precision = str(metrics_util.calculate_precision(fp_fn_tp_tn))
    recall = str(metrics_util.calculate_recall(fp_fn_tp_tn))
    f1 = str(metrics_util.calculate_f1_score(fp_fn_tp_tn))
    f05 = str(metrics_util.calculate_fhalf_score(fp_fn_tp_tn))
    f09 = str(metrics_util.calculate_f_Beta_score(fp_fn_tp_tn, 0.9))
    f01 = str(metrics_util.calculate_f_Beta_score(fp_fn_tp_tn, 0.1))
    f015 = str(metrics_util.calculate_f_Beta_score(fp_fn_tp_tn, 0.15))
    f02 = str(metrics_util.calculate_f_Beta_score(fp_fn_tp_tn, 0.2))
    f03 = str(metrics_util.calculate_f_Beta_score(fp_fn_tp_tn, 0.3))
    f04 = str(metrics_util.calculate_f_Beta_score(fp_fn_tp_tn, 0.4))

    print('fp: ' + fp + ' fn: ' + fn + ' tp: ' + tp + ' tn: ' + tn +
          ' precision: ' + precision + ' recall: ' + recall +
          ' \nf1 score: ' + f1 + ' f0.5 score: ' + f05 + ' f0.9 score: ' + f09 +
          ' \nf0.1 score: ' + f01 + ' f0.15 score: ' + f015 + ' f0.2 score: ' + f02 +
          ' f0.3 score: ' + f03 + ' \nf0.4 score: ' + f04)

    return fp_fn_tp_tn
def formula_val_list_into_concat_formula_list(prefix_formula_val_list,
                                              folder_name, signal_file_base,
                                              trace_count, signal_file_rest,
                                              return_type):
    """
    Designed for debug purposes of cause mining algorithm
    Takes only the formula parts of a Formula_Valuation list, turns them into their infix forms,
    concatenates them with or and calculates the valuation of the resulting formula. Returns the resulting formula and
    the valuation as a FormulaValuation.
    Args:
        prefix_formula_val_list: A list of Formula Valuations where formulas are in prefix forms.
         Ex: [FormulaValuation(formula='A 0 4 x5 = 0', valuation=0.7824),
         FormulaValuation(formula='& A 0 2 x5 = 0 P 1 1 x3 > 10', valuation=0.921521)]
        return_type:

    Returns: a FormulaValuation

    """
    infix_formula_list = [fv.formula for fv in prefix_formula_val_list]
    prefix_to_infix_list(infix_formula_list)
    concat_with_or_infix(infix_formula_list)
    formula = STL.infix_to_prefix(infix_formula_list[0])
    valuation = optimization.evaluator.evaluate_signals(
        formula, folder_name, signal_file_base, trace_count, signal_file_rest,
        return_type)
    return stl_constants.FormulaValuation(formula=infix_formula_list[0],
                                          valuation=valuation)
def convert_and_evaluate(formula_list, parallel_process_count, parameter_domains, folder_name, signal_file_base,
                         return_type, trace_count, metric_list, set_valued_metrics):
    nodes_list = []
    for formula in formula_list:
        formula = inject_parameters(formula, parameter_domains, metric_list, set_valued_metrics)
        formula = STL.infix_to_prefix(formula)
        syntax_tree_node = STL.SyntaxTreeNode()
        syntax_tree_node.initialize_node(formula.split(), 0)
        nodes_list.append(syntax_tree_node)

    pool = Pool(processes=parallel_process_count)
    fitness_partial = partial(insert_fitness_value_to_individual, folder_name, signal_file_base, return_type,
                              trace_count)
    results = (pool.map(fitness_partial, nodes_list))
    pool.close()
    pool.join()

    return results
def return_sc_form(formula, prefix=True):
    """

    Args:
        formula: formula to be written with "next" statements
        prefix:  bool value that indicates whether the given formula is prefix or infix

    Returns: formula written with only X and !. For example, return_sc_form('P 1 1 ( x0 = 0 ))', False) = 'X (x0=0.0)'

    """

    if not prefix:
        formula = STL.infix_to_prefix(formula)
    stn = STL.SyntaxTreeNode()
    stn.initialize_node(formula.split(), 0)

    next_form_str = return_next_form(stn)
    #print(next_form_str)
    return next_form_str
예제 #9
0
def break_formula(cause_formula):
    """
    Breaks a cause formula Phi = Phi_1 | Phi_2 | ... | Phi_n into an array formula_list = [Phi_1, Phi_2, ..., Phi_n]
    where Phi_i = A[1,a](u_i = c_i) & P[1,1] (phi_i)
    Args:
        cause_formula:
    Returns: stn_list of all formula components of the given concatenated formula

    """
    stn = STL.SyntaxTreeNode()
    stn.initialize_node(cause_formula.split(), 0)
    return break_formula_helper(stn)
def prefix_to_infix_list(prefix_list):
    """
    Changes prefix formulas in a list to their infix forms

    Args:
        prefix_list: list of prefix formulas

    Returns: nothing

    """
    length = len(prefix_list)
    for i in range(0, length):
        prefix_list.append(STL.prefix_to_infix(prefix_list[0]))
        prefix_list.pop(0)
예제 #11
0
def find_best_formula(folder_name,
                      trace_count,
                      heuristic,
                      duration,
                      signal_file_base,
                      signal_file_rest,
                      return_type,
                      operator_count_limit,
                      pc,
                      upto,
                      cause_limit,
                      withoutS,
                      valuation_limit=None):
    """

    Returns: the best formula found with heuristic algorithm if heuristic == True, found with search_all_search_space if
    heuristic == False.

    """
    if not heuristic:
        best_result = search_all_search_space_traffic_data(
            pc=pc,
            return_type=return_type,
            folder_name=folder_name,
            trace_count=trace_count,
            signal_file_base=signal_file_base,
            cause_limit=cause_limit,
            operator_count_limit=operator_count_limit,
            upto=upto,
            withoutS=withoutS)
        cause_formula_prefix = STL.infix_to_prefix(best_result.formula)

    else:
        cause_formula_prefix = cause_mining_traffic_data(
            pc=pc,
            valuation_limit=valuation_limit,
            folder_name=folder_name,
            trace_count=trace_count,
            signal_file_base=signal_file_base,
            return_type=return_type,
            operator_count_limit=operator_count_limit,
            withoutS=withoutS)  # best formula in prefix form

    cmm.print_detailed_result(prefix=1,
                              formula=cause_formula_prefix,
                              folder_name=folder_name,
                              signal_file_base=signal_file_base,
                              signal_file_rest=signal_file_rest,
                              trace_count=trace_count)
    return cause_formula_prefix
def print_past_formulas_prefix_infix_valuation(past_results, folder_name,
                                               signal_file_base, trace_count,
                                               signal_file_rest, return_type):
    """
        Debugging tool for past formulas.
        Calls formula_val_list_into_concat_formula_list and calculates the resulting formula from past_results list
         (or any FormulaValuation list with formulas in prefix forms), returns the prefix and infix form and the
         valuation of the resulting formula
    """

    forVal = formula_val_list_into_concat_formula_list(
        past_results, folder_name, signal_file_base, trace_count,
        signal_file_rest, return_type)
    print("Infix Formula: " + forVal.formula)
    print("Prefix Formula: " + STL.infix_to_prefix(forVal.formula))
    print("Valuation: " + str(forVal.valuation))
예제 #13
0
def look_for_any_formula(folder_name,
                         trace_count,
                         heuristic,
                         duration,
                         signal_file_base,
                         signal_file_rest,
                         return_type,
                         operator_count_limit,
                         pc,
                         upto,
                         cause_limit,
                         withoutS,
                         valuation_limit=None):
    if not heuristic:
        best_result = search_all_search_space_traffic_data(
            pc=pc,
            return_type=return_type,
            folder_name=folder_name,
            trace_count=trace_count,
            signal_file_base=signal_file_base,
            cause_limit=cause_limit,
            operator_count_limit=operator_count_limit,
            upto=upto,
            withoutS=withoutS,
            controllable_formulas=False)
        cause_formula_prefix = STL.infix_to_prefix(best_result.formula)

    else:
        cause_formula_prefix = cause_mining_traffic_data(
            pc=pc,
            valuation_limit=valuation_limit,
            folder_name=folder_name,
            trace_count=trace_count,
            signal_file_base=signal_file_base,
            return_type=return_type,
            operator_count_limit=operator_count_limit,
            withoutS=withoutS,
            controllable_formulas=False)  # best formula in prefix form

    cmm.print_detailed_result(prefix=1,
                              formula=cause_formula_prefix,
                              folder_name=folder_name,
                              signal_file_base=signal_file_base,
                              signal_file_rest=signal_file_rest,
                              trace_count=trace_count)
    return cause_formula_prefix
예제 #14
0
def print_detailed_result(prefix, formula, folder_name, signal_file_base,
                          signal_file_rest, trace_count):
    """

    Args:
        prefix: (bool) 1 if formula given is prefix, 0 if its infix
        formula: STL formula

    Returns: nothing

    """
    if prefix:
        infix_formula = STL.prefix_to_infix(formula)
    else:
        infix_formula = formula

    fp_fn_tp_tn = cause_mining_heuristic.cause_mining_print_detailed_result(
        infix_formula, folder_name, signal_file_base, trace_count,
        signal_file_rest)
    return fp_fn_tp_tn
예제 #15
0
def traffic_signal_generator(folder_name, pc):
    # This function uses the package "signal_generation". This is for "cause mining."
    # generates new traffic_signal data with given violation_formula, trace_count and duration.
    #viol_formula = "( ( ( ( ( x0 < 30 ) & ( x1 < 30 ) ) & ( x2 < 30 ) ) & ( x3 < 15 ) ) & ( x4 < 15 ) )"
    #viol_formula_no_soln = "( ( ( ( ( x0 < 32 ) & ( x1 < 32 ) ) & ( x2 < 32 ) ) & ( x3 < 16 ) ) & ( x4 < 16 ) )"
    #viol_formula_no_soln2 = "( ( ( ( ( x0 < 30 ) & ( x1 < 30 ) ) & ( x2 < 30 ) ) & ( x3 < 15 ) ) & ( x4 < 15 ) )"
    viol_formula_no_soln3 = "( ( ( ( ( x0 < 30 ) & ( x1 < 30 ) ) & ( x2 < 30 ) ) & ( x3 < 15 ) ) & ( x4 < 15 ) )"
    viol_formula_prefix = STL.infix_to_prefix(viol_formula_no_soln3)
    trace_count = 20
    duration = 100
    #traffic_file = "test_data/traffic_data/l5_system"
    #traffic_file_no_soln =  "test_data/traffic_data/l5_system_no_soln"
    #traffic_file_no_soln2 =  "test_data/traffic_data/l5_system_no_soln2"
    traffic_file_no_soln3 = "test_data/traffic_data/l5_system_no_soln3"

    generator.generate_traffic_traces(folder_name=folder_name,
                                      file_name="test",
                                      trace_count=trace_count,
                                      viol_formula=viol_formula_prefix,
                                      traffic_file=traffic_file_no_soln3,
                                      duration=duration,
                                      pc=pc)
예제 #16
0
def controller_n_iterations(n, heuristic):
    folder_name = 'test_data/toy_example_data/'
    trace_count = 20
    signal_file_base = 'test'
    signal_file_rest = ""
    duration = 100

    cause_limit = 1
    oc_limit = 0
    pc = 8
    return_type = stl_constants.__F_03_SCORE
    withoutS = True
    upto = False

    uk_domain = [1, 2, 3, 4]
    uk_count = 1

    violation_formula = ' ! ( x0 = 0 ) & ! ( x1 = 5 ) & ! ( x1 = 6 ) '  # violation formula of game_map2
    violation_formula2 = '! ( ( x0 < 2 ) & ( x1 < 4 ) ) & ! ( ( x0 > 3 ) & ( x1 > 3 ) )'  # violation formula of game_map

    viol_formula_prefix = STL.infix_to_prefix(violation_formula2)

    formula_list = []

    valuation_limit = 0.1
    operator_count_limit_heuristic = 100

    label_cnt = hf.label_count(folder_name=folder_name,
                               label_file_base='test_',
                               label_file_rest='_label',
                               trace_count=trace_count)
    print("label count before the controller: " + str(label_cnt))
    for i in range(0, n):
        if heuristic:
            cause_formula_prefix = heuristic_toy_example(
                pc=pc,
                folder_name=folder_name,
                valuation_limit=valuation_limit,
                trace_count=trace_count,
                signal_file_base=signal_file_base,
                operator_count_limit=operator_count_limit_heuristic,
                return_type=return_type,
                withoutS=withoutS)  # returns prefix formula (string)

        else:
            best_formula = search_all_search_space_toy_example(
                cause_limit=cause_limit,
                pc=pc,
                return_type=return_type,
                folder_name=folder_name,
                trace_count=trace_count,
                signal_file_base=signal_file_base,
                upto=upto,
                operator_count_limit=oc_limit,
                withoutS=withoutS)
            if best_formula == "":
                print("no formula with positive valuation")
                break
            cause_formula_prefix = STL.infix_to_prefix(best_formula)

        cma.cause_mining_main.print_detailed_result(
            prefix=1,
            formula=cause_formula_prefix,
            folder_name=folder_name,
            signal_file_base=signal_file_base,
            signal_file_rest=signal_file_rest,
            trace_count=trace_count)

        formula_list.append(cause_formula_prefix)
        cause_formula_prefix = cma.helper_funs.concat_with_or_prefix(
            formula_list)

        sg.controller(folder_name=folder_name,
                      name='test',
                      trace_count=trace_count,
                      duration=duration,
                      viol_formula=viol_formula_prefix,
                      cause_formula=cause_formula_prefix,
                      step_function=toy_example_step_function,
                      xk_initialized=(3, 4),
                      uk_domain=uk_domain,
                      uk_count=uk_count,
                      num_to_let=False)

        label_cnt = hf.label_count(folder_name=folder_name,
                                   label_file_base='test_',
                                   label_file_rest='_label',
                                   trace_count=trace_count)
        print("label count after controller " + str(i) + " is: " +
              str(label_cnt))

        if label_cnt == 0:
            break
예제 #17
0
def traffic_signal_generator(trace_start_index, folder_name, name,
                             traffic_file, trace_count, viol_formula,
                             duration):
    """

  Args:
    trace_start_index:
    folder_name:
    name:
    traffic_file:
    trace_count:
    viol_formula:
    duration:

  Returns tuple (metrics,inputs, parameter_domains)  where
    metrics: The list of metrics
    inputs: A list of controllable metrics (inputs is subset of metrics)
    parameter_domains: A dictionary containing the domains of parameters

    Sample return: ([0,1,2], [2], {'p0': [0, 10], 'p1': [0, 10], 'p2': ['a', 'b']}) Note that the domain for the input
    metrics is always set valued.
  """

    # First construct the traffic network.
    # In loop, generate trace. check it against the formula, produce the label. Save both
    link_dict, intersection_dict = read_input.load_from_annotated_file(
        traffic_file)
    tn = network.Network(link_dict, intersection_dict, scale=5)

    tc = 0
    while tc < trace_count:
        index = trace_start_index + tc
        f_signal_name = folder_name + "/" + name + "_" + str(index)
        f_label_name = f_signal_name + "_label"
        f_s = open(f_signal_name, 'w')
        f_l = open(f_label_name, 'w')

        time = 0
        # The states of the links
        xk = np.zeros(tn.get_link_count())
        sm = [_ for _ in range(tn.get_intersection_count())]

        tn.initialize_links(xk, 0.1)
        tn.set_random_signal_mode(sm)

        # Initialize the checker:
        stn_viol = STL.SyntaxTreeNode()
        stn_viol.initialize_node(viol_formula.split(), 0)
        sm_numbers = [0 if x == 'a' else 1 for x in sm]

        while time <= duration:
            # Store the values to the file:
            stn_viol.compute_qv(
                STL.DataPoint(value=xk.tolist() + sm_numbers, time=time))
            f_s.write("%s %s %s\n" % (str(time), " ".join(
                [str(x) for x in xk]), " ".join([str(x) for x in sm_numbers])))
            qual = 0 if stn_viol.qv >= 0 else 1
            f_l.write("%s %s\n" % (str(time), str(qual)))
            xk, _ = tn.step(xk, sm)
            tn.set_random_signal_mode(sm)
            sm_numbers = [0 if x == 'a' else 1 for x in sm]

            time += 1

        f_s.close()
        f_l.close()
        print("Done %d" % index)
        tc += 1

    if trace_count == 0:
        # return the set of metrics
        link_count = tn.get_link_count()
        link_metrics = list(range(0, link_count))
        intersection_metrics = list(range(tn.get_intersection_count()))
        intersection_metrics = [
            x + tn.get_link_count() for x in intersection_metrics
        ]  # shift the indices
        c = tn.get_all_intersection_indices_and_modes()

        parameter_domains = {}
        for i in range(tn.get_intersection_count()):
            pi = 'p' + str(i + link_count)
            parameter_domains[pi] = next(
                list(x[1].keys()) for x in c if x[0] == i)

        capacities = tn.np_xcap
        for i in range(link_count):
            parameter_domains['p' + str(i)] = [0, capacities[i]]
        return link_metrics + intersection_metrics, intersection_metrics, parameter_domains  # All metrics, set valued metrics, domains for set valued metrics
def basic_example(heuristic):
    """
    finds the best formula with heuristic or search_all_search_space and applies controller refinement loop_count times.
    Args:
        heuristic: (bool) True -> search the best formula by heuristic algorithm,
                          False -> search the best formula bu search_all_search_space

    Returns: nothing

    """

    loop_count = 6

    folder_name = 'test_data/basic_example_data/'
    trace_count = 20
    duration = 100
    pc = 24
    return_type = stl_constants.__F_03_SCORE
    oc_limit = 0
    cause_limit = 1
    upto = False
    withoutS = True

    #for heuristic==True and print_detailed_results
    valuation_limit = 0.01
    signal_file_base = 'test'
    signal_file_rest = ''
    operator_count_limit = 1

    viol_formula = 'x0 < 5'
    viol_formula_prefix = STL.infix_to_prefix(viol_formula)
    uk_domain = [-2, 1, 2]
    uk_count = 1

    #generate random traces and check the label count
    generate_basic_traces(folder_name, trace_count, duration)
    label_cnt = hf.label_count(folder_name=folder_name,
                               label_file_base='test_',
                               label_file_rest='_label',
                               trace_count=trace_count)
    print("label count before the controller: " + str(label_cnt))
    formula_list = []
    for i in range(loop_count):

        if not heuristic:
            best_formula = search_all_search_space_for_basic_example(
                cause_limit=cause_limit,
                pc=pc,
                return_type=return_type,
                operator_count_limit=oc_limit,
                upto=upto,
                withoutS=withoutS)
            cause_formula_prefix = STL.infix_to_prefix(best_formula)

        else:
            cause_formula_prefix = cause_mining_for_basic_example(
                pc=pc,
                valuation_limit=valuation_limit,
                folder_name=folder_name,
                trace_count=trace_count,
                signal_file_base=signal_file_base,
                return_type=return_type,
                operator_count_limit=operator_count_limit,
                withoutS=withoutS)  # best formula in prefix form
        cma.cause_mining_main.print_detailed_result(
            prefix=1,
            formula=cause_formula_prefix,
            folder_name=folder_name,
            signal_file_base=signal_file_base,
            signal_file_rest=signal_file_rest,
            trace_count=trace_count)
        formula_list.append(cause_formula_prefix)
        cause_formula_prefix = helper_funs.concat_with_or_prefix(formula_list)

        sg.controller(folder_name=folder_name,
                      name='test',
                      trace_count=trace_count,
                      duration=duration,
                      viol_formula=viol_formula_prefix,
                      cause_formula=cause_formula_prefix,
                      step_function=basic_example_step_function,
                      xk_initialized=[0],
                      uk_domain=uk_domain,
                      uk_count=uk_count,
                      num_to_let=False)

        label_cnt = hf.label_count(folder_name=folder_name,
                                   label_file_base='test_',
                                   label_file_rest='_label',
                                   trace_count=trace_count)
        print("label count after controller " + str(i) + " is: " +
              str(label_cnt))

        if label_cnt == 0:
            break
def find_best_formula(heuristic, controllable_formulas=True):
    """

    Args:
        heuristic: (bool) True -> search the best formula by heuristic algorithm,
                          False -> search the best formula bu search_all_search_space

    Returns: the best formula in prefix form

    """
    folder_name = 'test_data/basic_example_data/'
    trace_count = 20
    duration = 100
    pc = 0
    return_type = stl_constants.__F_03_SCORE
    cause_limit = 1
    upto = False
    withoutS = True
    if controllable_formulas:
        oc_limit_lhs = 1
        oc_limit_rhs = 0
        oc_limit = [oc_limit_lhs, oc_limit_rhs]
    else:
        oc_limit = 0

    # for heuristic==True and print_detailed_results
    valuation_limit = 0.01
    signal_file_base = 'test'
    signal_file_rest = ''
    operator_count_limit = 1

    print("operator_count_limit = " + str(oc_limit))
    print("pc = " + str(pc))
    print("return type = " + str(return_type.category))
    print("withoutS = " + str(withoutS))
    print("heuristic = " + str(heuristic))
    if heuristic:
        print("valuation_limit = " + str(valuation_limit))
    else:
        print("cause_limit = " + str(cause_limit))
        print("upto = " + str(upto))

    # generate random traces and check the label count
    generate_basic_traces(folder_name, trace_count, duration)

    if not heuristic:
        best_formula = search_all_search_space_for_basic_example(
            cause_limit=cause_limit,
            pc=pc,
            return_type=return_type,
            operator_count_limit=oc_limit,
            upto=upto,
            withoutS=withoutS,
            controllable_formulas=controllable_formulas)
        cause_formula_prefix = STL.infix_to_prefix(best_formula)

    else:
        cause_formula_prefix = cause_mining_for_basic_example(
            pc=pc,
            valuation_limit=valuation_limit,
            folder_name=folder_name,
            trace_count=trace_count,
            signal_file_base=signal_file_base,
            return_type=return_type,
            operator_count_limit=operator_count_limit,
            withoutS=withoutS,
            controllable_formulas=controllable_formulas
        )  # best formula in prefix form
    cma.cause_mining_main.print_detailed_result(
        prefix=1,
        formula=cause_formula_prefix,
        folder_name=folder_name,
        signal_file_base=signal_file_base,
        signal_file_rest=signal_file_rest,
        trace_count=trace_count)
    return cause_formula_prefix
예제 #20
0
def cause_mining_traffic_data(pc,
                              valuation_limit,
                              folder_name,
                              trace_count,
                              signal_file_base,
                              return_type,
                              operator_count_limit,
                              withoutS=False,
                              controllable_formulas=True):
    """
    Calls cause_mining_algorithm from cause_mining_algo package with traffic data.

    Returns: best formula in prefix form

    """
    print(
        "---------------------------------------------------------------------------------------"
    )
    print("                         cause_mining_traffic_data ")
    print(
        "---------------------------------------------------------------------------------------"
    )
    start_time = time.time()
    save = True
    metric_list = ['6', '1', '2', '3', '4', '5', '0']
    control_metrics = ['5', '6']
    set_valued_metrics = ['6', '5']
    parameter_domains = {
        'p0': range(10, 40, 5),
        'p1': range(10, 40, 5),
        'p2': range(10, 40, 5),
        'p3': range(5, 20, 5),
        'p4': range(5, 20, 5),
        'p5': range(0, 2, 1),
        'p6': range(0, 2, 1),
        'pA': range(0, 6, 1),
        'pP': range(0, 6, 1),
        'pS': range(0, 6, 2),
        'pT': [1, 2]
    }
    result_file = 'min_max'
    strictly_increasing_oc = False
    best_result = cause_mining_heuristic.cause_mining_algorithm(
        metric_list=metric_list,
        control_metrics=control_metrics,
        set_valued_metrics=set_valued_metrics,
        parameter_domains=parameter_domains,
        folder_name=folder_name,
        trace_count=trace_count,
        signal_file_base=signal_file_base,
        process_count=pc,
        save=save,
        result_file=result_file,
        return_type=return_type,
        strictly_increasing_oc=strictly_increasing_oc,
        valuation_limit=valuation_limit,
        operator_count_limit=operator_count_limit,
        withoutS=withoutS,
        controllable_formulas=controllable_formulas,
        time_shift=1)  # type: FormulaValuation

    print('### --------end of cause mining for traffic data-------- ### ')
    print("Best Result in prefix form : " + best_result.formula +\
          "\nBest Result in infix form: " + STL.prefix_to_infix(best_result.formula) + \
          "\nWith the Valuation : " + str(best_result.valuation))
    end_time = time.time()
    print("")
    print(
        "---------------------------------------------------------------------------------------"
    )
    print("cause_mining_traffic_data ended in %s seconds" %
          str(end_time - start_time))
    print(
        "---------------------------------------------------------------------------------------"
    )
    print("folder name: " + folder_name)
    print("trace count: " + str(trace_count))
    print("processor count: " + str(pc))
    print("parameter domains: " + str(parameter_domains))
    print("return type: " + return_type.name)
    print("strictly increasing: " + str(strictly_increasing_oc))
    print("searched until operator count: " + str(operator_count_limit))

    return best_result.formula
예제 #21
0
def evaluate(formula,
             signal_file_name,
             label_file_name,
             stn,
             return_type,
             past_results=[]):
    """
    evaluates the given formulas false_positive, false_negative, true_positive, true_negative results in the given files
    end returns the necessary ones based on the result_type. If there are past_results, all formulas are concatenated with
    or and the resulting formula's results are returned.

    Args:
        formula: prefix formula
        signal_file_name:
        label_file_name:
        stn:
        return_type: one of the types in stl_constants, determines the valuation best_result will be chosen based on in
                     evaluate_signals.
        past_results: a list of formula valuations (formulas inside being prefix)
        If past_results is not empty, formula and the formulas in past_results are concatenated using "or" and
        evaluation is done based on the concatenated formula.

    Returns: if return_type is TYPE_RATIO;      true positives / # of data points is returned
             if return_type is TYPE_MISMATCH;   # of data points - true positives is returned
             else;                              detailed_result (i.e. an array of false_positive, false_negative,
                                                true_positive, true_negative is returned

    """

    # Construct syntax tree
    if stn and past_results == []:
        stn.clean()
    else:
        # create new formula by concatenating the formula with past formulas with or, and compute this formula on tests
        new_formula = formula
        for frml in past_results:
            new_formula = ' | ' + new_formula + ' ' + frml.formula
        stn = STL.SyntaxTreeNode()
        stn.initialize_node(new_formula.split(), 0)

    result = 0
    counter = 0
    # detailed result is false_positive, false_negative, true_positive, true_negative
    detailed_result = [0, 0, 0, 0]

    skip_count = 10  # skip the first 10 data points, not important in monitoring.
    sc = 0

    with open(signal_file_name, 'r') as sf, open(label_file_name, 'r') as lf:
        for ts, te in zip(sf, lf):
            s = ts.split()
            t = s[0]
            s = s[1:]
            _, e = te.split()
            t = float(t)
            s = [float(x) for x in s]
            e = float(e)
            while t > stn.nt:
                stn.compute_qv(STL.DataPoint(value=s, time=stn.nt))
                if sc > skip_count:
                    result += (stn.qv > 0) == ep
                    counter += 1
                    # label is false
                    if (ep == 0):
                        # if stn.qv > 0 is true then it is false positive
                        # if stn.qv > 0 is false then it is true negative
                        detailed_result = (detailed_result[0] + int(
                            (stn.qv > 0) != ep), detailed_result[1],
                                           detailed_result[2],
                                           detailed_result[3] +
                                           int((stn.qv > 0) == ep))
                    # label is true
                    else:
                        # if stn.qv > 0 is false then it is false negative
                        # if stn.qv > 0 is true then it is true positive
                        detailed_result = (detailed_result[0],
                                           detailed_result[1] +
                                           int((stn.qv > 0) != ep),
                                           detailed_result[2] +
                                           int((stn.qv > 0) == ep),
                                           detailed_result[3])
                else:
                    sc += 1

            stn.compute_qv(STL.DataPoint(time=t, value=s))
            if sc > skip_count:
                result += (stn.qv > 0) == e
                counter += 1
                # label is false
                if (e == 0):
                    # if stn.qv > 0 is true then it is false positive
                    # if stn.qv > 0 is false then it is true negative
                    detailed_result = (detailed_result[0] + int(
                        (stn.qv > 0) != e), detailed_result[1],
                                       detailed_result[2], detailed_result[3] +
                                       int((stn.qv > 0) == e))
                # label is true
                else:
                    # if stn.qv > 0 is false then it is false negative
                    # if stn.qv > 0 is true then it is true positive
                    detailed_result = (detailed_result[0], detailed_result[1] +
                                       int((stn.qv > 0) != e),
                                       detailed_result[2] +
                                       int((stn.qv > 0) == e),
                                       detailed_result[3])
            else:
                sc += 1
            sp = s
            ep = e

    if return_type.type == stl_constants.TYPE_RATIO:
        return float(result) / counter
    if return_type.type == stl_constants.TYPE_MISMATCH:  # return the mismatch count
        return counter - result
    else:  # return detailed results
        return detailed_result
예제 #22
0
def evaluate_signals(formula,
                     folder_name,
                     signal_file_base,
                     trace_count,
                     signal_file_rest,
                     return_type,
                     stn=None,
                     past_results=[]):
    """
    Checks if the formula's lower bounds & upper bounds are within the limits. Calls evaluate, returns valuation based
    on return_type.
    Args:
        formula: prefix formula
        folder_name:
        signal_file_base:
        trace_count:
        signal_file_rest:
        return_type:
        stn:
        past_results:

    Returns:

    """

    # Below code piece checks if lower bounds are smaller than upper bounds in "formula",
    # if not, it returns the worst value.
    if not stn:
        stn = STL.SyntaxTreeNode()
        stn.initialize_node(formula.split(), 0)

    flag = helper_funs.traverse_formula_check_intervals(stn)
    if not flag:
        if return_type.category == stl_constants.CATEGORY_MAXIMIZATION:
            return 0.0
        elif return_type.type == stl_constants.__DETAILED:
            return [0, 0, 0, 0]
        elif return_type.category == stl_constants.CATEGORY_MINIMIZATION:
            return stl_constants.MAX_EVAL

    # start evaluation
    count = 0
    total = 0
    detailed_result = [0, 0, 0, 0]
    for i in range(trace_count):
        s_file = folder_name + signal_file_base + '_' + str(
            i) + signal_file_rest
        label_file = s_file + "_label"
        r = evaluate(formula=formula,
                     signal_file_name=s_file,
                     label_file_name=label_file,
                     stn=stn,
                     return_type=return_type,
                     past_results=past_results)
        count += 1
        if return_type.type == stl_constants.TYPE_RATIO or return_type.type == stl_constants.TYPE_MISMATCH:
            total += r  # total number of mismatches for ret_type = MISMATCH
        else:
            detailed_result = [
                detailed_result[0] + r[0], detailed_result[1] + r[1],
                detailed_result[2] + r[2], detailed_result[3] + r[3]
            ]  # fp, fn, tp, tn

    if return_type.type == stl_constants.TYPE_RATIO:
        return total / count
    elif return_type.type == stl_constants.TYPE_MISMATCH:
        return total
    elif return_type.type == stl_constants.TYPE_PRECISION:
        return float(metrics_util.calculate_precision(detailed_result))
    elif return_type.type == stl_constants.TYPE_RECALL:
        return float(metrics_util.calculate_recall(detailed_result))
    elif return_type.type == stl_constants.TYPE_F1_SCORE:
        return float(metrics_util.calculate_f1_score(detailed_result))
    elif return_type.type == stl_constants.TYPE_FHALF_SCORE:
        return float(metrics_util.calculate_fhalf_score(detailed_result))
    elif return_type.type == stl_constants.TYPE_F_015_SCORE:
        return float(metrics_util.calculate_f_Beta_score(
            detailed_result, 0.15))
    elif return_type.type == stl_constants.TYPE_F_02_SCORE:
        return float(metrics_util.calculate_f_Beta_score(detailed_result, 0.2))
    elif return_type.type == stl_constants.TYPE_F_03_SCORE:
        return float(metrics_util.calculate_f_Beta_score(detailed_result, 0.3))
    elif return_type.type == stl_constants.TYPE_F_04_SCORE:
        return float(metrics_util.calculate_f_Beta_score(detailed_result, 0.4))
    else:
        return detailed_result
예제 #23
0
import unittest
import random
from trace_checker import STL
from trace_checker import formula_utilities as U
import syntactically_cosafe_form as scf

_data_points = [
    STL.DataPoint(0, [0]),
    STL.DataPoint(2, [1]),
    STL.DataPoint(4, [3]),
    STL.DataPoint(6, [8])
]


class Test_syntactically_cosafe_form(unittest.TestCase):
    def test_scf(self):
        formula = 'P 1 1 ( x0 = 1 )'
        formula_X0, dict0 = 'X p0', {'x0=1.0': 'p0'}
        sc_formula = scf.return_sc_form(formula, prefix=False)
        formula_X, dict = scf.turn_inequalities_to_atomic_propositions(
            sc_formula)
        self.assertEqual(formula_X, formula_X0)
        self.assertEqual(dict, dict0)

        formula = 'P 1 2 ( x0 = 1 )'
        formula_X0, dict0 = '( X p0 | XX p0 )', {'x0=1.0': 'p0'}
        sc_formula = scf.return_sc_form(formula, prefix=False)
        formula_X, dict = scf.turn_inequalities_to_atomic_propositions(
            sc_formula)
        self.assertEqual(formula_X, formula_X0)
        self.assertEqual(dict, dict0)
def cause_mining_algorithm(metric_list, control_metrics, set_valued_metrics, parameter_domains, folder_name,
                           trace_count, signal_file_base, process_count, save, result_file, return_type,
                           strictly_increasing_oc, valuation_limit, operator_count_limit, withoutS=False,
                           controllable_formulas=True, time_shift=0):
    """

    Args:
        metric_list:
        control_metrics:
        set_valued_metrics:
        parameter_domains:
        folder_name:
        trace_count:
        signal_file_base:
        process_count:
        save:
        result_file:
        return_type:
        strictly_increasing_oc: (bool) If False, the heuristic is applied while increasing operator count, if True,
        operator count increases by one in each loop.
        valuation_limit: the predefined limit which decides how much of a value addition is enough for a best formula of
        an operator count to enter the past_formula list.
        operator_count_limit: Last operator count. The best_formulas are searched for until operator count reaches this
        integer value.
        controllable_formulas: (bool) if True, cause_mining input is given to formula_search as True, and
                               generate_formula_tree_cause_mining is called inside formula_search_operator_count as a
                               consequence. That is, controllable formulas are synthesized.
                                    if False, cause_mining input is given to formula_search as False, and
                                    generate_formula_tree_iterative is called inside formula_search_operator_count as a
                                    consequence. That is, all kinds of formulas are generated.
                                By default, controllable_formulas = True, so only controllable formulas are generated.
    Returns: FormulaValuation(the resulting formula -small best formulas concatenated with ors- in prefix form, its valuation)

    """
    if type(operator_count_limit) is int:
        oc_rhs_limit = operator_count_limit
    else:
        _, oc_rhs_limit = operator_count_limit

    if controllable_formulas:  # we do this since if controllable_formulas == True, the code will enter generate_formula_tree_iterative and this function cannot process oc = -1
        current_oc = -1
    else:
        current_oc = 0
    past_results = []  # all formulas in past_results must be in prefix form

    if not strictly_increasing_oc:
        last_used_oc = current_oc
        while True:
            results, best_formula = formula_search.formula_search(metric_list=metric_list,
                                                                  set_valued_metrics=set_valued_metrics,
                                                                  operator_counts=[current_oc],
                                                                  parameter_domains=parameter_domains,
                                                                  folder_name=folder_name,
                                                                  trace_count=trace_count, generate_signals="",
                                                                  signal_file_base=signal_file_base,
                                                                  process_count=process_count,
                                                                  save=save, cause_mining=controllable_formulas,
                                                                  return_type=return_type,
                                                                  result_file=result_file,
                                                                  control_metrics=control_metrics,
                                                                  past_results=past_results, withoutS=withoutS,
                                                                  time_shift=time_shift)
            # turn the formula into prefix form, and then append it to past_results.
            best_formula_prefix = stl_constants.FormulaValuation(formula=STL.infix_to_prefix(best_formula.formula),
                                                                  valuation=best_formula.valuation)
            past_results.append(best_formula_prefix)
            if len(past_results) > 1 and (past_results[-1].valuation - past_results[-2].valuation) < valuation_limit:
                past_results.pop()
                if last_used_oc < current_oc:
                    print("break 1")
                    break
                current_oc += 1
                print("oc change to " + str(current_oc))

            elif len(past_results) > 1 and (past_results[-1].valuation - past_results[-2].valuation) > valuation_limit:
                last_used_oc = current_oc
                print("last used oc : " + str(last_used_oc))

            print("?????????????????? PAST RESULTS SO FAR ???????????????????????????")
            print(past_results)
            #helper_funs.print_past_formulas_prefix_infix_valuation(past_results=past_results, folder_name=folder_name,
            #                                                       signal_file_base=signal_file_base,
            #                                                       trace_count=trace_count,
            #                                                       signal_file_rest='', return_type=return_type)

            if current_oc == oc_rhs_limit+1:
                break

    else:  # i.e. if strictly_increasing_oc:

        while True:
            results, best_formula = formula_search.formula_search(metric_list=metric_list,
                                                                  set_valued_metrics=set_valued_metrics,
                                                                  operator_counts=[current_oc],
                                                                  parameter_domains=parameter_domains,
                                                                  folder_name=folder_name,
                                                                  trace_count=trace_count, generate_signals="",
                                                                  signal_file_base=signal_file_base,
                                                                  process_count=process_count,
                                                                  save=save, cause_mining=controllable_formulas,
                                                                  return_type=return_type,
                                                                  result_file=result_file,
                                                                  control_metrics=control_metrics,
                                                                  past_results=past_results,
                                                                  time_shift=time_shift)
            # turn the formula into prefix form, and the append it to past_results.
            best_formula_prefix = stl_constants.FormulaValuation(formula=STL.infix_to_prefix(best_formula.formula),
                                                                  valuation=best_formula.valuation)
            past_results.append(best_formula_prefix)

            if len(past_results) > 1 and (past_results[-1].valuation - past_results[-2].valuation) < valuation_limit:
                past_results.pop()
                print("break 2")
                break
            current_oc += 1
            if current_oc == operator_count_limit+1:
                break

            print("?????????????????? PAST RESULTS SO FAR ???????????????????????????")
            print(past_results)

    past_formulas = [fv.formula for fv in past_results]
    #for formula_valuation in past_results:
        #past_formulas.append(STL.prefix_to_infix(formula_valuation.formula))
    # now the list is consisted of infix formulas, it can go into concat_with_or
    result = stl_constants.FormulaValuation(formula=helper_funs.concat_with_or_prefix(past_formulas),
                                             valuation=past_results[-1].valuation)
    return result
def plot_change_wrt_parameter(formula, parameter_name, parameter_domain, folder_name, signal_file_base, trace_count):

    """
        Written as a function to see how "good" a formula is, mainly to help us debug.
        This function takes a formula with one parameter and parameter domain, replaces the parameter name
        with numbers in parameter domain and plots the change in the tp, tn, fp, tp+tn, precision, recall results
    """

    tp_plus_tn = []
    fp_plus_fn = []
    index_cnt = 0
    formulas = np.zeros((len(parameter_domain),
                         13))  # 13 corresponds to the 13 values evaluate_signals_deneme returs: fp,fn,tp,tn,precision,recall,f.5,f.4,f.3,f.2,f.15,f.1
    for i in parameter_domain:
        new_formula = formula.replace(parameter_name, str(i))
        print(new_formula)
        return_type = stl_constants.__DETAILED  # evaluate_signals returns fp,fn,tp,tn
        formulas[index_cnt, :4] = evaluator.evaluate_signals(formula=new_formula, folder_name=folder_name,
                                                             signal_file_base=signal_file_base, trace_count=trace_count,
                                                             signal_file_rest='', return_type=return_type)
        formulas[index_cnt, 5] = metrics_util.calculate_precision(formulas[index_cnt, :4])
        formulas[index_cnt, 6] = metrics_util.calculate_recall(formulas[index_cnt, :4])
        formulas[index_cnt, 7] = metrics_util.calculate_f_Beta_score(formulas[index_cnt, :4], 0.5)  # f0.5
        formulas[index_cnt, 8] = metrics_util.calculate_f_Beta_score(formulas[index_cnt, :4], 0.4)  # f0.4
        formulas[index_cnt, 9] = metrics_util.calculate_f_Beta_score(formulas[index_cnt, :4], 0.3)  # f0.3
        formulas[index_cnt, 10] = metrics_util.calculate_f_Beta_score(formulas[index_cnt, :4], 0.2)  # f0.2
        formulas[index_cnt, 11] = metrics_util.calculate_f_Beta_score(formulas[index_cnt, :4], 0.15)  # f0.15
        formulas[index_cnt, 12] = metrics_util.calculate_f_Beta_score(formulas[index_cnt, :4], 0.1)  # f0.1


        # the code piece between two identical prints only serves the need to see the values in the console, this part is useless for the plot
        #     print('\n#################### plot_change_wrt_parameter #####################')
        #     tp = int(formulas[index_cnt][0])
        #     tn = int(formulas[index_cnt][1])
        #     fp = int(formulas[index_cnt][2])
        #     fn = int(formulas[index_cnt][3])
        #     prec = int(formulas[index_cnt][4])
        #     recall = int(formulas[index_cnt][5])
        #     f1score = int(formulas[index_cnt][6])
        #     fhalfscore = int(formulas[index_cnt][7])
        #     print('tp: '+ str(tp) + ' tn: '+str(tn) + ' fp: '+ str(fp) + ' fn: ' + str(fn) + ' precision: '+ str(prec) + ' recall: ' + str(recall) + ' f1 score: ' + str(f1score) + ' f0.5 score: ' + str(fhalfscore))
        #     print('#################### plot_change_wrt_parameter #####################\n')

        tp_plus_tn.append(formulas[index_cnt][2] + formulas[index_cnt][3])
        fp_plus_fn.append(formulas[index_cnt][0] + formulas[index_cnt][1])
        index_cnt += 1

    t = [i for i in parameter_domain]
    # plot 1 : t vs. True Positive
    plt.subplot(8, 1, 1)
    plt.plot(t, formulas[:, 0], '-go')

    # above operations are done to write the formula in infix form
    stn = STL.SyntaxTreeNode()
    dummy_parameter = '999'  # this parameter is solely used to get our way around the stn.initialize_node function
    # by giving a dummy parameter in stead of parameter name to initialize the node properly. Then we replace this
    # dummy variable with parameter_name again to print the formula in infix form
    formula = formula.replace(parameter_name, dummy_parameter)
    stn.initialize_node(formula.split(), 0)

    plt.title('Formula = ' + stn.to_formula().replace(dummy_parameter, parameter_name))
    plt.ylabel('True Positive')

    # arranging plot 1 view
    [xmin, xmax, ymin, ymax] = plt.axis()
    y_axis_space = (ymax - ymin) / 5
    plt.axis([xmin, xmax, ymin - y_axis_space, ymax + y_axis_space])

    # arranging x axis labels
    ax = plt.gca()
    ax.set_xticks(t)
    ax.set_xticklabels(t)

    # plot 2 : t vs. False Positive
    plt.subplot(8, 1, 2)
    plt.plot(t, formulas[:, 0], '-co')
    plt.ylabel('False Positive')

    # arranging x axis labels
    ax = plt.gca()
    ax.set_xticks(t)
    ax.set_xticklabels(t)

    # plot 3 : t vs. F 0.5 Score
    plt.subplot(8, 1, 3)
    plt.plot(t, formulas[:, 7], '-ro', label="F 0.5")
    plt.ylabel('F 0.5')
    plt.legend()

    # arranging x axis labels
    ax = plt.gca()
    ax.set_xticks(t)
    ax.set_xticklabels(t)

    # plot 4 : t vs. F 0.4 Score
    plt.subplot(8, 1, 4)
    plt.plot(t, formulas[:, 8], '-ro', label="F 0.4")
    plt.ylabel('F 0.4')
    plt.legend()

    # arranging x axis labels
    ax = plt.gca()
    ax.set_xticks(t)
    ax.set_xticklabels(t)

    # plot 5 : t vs. F 0.3 Score
    plt.subplot(8, 1, 5)
    plt.plot(t, formulas[:, 9], '-ro', label="F 0.3")
    plt.ylabel('F 0.3')
    plt.legend()

    # arranging x axis labels
    ax = plt.gca()
    ax.set_xticks(t)
    ax.set_xticklabels(t)

    # plot 6 : t vs. F 0.2 Score
    plt.subplot(8, 1, 6)
    plt.plot(t, formulas[:, 10], '-ro', label="F 0.2")
    plt.ylabel('F 0.2')
    plt.legend()

    # plot 7 : t vs. F 0.15 Score
    plt.subplot(8, 1, 7)
    plt.plot(t, formulas[:, 11], '-ro', label="F 0.15")
    plt.ylabel('F 0.15')
    plt.legend()

    # arranging x axis labels
    ax = plt.gca()
    ax.set_xticks(t)
    ax.set_xticklabels(t)

    # plot 8 : t vs. F 0.1 Score
    plt.subplot(8, 1, 8)
    plt.plot(t, formulas[:, 12], '-ro', label="F 0.1")
    plt.ylabel("F 0.1")
    plt.legend()

    # arranging plot 3 view
    #[xmin, xmax, ymin, ymax] = plt.axis()
    #y_axis_space = (ymax - ymin) / 5
    #plt.axis([xmin, xmax, ymin - y_axis_space, ymax + y_axis_space])

    # arranging x axis labels
    ax = plt.gca()
    ax.set_xticks(t)
    ax.set_xticklabels(t)

    # plt.legend(bbox_to_anchor=(0.8, 1), loc=2, borderaxespad=0.)
    plt.show()
import sys

from trace_checker import STL
import evaluator
import stl_constants

#( XX p0 & ( p1 & p2 ) ) {'x5=0.0': 'p0', 'x3>10.0': 'p1', 'x2<20.0': 'p2'}
#( p0 & XX p1 ) {'x5=0.0': 'p0', 'x3>10.0': 'p1'}
#( P 1 1 ( ( x1 > 15 ) & ( x7 = 1 ) & ( x6 = 0 ) ) )  |  ( P 1 1 ( ( x1 > 25 ) & ( x7 = 1 ) ) )  |  ( P 1 1 ( ( x4 < 10 ) & ( x7 = 1 ) & ( x6 = 0 ) ) )

#print(sys.argv[1])
#optimized_formula=sys.argv[1]
optimized_formula='( P 1 1 ( ( v1 > 15 ) & ( v7 = 1 ) & ( v6 = 0 ) ) )  |  ( P 1 1 ( ( v1 > 25 ) & ( v7 = 1 ) ) )  |  ( P 1 1 ( ( v4 < 10 ) & ( v7 = 1 ) & ( v6 = 0 ) ) )'
folder_name = 'D:/CASE STUDY/ptSTL/stl_fs_sm-master/stl_fs_sm-master/test_data/traffic_data/traffic_data_l6/'
signal_file_base = 'test'

result = evaluator.evaluate_signals(STL.infix_to_prefix(optimized_formula), folder_name, signal_file_base, 20,
                                    '',
                                    stl_constants.__DETAILED, stn=None,
                                    past_results=[])
# print('for formula = ' + optimized_formula + ' result is: ' + str(result))

print(str(result))
#[22, 2, 454, 1322]
def cause_mining_for_basic_example(pc,
                                   valuation_limit,
                                   folder_name,
                                   trace_count,
                                   signal_file_base,
                                   return_type,
                                   operator_count_limit,
                                   withoutS=False,
                                   controllable_formulas=True):
    """
    Calls cause_mining_algorithm -with heuristic- from cause_mining_algo package with basic_example data.

    Returns: best formula in prefix form

    """
    print(
        "---------------------------------------------------------------------------------------"
    )
    print("                         cause_mining_for_basic_example ")
    print(
        "---------------------------------------------------------------------------------------"
    )
    start_time = time.time()
    save = False

    metric_list = ['0', '1']
    control_metrics = ['1']
    set_valued_metrics = ['1']
    parameter_domains = {
        'p0': range(3, 6, 1),
        'p1': [-2, 1, 2],
        'pA': range(0, 3, 1),
        'pP': range(0, 3, 1),
        'pS': range(0, 3, 1),
        'pT': [1, 2]
    }
    result_file = 'min_max'
    strictly_increasing_oc = False
    best_result = cause_mining_heuristic.cause_mining_algorithm(
        metric_list=metric_list,
        control_metrics=control_metrics,
        set_valued_metrics=set_valued_metrics,
        parameter_domains=parameter_domains,
        folder_name=folder_name,
        trace_count=trace_count,
        signal_file_base=signal_file_base,
        process_count=pc,
        save=save,
        result_file=result_file,
        return_type=return_type,
        strictly_increasing_oc=strictly_increasing_oc,
        valuation_limit=valuation_limit,
        operator_count_limit=operator_count_limit,
        withoutS=withoutS,
        controllable_formulas=controllable_formulas)  # type: FormulaValuation
    # formula is in prefix form

    print('### --------end of cause mining for basic example -------- ### ')
    print("Best Result in prefix form : " + best_result.formula +\
          "\nBest Result in infix form: " + STL.prefix_to_infix(best_result.formula) + \
          "\nWith the Valuation : " + str(best_result.valuation))
    end_time = time.time()
    print("")
    print(
        "---------------------------------------------------------------------------------------"
    )
    print("cause_mining_for_basic_example ended in %s seconds" %
          str(end_time - start_time))
    print(
        "---------------------------------------------------------------------------------------"
    )
    print("folder name: " + folder_name)
    print("trace count: " + str(trace_count))
    print("processor count: " + str(pc))
    print("parameter domains: " + str(parameter_domains))
    print("return type: " + return_type.name)
    print("strictly increasing: " + str(strictly_increasing_oc))
    print("searched until operator count: " + str(operator_count_limit))

    return best_result.formula  # prefix formula
예제 #28
0
def signal_generator_for_plot(trace_start_index, folder_name, name,
                              traffic_file, trace_count, viol_formula,
                              duration, formula):
    """

    Args:
      trace_start_index:
      folder_name:
      name:
      traffic_file:
      trace_count:
      viol_formula:
      duration:
      cause_formula: (prefix) This is None if we are not constructing a controller, has a value otherwise.

    Returns tuple (metrics,inputs, parameter_domains)  where
      metrics: The list of metrics
      inputs: A list of controllable metrics (inputs is subset of metrics)
      parameter_domains: A dictionary containing the domains of parameters

      Sample return: ([0,1,2], [2], {'p0': [0, 10], 'p1': [0, 10], 'p2': ['a', 'b']}) Note that the domain for the input
      metrics is always set valued.
    """

    # First construct the traffic network.
    # In loop, generate trace. check it against the formula, produce the label. Save both
    link_dict, intersection_dict = read_input.load_from_annotated_file(
        traffic_file)
    tn = network.Network(link_dict, intersection_dict, scale=5)

    tc = 0
    while tc < trace_count:
        index = trace_start_index + tc
        f_signal_name = folder_name + "/" + name + "_" + str(index)
        f_label_name = f_signal_name + "_label"
        f_formula_label_name = f_signal_name + "_formula_label"
        f_s = open(f_signal_name, 'w')
        f_l = open(f_label_name, 'w')
        f_fl = open(f_formula_label_name, 'w')

        time = 0
        # The states of the links
        xk = np.zeros(tn.get_link_count())
        sm = [_ for _ in range(tn.get_intersection_count())]

        tn.initialize_links(xk, 0.1)
        tn.set_random_signal_mode(sm)

        # Initialize the checker:
        stn_viol = STL.SyntaxTreeNode()
        stn_viol.initialize_node(viol_formula.split(), 0)
        stn_cause = STL.SyntaxTreeNode()
        stn_cause.initialize_node(formula.split(), 0)
        sm_numbers = [0 if x == 'a' else 1 for x in sm]

        while time <= duration:
            # Store the values to the file:
            stn_viol.compute_qv(
                STL.DataPoint(value=xk.tolist() + sm_numbers, time=time))
            f_s.write("%s %s %s\n" % (str(time), " ".join(
                [str(x) for x in xk]), " ".join([str(x) for x in sm_numbers])))
            qual1 = 0 if stn_viol.qv >= 0 else 1
            f_l.write("%s %s\n" % (str(time), str(qual1)))
            stn_cause.compute_qv(
                STL.DataPoint(value=xk.tolist() + sm_numbers, time=time))
            qual2 = 0 if stn_cause.qv >= 0 else 1
            f_fl.write("%s %s\n" % (str(time), str(qual2)))

            xk, _ = tn.step(xk, sm)
            tn.set_random_signal_mode(sm)
            sm_numbers = [0 if x == 'a' else 1 for x in sm]

            time += 1

        f_s.close()
        f_l.close()
        f_fl.close()
        print("Done %d" % index)
        tc += 1
예제 #29
0
def controller(folder_name,
               name,
               trace_count,
               duration,
               viol_formula,
               cause_formula,
               step_function,
               xk_initialized,
               uk_domain,
               uk_count,
               num_to_let=False):
    """
  IMPORTANT!:  We make the assumption that an input value (control or system) is ordered in the following way:
  The first xk_count numbers starting from 0 are for system inputs, the following uk_count ones, starting from xk_count
  are control inputs. For example, if xk_count = 3 and uk_count = 2, x0,x1 and x2 are system inputs and x3,x4 are control
  inputs. We also make the assumption that uk_domain is the same for each control input.
  Args:
    folder_name:
    name:
    trace_count:
    viol_formula:
    duration:
    cause_formula: (prefix) This is None if we are not constructing a controller, has a value otherwise.
    step_function: a function xk, _ = step(xk,uk) that takes old xk and uk values and returns the new xk value with
    another unimportant value.
    uk_domain: (list) of domain of uk values
    uk_count: the number of control inputs
    xk_initialized: (tuple, numpy array or list) initialized xk values
    num_to_let:(bool) if step_function takes xk's in the form of letters a and b instead of numbers 1 and 0, this value
    must be given as True. This variable is set specifically for traffic network's step function's needs.

  """
    npml = 0  # "no possible modes left" count
    #viol_cnt = 0
    xk_count = len(xk_initialized)
    iter_uk_crossproduct = product(uk_domain, repeat=uk_count)
    uk_crossproduct = []
    # set list of all possible uk combinations
    for prod in iter_uk_crossproduct:
        uk_crossproduct.append(prod)

    # First construct the traffic network.
    # In loop, generate trace. check it against the formula, produce the label. Save both

    tc = 0
    while tc < trace_count:
        f_signal_name = folder_name + "/" + name + "_" + str(tc)
        f_label_name = f_signal_name + "_label"
        f_s = open(f_signal_name, 'w')
        f_l = open(f_label_name, 'w')

        time = 0
        # initialize the states of system inputs
        xk = xk_initialized
        xk = xk_tolist(xk)

        # break the formula into its components
        formula_list = hf.break_formula(cause_formula)
        formula_components = hf.give_formula_components(formula_list)

        # Initialize the checker:
        stn_viol = STL.SyntaxTreeNode()
        stn_viol.initialize_node(viol_formula.split(), 0)

        # Initialize a number representing the last value where uk was not ck for each formula component's left side
        control_array = np.full((len(formula_list), 1), -1)

        while time <= duration:

            # new uk's free values are determined upon old xk and uk values
            uk_works = False
            free_control_values = copy.deepcopy(uk_crossproduct)
            while not uk_works:
                # set uk randomly from free_control_values
                rand_index = random.randint(
                    0,
                    len(free_control_values) -
                    1)  # very weirdly, random.randint(a,b) can give out b
                uk = list(free_control_values[rand_index])

                j = 0
                while j in range(len(formula_list)):
                    # check if left side is satisfied by checking if A 1, b-1 (u=c) is satisfied
                    # and if u = c at this randomly generated uk.
                    control_input = formula_components[j][
                        0].left_node.metric - xk_count
                    control_input_val = formula_components[j][
                        0].left_node.param
                    control_input_length = formula_components[j][
                        0].interval.ub + 1  # orjinal formul A 1 1 ise length = 0
                    if uk[control_input] == control_input_val and (
                            control_input_length == 0
                            or time - control_array[j] > control_input_length):
                        # left side is satisfied for A 0 b-2 ( u = c ), check if right formula is satisfied
                        right_side_satisfied = False
                        if formula_components[j][1] == None:
                            right_side_satisfied = True
                        else:
                            copy_stn = copy.deepcopy(formula_components[j][1])
                            copy_stn.compute_qv(
                                STL.DataPoint(value=xk + uk, time=time))
                            if copy_stn.qv > 0:
                                right_side_satisfied = True
                        if right_side_satisfied:
                            break
                    j += 1

                if j == len(formula_list):
                    uk_works = True
                else:
                    free_control_values = hf.safe_remove(
                        free_control_values, tuple(uk))
                if len(free_control_values) == 0:
                    print("No possible free control combinations left")
                    npml += 1
                    rand_index = random.randint(0, len(uk_crossproduct) - 1)
                    uk = list(uk_crossproduct[rand_index])
                    uk_works = True

            # we found a working uk for the corresponding xk
            # update all stns and linked_list values with this uk and xk values
            for i in range(len(formula_list)):
                if formula_components[i][1] is not None:
                    formula_components[i][1].compute_qv(
                        STL.DataPoint(value=xk + uk, time=time))
                control_input = formula_components[i][
                    0].left_node.metric - xk_count
                control_input_val = formula_components[i][0].left_node.param
                if not uk[control_input] == control_input_val:
                    control_array[
                        i] = time  # en son bu time'da uk[control_input], control_input_val'dan degisikti

            # compute label, write new xk, uk and label to the file
            stn_viol.compute_qv(STL.DataPoint(value=xk + uk, time=time))
            f_s.write("%s %s\n" %
                      (str(time), " ".join([str(x) for x in xk + uk])))
            qual = 0 if stn_viol.qv >= 0 else 1
            f_l.write("%s %s\n" % (str(time), str(qual)))

            # new xk is calculated from this loop's xk and uk values
            if num_to_let:
                uk_letters = ['a' if x == 0 else 'b' for x in uk]
                xk, _ = step_function(xk, uk_letters)
            else:
                xk, _ = step_function(xk, uk)

            xk = xk_tolist(xk)

            time += 1

        f_s.close()
        f_l.close()
        print("Done %d" % tc)
        tc += 1

    print("There were no possible modes left for a controller input for " +
          str(npml) + " times.")
예제 #30
0
def find_best_formula(heuristic, controllable_formulas):
    folder_name = 'test_data/toy_example_data/'
    trace_count = 20
    signal_file_base = 'test'
    signal_file_rest = ""
    duration = 100

    if controllable_formulas:
        oc_limit_lhs = 1
        oc_limit_rhs = 0
        oc_limit = [oc_limit_lhs, oc_limit_rhs]
    else:
        oc_limit = 2
    cause_limit = 1
    pc = 8
    return_type = stl_constants.__F_03_SCORE
    withoutS = True
    upto = False

    valuation_limit = 0.0001
    operator_count_limit_heuristic = 100

    print("operator_count_limit = " + str(oc_limit))
    print("pc = " + str(pc))
    print("return type = " + str(return_type.category))
    print("withoutS = " + str(withoutS))
    print("heuristic = " + str(heuristic))
    if heuristic:
        print("valuation_limit = " + str(valuation_limit))
    else:
        print("cause_limit = " + str(cause_limit))
        print("upto = " + str(upto))

    if heuristic:
        cause_formula_prefix = heuristic_toy_example(
            pc=pc,
            folder_name=folder_name,
            valuation_limit=valuation_limit,
            trace_count=trace_count,
            signal_file_base=signal_file_base,
            operator_count_limit=operator_count_limit_heuristic,
            return_type=return_type,
            withoutS=withoutS,
            controllable_formulas=controllable_formulas
        )  # returns prefix formula (string)

    else:
        best_formula = search_all_search_space_toy_example(
            cause_limit=cause_limit,
            pc=pc,
            return_type=return_type,
            folder_name=folder_name,
            trace_count=trace_count,
            signal_file_base=signal_file_base,
            upto=upto,
            operator_count_limit=oc_limit,
            withoutS=withoutS,
            controllable_formulas=controllable_formulas)
        cause_formula_prefix = STL.infix_to_prefix(best_formula)

    cma.cause_mining_main.print_detailed_result(
        prefix=1,
        formula=cause_formula_prefix,
        folder_name=folder_name,
        signal_file_base=signal_file_base,
        signal_file_rest=signal_file_rest,
        trace_count=trace_count)

    return cause_formula_prefix