def _to_automaton(self): self._spot_formula = spot.formula(self._formula) # Follow https://spot.lrde.epita.fr/tut12.html to convert to finite semantics aut = spot.from_ltlf(self._formula).translate('low', 'sbacc') rem = spot.remove_ap() rem.add_ap('alive') aut = rem.strip(aut) aut = spot.postprocess(aut, 'low', 'sbacc') self._spot_automaton = aut init_states = [d for d in aut.univ_dests(aut.get_init_state_number())] bdd_dict = aut.get_dict() for s in range(aut.num_states()): is_init = s in init_states is_accepting = aut.state_is_accepting(s) self.add_state(str(s), init=is_init, accept=is_accepting) state_id = aut.num_states() for ed in aut.edges(): label = spot.bdd_to_formula(ed.cond, bdd_dict) if self._add_flexible_state and str(ed.src) != str(ed.dst): state_name = 'e_' + str(state_id) self.add_state(state_name) # add transition to the new state self.add_transition(str(ed.src), state_name, label='1') # add transition of the self loop self.add_transition(state_name, state_name, label='1') # add transition from the new state to destination self.add_transition(state_name, str(ed.dst), label=str(label)) state_id += 1 else: self.add_transition(str(ed.src), str(ed.dst), label=str(label)) if self._alphabets is None: self._alphabets = set() for ap in spot.atomic_prop_collect(self._spot_formula): self._alphabets.add(str(ap)) # replace all '1' labels to be all possible alphabets for src, dst, label in self._graph.edges(data='label'): if self._graph[src][dst]['label'] == '1': self._graph[src][dst]['label'] = self._get_alphabet_str() self._graph[src][dst]['print_label'] = '1' elif self._graph[src][dst]['label'] == '0': self._graph[src][dst]['label'] = self._get_neg_alphabet_str() self._graph[src][dst]['print_label'] = '0' else: self._graph[src][dst]['print_label'] = self._graph[src][dst][ 'label']
def ap_project(self, aps): if not aps: return self settings.log(3, lambda: 'ap_project: {}'.format(aps)) # Do a quick check here to simplify if we're empty; the emptiness checking algorithm is very fast (can be done in linear time) # Compared to the cost of postprocessing (depends on the underlying automaton, but generally atrocious) # this is very cheap, and gives us an easy simplification if it works. if self.aut.is_empty(): return self.make_empty_aut() remover = spot.remove_ap() for ap in aps: remover.add_ap(ap) res_aut = remover.strip(self.get_aut()) return BuchiAutomaton(res_aut, self.get_var_map())
try: spot.iar(spot.translate('GFa & GFb & GFc')) except RuntimeError as e: assert 'iar() expects Rabin-like or Streett-like input' in str(e) alt = spot.dualize(spot.translate('FGa | FGb')) try: spot.tgba_determinize(alt) except RuntimeError as e: assert 'tgba_determinize() does not support alternation' in str(e) aut = spot.translate('a U b U c') aps = aut.ap() rem = spot.remove_ap() rem.add_ap('"a"=0,b') aut = rem.strip(aut) assert aut.ap() == aps[2:] try: rem.add_ap('"a=0,b') except ValueError as e: assert """missing closing '"'""" in str(e) try: rem.add_ap('a=0=b') except ValueError as e: assert """unexpected '=' at position 3""" in str(e) si = spot.scc_info(alt)
try: spot.iar(spot.translate('GFa & GFb & GFc')) except RuntimeError as e: assert 'iar() expects Rabin-like input' in str(e) alt = spot.dualize(spot.translate('FGa | FGb')) try: spot.tgba_determinize(alt) except RuntimeError as e: assert 'tgba_determinize() does not support alternation' in str(e) aut = spot.translate('a U b U c') aps = aut.ap() rem = spot.remove_ap() rem.add_ap('"a"=0,b') aut = rem.strip(aut) assert aut.ap() == aps[2:] try: rem.add_ap('"a=0,b') except ValueError as e: assert """missing closing '"'""" in str(e) try: rem.add_ap('a=0=b') except ValueError as e: assert """unexpected '=' at position 3""" in str(e) si = spot.scc_info(alt)