def evaluate_node(self, prog): if self.annotation_name == '@no_simplify': orig_level = settings.get_simplication_level() settings.set_simplification_level(0) res = self.body.evaluate(prog) settings.set_simplification_level(orig_level) return res elif self.annotation_name == '@simplify': orig_level = settings.get_simplication_level() settings.set_simplification_level(1) res = self.body.evaluate(prog) settings.set_simplification_level(orig_level) return res elif self.annotation_name == '@postprocess': return self.body.evaluate(prog).postprocess() elif self.annotation_name == '@simplify_states': return self.body.evaluate(prog).simplify_states() elif self.annotation_name == '@simplify_edges': return self.body.evaluate(prog).simplify_edges() elif self.annotation_name == '@merge_states': return self.body.evaluate(prog).merge_states() elif self.annotation_name == '@merge_edges': return self.body.evaluate(prog).merge_edges() # elif self.annotation_name == '@minimize': # return self.body.evaluate(prog).minimize() else: raise Exception('Unknown annotation: {}'.format( self.annotation_name))
def project(self, var_refs, env_var_map): from pecan.lang.ir.prog import VarRef aps = [] pecan_var_names = [] for v in var_refs: if type(v) is VarRef: aps.extend(self.var_map[v.var_name]) pecan_var_names.append(v.var_name) result = self.ap_project(aps) if settings.get_simplication_level() > 0: result.merge_states() result.postprocess() for var_name in pecan_var_names: # It may not be there (e.g., it's perfectly valid to do "exists x. y = y", even if it's pointless) if var_name in result.get_var_map(): result.get_var_map().pop(var_name) if var_name in env_var_map: env_var_map.pop(var_name) return result
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 relabel(self): level_before = settings.get_simplication_level() settings.set_simplification_level(0) ap_set = set(map(str, self.aut.ap())) new_aps = {} for ap in self.aut.ap(): # Make sure that we don't try to relabel with an AP that's already in the automaton. # This can happen when we load an automaton from a file. new_ap = self.fresh_ap() while new_ap in ap_set: new_ap = self.fresh_ap() new_aps[ap.ap_name()] = new_ap settings.log(3, lambda: 'Relabeling: {}'.format(new_aps)) res = self.ap_substitute(new_aps) settings.set_simplification_level(level_before) return res
def complement(self): if settings.get_simplication_level() > 0: self.postprocess() result = BuchiAutomaton(spot.complement(self.get_aut()), self.var_map) result.dump_aut() return result