예제 #1
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!")
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
예제 #3
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.")
예제 #4
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
예제 #5
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
예제 #6
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
예제 #7
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)