def _fixPreProcessing(channel_dict, tap_dict, template_numeric_dict=None, timing_exp_list=None): """ after applying this, there is no template rule anymore, and every tap rule only causes one edge :param system: :param template_numeric_dict: :return: """ # break down templates if not template_numeric_dict: template_numeric_dict = dict() if not timing_exp_list: timing_exp_list = list() for tap_name, tap in tap_dict.items(): template_match = _triggerTemplateMatch(tap.trigger, list(template_numeric_dict.keys())) if template_match: del tap_dict[tap_name] template = template_match.group('template') operator = template_match.group('operator') value = float(template_match.group('value')) for crit_value in _getEnhancedNumericList(template_numeric_dict[template]): if (crit_value > value and operator == '>') or \ (crit_value < value and operator == '<') or (crit_value == value and operator == '='): new_tap_name = tap_name + str(crit_value).replace('.', '_') new_trigger = template + 'SetTo' + str(crit_value).replace('.', '_') tap_dict[new_tap_name] = Tap(tap.action, new_trigger, tap.condition) _channel_dict = copy.deepcopy(channel_dict) result = generateIoTSystem('TempSystem', _channel_dict, tap_dict, timing_exp_list) # break down every rule tap_index_dict = {key: 0 for key, tap in result.tap_dict.items()} new_tap_dict = dict() ts = result.transition_system for transition in ts.trans_list: if '->' in transition.act: # add a new rule handling this rule_name = re.match(r'rule\((?P<rule_name>[\s\S]+)\)->[^ ]+', transition.act).group('rule_name') prev_index = ts.getPrevIndex(transition.src_index) prev_field = ts.getField(prev_index) ap_list = [ap for ap in result.getApList(prev_field) if '@' not in ap and 'trigger' not in ap and ap not in result.tap_dict] ap_list = ap_list + ['!' + ap for ap in result.getAllAp() if '@' not in ap and 'trigger' not in ap and ap not in ap_list and ap not in result.tap_dict] new_rule_name = rule_name + '_' + str(tap_index_dict[rule_name]) action = result.tap_dict[rule_name].action trigger = result.tap_dict[rule_name].trigger tap_index_dict[rule_name] = tap_index_dict[rule_name] + 1 new_tap_dict[new_rule_name] = Tap(action, trigger, ap_list) _channel_dict = copy.deepcopy(channel_dict) result = generateIoTSystem('systemAfterPreProcess', _channel_dict, new_tap_dict, timing_exp_list) ts = result.transition_system # put system back to initial state result._restoreFromStateVector(ts.getField(0)) return result
def _fixRuleEdges(system, ltl, record_exp_list): """ a pre-requirement it that each tap rule in the system only triggers one rule edge :param system: :param ltl: :param template_numeric_dict: :return: """ name = 'systemAfterRuleEdgeFixing' channel_dict = {key: copy.deepcopy(value) for key, value in system.channel_dict.items()} timing_exp_list = [key[0] for key in system.timer_type1_dict.items()] + \ [key[0] for key in system.timer_type2_dict.items()] while True: # find all bad edges bad_edges, other_edges = _getBadEdges(system, ltl, record_exp_list) bad_edges = [edge for edge in bad_edges if '->' in edge.action] if not bad_edges: # terminate, no bad edges caused by rule break else: # fix all rule edges tap_dict = system.tap_dict for edge in bad_edges: rule_name = re.match(r'rule\((?P<rule_name>[\s\S]+)\)->[^ ]+', edge.action).group('rule_name') if rule_name in tap_dict: del tap_dict[rule_name] _channel_dict = copy.deepcopy(channel_dict) system = generateIoTSystem(name, _channel_dict, tap_dict, timing_exp_list) return system
def generateTrace(cap_dict, tap_dict, length=100000, template_dict=vars(DeviceList)): """ :param cap_dict: key: capability name, value: event generator (Generator) :param tap_dict: key: name of the rule, value: TAP class :param length: maximum time :param template_dict: dict of template :return: a trace object (or list of events?) """ tap_list = [val for key, val in tap_dict.items()] exp_t_list, record_exp_list = generateTimeExp('0', tap_list) crit_value_dict = generateCriticalValue('0', tap_list) cap_name_list = list(set([cap_name for cap_name, gen in cap_dict.items()])) channel_name_list = list( set([cap_name.split('.')[0] for cap_name, gen in cap_dict.items()])) tap_dict = namedTapFormat(tap_dict, crit_value_dict) channel_dict = generateChannelDict(channel_name_list, crit_value_dict, {}, cap_name_list, template_dict) system = generateIoTSystem('temp', channel_dict, tap_dict, exp_t_list, build_ts=False) init_field = system.saveToStateVector() current_time = 0 event_time_list = list() while current_time < length: time_dict = { cap_name: gen.next(current_time) for cap_name, gen in cap_dict.items() } nearest_event_time = min( [time for cap_name, time in time_dict.items()]) smallest_timer = system.getSmallestTimerValue() if smallest_timer + current_time <= nearest_event_time: # should apply tick current_time = current_time + smallest_timer system.applyTick() event_list = system.resolveTriggeredRules() event_time_list = event_time_list + [ (current_time, textToformula(event), True) for event in event_list ] else: # should apply the nearest event selected_cap_list = [ cap_name for cap_name, time in time_dict.items() if time == nearest_event_time ] selected_cap = random.choice(selected_cap_list) event_list = system.getPossibleEvents(selected_cap) selected_event = random.choice(event_list) interval = time_dict[selected_cap] - current_time current_time = time_dict[selected_cap] system.applyTick(time=interval) system.applyAction(selected_event) following_event_list = system.resolveTriggeredRules() event_time_list.append( (current_time, textToformula(selected_event), True)) event_time_list = event_time_list + \ [(current_time, textToformula(event), True) for event in following_event_list] system.restoreFromStateVector(init_field) system_no_tap = generateIoTSystem('temp', channel_dict, {}, exp_t_list, build_ts=False) init_field_no_tap = system_no_tap.saveToStateVector() return Trace(init_field_no_tap, system_no_tap, event_time_list)