def as_buchi(cls, aut): if aut.get_aut_type() == 'buchi': return aut elif aut.get_aut_type() == 'true': return BuchiAutomaton(spot.translate('1'), VarMap()) elif aut.get_aut_type() == 'false': return BuchiAutomaton(spot.translate('0'), VarMap()) else: raise NotImplementedError
def ap_substitute(self, ap_subs): # If we try something like [x/x]P, just don't do anything ap_subs = {k: v for k, v in ap_subs.items() if k != v} if not ap_subs: return self bdd_subs = {self.aut.register_ap(k): v for k, v in ap_subs.items()} settings.log(3, lambda: 'ap_subs: {}'.format(ap_subs)) if settings.get_simplication_level() > 0: self.postprocess() new_var_map = VarMap() to_register = [] for v, aps in self.var_map.items(): new_var_map[v] = [] for ap in aps: # Get the new name of this ap, or just the ap if the name didn't get new_ap = ap_subs.get(ap, ap) new_var_map[v].append(new_ap) to_register.append(new_ap) settings.log( 3, lambda: 'ap_subs: {}, {}, {}'.format(ap_subs, self.var_map, new_var_map)) new_aut = buchi_transform(self.aut, Substitution(bdd_subs)) for new_ap in to_register: new_aut.register_ap(new_ap) return BuchiAutomaton(new_aut, new_var_map) #.postprocess()
def __init__(self, input_alphabets, formal_arg_names): self.input_alphabets = input_alphabets self.formal_arg_names = formal_arg_names if len(self.input_alphabets) != len(self.formal_arg_names): raise Exception( 'Number of inputs must match number of formal arguments ({} vs {})' .format(self.input_alphabets, self.formal_arg_names)) self.states = [] self.state_num_map = {} self.state_name_map = {} self.state_num = 0 self.hoa_aut = spot.make_twa_graph() self.var_map = VarMap() self.bdds = {} for formal, base in zip(self.formal_arg_names, self.input_alphabets): self.var_map[formal] = [ BuchiAutomaton.fresh_ap() for _ in range(base_len(base)) ] self.bdds[formal] = [ buddy.bdd_ithvar(self.hoa_aut.register_ap(ap)) for ap in self.var_map[formal] ] self.hoa_aut.set_buchi()
def from_spot_aut(base_aut): # In this case, we have no information about the encoding, so we just assume that each variable maps 1-1 in the HOA file specified. var_map = VarMap() for ap in base_aut.ap(): var_map[ap.ap_name()] = [ap.ap_name()] return BuchiAutomaton(base_aut, var_map)
def substitute(self, arg_map, env_var_map): new_var_map = VarMap() ap_subs = {} for formal_arg, actual_arg in arg_map.items(): # Get the aps for the formal argument in this automaton formal_aps = self.var_map[formal_arg] # Get the aps for the actual argument in the current environment actual_aps = env_var_map.get_or_gen(actual_arg, self.fresh_ap, len(formal_aps)) # Set up the substitutions we need to do for formal_ap, actual_ap in zip(formal_aps, actual_aps): ap_subs[formal_ap] = actual_ap # Rename the formal arg to the actual arg, but leave the aps as the formal aps because that'll be done by `ap_substitute` below new_var_map[actual_arg] = formal_aps # print('substitute()', arg_map, new_var_map, env_var_map, ap_subs) return BuchiAutomaton(self.aut, new_var_map).ap_substitute(ap_subs)
def enter_var_map_scope(self, var_map=None): self.var_map.append(var_map or VarMap())
def merge_maps(aut, map_a: VarMap, map_b: VarMap): merged_var_map, subs = map_a.merge_with(map_b) return BuchiAutomaton(aut, merged_var_map).ap_substitute(subs)