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 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 
예제 #3
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 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 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 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 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 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 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 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
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 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
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
예제 #16
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