Ejemplo n.º 1
0
    def __makeBuechiAutomaton(self, mhState, transDict, weDict, sim):
        # mhState: Pair of Tuple of State, transDict: Dictionary
        # sim: SimulationRelation
        "Constructs an equivalent NBA using an adapted optimization of the \
         algorithm of Miyano-Hayashi.\
         Diese Methode wird aus toBuechiAutomaton aufgerufen.\
         Wir nehmen als Zustände des NBA Paare von Tupeln von Zuständen: \
         MHstate = pair of tuple of state. \
         Und transDict ist Dictionary of (MHstate, Dictionary of (tuple(Term),\
         List of MHstate))."

        if transDict.has_key(mhState) or weDict.has_key(mhState):
            return ## Rekursionsabbruch
        
        transDict[mhState] = {}

        #Berechnen der möglichen Terme von mhState
        auxList = [0] * len(mhState[0])
        for i in range(len(mhState[0])):
            auxList[i] = self.possibleTerms[mhState[0][i]]
        posTerms = Utilities.termAndForLists(auxList)

        STATIC = 'static'
        PROGRESS = 'progress'
        for posT in posTerms:
            posT = tuple(posT)
            transDict[mhState][posT] = []
            succ4posT = {}
            # 1. Zu jedem p in mhState[0] finde Liste von Listen von
            # Nachfolgezuständen succ4posT[p]
            for p in mhState[0]:
                succ4posT[p] = []
                for t in self.powerSet[p].keys():
                    if LTLUtils.oneTermImplies(posT, t):
                        for aSet in self.powerSet[p][t]:
                            succ4posT[p].append([])
                            for q in aSet:
                                succ4posT[p][-1].append(q)
                        # Und nicht succ4posT[p] += self.powerSet[p][t]
                        
            # 2. Mache removeDuplicates
            for p in mhState[0]:
                removeDuplicates(succ4posT[p])

            # 3. Wenn p in mhState[1], dann erweitere jede Liste aSet in
            # succ4posT[p], für die p in aSet gilt, um einen Sonderwert
            # 'static'; erweitere die, für die p \notin aSet gilt, um einen
            # Sonderwert 'progress'.
            if (mhState[1] != ()):
                p = mhState[1][0]
                for aSet in succ4posT[p]:
                    if (p in aSet):
                        aSet.append(STATIC)
                    else:
                        aSet.append(PROGRESS)
           
            # 4. Iteriere listMerge über succ4posT[q] für alle q in mhState[0].
            # Das Ergebnis sei erg1stCposT, eine Liste von Listen von
            # Zuständen.
            erg1stCposT = [[]]
            for q in mhState[0]:
                erg1stCposT = Utilities.listMerge(erg1stCposT, succ4posT[q])

            # 5. Fallunterscheidung in Schleife:
            erg2ndCposT = []
            for succSet in erg1stCposT:
                if (mhState[1] == ()):
                    nextValue = self.next(succSet, -1)
                    if (nextValue == -1):
                        erg2ndCposT.append([])
                    else:
                        erg2ndCposT.append([self.zInversed[nextValue]])
                elif (STATIC in succSet):
                    erg2ndCposT.append([mhState[1][0]])
                    succSet.remove(STATIC)
                else: # PROGRESS in succSet
                    nextValue = self.next(succSet, self.zNormal[mhState[1][0]])
                    if (nextValue == -1):
                        erg2ndCposT.append([])
                    else:
                        erg2ndCposT.append([self.zInversed[nextValue]])
                    succSet.remove(PROGRESS)

            # Geeignetes Entfernen nichtminimaler Zustände aus den Mengen in
            # erg1stCposT
            if (sim != None):
                for i in range(len(erg1stCposT)):
                    erg1stCposT[i] = minimalElements(erg1stCposT[i], \
                                                     sim.isLess)
                    if ((erg2ndCposT[i] != []) and \
                        not (erg2ndCposT[i][0] in erg1stCposT[i])):
                        erg1stCposT[i].append(erg2ndCposT[i][0])

            # Kopieren nach transDict
            for i in range(len(erg1stCposT)):
                transDict[mhState][posT] += [(tuple(erg1stCposT[i]), \
                                              tuple(erg2ndCposT[i]))]

	    # Neu für schwache Äquivalenz
	    for i in range(len(transDict[mhState][posT])):
		if weDict.has_key(transDict[mhState][posT][i]):
		    transDict[mhState][posT][i] = weDict[transDict[mhState][posT][i]]
            transDict[mhState][posT].sort()
            removeDuplicates(transDict[mhState][posT])

        # Vernünftigerweise macht man hier schon 'richtiges' Simplifizieren.
        LTLUtils.simplifyMHtransition(mhState, transDict, weDict, \
				      (lambda x: x[1] == tuple([])), sim)
   
        # Rekursion einleiten
	toBeDone = []
	if transDict.has_key(mhState):
	    toBeDone = transDict[mhState].values() # List of list of MH-State
        auxList = []
        for listOfMHState in toBeDone:
            auxList += listOfMHState
        toBeDone = auxList # List of MH-State
        toBeDone.sort()
        removeDuplicates(toBeDone)
	
        for nextMHState in toBeDone:
            self.__makeBuechiAutomaton(nextMHState, transDict, weDict, sim)
Ejemplo n.º 2
0
    def __doPSet(self, state, dict): # state: State,
        # dict: Dictionary of (State, Dictionary of (tuple(term), List of List
        # of States))
        ## 'Term' ist dabei wirklich nur ein Vektor über {0, 1, -1}
        if dict.has_key(state):
            return

        dict[state] = {}

        ## Rekursion: Alle \epsi-Nachfolger bearbeiten
        for q in self.transitionRelation[state].keys():
            if [] in self.transitionRelation[state][q]:
                self.__doPSet(q, dict)
        ## Ab jetzt sind alle \epsi-Nachfolger in dict als quasi-existentielle
        ## Zustände OHNE \EPSI-TRANSITIONEN eingetragen.

        ## state im o.g. Format in dict eintragen
        for q in self.transitionRelation[state].keys():
            for t in self.transitionRelation[state][q]:
                term = tuple(t)
                if not dict[state].has_key(term):
                    dict[state][term] = [[q]]
                else:
                    dict[state][term] += [[q]]
        # Jetzt ist dict[state] im o.g. Format

        if self.isExistentialState(state):
            ## Der einfache Fall
            if not dict[state].has_key(()):
                return # keine \epsi-Transitionen -> fertig
            for stateList in dict[state][()]:
                for q in stateList:
                    for t in dict[q].keys():
                        if not dict[state].has_key(t):
                            dict[state][t] = []
                        dict[state][t] += dict[q][t]
                        # einfach rüberkopieren
            del dict[state][()]
            # und hübsch machen
            for t in dict[state].keys():
                dict[state][t].sort()
                removeDuplicates(dict[state][t])                    
        elif self.isUniversalState(state):
            ## Der schwierige Fall
            reachOfTerms = {}
            # reachOfTerms ist die neue Transitionsliste, die dict[state]
            # ersetzen wird.
            for posT in self.possibleTerms[state]:
                posT = tuple(posT)
                reachOfTerms[posT] = [[]]
                for t in dict[state].keys():
                    if LTLUtils.oneTermImplies(posT, t):
                        # Beachte, daß oneTermImplies(posT, ()) == 0 gilt.
                        for q in dict[state][t]:
                            reachOfTerms[posT][0] += q
                ## Jetzt haben wir reachOfTerms[posT] = [[q0, ..., qn]], wobei
                ## die qi die Zustände sind, die von state über eine
                ## Termtransition (mit posT) erreichbar sind

                if dict[state].has_key(()):
                    # Wenn es \epsi-Transitionen von state gibt:                
                    for stateList in dict[state][()]:
                        for q in stateList:
                            # Für jeden \epsi-Nachfolger q:
                            ergQ = []                            
                            for tQ in dict[q].keys():
                                if LTLUtils.oneTermImplies(posT, tQ):
                                    # Kommt man mit tState auch über die
                                    # tQ-Transition von q?
                                    ergQ += dict[q][tQ]
                                    # Dann trage tQ-Nachf. von q in ergQ ein.
                            reachOfTerms[posT] = Utilities.listMerge(reachOfTerms[posT], ergQ)
                            ## Zu den Zuständen in reachOfTerms[posT] kommt je
                            ## ein Zustand aus ergQ
                            
            dict[state] = reachOfTerms

        ## Und noch mal Rekursion: Jetzt die Termnachfolger
        for q in self.transitionRelation[state].keys():
            if not ([] in self.transitionRelation[state][q]):
                self.__doPSet(q, dict)