def ltw_to_dtw(ltw): dtw = [] for i in range(len(ltw)): if i == 0 or reset[i - 1]: dtw.append(Timedword(ltw[i].action, ltw[i].time)) else: dtw.append( Timedword(ltw[i].action, round1(ltw[i].time - ltw[i - 1].time))) return Element(dtw, [])
def guess_ctx_reset(dtws, ota): """When receiving a counterexample (delay timed word), guess all resets and return all reset delay timed words as ctx candidates. """ new_tws = [Timedword(tw.action, tw.time) for tw in dtws] ctxs = [[]] for i in range(len(new_tws)): templist = [] res = ota.is_accepted_delay( dtws[:i + 1]) # Whether the counterexample leads to the sink for rtws in ctxs: if res == -1: temp_r = rtws + [ ResetTimedword(new_tws[i].action, new_tws[i].time, True) ] templist.append(temp_r) else: temp_n = rtws + [ ResetTimedword(new_tws[i].action, new_tws[i].time, False) ] temp_r = rtws + [ ResetTimedword(new_tws[i].action, new_tws[i].time, True) ] templist.append(temp_n) templist.append(temp_r) ctxs = templist return ctxs
def init_table_normal(sigma, ota): """Initial tables. """ S = [Element([], [])] R = [] E = [] for s in S: if ota.initstate_name in ota.accept_names: s.value.append(1) else: s.value.append(0) tables = [OTATable(S, R, E, parent=-1, reason="init")] for i in range(0, len(sigma)): temp_tables = [] for table in tables: new_tw = Timedword(sigma[i], 0) res = ota.is_accepted_delay([new_tw]) if res == -1: # Now at sink guesses = [True] else: guesses = [True, False] for guess in guesses: new_rtw = ResetTimedword(new_tw.action, new_tw.time, guess) new_element = Element([new_rtw], [res]) temp_R = table.R + [new_element] new_table = OTATable(S, temp_R, E, parent=-1, reason="init") temp_tables.append(new_table) tables = temp_tables return tables
def is_evidence_closed(self, ota): """ Determine whether the table is evidence-closed. """ flag = True table_tws = [s.tws for s in self.S] + [r.tws for r in self.R] new_added = [] for s in self.S: local_s = s.tws current_location_name = ota.run_resettimedwords(local_s) for e in self.E: temp_e = [] current_location = copy.deepcopy(current_location_name) reset = True clock_valuation = 0 if len(s.tws) > 0: reset = local_s[len(local_s) - 1].reset clock_valuation = local_s[len(local_s) - 1].time for tw in e: new_timedword = Timedword(tw.action, tw.time) if not reset and new_timedword.time < clock_valuation: temp_e.append(ResetTimedword(tw.action, tw.time, True)) break else: for otatran in ota.trans: if otatran.source == current_location and otatran.is_pass( new_timedword): new_resettimedword = ResetTimedword( tw.action, tw.time, otatran.reset) temp_e.append(new_resettimedword) clock_valuation = new_timedword.time reset = otatran.reset if reset: clock_valuation = 0 current_location = otatran.target break temp_se = [rtw for rtw in s.tws] + [rtw for rtw in temp_e] prefs = prefixes(temp_se) for pref in prefs: if pref not in table_tws: table_tws.append(pref) new_tws = [tws for tws in pref] new_element = Element(new_tws, []) new_added.append(new_element) if len(new_added) > 0: flag = False return flag, new_added
def sampleGeneration(inputs, upperGuard, stateNum, length=None): """ Generate a sample. """ sample = [] if length is None: length = random.randint(1, stateNum) 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 Element(sample, [])
def make_consistent(new_a, new_e_index, fix_reset_i, fix_reset_j, reset_i, reset_j, table, sigma, ota): """Make table consistent. """ new_E = [tws for tws in table.E] new_e = [Timedword(tw.action, tw.time) for tw in new_a] if new_e_index > 0: e = table.E[new_e_index - 1] new_e.extend(e) new_E.append(new_e) new_table = OTATable(table.S, table.R, new_E, parent=table.id, reason="makeconsistent") temp_suffixes_resets = guess_resets_in_newsuffix(new_table, fix_reset_i, fix_reset_j, reset_i, reset_j, ota) OTAtables = [] for situation in temp_suffixes_resets: temp_situation = [] for resets in situation: temp_situation.extend(resets) if temp_situation[fix_reset_i] in ( None, reset_i) and temp_situation[fix_reset_j] in (None, reset_j): temp_table = copy.deepcopy(table) temp_table.E = copy.deepcopy(new_E) flag_valid = True for i in range(0, len(situation)): if i < len(table.S): temp_table.S[i].suffixes_resets.append(situation[i]) if fill(temp_table.S[i], temp_table.E, ota) == False: flag_valid = False break else: temp_table.R[i - len(temp_table.S)].suffixes_resets.append( situation[i]) if fill(temp_table.R[i - len(temp_table.S)], temp_table.E, ota) == False: flag_valid = False break if flag_valid: OTAtables.append(temp_table) return OTAtables
def minimizeCounterexample(teacher, hypothesis, sample): """ Minimize a given delay-timed word. """ reset = [] current_state = hypothesis.initstate_name current_clock = 0 ltw = [] # 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 for tw in sample.tws: current_clock = round1(current_clock + tw.time) ltw.append(Timedword(tw.action, current_clock)) for tran in hypothesis.trans: found = False if current_state == tran.source and tran.is_pass( Timedword(tw.action, current_clock)): reset.append(tran.reset) current_state = tran.target if tran.reset: current_clock = 0 found = True break assert found # print('ltw:', ltw) def ltw_to_dtw(ltw): dtw = [] for i in range(len(ltw)): if i == 0 or reset[i - 1]: dtw.append(Timedword(ltw[i].action, ltw[i].time)) else: dtw.append( Timedword(ltw[i].action, round1(ltw[i].time - ltw[i - 1].time))) return Element(dtw, []) # print('initial:', ltw_to_dtw(ltw).tws) 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].action, one_lower(ltw[i].time)) # print('try', ltw_to_dtw(ltw2).tws) if not isCounterexample(teacher, hypothesis, ltw_to_dtw(ltw2)): break # print('change') ltw = ltw2 # print('final:', ltw_to_dtw(ltw).tws) return ltw_to_dtw(ltw)
def sampleGeneration_valid(teacher, upperGuard, length): """ Generate a sample adapted to the given teacher. """ # First produce a path (as a list of transitions) in the OTA path = [] current_state = teacher.initstate_name 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.constraints) == 1 min_time.append(min_constraint_double(tran.constraints[0])) max_time.append(max_constraint_double(tran.constraints[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.reset: 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].reset: 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].label, time)) # Convert logical-timed word to delayed-timed word. dtw = [] for i in range(length): if i == 0 or path[i - 1].reset: dtw.append(Timedword(path[i].label, ltw[i].time)) else: dtw.append(Timedword(path[i].label, ltw[i].time - ltw[i - 1].time)) return Element(dtw, [])
def make_closed(new_S, new_R, move, table, sigma, ota): """ Make table closed. """ new_E = table.E closed_table = OTATable(new_S, new_R, new_E, parent=table.id, reason="makeclosed") table_tws = [s.tws for s in closed_table.S] + [r.tws for r in closed_table.R] temp_resets = [[]] for i in range(0, len(sigma)): dtws = lRTWs_to_DTWs(move.tws) res = ota.is_accepted_delay(dtws + [Timedword(sigma[i], 0)]) if res == -1: guesses = [True] else: guesses = [True, False] new_situations = [] for guess in guesses: new_rtw = ResetTimedword(sigma[i], 0, guess) for situation in temp_resets: temp = copy.deepcopy(situation) + [new_rtw] new_situations.append(temp) temp_resets = new_situations OTAtables = [] for situation in temp_resets: new_rs = [] for new_rtw in situation: new_r = [tw for tw in move.tws] + [new_rtw] if new_r not in table_tws: new_rs.append(Element(new_r, [], [])) temp_R = [r for r in new_R] + new_rs temp_table = OTATable(new_S, temp_R, new_E, parent=table.id, reason="makeclosed") OTAtables.append(temp_table) # guess the resets of suffixes for each prefix and fill OTAtables_after_guessing_resets = [] for otatable in OTAtables: new_r_start_index = len(new_R) new_r_end_index = len(otatable.R) temp_otatables = [otatable] for i in range(new_r_start_index, new_r_end_index): res = get_empty_E(otatable.R[i], ota) if res == -1: resets_situations = guess_resets_in_suffixes(otatable, to_guess=False) else: resets_situations = guess_resets_in_suffixes(otatable) resets_situations = guess_resets_in_suffixes(otatable) new_tables = [] for j in range(0, len(resets_situations)): for temp_table in temp_otatables: new_table = copy.deepcopy(temp_table) temp_otatable = OTATable(new_table.S, new_table.R, new_table.E, parent=table.id, reason="makeclosed") temp_otatable.R[i].suffixes_resets = resets_situations[j] new_table = copy.deepcopy(temp_otatable) if True == fill(new_table.R[i], new_table.E, ota): new_tables.append(new_table) temp_otatables = [tb for tb in new_tables] OTAtables_after_guessing_resets = OTAtables_after_guessing_resets + temp_otatables return OTAtables_after_guessing_resets