def ltw_to_dtw(ltw): dtw = [] for j in range(len(ltw)): if j == 0 or reset[j - 1]: dtw.append(TimedWord(ltw[j].input, ltw[j].time)) else: dtw.append( TimedWord(ltw[j].input, round1(ltw[j].time - ltw[j - 1].time))) return dtw
def getHpyDTWsValue(sample, hypothesis): DRTWs = [] nowTime = 0 curState = hypothesis.initState for dtw in sample: if curState == hypothesis.sinkState: DRTWs.append(ResetTimedWord(dtw.input, dtw.time, True)) else: time = dtw.time + nowTime newLTW = TimedWord(dtw.input, time) for tran in hypothesis.trans: if tran.source == curState and tran.isPass(newLTW): curState = tran.target if tran.isReset: nowTime = 0 isReset = True else: nowTime = time isReset = False DRTWs.append(ResetTimedWord(dtw.input, dtw.time, isReset)) break if curState in hypothesis.acceptStates: value = 1 elif curState == hypothesis.sinkState: value = -1 else: value = 0 return DRTWs, value
def systemTest(DTWs, targetSys): DRTWs = [] value = [] nowTime = 0 curState = targetSys.initState for dtw in DTWs: if curState == "sink": DRTWs.append(ResetTimedWord(dtw.input, dtw.time, True)) value = -1 else: time = dtw.time + nowTime newLTW = TimedWord(dtw.input, time) flag = False for tran in targetSys.trans: if tran.source == curState and tran.isPass(newLTW): flag = True curState = tran.target if tran.isReset: nowTime = 0 isReset = True else: nowTime = time isReset = False DRTWs.append(ResetTimedWord(dtw.input, dtw.time, isReset)) break if not flag: DRTWs.append(ResetTimedWord(dtw.input, dtw.time, True)) value = -1 curState = "sink" if curState in targetSys.acceptStates: value = 1 elif curState != 'sink': value = 0 return DRTWs, value
def systemOutput(DTW, nowTime, curState, targetSys): value = None resetFlag = False tranFlag = False # tranFlag为true表示有这样的迁移 if DTW is None: if curState in targetSys.acceptStates: value = 1 else: value = 0 else: LTW = TimedWord(DTW.input, DTW.time + nowTime) for tran in targetSys.trans: if tran.source == curState and tran.isPass(LTW): tranFlag = True curState = tran.target if tran.isReset: resetFlag = True break if not tranFlag: value = -1 curState = 'sink' resetFlag = True if curState in targetSys.acceptStates: value = 1 elif curState != 'sink': value = 0 return curState, value, resetFlag
def normalize(trace): newTrace = [] for k in trace: if math.modf(float(k.time))[0] == 0.0: time = math.modf(float(k.time))[1] else: time = math.modf(float(k.time))[1] + 0.1 newTrace.append(TimedWord(k.input, time)) return newTrace
def hpyCompare(stableHpy, hypothesisOTA, upperGuard, targetSys, mqNum): """ stableHpy: old candidate automata hypothesisOTA: new candidate automata upperGuard: maximum time value targetSys: teacher automata targetFullSys: complete teacher automata mqNum: number of membership queries metric: distance between hypothesisOTA and targetSys """ # 第一次不进行比较 if stableHpy is None: return True, [], mqNum sys = transform_system(stableHpy, "A", "s") sys2 = transform_system(hypothesisOTA, "B", "q") max_time_value = max(sys.max_time_value(), sys2.max_time_value(), upperGuard) res, w_pos = equivalence.ota_inclusion(int(max_time_value), sys, sys2) # dtw_pos is accepted by sys2 but not sys. if not res: dtw_pos = equivalence.findDelayTimedwords(w_pos, 'q', sys2.sigma) # print('res', dtw_pos) res2, w_neg = equivalence.ota_inclusion(int(max_time_value), sys2, sys) # dtw_neg is accepted by sys but not sys2. if not res2: dtw_neg = equivalence.findDelayTimedwords(w_neg, 'q', sys.sigma) # print('res2', dtw_neg) if res and res2: raise NotImplementedError('hpyCompare should always find a difference') if res and not res2: hpy_flag, ctx = 0, dtw_neg elif res2 and not res: hpy_flag, ctx = 1, dtw_pos elif len(w_pos.lw) <= len(w_neg.lw): hpy_flag, ctx = 1, dtw_pos else: hpy_flag, ctx = 0, dtw_neg flag = True newCtx = [] tempCtx = [] for i in ctx: tempCtx.append(TimedWord(i.action, i.time)) realDRTWs, realValue = testDTWs(tempCtx, targetSys) if (realValue == 1 and hpy_flag != 1) or (realValue != 1 and hpy_flag == 1): flag = False newCtx = realDRTWs return flag, newCtx, mqNum + 1
def isConsistent(table): flag = True consistentAdd = [] tableElement = [s for s in table.S] + [r for r in table.R] for i in range(0, len(tableElement) - 1): for j in range(i + 1, len(tableElement)): if tableElement[i].valueList == tableElement[j].valueList: tempElements1 = [] tempElements2 = [] for element in tableElement: if isPrefix(element.LRTWs, tableElement[i].LRTWs): tempElements1.append(element) if isPrefix(element.LRTWs, tableElement[j].LRTWs): tempElements2.append(element) for e1 in tempElements1: for e2 in tempElements2: newLRTWs1 = deletePrefix(e1.LRTWs, tableElement[i].LRTWs) newLRTWs2 = deletePrefix(e2.LRTWs, tableElement[j].LRTWs) if len(newLRTWs1) == len(newLRTWs2) == 1: if newLRTWs1[0].input == newLRTWs2[ 0].input and newLRTWs1[ 0].time == newLRTWs2[0].time: if newLRTWs1[0].isReset != newLRTWs2[0].isReset: flag = False temp = TimedWord(newLRTWs1[0].input, newLRTWs1[0].time) consistentAdd = [temp] return flag, consistentAdd elif e1.valueList != e2.valueList: flag = False for k in range(0, len(e1.valueList)): if e1.valueList[k] != e2.valueList[k]: newIndex = k consistentAdd = [ TimedWord( newLRTWs1[0].input, newLRTWs1[0].time) ] + table.E[newIndex] return flag, consistentAdd return flag, consistentAdd
def sampleGenerationMain_old(inputs, upperGuard, stateNum): sample = [] length = random.randint(1, stateNum * 2) for i in range(length): input = inputs[random.randint(0, len(inputs) - 1)] time = random.randint(0, upperGuard * 2 + 1) if time % 2 == 0: time = time // 2 else: time = time // 2 + 0.1 temp = TimedWord(input, time) sample.append(temp) return sample
def extendR(s, inputs, table, targetSys, mqNum): tableTrace = [s.LRTWs for s in table.S] + [r.LRTWs for r in table.R] for input in inputs: LTWs = LRTW_to_LTW(s.LRTWs) + [TimedWord(input, 0)] LRTWs, tempValue, mqNum = TQs(LTWs, targetSys, mqNum) if tempValue == -1: element, mqNum = fillTableRow(LRTWs, table, True, targetSys, mqNum) else: element, mqNum = fillTableRow(LRTWs, table, False, targetSys, mqNum) if element.LRTWs not in tableTrace: table.R.append(element) return table, mqNum
def sampleGeneration_invalid(teacher, upperGuard, length): assert length > 0 sample_prefix = None while sample_prefix is None: sample_prefix = sampleGeneration_valid(teacher, upperGuard, length) action = random.choice(teacher.inputs) time = random.randint(0, upperGuard * 3 + 1) if time % 2 == 0: time = time // 2 else: time = time // 2 + 0.1 index = random.randint(0, len(sample_prefix) - 1) sample_prefix[index] = TimedWord(action, time) return sample_prefix
def testLTWs(LTWs, targetSys): if not LTWs: if targetSys.initState in targetSys.acceptStates: value = 1 else: value = 0 return [], value else: LRTWs = [] value = None nowTime = 0 curState = targetSys.initState for ltw in LTWs: if ltw.time < nowTime: value = -1 LRTWs.append(ResetTimedWord(ltw.input, ltw.time, True)) break else: DTW = TimedWord(ltw.input, ltw.time - nowTime) curState, value, resetFlag = systemOutput( DTW, nowTime, curState, targetSys) if resetFlag: LRTWs.append(ResetTimedWord(ltw.input, ltw.time, True)) nowTime = 0 else: LRTWs.append(ResetTimedWord(ltw.input, ltw.time, False)) nowTime = ltw.time if value == -1: break # 补全 lenDiff = len(LTWs) - len(LRTWs) if lenDiff != 0: temp = LTWs[len(LRTWs):] for i in temp: LRTWs.append(ResetTimedWord(i.input, i.time, True)) return LRTWs, value
if not res: dtw_pos = equivalence.findDelayTimedwords(w_pos, 'q', sys2.sigma) print('res', dtw_pos) res2, w_pos2 = equivalence.ota_inclusion(max_time_value, sys2, sys) # drtw_pos2 is accepted by sys but not sys2. if not res2: dtw_neg = equivalence.findDelayTimedwords(w_pos2, 'q', sys.sigma) print('res2', dtw_neg) print(res) print(res2) if res and not res2: hpy_flag = 0 elif res2 and not res: hpy_flag = 1 elif len(w_pos.lw) <= len(w_pos2.lw): hpy_flag = 1 else: hpy_flag = 0 print(hpy_flag) ctx = [] for i in dtw_neg: ctx.append(TimedWord(i.action, i.time)) DRTWs, value = getHpyDTWsValue(ctx, AA) DRTWs2, value2 = getHpyDTWsValue(ctx, HH) print(value, value2)
def sampleGeneration_valid(teacher, upperGuard, length): # First produce a path (as a list of transitions) in the OTA path = [] current_state = teacher.initState for i in range(length): edges = [] for tran in teacher.trans: if current_state == tran.source: edges.append(tran) edge = random.choice(edges) path.append(edge) current_state = edge.target # Next, figure out (double of) the minimum and maximum logical time. min_time, max_time = [], [] for tran in path: assert len(tran.guards) == 1 min_time.append(min_constraint_double(tran.guards[0])) max_time.append(max_constraint_double(tran.guards[0], upperGuard)) # For each transition, maintain a mapping from logical time to the number of choices. weight = dict() for i in reversed(range(length)): tran = path[i] mn, mx = min_time[i], max_time[i] weight[i] = dict() if i == length - 1 or tran.isReset: for j in range(mn, mx + 1): weight[i][j] = 1 else: for j in range(mn, mx + 1): weight[i][j] = 0 for k, w in weight[i + 1].items(): if k >= j: weight[i][j] += w # Now sample according to the weights double_times = [] cur_time = 0 for i in range(length): start_time = max(min_time[i], cur_time) distr = [] for j in range(start_time, max_time[i] + 1): distr.append(weight[i][j]) if sum(distr) == 0: return None # sampling failed cur_time = sampleDistribution(distr) + start_time double_times.append(cur_time) if path[i].isReset: cur_time = 0 # Finally, change doubled time to fractions. ltw = [] for i in range(length): if double_times[i] % 2 == 0: time = double_times[i] // 2 else: time = double_times[i] // 2 + 0.1 ltw.append(TimedWord(path[i].input, time)) # Convert logical-timed word to delayed-timed word. dtw = [] for i in range(length): if i == 0 or path[i - 1].isReset: dtw.append(TimedWord(path[i].input, ltw[i].time)) else: dtw.append(TimedWord(path[i].input, ltw[i].time - ltw[i - 1].time)) return dtw
def minimizeCounterexample(teacher, hypothesis, sample): reset = [] # Fix computation with 0.1 def round1(x): return int(x * 10 + 0.5) / 10 def one_lower(x): if round1(x - int(x)) == 0.1: return int(x) else: return round1(x - 0.9) # Find sequence of reset information realDRTWs, realValue = testDTWs(sample, teacher) ltw = LRTW_to_LTW(DRTW_to_LRTW(realDRTWs)) for DRTW in realDRTWs: reset.append(DRTW.isReset) def normalize(trace): newTrace = [] for k in trace: if math.modf(float(k.time))[0] == 0.0: time = math.modf(float(k.time))[1] else: time = math.modf(float(k.time))[1] + 0.1 newTrace.append(TimedWord(k.input, time)) return newTrace ltw = normalize(ltw) # print('ltw:', [i.show() for i in ltw]) def ltw_to_dtw(ltw): dtw = [] for j in range(len(ltw)): if j == 0 or reset[j - 1]: dtw.append(TimedWord(ltw[j].input, ltw[j].time)) else: dtw.append( TimedWord(ltw[j].input, round1(ltw[j].time - ltw[j - 1].time))) return dtw # print('initial dtw:', [i.show() for i in ltw_to_dtw(ltw)]) for i in range(len(ltw)): while True: if i == 0 or reset[i - 1]: can_reduce = (ltw[i].time > 0) else: can_reduce = (ltw[i].time > ltw[i - 1].time) if not can_reduce: break ltw2 = copy.deepcopy(ltw) ltw2[i] = TimedWord(ltw[i].input, one_lower(ltw[i].time)) if not isCounterexample(teacher, hypothesis, ltw_to_dtw(ltw2)): break ltw = copy.deepcopy(ltw2) # print('final dtw:', [i.show() for i in ltw_to_dtw(ltw)]) return ltw_to_dtw(ltw)