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)
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)