def IsNextStateUncertain(diag_fault_statestring_ID):  # evaluate if next state is uncertain and add it to the fault sequence if it is
    last_state = [] 
    i = 0 
    rows = len(diag_fault_statestring_ID) 
    while i < rows:
        last_state.append(diag_fault_statestring_ID[i][-1]) 
        i += 1 
    i = 0 
    end_loop = [['no'], ['no']] 
    while i < rows: 
        for ended in end_loop: 
            while ended == ['no']: 
                a = DiagnoserFunctions.GetNextStatesInID(last_state[i]) 
                for each in a: 
                    b = DiagnoserFunctions.GetStateName(each) 
                    if DiagnoserFunctions.IsUncertain(b) and each not in diag_fault_statestring_ID[i]: 
                        last_state[i] = each 
                        end_loop[i] = ['no'] 
                        diag_fault_statestring_ID[i].append(each)
                        break  
                    else: 
                        end_loop[i] = ['yes'] 
                ended = end_loop[i] 
        i += 1 
    return diag_fault_statestring_ID 
예제 #2
0
def AnalyseStatePath(state):
    answer = []
    NextStateIds = DiagnoserFunctions.GetNextStatesInID(state)
    status = False

    while status != True:
        for each in NextStateIds:
            NextStateNames = str(
                DiagnoserFunctions.GetNextStatesInNames(str(each)))

            if DiagnoserFunctions.IsCertain(NextStateNames) == True:
                status = True
                answer.append(1)
            else:
                if DiagnoserFunctions.IsOnlySelfloop(each) == 1:
                    status = True
                    answer.append(0)
                else:
                    state_id = DiagnoserFunctions.GetNextStatesInID(each)
                    for cada in state_id:
                        if NextStateIds.__contains__(cada) == False:
                            NextStateIds.append(cada)

            if answer.__contains__(0) == True:
                resposta_final = 0
            else:
                resposta_final = 1

    return (resposta_final)
def IsSafeDiag():
    """[Check if the automata is safe diagnosable. If it is, return True, else, return False]
    """
    # if it is Language Diagnosable:
    if IsDiag():
        strings = FU_s.GetStringPath()

        # run one time for each string
        FC_s_IDs = []
        string_num = 0
        j = 0
        len_strings = 0
        while j < len(strings):
            for cada in strings[j]:
                len_strings += 1
            j += 1

        while string_num < len_strings:
            FC_s_IDs.append(FC_s.GetFC_s_IDs(string_num))
            string_num += 1

        # getting FC(s) names
        FC_s_Names = []
        i = 0
        while i < len(FC_s_IDs):
            names = []
            for each in FC_s_IDs[i]:
                names.append(DiagnoserFunctions.GetStateName(each))
            FC_s_Names.append(names)
            i += 1

    # getting the bad states
        Bad_State = []
        i = 0
        while i < len(FC_s_Names):
            isbad = []
            for each in FC_s_Names[i]:
                if DiagnoserFunctions.IsNotBad(each):
                    isbad.append(False)
                else:
                    isbad.append(True)
            Bad_State.append(isbad)
            i += 1

        i = 0
        diag_seg = True
        while i < len(strings):
            if True in Bad_State[i]:
                diag_seg = False
            i += 1
        return diag_seg

    else:
        return False
def GetFP_s():
    strings = FU_s.GetStringPath()

    Strings = []
    for k in strings:
        for n in k:
            Strings.append(n)

    Fault_Diag_EventStrings_IDs = list()
    for i in range(len(Strings)):
        f_strings = list()
        for each in Strings[i]:
            f_strings.append(
                DiagnoserFunctions.GetEquivalentDiagEventFromAut(each))
        Fault_Diag_EventStrings_IDs.append(f_strings)

    # print(f'Fault_Diag_EventStrings_IDs = {Fault_Diag_EventStrings_IDs}')
    cadeias = DefineStrings.GetDiagStates(Fault_Diag_EventStrings_IDs)
    # print(f'cadeias = {cadeias}')

    lista_fp = []
    for each in cadeias:
        FP = False
        last = each[-1]

        if not PathManager.ConditionCHolds(last, antes_fu=True):
            lista_fp.append('')
        else:
            target_id_last = DiagnoserFunctions.GetNextStatesInID(last)

            if FP:
                lista_fp.append(fp)
            else:
                j = 0
                for i in range(len(each), 0, -1):
                    if i - 2 < 0:
                        break
                    else:
                        if j == 0 and not PathManager.ConditionCHolds(
                                each[i - 2], antes_fu=True):
                            fp = each[i - 1]
                        if PathManager.ConditionCHolds(each[i - 2],
                                                       antes_fu=True):
                            fp = each[i - 2]
                        else:
                            break
                    j += 0
                lista_fp.append(fp)

    nomes_lista_fp = []
    for each in lista_fp:
        nomes_lista_fp.append(DiagnoserFunctions.GetNextStatesInNames(each))

    return nomes_lista_fp
def Get_FU_s():
    Strings = []

    Fault_Events = DefineStrings.GetFaultEventsPosition()

    for each in Fault_Events:
        y = DefineStrings.GetString(each)
        for i in range(0, len(y)):
            Strings.append(y[i])

    i = 0
    Diag_Event_ID = []
    while i < len(Strings):
        diag_event_id = []
        for each in Strings[i]:
            event_id = each
            n = AutomataFunctions.GetEventPosition(event_id)
            aut_event_name = AutomataParser.Aut_Event_Name_Table[n]
            for diag_event_name in DiagnoserParser.Event_Name_Table:
                if aut_event_name == diag_event_name:
                    n = DiagnoserParser.Event_Name_Table.index(diag_event_name)
                    diag_event_id.append(DiagnoserParser.Event_Id_Table[n])
                    break
        Diag_Event_ID.append(diag_event_id)
        i += 1

    FU_s = []
    i = 0
    while i < len(Diag_Event_ID):
        # starting from initial state:
        actual_state = DiagnoserParser.Initial_State_ID
        for each in Diag_Event_ID[i]:
            n = 0
            while n < len(DiagnoserParser.Transition_Event_Table):
                if (each == DiagnoserParser.Transition_Event_Table[n]
                        and actual_state
                        == DiagnoserParser.Transition_Source_Table[n]):
                    actual_state = DiagnoserParser.Transition_Target_Table[n]
                    break
                n += 1
        actual_state_name = DiagnoserFunctions.GetStateName(actual_state)

        if DiagnoserFunctions.IsUncertain(
                actual_state_name):  # just to be sure
            FU_s.append(actual_state_name)
        i += 1

    return FU_s
def GetStringsToFault():
    fault_events = GetFaultEventsPosition() 

    # gets the sequence of events that lead to fault on automata
    fault_aut_strings = []
    for each in fault_events: 
        y = GetString(each) 
        fault_aut_strings.append(y) 
    i = 0 
    rows = len(fault_aut_strings)
    while i < rows:
        fault_aut_strings[i] = list(reversed(fault_aut_strings[i]))
        i += 1

    # gets the same sequence for diagnoser (event IDs may be different)
    fault_diag_strings = []
    i = 0
    while i < (len(fault_aut_strings)):
        diag_string = []
        for each in fault_aut_strings[i]:
            x = DiagnoserFunctions.GetEquivalentDiagEventFromAut(each)
            diag_string.append(x)
        fault_diag_strings.append(diag_string)
        i += 1
    i += 1

    return fault_aut_strings, fault_diag_strings
예제 #7
0
def GetFC_s_IDs(string):  # gets the FC(s) for a given string number

    FU_s_StateNames = FU_s.Get_FU_s() 

    # for this string only, getting the FU(s):
    FU_s_StateIDs = []
    FU_s_StateIDs.append(DiagnoserFunctions.GetStateId(FU_s_StateNames[string]))  

    # and getting the reachable states for this string in ID
    string_states_IDs = DefineStrings.GetDiagReachable(FU_s_StateIDs[0])  

    # getting the names
    string_states_names = []  
    for each in string_states_IDs:  
        string_states_names.append(DiagnoserFunctions.GetStateName(each)) 


    # ignoring the non-certain ones
    the_certain_IDs = [] 
    i = 0  
    while i < len(string_states_names):  
        if DiagnoserFunctions.IsCertain(string_states_names[i]):  
            the_certain_IDs.append(string_states_IDs[i])  
        i += 1  

    # getting the names
    the_certain_names = []
    for each in the_certain_IDs:
        the_certain_names.append(DiagnoserFunctions.GetStateName(each))


    previus_states_uncertain = list()
    for each in the_certain_IDs:
        a = DiagnoserFunctions.GetPrevisousStatesInID(each)
        for k in a:
            b = DiagnoserFunctions.GetStateName(k)
            if DiagnoserFunctions.IsUncertain(b):
                if FU_s_StateNames[string] == b:
                    previus_states_uncertain.append(DiagnoserFunctions.GetStateName(each))
                elif FU_s_StateNames[string] != b and b not in FU_s_StateNames:
                    previus_states_uncertain.append(DiagnoserFunctions.GetStateName(each))            

    FC_s = []
    for each in previus_states_uncertain:
        FC_s.append(DiagnoserFunctions.GetStateId(each))

    return (FC_s)
def IsDiag():  # returns True if automata is diagnosable, and False if it's not
    """[Check if automata is diagonosable. If it is, return True, else, return False]
    """

    # # getting the event sequence to the fault
    strings = FU_s.GetStringPath()

    Strings = []
    for k in strings:
        for n in k:
            Strings.append(n)

    Fault_Diag_EventStrings_IDs = list()
    for i in range(len(Strings)):
        f_strings = list()
        for each in Strings[i]:
            f_strings.append(
                DiagnoserFunctions.GetEquivalentDiagEventFromAut(each))
        Fault_Diag_EventStrings_IDs.append(f_strings)

    # getting these events names
    Fault_Aut_Strings_Names = []
    i = 0
    while i < len(Fault_Diag_EventStrings_IDs):
        state_name = []
        for each in Fault_Diag_EventStrings_IDs[i]:
            state_name.append(DiagnoserFunctions.GetEventName(each))
        state_name.append(AutomataFunctions.GetFaultEventName())
        Fault_Aut_Strings_Names.append(state_name)
        i += 1

    # getting the states to the fail by the ID
    Diag_Fault_StateString_IDs = DefineStrings.GetDiagStates(
        Fault_Diag_EventStrings_IDs)
    # add next states of the string if they're uncertain
    Diag_Uncertain_StateString_IDs = DefineStrings.IsNextStateUncertain(
        Diag_Fault_StateString_IDs)

    test = DefineStrings.IsUncertainCycle(Diag_Uncertain_StateString_IDs,
                                          antes_fu=False)

    if not test[0]:
        IsDiagnosable = True
    else:
        IsDiagnosable = False

    return IsDiagnosable
예제 #9
0
def Build(state):
    aux = []
    aux.append(state)
    for cada in aux:
        FS = Step1(state)
        aux = []
        for each in FS:
            eachname = DiagnoserFunctions.GetNextStatesInNames(str(each))
            if DiagnoserFunctions.IsNormal(eachname) == True:
                if DiagnoserFunctions.IsOnlySelfloop(each) == 0:
                    x = Step1(each)
                    for cada in x:
                        FS.append(str(cada))
            elif DiagnoserFunctions.IsCertain(eachname) == True:
                FCs.append(str(each))
            elif DiagnoserFunctions.IsUncertain(eachname) == True:
                FUax.append(str(each))
예제 #10
0
def Step1(FUn):
    FS = []

    for each in FUn:
        forwards = DiagnoserFunctions.GetNextStatesInID(str(each))
        for cada in forwards:
            FS.append(str(cada))
    return (FS)
예제 #11
0
def GetFU():
    x = 0
    # to_observe = []
    uf = []
    while x < len(DiagnoserParser.State_Name_Table):
        a = DiagnoserFunctions.GetTodoTable(x)
        uncertain_counter = 0
        comp = 0
        for each in a:
            comp = len(a)
            if DiagnoserFunctions.IsUncertain(each) == True:
                uf.append(each)
                uncertain_counter = uncertain_counter + 1
                #        to_observe.append(each)
        if (comp == uncertain_counter):
            x = len(DiagnoserParser.State_Name_Table)
        x = x + 1
    return (uf)
def DiagIDtoName(diag_statestrings_IDs):  # gets the names of diagnoser's states for a given ID sequence
    diag_fault_statestring_names = []
    i = 0
    while i < len(diag_statestrings_IDs):
        seq_row = []
        for each in diag_statestrings_IDs[i]:
            x = DiagnoserFunctions.GetStateName(each)
            seq_row.append(x)
        diag_fault_statestring_names.append(seq_row)
        i += 1
    return diag_fault_statestring_names
def IsNormalCycle(diag_statestring_IDs):  # find uncertain loop in a given string

    # mark all uncertain states on each string
    NormalCycle = False
    i = 0 
    Eventos_falhas = list()
    while i < len(diag_statestring_IDs): 
        j = 0
        for each in diag_statestring_IDs[i]: 
            if DiagnoserFunctions.GetNextStatesInID(each)[0] == each or len(DiagnoserFunctions.GetNextStatesInID(each)) == 0: 
                name = DiagnoserFunctions.GetStateName(each)
                if DiagnoserFunctions.IsNormal(name):
                    NormalCycle = True
                    Eventos_falhas.append(diag_statestring_IDs[i][j])
            j += 1
        i += 1
    if NormalCycle:
        return NormalCycle, Eventos_falhas
    a = '-1'
    Eventos_falhas.append(a)
    return NormalCycle, Eventos_falhas
def IsPred():
    """[Check if automata is predictable. If it is, return True, else, return False]
    """

    IsPredictable = False

    # if it is Language Diagnosable:
    if IsDiag():

        # get reachable states from FU
        FU_states = FU_s.Get_FU_s()

        Reachable = []
        for each in FU_states:
            each_name = DiagnoserFunctions.GetStateId(each)
            Reachable.append(DefineStrings.GetDiagReachable(each_name))

        # getting the names
        i = 0
        Reachable_Names = []
        while i < len(Reachable):
            names = []
            for each in Reachable[i]:
                names.append(DiagnoserFunctions.GetStateName(each))
            Reachable_Names.append(names)
            i += 1

        # test if there is any Normal or Uncertain Cycle (C condition)
        test_normal = DefineStrings.IsNormalCycle(Reachable)
        test_uncertain = DefineStrings.IsUncertainCycle(Reachable,
                                                        antes_fu=True)

        if not test_normal[0] and not test_uncertain[0]:
            IsPredictable = True

        return IsPredictable

    # if it is not Language Diagnosable:
    else:
        return IsPredictable
def GetDiagStates(diag_eventstrings_IDs):  # gets the sequence of diagnoser's states for a given event sequence

    sequence = [] 
    diag_fault_statestring_IDs = [] 

    for cada in diag_eventstrings_IDs: 
        seq_row = [DiagnoserParser.Initial_State_ID]  
        for n in range(0, len(cada)):
            x = DiagnoserFunctions.GetNextState(seq_row[n], cada[n]) 
            seq_row.append(x) 
        sequence.append(seq_row) 
        diag_fault_statestring_IDs.append(seq_row) 

    return diag_fault_statestring_IDs 
def GetDiagReachable(state_ID): 
    string_states_IDs = [] 
    verified_states = []
    actual_state_ID = [state_ID] 
    ended = False 
    while not ended: 
        for each in actual_state_ID:
            if each not in verified_states: 
                verified_states.append(each)
                next_state_IDs = DiagnoserFunctions.GetNextStatesInID(each) 
            for each in next_state_IDs: 
                if each not in string_states_IDs: 
                    string_states_IDs.append(each) 
                    actual_state_ID.append(each) 
        ended = True 
    return string_states_IDs
def AreAllWaysControllable(stateID1,stateID2): 
    event_string = GetDiagnoserStringBtw(stateID1,stateID2) 

    #finding if any event between the states is controllable
    i = 0 
    retval = True 
    while i < len(event_string): 
        test = False 
        for each in event_string[i]: 
            if DiagnoserFunctions.EventIsControllable(each[0]): 
                test = True 
        if not test: 
            retval = False 
        i += 1 

    return retval
def GetDiagnoserStringBtw(sourceID,targetID):
    if targetID in GetDiagReachable(sourceID): 
        State_Sequence = [[sourceID]]
        state = sourceID
        actual_state = state 
        actual_way = 0 
        way_num = 1 
        status = False 
        there_is_loop = False

        loops_event_sequence = list()
        todas_as_cadeias = list()
        num_loop = 0

        while not status:        
            lista_eventos_ruins = list()
            lista_eventos_bons = list()
            lista_termos_ruins = list()
            for i in range(len(State_Sequence)):

                #? Função que tirar loops indevidos. Exemplo: ['1', '2', '1', '2'] 
                #! Isso aqui da pra arrumar, não precisa usar strings, da pra fazer com lista

                n_termos = 0
                for numero in range(1, len(State_Sequence[i])):
                    if numero*2 <= len(State_Sequence[i]):
                        n_termos += 1
                        
                lista_termos = list()
                for k in range(n_termos, 1, -1):
                    for n in range(len(State_Sequence[i]) - k + 1):
                        lista_termos.append(State_Sequence[i][n:n+k])

                for k in range(len(lista_termos)):
                    if k+len(lista_termos[k]) < len(lista_termos):
                        targets_ultimo = DiagnoserFunctions.GetNextStatesInID(State_Sequence[i][-1])
                        if lista_termos[k] == lista_termos[k+len(lista_termos[k])] and len(targets_ultimo) < 3:
                            if len(targets_ultimo) == 1:
                                lista_termos_ruins.append(State_Sequence[i])
                                break

                            else:
                                for j in range(len(State_Sequence[i])):
                                    if State_Sequence[i][j] in DiagnoserFunctions.GetNextStatesInID(State_Sequence[i][j]):
                                        lista_termos_ruins.append(State_Sequence[i])
                                        break
                
                for j in range(len(State_Sequence[i])):
                    if State_Sequence[i].count(str(State_Sequence[i][j])) > 2:
                        lista_eventos_ruins.append(State_Sequence[i])
                        break
                    elif State_Sequence[i].count(str(actual_state)) == 2:
                        lista_eventos_bons.append(State_Sequence[i])
                        break

            if len(lista_eventos_ruins) > 0:
                maior = True
            else:
                maior = False

            if len(lista_eventos_bons) > 0:
                igual = True
            else:
                igual = False

            if len(lista_termos_ruins) > 0:
                repetido = True
            else:
                repetido = False 

            for i in range(0, len(State_Sequence)):
                if  maior:
                    for each in lista_eventos_ruins:
                        State_Sequence.remove(each)
                
                if repetido:
                    for each in lista_termos_ruins:
                        State_Sequence.remove(each)  
                
                
                elif igual:
                    for each in lista_eventos_bons:
                        a = each.copy()
                        State_Sequence.remove(a)
                        loops_sequences = [a]

                        todas_as_cadeias.append(a[:])

                        #? Essa parte faz a mesma coisa que uma parte há baixo, porém lá pega os eventos, enquanto que aqui 
                        #? pega os estados
                        if a[-1] != targetID:
                            final_cadeia = GetDiagnoserStringBtw_WithoutLoop(a[-1], targetID, just_string=True)

                            todas_as_cadeias[-1].pop(-1)
                            for k in range(len(final_cadeia)):
                                final_cadeia[k] = todas_as_cadeias[-1] + final_cadeia[k]
                            todas_as_cadeias.pop(-1)

                            for cadeia in final_cadeia:
                                todas_as_cadeias.append(cadeia)

                        nao = False
                        if targetID in a:
                            nao = True

                        k = 0
                        while k < len(loops_sequences):
                            answer = []
                            j = 0
                            while j < len(loops_sequences[k])-1:
                                answer.append(DiagnoserFunctions.GetEventBetween(loops_sequences[k][j], loops_sequences[k][j+1]))
                                j += 1
                            loops_event_sequence.append(answer)
                            k += 1
                        
                        if not nao:
                            loop_event_sequence = GetDiagnoserStringBtw_WithoutLoop(a[-1], targetID)

                            for k in range(len(loop_event_sequence)):
                                loop_event_sequence[k] = loops_event_sequence[-1] + loop_event_sequence[k]
                            loops_event_sequence.pop(-1)

                            for cadeia in loop_event_sequence:
                                loops_event_sequence.append(cadeia)

                if len(State_Sequence) == 1 and State_Sequence[0][-1] == targetID:
                    status = True

                if len(State_Sequence) == 0:
                    status = True

                if igual or maior or repetido or there_is_loop:
                    if len(State_Sequence) != 0:
                        for k in range(len(State_Sequence)):
                            if State_Sequence[k][-1] == targetID:
                                status = True

                            if State_Sequence[k][-1] != targetID:
                                actual_state = State_Sequence[k][-1]
                                actual_way = k
                                status = False
                                break
                    break

            if status:
                break
            
            NextStatesIds = DiagnoserFunctions.GetNextStatesInID(actual_state) 
            NextState = [] 
            n = 0

            for each in NextStatesIds:
                targets = GetDiagReachable(each) 

                if ((targetID in targets) or (each == targetID)): 
                    NextState.append(each) 
                    n += 1 

            # if more then one next state was saved, increases the number of ways to get to the target
            way_num += len(NextState) -1 

            # and copy actual way how many times it's needed
            i = 1 
            while i < len(NextState): 
                State_Sequence.insert(i+actual_way,copy.deepcopy(State_Sequence[actual_way])) 
                i += 1 

            #save the next states on respectives copied ways
            i = actual_way 
            for each in NextState: 
                State_Sequence[i].append(each) 
                i += 1 

            # if ended one string, go to the next one
            if State_Sequence[actual_way][-1] == targetID:
                actual_way += 1

            # if still have strings to test, update actual_state to last one
            if actual_way < len(State_Sequence):
                actual_state = State_Sequence[actual_way][-1]
            # and if there is no more strings to test, end it
            else:
                status = True

        #? Pega a combinação linear dos loops
        if len(todas_as_cadeias) > 1:

            inicial = True
            final = True
            ld = True

            strings_module = {
                'initial': [],
                'middle':[],
                'different':[],
                'final': []
            }

            i = 0 #posições
            parar = False
            while not parar:
                estado_igual1 = list()
                estado_igual2 = list()
                for j in range(len(todas_as_cadeias)):  #cadeia
                    estado_igual1.append(todas_as_cadeias[j][i])
                    if i != 0:
                        estado_igual2.append(todas_as_cadeias[j][-i])
                        
                    if i+1 == len(todas_as_cadeias[j]):
                        parar = True
                
                if len(set(estado_igual1)) == 1 and inicial:
                    strings_module['initial'].append(estado_igual1[0])
                else:
                    inicial = False
                    
                if len(set(estado_igual2)) == 1 and final:
                    strings_module['final'].append(estado_igual2[0])
                elif i != 0:
                    final = False
                    
                i += 1

            strings_module['final'].reverse()
            strings_module['final'].pop(0)

            diferente = todas_as_cadeias[:]
            for n in range(len(diferente)):
                del(diferente[n][:len(strings_module['initial'])])
                del(diferente[n][-len(strings_module['final']):])
            key_state = diferente[0][-1]

            diferente1 = list()
            for i in range(len(diferente)):
                for k in range(len(diferente[i])):
                    if diferente[i][k] == key_state and k != len(diferente[i])-1:
                        diferente1.append(diferente[i][:k+1])
                        diferente[i] = diferente[i][k+1:]
                        break
            [strings_module['middle'].append(x) for x in diferente1 if not strings_module['middle'].count(x)]
            [strings_module['different'].append(x) for x in diferente if not strings_module['different'].count(x)]

            if len(strings_module['middle']) == 0:
                while strings_module['initial'][-1] != strings_module['different'][0][-1]: #comparando
                    for n in range(len(strings_module['different'])): #adicionando
                        strings_module['different'][n].insert(0, strings_module['initial'][-1])
                    strings_module['initial'].pop(-1) #excluindo
                    if len(strings_module['initial']) == 0:
                        ld = False #então não é linearmente dependente
                        break
            else:
                for i in range(len(strings_module['middle'])):
                    while strings_module['middle'][i][-1] != strings_module['different'][0][-1]: #comparando
                        for n in range(len(strings_module['different'])): #adicionando
                            strings_module['different'][n].insert(0, strings_module['initial'][-1])
                        strings_module['initial'].pop(-1) #excluindo

            if ld: #verificando se é linearmente dependente 
                listao = list()
                if strings_module['middle'] != []:
                    for state in strings_module['middle']:
                        for n in range(len(strings_module['different'])):
                            for k in range(len(strings_module['different'])):
                                if n + k < len(strings_module['different']) and strings_module['different'][n] != strings_module['different'][n+k] and strings_module['initial'] + strings_module['different'][n] + strings_module['different'][n+k] + strings_module['final'] not in State_Sequence: 
                                    listao.append(strings_module['initial'] + state + strings_module['different'][n] + strings_module['different'][n+k] + strings_module['final'])

                                elif strings_module['different'][n] != strings_module['different'][n+k-len(strings_module['different'])] and strings_module['initial'] + strings_module['different'][n] + strings_module['different'][n+k-len(strings_module['different'])] + strings_module['final'] not in State_Sequence:
                                    listao.append(strings_module['initial'] + state + strings_module['different'][n] + strings_module['different'][n+k-len(strings_module['different'])] + strings_module['final'])

                else:
                    for n in range(len(strings_module['different'])):
                            for k in range(len(strings_module['different'])):
                                if n + k < len(strings_module['different']) and strings_module['different'][n] != strings_module['different'][n+k] and strings_module['initial'] + strings_module['different'][n] + strings_module['different'][n+k] + strings_module['final'] not in State_Sequence: 
                                    listao.append(strings_module['initial'] + strings_module['different'][n] + strings_module['different'][n+k] + strings_module['final'])

                                elif strings_module['different'][n] != strings_module['different'][n+k-len(strings_module['different'])] and strings_module['initial'] + strings_module['different'][n] + strings_module['different'][n+k-len(strings_module['different'])] + strings_module['final'] not in State_Sequence:
                                    listao.append(strings_module['initial'] + strings_module['different'][n] + strings_module['different'][n+k-len(strings_module['different'])] + strings_module['final'])
                                    
                for each in listao:
                    n_termos = 0
                    for numero in range(1, len(each)):
                        if numero*2 <= len(each):
                            n_termos += 1

                    lista_termos = list()
                    for i in range(n_termos, 1, -1):
                        for n in range(len(each) - i + 1):
                            lista_termos.append(each[n:n+i])
                            
                    bad_string = False
                    for k in range(len(lista_termos)):
                        if k + len(lista_termos[k]) < len(lista_termos):
                            if lista_termos[k] == lista_termos[k + len(lista_termos[k])]: #verificando se a cadeia repetida
                                if len(lista_termos[k + len(lista_termos[k])]) == len(lista_termos[k + len(lista_termos[k]) + 1]): #verificando se os tamanhos das cadeias são iguais
                                #existe esse if pois se o tamanho for diferente, "lista_termos[k + len(lista_termos[k]) + 1]" não estará correto
                                    if lista_termos[k][-1] + lista_termos[k + len(lista_termos[k])][0] == lista_termos[k + len(lista_termos[k])][-1] + lista_termos[k + len(lista_termos[k]) + 1][-1]:
                                        #verificando se a cadeia está correta, ou seja, se esse loop a mais criado agrega em algo na cadeia final ou é apenas uma repetição
                                        bad_string = True
                                        break
                    if not bad_string:
                        State_Sequence.append(each)

        if len(State_Sequence) != 0:
            primordia_state_sequence = list()
            k = 0
            while k < len(State_Sequence):
                answer = []
                j = 0
                while j < len(State_Sequence[k])-1:
                    answer.append(DiagnoserFunctions.GetEventBetween(State_Sequence[k][j], State_Sequence[k][j+1]))
                    if State_Sequence[k][j+1] == targetID:
                        break
                    j += 1
                
                if len(State_Sequence[k]) == 1:
                    answer.append(DiagnoserFunctions.GetEventBetween(State_Sequence[k][0], State_Sequence[k][0]))
                primordia_state_sequence.append(answer)
                k += 1

            i = 0
            for x in primordia_state_sequence:
                loops_event_sequence.insert(i, x)
                i += 1

        return loops_event_sequence
def GetDiagnoserStringBtw_WithoutLoop(sourceID,targetID, just_string=False):
    Event_Sequence = [] 
    W = 0
    # runs only if it is possible to reach it (returns [] if there is no possible string)
    if targetID in GetDiagReachable(sourceID): 
        State_Sequence = [[sourceID]]
        state = sourceID 
        actual_state = state 
        actual_way = 0 
        way_num = 1 
        status = False 
        first_loop_state = 0
        NextStatesIdsLoop = False

        while not status: 
            NextStatesIds = DiagnoserFunctions.GetNextStatesInID(actual_state) 
            NextState = [] 
            n = 0 

            if first_loop_state == actual_state:
                NextStatesIdsLoop = True
                W += 1
            else:
                first_loop_state = actual_state

            for each in NextStatesIds: 
                targets = GetDiagReachable(each) 
                Loop = AuxiliaryFunctions.loop_verification(targets, State_Sequence[actual_way])

                if ((targetID in targets) or (each == targetID)) and (each not in State_Sequence[actual_way]) and not Loop: 
                    NextState.append(each) 
                    n += 1 

            # if more then one next state was saved, increases the number of ways to get to the target
            way_num += len(NextState) -1 

            if NextStatesIdsLoop and W > 5:
                State_Sequence = AuxiliaryFunctions.NextStatesIdsLoopWithoutLoop(actual_state, targetID, State_Sequence)
                break

            # and copy actual way how many times it's needed
            i = 1 
            while i < len(NextState): 
                State_Sequence.insert(i+actual_way,copy.deepcopy(State_Sequence[actual_way])) 
                i += 1 

            #save the next states on respectives copied ways
            i = actual_way 
            for each in NextState: 
                State_Sequence[i].append(each) 
                i += 1 

            # if ended one string, go to the next one
            if State_Sequence[actual_way][-1] == targetID:
                actual_way += 1

            # if still have strings to test, update actual_state to last one
            if actual_way < len(State_Sequence):
                actual_state = State_Sequence[actual_way][-1]
            # and if there is no more strings to test, end it
            else:
                status = True
        
        if just_string:
            return State_Sequence

        # getting the events for the state sequence
        i = 0
        while i < len(State_Sequence):
            answer = []
            j = 0
            while j < len(State_Sequence[i])-1:
                answer.append(DiagnoserFunctions.GetEventBetween(State_Sequence[i][j], State_Sequence[i][j+1]))
                j += 1
            Event_Sequence.append(answer)
            i += 1
    return Event_Sequence
def IsUncertainCycle(diag_statestring_IDs,antes_fu=False):  # find uncertain loop in a given string

    if not antes_fu:
        UncertainCycle = False
        i = 0 
        Eventos_falhas = list()
        while i < len(diag_statestring_IDs): 
            j = 0
            for each in diag_statestring_IDs[i]:
                target =  DiagnoserFunctions.GetNextStatesInID(each)[0]
                if target == each or len(target) == 0 or each in DiagnoserFunctions.GetNextStatesInID(target): 
                    name = DiagnoserFunctions.GetStateName(each)
                    if DiagnoserFunctions.IsUncertain(name):
                        UncertainCycle = True
                        Eventos_falhas.append(diag_statestring_IDs[i][j])
                Next_States = DiagnoserFunctions.GetNextStatesInID(each) 
                for k in Next_States: 
                    name_next_state = DiagnoserFunctions.GetStateName(k) 
                    if DiagnoserFunctions.IsUncertain(name_next_state) and each in GetDiagReachable(k) and len(Next_States) > 1: 
                        estado_anterior = DiagnoserFunctions.GetPrevisousStatesInID(int(each))
                        nome_estado_anterior = DiagnoserFunctions.GetStateName(estado_anterior[0])
                        
                        if DiagnoserFunctions.IsUncertain(nome_estado_anterior): 
                            UncertainCycle = True
                            Eventos_falhas.append(diag_statestring_IDs[i][j])
                            break
                j += 1
            i += 1
        if UncertainCycle:
            return UncertainCycle, Eventos_falhas
        a = '-1'
        Eventos_falhas.append(a)

        return UncertainCycle, Eventos_falhas

    else:

        fu_name = FU_s.Get_FU_s()
        state_names = []
        state_ids = []
        for k in diag_statestring_IDs:
            for n in k:
                state_ids.append(n)
                state_names.append(DiagnoserFunctions.GetStateName(n))

        uncertain_cycle = False
        uncertain_state = ['-1']
        for i in range(len(state_names)):
            if DiagnoserFunctions.IsUncertain(state_names[i]):
                if state_names[i] not in fu_name:
                    uncertain_cycle = True
                    uncertain_state = [state_ids[i]]

        return uncertain_cycle, uncertain_state
def IsSafeControlByDiag():
    """[Check if automata is safe control by diagnosis. If it is, return True, else, return False]
    """
    # if it is Language Diagnosable:
    if IsDiag():
        strings = FU_s.GetStringPath()

        # getting FC(s) IDs
        FC_s_IDs = []
        string_num = 0
        j = 0
        len_strings = 0
        while j < len(strings):
            for cada in strings[j]:
                len_strings += 1
            j += 1

        while string_num < len_strings:
            FC_s_IDs.append(FC_s.GetFC_s_IDs(string_num))
            string_num += 1

        # getting FC(s) names
        FC_s_Names = []
        i = 0  #atribuindo 0 a i
        while i < len(FC_s_IDs):
            names = []
            for each in FC_s_IDs[i]:
                names.append(DiagnoserFunctions.GetStateName(each))
            FC_s_Names.append(names)
            i += 1

        # getting the FB states
        FB_s_IDs = []
        string_num = 0
        j = 0
        len_strings = 0
        while j < len(strings):
            for cada in strings[j]:
                len_strings += 1
            j += 1

        while string_num < len_strings:
            FB_s_IDs.append(FB_s.GetFB_s_IDs(string_num))
            string_num += 1

        # getting FB(s) names
        FB_s_Names = []
        i = 0
        while i < len(FB_s_IDs):
            names = []
            for each in FB_s_IDs[i]:
                names.append(DiagnoserFunctions.GetStateName(each))
            FB_s_Names.append(names)
            i += 1

        # * first condition is: FC can not be a bad state

        # searching for bad states in FC
        Bad_State = []
        i = 0
        while i < len(FC_s_Names):
            isbad = []
            for each in FC_s_Names[i]:
                if DiagnoserFunctions.IsNotBad(each):
                    isbad.append(False)
                else:
                    isbad.append(True)
            Bad_State.append(isbad)
            i += 1

        # * second condition is: sub-strings must have a controllable state between a FC and a FB

        # getting reachable for each FC
        Sub_Strings_IDs = []
        i = 0
        while i < len(FC_s_IDs):
            reachable = []
            for each in FC_s_IDs[i]:
                reachable.append(DefineStrings.GetDiagReachable(each))
            Sub_Strings_IDs.append(reachable)
            i += 1

        # ignoring the not-FB ones for each sub string
        the_bads_IDs = []
        i = 0
        while i < len(Sub_Strings_IDs):
            j = 0
            bad_sub = []
            while j < len(Sub_Strings_IDs[i]):
                bad_subsub = []
                for each in Sub_Strings_IDs[i][j]:
                    if each in FB_s_IDs[i]:
                        bad_subsub.append(each)
                bad_sub.append(bad_subsub)
                j += 1
            the_bads_IDs.append(bad_sub)
            i += 1

        i = 0
        Controllability = []
        while i < len(FC_s_IDs):
            j = 0
            contr = []
            while j < len(FC_s_IDs[i]):
                cont = []
                for each in the_bads_IDs[i][j]:
                    cont.append(
                        DefineStrings.AreAllWaysControllable(
                            FC_s_IDs[i][j], each))
                j += 1
                contr.append(cont)
            i += 1
            Controllability.append(contr)

        final_strings = []
        for each in strings:
            for j in each:
                final_strings.append(j)

        # testing both conditions:
        i = 0
        Is_Controllable_By_Diagnosis = True
        Each_String_Diag_Controllable = []
        while i < len(final_strings):
            Each_String = True
            if True in Bad_State[i]:
                j = Bad_State[i].index(True)
                Is_Controllable_By_Diagnosis = False
                Each_String = False
            if Each_String:
                w = 0
                while w < len(Controllability[i]):
                    if False in Controllability[i][w]:
                        Is_Controllable_By_Diagnosis = False
                        Each_String = False
                        break
                    w += 1
            Each_String_Diag_Controllable.append(Each_String)
            i += 1
        return Each_String_Diag_Controllable

    # if it is not Language Diagnosable:
    else:
        return False
def IsSafeDiag_Publish():
    """[Check if automata is diagonosable. Return if each string is safe diagonosable]
    """
    print('\n\n* DIAGNOSTICABILIDADE SEGURA\n')

    # if it is Language Diagnosable:
    if IsDiag():
        strings = FU_s.GetStringPath()

        # run one time for each string
        FC_s_IDs = []
        string_num = 0
        j = 0
        len_strings = 0
        while j < len(strings):
            for cada in strings[j]:
                len_strings += 1
            j += 1

        while string_num < len_strings:
            FC_s_IDs.append(FC_s.GetFC_s_IDs(string_num))
            string_num += 1

        # getting FC(s) names
        FC_s_Names = []
        i = 0
        while i < len(FC_s_IDs):
            names = []
            for each in FC_s_IDs[i]:
                names.append(DiagnoserFunctions.GetStateName(each))
            FC_s_Names.append(names)
            i += 1

        # getting the bad states for each string
        Bad_State = []
        i = 0
        while i < len(FC_s_Names):
            isbad = []
            for each in FC_s_Names[i]:
                if DiagnoserFunctions.IsNotBad(each):
                    isbad.append(False)
                else:
                    isbad.append(True)
            Bad_State.append(isbad)
            i += 1

        print('Para cada cadeia da linguagem, calcula-se o FC(s)\n')
        i = 0
        diag_seg = True

        while i < len_strings:
            print('FC(', i + 1, ') =', FC_s_Names[i])
            if True in Bad_State[i]:
                j = Bad_State[i].index(True)
                print('O estado [', FC_s_Names[i][j], '] é um Bad State.',
                      'Portanto, a cadeia', i + 1,
                      'não é diagnosticável segura.\n')
                diag_seg = False
            else:
                print(
                    'A cadeia', i + 1,
                    'não possui Bad States no FC, portanto é diagnosticável segura.\n'
                )
            i += 1

        if diag_seg:
            print('A linguagem é diagnosticável segura.')
        else:
            print('A linguagem não é diagnosticável segura.')

        return diag_seg

    # if it is not Language Diagnosable:
    else:
        print(
            'A linguagem não é diagnosticável segura, pois não é diagnosticável em primeiro lugar.'
        )
        return False
def IsDiag_Publish(
):  # returns True if automata is diagnosable, and False if it's not
    """[Check if automata is diagonosable. Return if each string is diagonosable]
    """

    print('\n\n* DIAGNOSTICABILIDADE\n')

    # # getting the event sequence to the fault
    strings = FU_s.GetStringPath()

    Strings = []
    for k in strings:
        for n in k:
            Strings.append(n)

    Fault_Diag_EventStrings_IDs = list()
    for i in range(len(Strings)):
        f_strings = list()
        for each in Strings[i]:
            f_strings.append(
                DiagnoserFunctions.GetEquivalentDiagEventFromAut(each))
        Fault_Diag_EventStrings_IDs.append(f_strings)

    # getting these events names
    Fault_Aut_Strings_Names = []
    i = 0
    while i < len(Fault_Diag_EventStrings_IDs):
        state_name = []
        for each in Fault_Diag_EventStrings_IDs[i]:
            state_name.append(DiagnoserFunctions.GetEventName(each))
        state_name.append(AutomataFunctions.GetFaultEventName())
        Fault_Aut_Strings_Names.append(state_name)
        i += 1

    # getting the states to the fail by the ID
    Diag_Fault_StateString_IDs = DefineStrings.GetDiagStates(
        Fault_Diag_EventStrings_IDs)
    # add next states of the string if they're uncertain
    Diag_Uncertain_StateString_IDs = DefineStrings.IsNextStateUncertain(
        Diag_Fault_StateString_IDs)
    # get the names for the state string
    Diag_Uncertain_StateString_Names = DefineStrings.DiagIDtoName(
        Diag_Fault_StateString_IDs)

    test = DefineStrings.IsUncertainCycle(Diag_Uncertain_StateString_IDs,
                                          antes_fu=False)

    IsDiagnosable = True
    for i in range(len(Diag_Uncertain_StateString_IDs)):
        incerto = False
        for k in test[1]:
            if k in Diag_Uncertain_StateString_IDs[i]:
                print('A cadeia', i + 1, 'possui um ciclo indeterminado em [',
                      DiagnoserFunctions.GetStateName(k),
                      '] e, portanto, não é diagnosticável.')
                incerto = True
                IsDiagnosable = False
                break
        if not incerto:
            print(
                'A cadeia', i + 1,
                'não possui ciclo indeterminado e, portanto, é diagnosticável.'
            )

    if IsDiagnosable == True:
        print('\nA linguagem é diagnosticável.')
    else:
        print('\nA linguagem não é diagnosticável.')

    return IsDiagnosable
def IsSafeControlByProg_Publish():
    """[Check if automata is safe control by prognosis. Return if each string is safe control by prognosis]
    """
    print('\n\n* CONTROLABILIDADE SEGURA PELA PROGNOSE\n')

    # if it is Language Diagnosable:
    if IsDiag():
        # * first condition is C condition

        # get reachable states from FU.
        FU_states = FU_s.Get_FU_s()
        FU_states_ID = []
        for each in FU_states:
            FU_states_ID.append(DiagnoserFunctions.GetStateId(each))

        Reachable = []
        for each in FU_states:
            each_name = DiagnoserFunctions.GetStateId(each)
            Reachable.append(DefineStrings.GetDiagReachable(each_name))

        # getting the names. Pegando o nomes dos estados alcançaveis a partir dos Fu(s)
        i = 0
        Reachable_Names = []
        while i < len(Reachable):
            names = []
            for each in Reachable[i]:
                names.append(DiagnoserFunctions.GetStateName(each))
            Reachable_Names.append(names)
            i += 1

        # test if there is any Normal or Uncertain Cycle (C condition).
        test_normal = DefineStrings.IsNormalCycle(Reachable)
        test_uncertain = DefineStrings.IsUncertainCycle(Reachable,
                                                        antes_fu=True)

        # * second condition is: sub-strings must have a controllable state between a FP and a FB

        # getting FP(s) names
        FP_s_Names = FP_s.GetFP_s()

        FP_s_IDs = []
        for each in FP_s_Names:
            FP_s_IDs.append(DiagnoserFunctions.GetStateId(each))

        # getting the FB states
        i = 0
        FB_s_IDs = []
        while i < len(FU_states):
            FB_s_IDs.append(FB_s.GetFB_s_IDs(i))
            i += 1

        # getting FB(s) names
        FB_s_Names = []
        i = 0
        while i < len(FB_s_IDs):
            names = []
            for each in FB_s_IDs[i]:
                names.append(DiagnoserFunctions.GetStateName(each))
            FB_s_Names.append(names)
            i += 1

        Sub_Strings_IDs = []
        for each in FP_s_IDs:
            Sub_Strings_IDs.append(DefineStrings.GetDiagReachable(each))

        # ignoring the not-FB ones for each sub string
        the_bads_IDs = []
        i = 0
        while i < len(Sub_Strings_IDs):
            bad_subsub = []
            for each in Sub_Strings_IDs[i]:
                if each in FB_s_IDs[i]:
                    bad_subsub.append(each)
            the_bads_IDs.append(bad_subsub)
            i += 1

        i = 0
        control_FP_FB = []
        j = 0
        while j < len(the_bads_IDs):
            cont = []
            for each in the_bads_IDs[j]:
                cont.append(
                    DefineStrings.AreAllWaysControllable(FP_s_IDs[j], each))
            j += 1
            control_FP_FB.append(cont)

        # * testing both conditions:

        # calculating and printing the answers

        Is_Controllable_By_Prognosis = True
        Each_String_Diag_Controllable = []

        for i in range(len(FU_states)):

            Each_String = True
            print('Para a cadeia', i + 1, 'calcula-se o FP(s) e o FB(s)')

            if len(FP_s_Names[i]) == 0:
                print(
                    'FP(',
                    i + 1,
                    ') =',
                    FP_s_Names[i],
                )
            else:
                print('FP(', i + 1, ') = [', FP_s_Names[i], ']')
            print('FB(', i + 1, ') =', FB_s_Names[i], '\n')

            if len(FP_s_Names[i]) == 0:
                print(
                    'A cadeia', i + 1,
                    'não garante prognose e, portanto, não é prognosticável.\n'
                )
                Is_Controllable_By_Prognosis = False
                Each_String = False

            normal = False
            incerto = False
            for k in test_normal[1]:
                if k in Reachable[i] and not incerto and Each_String:
                    print('A cadeia', i + 1, 'possui um ciclo normal em [', k,
                          '] e, portanto, não é prognosticável.\n')
                    Is_Controllable_By_Prognosis = False
                    normal = True
                    break
            for k in test_uncertain[1]:
                if k in Reachable[i] and not normal and Each_String:
                    print('A cadeia', i + 1, 'possui um ciclo incerto em [', k,
                          '] e, portanto, não é prognosticável.\n')
                    Is_Controllable_By_Prognosis = False
                    incerto = True
                    break

            if Each_String:
                if False in control_FP_FB[i]:
                    index = control_FP_FB[i].index(False)
                    print(
                        'No conjunto de eventos que ocorre entre [',
                        FP_s_Names[i], '] e [', FB_s_Names[i][index],
                        '] não há um evento controlável.'
                        '\nPortanto, a cadeia', i + 1,
                        'não é controlável segura pela prognose.\n')
                    Is_Controllable_By_Prognosis = False
                    Each_String = False

            if Each_String:
                print(
                    'Na cadeia', i + 1,
                    'não há ciclos incertos ou normais. Além disso, sempre há um',
                    'evento controlável entre um estado FP(', i + 1,
                    ') e um estado FB(', i + 1, ').', '\nPortanto, a cadeia',
                    i + 1, 'é controlável segura pela prognose.\n')
            Each_String_Diag_Controllable.append(Each_String)
            i += 1

        if Is_Controllable_By_Prognosis == True:
            print('A linguagem é controlável segura pela prognose.')
        else:
            print('A linguagem não é controlável segura pela prognose.')

        return Each_String_Diag_Controllable

    # if it is not Language Diagnosable:
    else:
        print(
            '\nA linguagem não é controlável segura pela prognose, pois não é diagnosticável em primeiro lugar.'
        )
        return False
def IsSafeControlByDiag_Publish():
    """[Check if automata is safe control by diagnosis. Return if each string is safe control by diagnosis]
    """
    print('\n\n* CONTROLABILIDADE SEGURA PELA DIAGNOSE\n')

    # if it is Language Diagnosable:
    if IsDiag():
        strings = FU_s.GetStringPath()

        # getting FC(s) IDs
        FC_s_IDs = []
        string_num = 0
        j = 0
        len_strings = 0
        while j < len(strings):
            for cada in strings[j]:
                len_strings += 1
            j += 1

        while string_num < len_strings:
            FC_s_IDs.append(FC_s.GetFC_s_IDs(string_num))
            string_num += 1

        # getting FC(s) names
        FC_s_Names = []
        i = 0
        while i < len(FC_s_IDs):
            names = []
            for each in FC_s_IDs[i]:
                names.append(DiagnoserFunctions.GetStateName(each))
            FC_s_Names.append(names)
            i += 1

        # getting the FB states
        FB_s_IDs = []
        string_num = 0
        j = 0
        len_strings = 0
        while j < len(strings):
            for cada in strings[j]:
                len_strings += 1
            j += 1

        while string_num < len_strings:
            FB_s_IDs.append(FB_s.GetFB_s_IDs(string_num))
            string_num += 1

        # getting FB(s) names
        FB_s_Names = []
        i = 0
        while i < len(FB_s_IDs):
            names = []
            for each in FB_s_IDs[i]:
                names.append(DiagnoserFunctions.GetStateName(each))
            FB_s_Names.append(names)
            i += 1

        # * first condition is: FC can not be a bad state

        # searching for bad states in FC
        Bad_State = []
        i = 0
        while i < len(FC_s_Names):
            isbad = []
            for each in FC_s_Names[i]:
                if DiagnoserFunctions.IsNotBad(each):
                    isbad.append(False)
                else:
                    isbad.append(True)
            Bad_State.append(isbad)
            i += 1

        # * second condition is: sub-strings must have a controllable state between a FC and a FB

        # getting reachable for each FC
        Sub_Strings_IDs = []
        i = 0
        while i < len(FC_s_IDs):
            reachable = []
            for each in FC_s_IDs[i]:
                reachable.append(DefineStrings.GetDiagReachable(each))
            Sub_Strings_IDs.append(reachable)
            i += 1

        # ignoring the not-FB ones for each sub string
        the_bads_IDs = []
        i = 0
        while i < len(Sub_Strings_IDs):
            j = 0
            bad_sub = []
            while j < len(Sub_Strings_IDs[i]):
                bad_subsub = []
                for each in Sub_Strings_IDs[i][j]:
                    if each in FB_s_IDs[i]:
                        bad_subsub.append(each)
                bad_sub.append(bad_subsub)
                j += 1
            the_bads_IDs.append(bad_sub)
            i += 1

        i = 0
        Controllability = []
        while i < len(FC_s_IDs):
            j = 0
            contr = []
            while j < len(FC_s_IDs[i]):
                cont = []
                for each in the_bads_IDs[i][j]:
                    cont.append(
                        DefineStrings.AreAllWaysControllable(
                            FC_s_IDs[i][j], each))
                j += 1
                contr.append(cont)
            i += 1
            Controllability.append(contr)

        final_strings = []
        for each in strings:
            for j in each:
                final_strings.append(j)

        # testing both conditions:
        i = 0
        Is_Controllable_By_Diagnosis = True
        Each_String_Diag_Controllable = []
        while i < len(final_strings):
            Each_String = True
            print('Para a cadeia', i + 1, 'calcula-se o FC(s) e o FB(s)')
            print('FC(', i + 1, ') =', FC_s_Names[i])
            print('FB(', i + 1, ') =', FB_s_Names[i], '\n')
            if True in Bad_State[i]:
                j = Bad_State[i].index(True)
                print('O estado', FC_s_Names[i][j], 'é um Bad State.',
                      '\nPortanto, a cadeia', i + 1,
                      'não é controlável segura pela diagnose.\n')
                Is_Controllable_By_Diagnosis = False
                Each_String = False
            if Each_String:
                w = 0
                while w < len(Controllability[i]):
                    if False in Controllability[i][w]:
                        print(
                            'No conjunto de eventos que ocorre entre o estado FC(',
                            i + 1, ') = [', FC_s_Names[i][w], ']',
                            'e o estado FB(', i + 1, ') = [', FB_s_Names[i][w],
                            '] não há um evento controlável',
                            '\nPortanto, a cadeia', i + 1,
                            'não é controlável segura pela diagnose.\n')
                        Is_Controllable_By_Diagnosis = False
                        Each_String = False
                        break
                    w += 1
            if Each_String:
                print(
                    'A cadeia', i + 1,
                    'não possui Bad States no FC. Além disso, sempre há um evento controlável',
                    'entre um estado FC(', i + 1, ') e um estado FB(', i + 1,
                    ').', '\nPortanto, a cadeia', i + 1,
                    'é controlável segura pela diagnose.\n')
            Each_String_Diag_Controllable.append(Each_String)
            i += 1

        if Is_Controllable_By_Diagnosis:
            print('A linguagem é controlável segura pela diagnose.')
        else:
            print('A linguagem não é controlável segura pela diagnose.')

        return Each_String_Diag_Controllable

    # if it is not Language Diagnosable:
    else:
        print(
            '\nA linguagem não é controlável segura pela diagnose, pois não é diagnosticável em primeiro lugar.'
        )
        return False
예제 #26
0
def GetFB_s_IDs(string):  # gets the FB(s) for a given string number

    FU_s_StateNames = FU_s.Get_FU_s()

    # for this string only, getting the FU(s):
    FU_s_StateIDs = []
    FU_s_StateIDs.append(DiagnoserFunctions.GetStateId(
        FU_s_StateNames[string]))

    # and getting the reachable states for this string in ID
    string_states_IDs = DefineStrings.GetDiagReachable(FU_s_StateIDs[0])

    # getting the names
    string_states_names = []
    for each in string_states_IDs:
        string_states_names.append(DiagnoserFunctions.GetStateName(each))

    # ignoring the non-bad ones
    the_bad_IDs = []
    i = 0
    while i < len(string_states_names):
        if not DiagnoserFunctions.IsNotBad(string_states_names[i]):
            the_bad_IDs.append(string_states_IDs[i])
        i += 1

    # and verifying if they lead to each other to ignore the target ones (once they're not the first ones)
    is_first = []
    for each in the_bad_IDs:
        i = 0
        first = True
        while i < len(DiagnoserParser.Transition_Target_Table):
            if (each == DiagnoserParser.Transition_Target_Table[i]
                    and DiagnoserParser.Transition_Source_Table[i] != each and
                    DiagnoserParser.Transition_Source_Table[i] in the_bad_IDs):
                first = False
            i += 1
        is_first.append(first)

    almost = []
    i = 0
    while i < len(the_bad_IDs):
        if is_first[i]:
            almost.append(the_bad_IDs[i])
        i += 1

    FC_s_StateIDs = []
    FC_s_StateIDs.append(FC_s.GetFC_s_IDs(string))

    FB_s = []
    i = 0
    while i < len(FC_s_StateIDs):
        j = 0
        while j < len(FC_s_StateIDs[i]):
            reachable_fc = DefineStrings.GetDiagReachable(FC_s_StateIDs[i][j])
            for each in almost:
                if each in reachable_fc:
                    FB_s.append(each)
            j += 1
        i += 1

    return FB_s
def IsSafeControlByDiagAndProg_SelfPublish():
    """[Check if automata is safe control by diagnosis and safe control by prognosis. 
    Return if each string is safe control by diagnosis and safe control by prognosis]
    """

    # if it is Language Diagnosable:
    if IsDiag():

        # get FU (so I know where diagnoser is going to fail)
        FU = FU_s.Get_FU_s()

        # getting the event sequence to the fault
        i = 0
        Fault_Diag_EventStrings_IDs = []
        while i < len(FU):
            fault_state = FU[i]
            fault_state_ID = DiagnoserFunctions.GetStateId(fault_state)
            Fault_Diag_EventStrings_IDs.append(
                DefineStrings.GetDiagnoserString(fault_state_ID))
            i += 1

        i = 0
        while i < len(Fault_Diag_EventStrings_IDs):
            state_name = []
            for each in Fault_Diag_EventStrings_IDs[i]:
                state_name.append(DiagnoserFunctions.GetEventName(each))
            state_name.append(AutomataFunctions.GetFaultEventName())
            i += 1

        by_diag = IsSafeControlByDiag()
        by_prog = IsSafeControlByProg()

        print('\n\n* CONTROLABILIDADE SEGURA PELA DIAGNOSE E PROGNOSE\n')

        # getting these events names
        Fault_Aut_Strings_Names = []
        i = 0
        while i < len(Fault_Diag_EventStrings_IDs):
            state_name = []
            for each in Fault_Diag_EventStrings_IDs[i]:
                state_name.append(DiagnoserFunctions.GetEventName(each))
            state_name.append(AutomataFunctions.GetFaultEventName())
            Fault_Aut_Strings_Names.append(state_name)
            i += 1

        Is_Controllable = True
        string = 0
        while string < len(by_diag):
            if by_diag[string] and by_prog[string]:
                print(
                    'A cadeia', string + 1,
                    'é controlável segura tanto pela diagnose quanto pela prognose.'
                )
            elif by_diag[string]:
                print('A cadeia', string + 1,
                      'é controlável segura pela diagnose.')
            elif by_prog[string]:
                print('A cadeia', string + 1,
                      'é controlável segura pela prognose.')
            else:
                print(
                    'A cadeia', string + 1,
                    'não é controlável segura pela diagnose ou pela prognose.')
                Is_Controllable = False
            string += 1

        if Is_Controllable:
            print(
                '\nPortanto, a linguagem é controlável segura pela diagnose e pela prognose'
            )
        else:
            print(
                '\nPortanto, a linguagem não é controlável segura pela diagnose e pela prognose'
            )

        return Is_Controllable

    # if it is not Language Diagnosable:
    else:
        print(
            'A linguagem não é controlável segura pela diagnose e prognose, pois não é diagnosticável em primeiro lugar.'
        )
        return False
def IsSafeControlByProg():
    """[Check if automata is safe control by prognosis. If it is, return True, else, return False]
    """
    # if it is Language Diagnosable:
    if IsDiag():
        # * first condition is C condition

        # get reachable states from FU. Pegando todos os estados alcançaveis a partir dos Fu(s)
        FU_states = FU_s.Get_FU_s()  #atribuindo a FU_states
        FU_states_ID = []
        for each in FU_states:
            FU_states_ID.append(DiagnoserFunctions.GetStateId(each))

        Reachable = []
        for each in FU_states:
            each_name = DiagnoserFunctions.GetStateId(each)
            Reachable.append(DefineStrings.GetDiagReachable(each_name))

        # getting the names. Pegando o nomes dos estados alcançaveis a partir dos Fu(s)
        i = 0
        Reachable_Names = []
        while i < len(Reachable):
            names = []
            for each in Reachable[i]:
                names.append(DiagnoserFunctions.GetStateName(each))
            Reachable_Names.append(names)
            i += 1

        # test if there is any Normal or Uncertain Cycle (C condition).
        test_normal = DefineStrings.IsNormalCycle(Reachable)
        test_uncertain = DefineStrings.IsUncertainCycle(Reachable,
                                                        antes_fu=True)

        # * second condition is: sub-strings must have a controllable state between a FP and a FB

        # getting FP(s) names
        FP_s_Names = FP_s.GetFP_s()

        FP_s_IDs = []
        for each in FP_s_Names:
            FP_s_IDs.append(DiagnoserFunctions.GetStateId(each))

        # getting the FB states
        i = 0
        FB_s_IDs = []
        while i < len(FU_states):
            FB_s_IDs.append(FB_s.GetFB_s_IDs(i))
            i += 1

        # getting FB(s) names
        FB_s_Names = []
        i = 0
        while i < len(FB_s_IDs):
            names = []
            for each in FB_s_IDs[i]:
                names.append(DiagnoserFunctions.GetStateName(each))
            FB_s_Names.append(names)
            i += 1

        Sub_Strings_IDs = []
        for each in FP_s_IDs:
            Sub_Strings_IDs.append(DefineStrings.GetDiagReachable(each))

        # ignoring the not-FB ones for each sub string
        the_bads_IDs = []
        i = 0
        while i < len(Sub_Strings_IDs):
            bad_subsub = []
            for each in Sub_Strings_IDs[i]:
                if each in FB_s_IDs[i]:
                    bad_subsub.append(each)
            the_bads_IDs.append(bad_subsub)
            i += 1

        i = 0
        control_FP_FB = []
        j = 0
        while j < len(the_bads_IDs):
            cont = []
            for each in the_bads_IDs[j]:
                cont.append(
                    DefineStrings.AreAllWaysControllable(FP_s_IDs[j], each))
            j += 1
            control_FP_FB.append(cont)

        # * testing both conditions:

        # calculating and printing the answers

        Is_Controllable_By_Prognosis = True
        Each_String_Diag_Controllable = []

        for i in range(len(FU_states)):
            Each_String = True

            if len(FP_s_Names[i]) == 0:
                Is_Controllable_By_Prognosis = False
                Each_String = False

            normal = False
            incerto = False
            for k in test_normal[1]:
                if k in Reachable[i] and not incerto and Each_String:
                    Is_Controllable_By_Prognosis = False
                    normal = True
                    break
            for k in test_uncertain[1]:
                if k in Reachable[i] and not normal and Each_String:
                    Is_Controllable_By_Prognosis = False
                    incerto = True
                    break

            if Each_String:
                if False in control_FP_FB[i]:
                    index = control_FP_FB[i].index(False)
                    Is_Controllable_By_Prognosis = False
                    Each_String = False

            Each_String_Diag_Controllable.append(Each_String)
            i += 1

        return Each_String_Diag_Controllable

    # if it is not Language Diagnosable:
    else:
        return False
def IsPred_Publish():
    """[Check if automata is predictable. Return if each string is predictable]
    """
    print('\n\n* PROGNOSTICABILIDADE\n')

    # if it is Language Diagnosable:
    if IsDiag():

        # # publishing only
        # get reachable states from FU
        FU_states = FU_s.Get_FU_s()

        Reachable = []
        for each in FU_states:
            each_name = DiagnoserFunctions.GetStateId(each)
            Reachable.append(DefineStrings.GetDiagReachable(each_name))

        # getting the names
        i = 0
        Reachable_Names = []
        while i < len(Reachable):
            names = []
            for each in Reachable[i]:
                names.append(DiagnoserFunctions.GetStateName(each))
            Reachable_Names.append(names)
            i += 1

        # test if there is any Normal or Uncertain Cycle (C condition)
        test_normal = DefineStrings.IsNormalCycle(Reachable)
        test_uncertain = DefineStrings.IsUncertainCycle(Reachable,
                                                        antes_fu=True)

        IsPredictable = True
        for i in range(len(Reachable)):
            normal = False
            incerto = False
            for k in test_normal[1]:
                if k in Reachable[i]:
                    print('A cadeia', i + 1, 'possui um ciclo normal em [',
                          DiagnoserFunctions.GetStateName(k),
                          '] e, portanto, não é prognosticável.\n')
                    normal = True
                    IsPredictable = False
                    break
            for k in test_uncertain[1]:
                if k in Reachable[i] and not normal:
                    print('A cadeia', i + 1, 'possui um ciclo incerto em [',
                          DiagnoserFunctions.GetStateName(k),
                          '] e, portanto, não é prognosticável.\n')
                    incerto = True
                    IsPredictable = False
                    break
            if not normal and not incerto:
                print(
                    'A cadeia', i + 1,
                    'não possui ciclo incerto ou normal e, portanto, é prognosticável.\n'
                )

        if IsPredictable == True:
            print('A linguagem é prognosticável.')
        else:
            print('A linguagem não é prognosticável.')

        return IsPredictable

    # if it is not Language Diagnosable:
    else:
        print(
            '\nA linguagem não é prognosticável, pois não é diagnosticável em primeiro lugar.'
        )
        return False