Ejemplo n.º 1
0
    def rec(current_table):
        """If solution is found, return target. Else, return None."""
        nonlocal t_number
        t_number += 1
        cur_depth = current_table.effective_len()
        if t_number % 10 == 0:
            print(t_number, cur_depth)

        if cur_depth > depth:
            return None

        # First check if the table is closed
        flag_closed, new_S, new_R, move = current_table.is_closed()
        if not flag_closed:
            temp_tables = make_closed(new_S, new_R, move, current_table, sigma, AA)
            for table in temp_tables:
                target = rec(table)
                if target is not None:
                    return target
            return None

        # If is closed, check if the table is consistent
        flag_consistent, new_a, new_e_index, reset_index_i, reset_index_j, reset_i, reset_j = current_table.is_consistent()
        if not flag_consistent:
            temp_tables = make_consistent(new_a, new_e_index, reset_index_i, reset_index_j, reset_i, reset_j, current_table, sigma, AA)
            for table in temp_tables:
                target = rec(table)
                if target is not None:
                    return target
            return None
        
        # If prepared, check conversion to FA
        fa_flag, fa, sink_name = to_fa(current_table, t_number)
        if not fa_flag:
            return None

        # Can convert to FA: convert to OTA and test equivalence
        h = fa_to_ota(fa, sink_name, sigma, t_number)
        equivalent, ctx = equivalence_query_normal(max_time_value, AA, h, prev_ctx)
        # Add counterexample to prev list
        if not equivalent and ctx not in prev_ctx:
            prev_ctx.append(ctx)
        if not equivalent:
            temp_tables = add_ctx_normal(ctx.tws, current_table, AA)
            for table in temp_tables:
                target = rec(table)
                if target is not None:
                    return target
            return None
        else:
            target = copy.deepcopy(h)
            return target
Ejemplo n.º 2
0
    def single_search():
        """Single path search: at each step, pick a random successor."""
        nonlocal round_num

        init_tables = init_table_normal(sigma, AA)
        current_table = random.choice(init_tables)

        # Current hypothesis
        cur_h = None

        while True:
            round_num += 1
            current_table = random_steps(current_table,
                                         15,
                                         cur_h,
                                         comparator=False)
            if current_table == 'failed':
                return None

            if current_table.effective_len() >= 15:
                return None

            print('ctx test:', current_table.effective_len())

            # If prepared, check conversion to FA
            fa_flag, fa, sink_name = to_fa(current_table, t_number)
            if not fa_flag:
                return None

            # Can convert to FA: convert to OTA and test equivalence
            cur_h = fa_to_ota(fa, sink_name, sigma, t_number)

            # equivalent, ctx = equivalence_query_normal(max_time_value, AA, cur_h, prev_ctx)
            equivalent, ctx, _ = pac_equivalence_query(A, max_time_value, AA,
                                                       cur_h, round_num, 0.001,
                                                       0.001)
            if ctx:
                print(ctx.tws)

            # Add counterexample to prev list
            if not equivalent and ctx not in prev_ctx:
                prev_ctx.append(ctx)

            if not equivalent:
                temp_tables = add_ctx_normal(ctx.tws, current_table, AA)
                if len(temp_tables) > 0:
                    current_table = random.choice(temp_tables)
                else:
                    return None
            else:
                return current_table, cur_h
Ejemplo n.º 3
0
    def random_steps(current_table, max_len, cur_h, comparator=True):
        """Execute random_one_step until reaching a candidate.

        Here a candidate means a prepared table that agrees with teacher
        on all existing counterexamples.

        """
        nonlocal t_number

        while current_table.effective_len() < max_len:
            res = random_one_step(current_table)
            if res == 'failed':
                return 'failed'
            elif res == 'candidate':
                # Find shortest difference
                if cur_h is None or not comparator:
                    return current_table
                else:
                    t_number += 1
                    fa_flag, fa, sink_name = to_fa(current_table, t_number)
                    if not fa_flag:
                        return 'failed'
                    h = fa_to_ota(fa, sink_name, sigma, t_number)
                    equivalent, ctx = equivalence_query_normal(
                        max_time_value, cur_h, h, None)
                    assert not equivalent
                    realValue = AA.is_accepted_delay(ctx.tws)
                    value = h.is_accepted_delay(ctx.tws)
                    if (realValue == 1 and value != 1) or (realValue != 1
                                                           and value == 1):
                        temp_tables = add_ctx_normal(ctx.tws, current_table,
                                                     AA)
                        if len(temp_tables) > 0:
                            current_table = random.choice(temp_tables)
                        else:
                            return 'failed'
                    else:
                        return current_table
            else:
                current_table = res
        return 'failed'
Ejemplo n.º 4
0
def main():
    #print("------------------A-----------------")
    paras = sys.argv
    A, _ = buildOTA(paras[1], 's')
    #A,_ = buildOTA("example.json", 's')
    #A.show()
    #print("------------------Assist-----------------")
    AA = buildAssistantOTA(A, 's')
    #AA.show()
    #print("--------------max value---------------------")
    max_time_value = A.max_time_value()
    #print(max_time_value)
    #print("--------------all regions---------------------")
    #regions = get_regions(max_time_value)
    # for r in regions:
    #     print(r.show())
    print("**************Start to learn ...*******************")
    print("---------------initial table-------------------")
    sigma = AA.sigma
    T1 = init_table(sigma, AA)
    t_number = 1
    print("Table " + str(t_number) + " is as follow.")
    T1.show()
    print("-----------------------------------------------")
    start = time.time()
    equivalent = False
    eq_total_time = 0
    table = copy.deepcopy(T1)
    eq_number = 0
    target = None
    while equivalent == False:
        prepared = table.is_prepared(AA)
        while prepared == False:
            flag_closed, new_S, new_R, move = table.is_closed()
            if flag_closed == False:
                temp = make_closed(new_S, new_R, move, table, sigma, AA)
                table = temp
                t_number = t_number + 1
                print("Table " + str(t_number) + " is as follow.")
                table.show()
                print("--------------------------------------------------")
            flag_consistent, new_a, new_e_index = table.is_consistent()
            if flag_consistent == False:
                temp = make_consistent(new_a, new_e_index, table, sigma, AA)
                table = temp
                t_number = t_number + 1
                print("Table " + str(t_number) + " is as follow.")
                table.show()
                print("--------------------------------------------------")
            flag_evi_closed, new_added = table.is_evidence_closed(AA)
            if flag_evi_closed == False:
                temp = make_evidence_closed(new_added, table, sigma, AA)
                table = temp
                t_number = t_number + 1
                print("Table " + str(t_number) + " is as follow.")
                table.show()
                print("--------------------------------------------------")
            prepared = table.is_prepared(AA)
        fa, sink_name = to_fa(table, t_number)
        #print("---------------------------------------------")
        #fa.show()
        #print("---------------------------------------------")
        h = fa_to_ota(fa, sink_name, sigma, t_number)
        #h.show()
        #print("---------------------------------------------")
        target = copy.deepcopy(h)
        eq_start = time.time()
        equivalent, ctx = equivalence_query(max_time_value, AA, h)
        eq_end = time.time()
        eq_total_time = eq_total_time + eq_end - eq_start
        #print(ctx.show())
        eq_number = eq_number + 1
        if equivalent == False:
            temp = add_ctx(ctx.tws, table, AA)
            table = temp
            t_number = t_number + 1
            print("Table " + str(t_number) + " is as follow.")
            table.show()
            print("--------------------------------------------------")
    end_learning = time.time()
    if target is None:
        print("Error! Learning Failed.")
        print("*******************Failed.***********************")
    else:
        print("Succeed! The learned OTA is as follows.")
        print("---------------------------------------------------")
        target.show()
        print("---------------------------------------------------")
        # print("Total time of learning: " + str(end-start))
        # print("---------------------------------------------------")
        # print("Time intervals simplification...")
        # print()
        print("Removing the sink location...")
        print()
        print("The learned One-clock Timed Automtaton: ")
        print()
        target_without_sink = remove_sinklocation(target)
        end_removesink = time.time()
        target_without_sink.show()
        print("---------------------------------------------------")
        print("Total time of learning: " + str(end_learning - start))
        #print("---------------------------------------------------")
        #print("Total time of equivalence queries: " + str(eq_total_time))
        print("---------------------------------------------------")
        print("Total time of learning + simplifying: " +
              str(end_removesink - start))
        print("---------------------------------------------------")
        print("The element number of S in the last table: " +
              str(len(table.S)))
        print("The element number of R in the last table: " +
              str(len(table.R)))
        print(
            "The element number of E in the last table (excluding the empty-word): "
            + str(len(table.E)))
        print("Total number of observation table: " + str(t_number))
        print("Total number of membership query: " +
              str((len(table.S) + len(table.R)) * (len(table.E) + 1)))
        print("Total number of equivalence query: " + str(eq_number))
        print("*******************Successful!***********************")
Ejemplo n.º 5
0
    def random_one_step(current_table):
        """Find a random successor of the current table.

        Here a successor is defined to be the table after executing
        one make_closed, one make_consistent, or one add_ctx_normal
        on existing counterexamples.

        """
        nonlocal t_number

        # First check if the table is closed
        flag_closed, new_S, new_R, move = current_table.is_closed()
        if not flag_closed:
            if debug_flag:
                print(
                    "------------------make closed--------------------------")
            temp_tables = make_closed(new_S, new_R, move, current_table, sigma,
                                      AA)
            if len(temp_tables) > 0:
                return random.choice(temp_tables)
            else:
                return 'failed'

        # If is closed, check if the table is consistent
        flag_consistent, new_a, new_e_index, reset_index_i, reset_index_j, reset_i, reset_j = current_table.is_consistent(
        )
        if not flag_consistent:
            if debug_flag:
                print(
                    "------------------make consistent--------------------------"
                )
            temp_tables = make_consistent(new_a, new_e_index, reset_index_i,
                                          reset_index_j, reset_i, reset_j,
                                          current_table, sigma, AA)
            if len(temp_tables) > 0:
                return random.choice(temp_tables)
            else:
                return 'failed'

        # If prepared, check conversion to FA
        t_number += 1
        fa_flag, fa, sink_name = to_fa(current_table, t_number)
        if not fa_flag:
            return 'failed'

        # Can convert to FA: convert to OTA and test equivalence
        h = fa_to_ota(fa, sink_name, sigma, t_number)

        equivalent, ctx = True, None
        if prev_ctx is not None:
            for ctx in prev_ctx:
                teacher_res = AA.is_accepted_delay(ctx.tws)
                hypothesis_res = h.is_accepted_delay(ctx.tws)
                if teacher_res != hypothesis_res and hypothesis_res != -2:
                    equivalent, ctx = False, ctx

        if equivalent:
            # If equivalent, the current table is a candidate
            return 'candidate'
        else:
            # Otherwise, add counterexample
            temp_tables = add_ctx_normal(ctx.tws, current_table, AA)
            if len(temp_tables) > 0:
                return random.choice(temp_tables)
            else:
                return 'failed'
Ejemplo n.º 6
0
    def parallel_search():
        """Parallel search.
        
        Maintain a list of current tables (of size width). At each iteration,
        pick a number of random successors (of size expand_factor) to form
        the new list of tables. Sort the new list and pick the best 'width'
        tables for the next iteration.

        """
        nonlocal round_num, t_number

        init_tables = init_table_normal(sigma, AA)
        width = 15
        expand_factor = 2
        tables = []
        for i in range(width):
            tables.append(random.choice(init_tables))

        while round_num < 10:
            round_num += 1
            print(round_num)

            new_tables = []
            for i in range(min(len(tables), width)):
                for j in range(expand_factor):
                    if round_num == 1:
                        current_table, cur_h = tables[i], None
                    else:
                        current_table, cur_h, ctx = tables[i]
                        temp_tables = add_ctx_normal(ctx.tws, current_table,
                                                     AA)
                        if len(temp_tables) > 0:
                            current_table = random.choice(temp_tables)
                        else:
                            continue

                    current_table = random_steps(current_table,
                                                 20,
                                                 cur_h,
                                                 comparator=False)
                    if current_table == 'failed':
                        continue

                    if current_table.effective_len() >= 20:
                        continue

                    # If prepared, check conversion to FA
                    t_number += 1
                    fa_flag, fa, sink_name = to_fa(current_table, t_number)
                    if not fa_flag:
                        continue

                    # Can convert to FA: convert to OTA and test equivalence
                    cur_h = fa_to_ota(fa, sink_name, sigma, t_number)

                    equivalent, ctx, sc = pac_equivalence_query(
                        A, max_time_value, AA, cur_h, round_num, 0.001, 0.001)

                    if not equivalent:
                        new_tables.append(
                            (sc, current_table, copy.deepcopy(cur_h), ctx))
                    else:
                        return current_table, cur_h

            new_tables = sorted(new_tables, reverse=True)
            tables = []
            for sc, table, cur_h, ctx in new_tables:
                print(sc, table.effective_len())
                tables.append((table, cur_h, ctx))
                if len(tables) >= width:
                    break

        return None
Ejemplo n.º 7
0
def learn_ota(paras, debug_flag):
    A = buildOTA(paras, 's')
    AA = buildAssistantOTA(A, 's')
    max_time_value = A.max_time_value()

    print("**************Start to learn ...*******************")
    print("---------------initial table-------------------")
    sigma = AA.sigma

    need_to_explore = queue.PriorityQueue()
    for table in init_table_normal(sigma, AA):
        need_to_explore.put((table.effective_len(), table))

    # List of existing counterexamples
    prev_ctx = []

    # Current number of tables
    t_number = 0
    start = time.time()
    eq_total_time = 0
    eq_number = 0
    target = None

    while True:
        if need_to_explore.qsize() == 0:
            break
        depth, current_table = need_to_explore.get()
        t_number = t_number + 1

        if t_number % 1 == 0:
            print(t_number, need_to_explore.qsize(), current_table.effective_len())
        if debug_flag:
            print("Table " + str(t_number) + " is as follow, %s has parent %s by %s" % (current_table.id, current_table.parent, current_table.reason))
            current_table.show()
            print("--------------------------------------------------")

        # First check if the table is closed
        flag_closed, new_S, new_R, move = current_table.is_closed()
        if not flag_closed:
            if debug_flag:
                print("------------------make closed--------------------------")
            temp_tables = make_closed(new_S, new_R, move, current_table, sigma, AA)
            if len(temp_tables) > 0:
                for table in temp_tables:
                    need_to_explore.put((table.effective_len(), table))
            continue

        # If is closed, check if the table is consistent
        flag_consistent, new_a, new_e_index, reset_index_i, reset_index_j, reset_i, reset_j = current_table.is_consistent()
        if not flag_consistent:
            if debug_flag:
                print("------------------make consistent--------------------------")
            temp_tables = make_consistent(new_a, new_e_index, reset_index_i, reset_index_j, reset_i, reset_j, current_table, sigma, AA)
            if len(temp_tables) > 0:
                for table in temp_tables:
                    need_to_explore.put((table.effective_len(), table))
            continue
        
        # If prepared, check conversion to FA
        fa_flag, fa, sink_name = to_fa(current_table, t_number)
        if not fa_flag:
            continue

        # Can convert to FA: convert to OTA and test equivalence
        h = fa_to_ota(fa, sink_name, sigma, t_number)
        eq_start = time.time()
        
        # equivalent, ctx = equivalence_query_normal(max_time_value, AA, h, prev_ctx)
        equivalent, ctx = True, None
        if prev_ctx is not None:
            for ctx in prev_ctx:
                teacher_res = AA.is_accepted_delay(ctx.tws)
                hypothesis_res = h.is_accepted_delay(ctx.tws)
                if teacher_res != hypothesis_res and hypothesis_res != -2:
                    equivalent, ctx = False, ctx
                    ctx = minimizeCounterexample(AA, h, ctx)

        if equivalent:
            AA.equiv_query_num += 1
            equivalent, ctx, _ = pac_equivalence_query(A, max_time_value, AA, h, AA.equiv_query_num, 0.001, 0.001)

        if not equivalent:
            # remove_sinklocation(copy.deepcopy(h)).show()
            print(ctx.tws)

        # print(ratio)

        # Add counterexample to prev list
        if not equivalent and ctx not in prev_ctx:
            prev_ctx.append(ctx)
        eq_end = time.time()
        eq_total_time = eq_total_time + eq_end - eq_start
        eq_number = eq_number + 1
        if not equivalent:
            temp_tables = add_ctx_normal(ctx.tws, current_table, AA)
            if len(temp_tables) > 0:
                for table in temp_tables:
                    need_to_explore.put((table.effective_len(), table))
        else:
            target = copy.deepcopy(h)
            break

    end_learning = time.time()
    if target is None:
        print("---------------------------------------------------")
        print("Error! Learning Failed.")
        print("*******************Failed.***********************")
        return False
    else:
        print("---------------------------------------------------")
        print("Succeed! The learned OTA is as follows.")
        print("-------------Final table instance------------------")
        current_table.show()
        print("---------------Learned OTA-------------------------")
        target.show()
        print("---------------------------------------------------")
        print("Removing the sink location...")
        print()
        print("The learned One-clock Timed Automtaton: ")
        print()
        target_without_sink = remove_sinklocation(target)
        end_removesink = time.time()
        target_without_sink.show()
        print("---------------------------------------------------")
        print("Number of transitions in teacher: " + str(len(A.trans)))
        print("Total number of membership query: " + str(len(AA.membership_query)))
        # print("Total number of membership query (no-cache): " + str(AA.mem_query_num))
        # print("Total number of equivalence query: " + str(len(prev_ctx) + 1))
        print("Total number of equivalence query (no-cache): " + str(AA.equiv_query_num))
        print("Total number of tests: " + str(AA.test_query_num))
        print("Total number of tables explored: " + str(t_number))
        # print("Total number of tables to explore: " + str(need_to_explore.qsize()))
        print("Number of locations in learned table: " + str(len(target_without_sink.locations)))
        print("Total time of learning: " + str(end_learning-start))
        return target_without_sink