def _bdd_for_label(self, label): """Get the BDD for given label (sequence of AP-indices).""" cond = buddy.bddtrue for ap_i, bdd_var in self.ap2bdd_var.items(): if ap_i in label: cond &= buddy.bdd_ithvar(bdd_var) else: cond -= buddy.bdd_ithvar(bdd_var) return cond
def _register_aprops(self, automaton): """Register the atomic proposition in the automaton""" self.bdd_vars = [ buddy.bdd_ithvar(automaton.register_ap(str(prop))) for prop in self.aprops ]
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 shuffle(self, disjunction=False): new_aut = spot.make_twa_graph() # We want to make sure that it visits infinitely often BOTH automata's accepting states if disjunction: new_aut.set_acceptance(2, 'Inf(0) | Inf(1)') else: new_aut.set_acceptance(2, 'Inf(0) & Inf(1)') new_aut.new_states(2 * self.aut_a.num_states() * self.aut_b.num_states()) idx = 0 for i in ['a', 'b']: for qa in range(self.aut_a.num_states()): for qb in range(self.aut_b.num_states()): self.state_encoding[(i, qa, qb)] = idx idx += 1 for ap in self.aut_a.ap(): buddy.bdd_ithvar(new_aut.register_ap(ap.ap_name())) for ap in self.aut_b.ap(): buddy.bdd_ithvar(new_aut.register_ap(ap.ap_name())) a_init = self.aut_a.get_init_state_number() b_init = self.aut_b.get_init_state_number() new_aut.set_init_state(self.state_encoding[('a', a_init, b_init)]) for e in self.aut_a.edges(): for qb in range(self.aut_b.num_states()): src = self.state_encoding[('a', e.src, qb)] dst = self.state_encoding[('b', e.dst, qb)] acc = self.transform_acc(e.acc, 0) # print('Adding edge: {} -> {} with cond {} and acc {}'.format(src, dst, spot.bdd_to_formula(e.cond), acc)) new_aut.new_edge(src, dst, e.cond, acc) for e in self.aut_b.edges(): for qa in range(self.aut_a.num_states()): src = self.state_encoding[('b', qa, e.src)] dst = self.state_encoding[('a', qa, e.dst)] acc = self.transform_acc(e.acc, 1) # print('Adding edge: {} -> {} with cond {} and acc {}'.format(src, dst, spot.bdd_to_formula(e.cond), acc)) new_aut.new_edge(src, dst, e.cond, acc) return new_aut.postprocess('BA')
def toSpot(self, bdict=default_bdd_dict): """ Translate a (generalized) buchi automaton into bdd in spot package :param bdict: the bdd_dict that the output automaton uses :return: an spot generalized buchi automaton """ aut = spot.make_twa_graph(bdict) ap_list = dict() state_map = dict() for ap in self.ap_list: # if ap not in ['0', '1']: ap_list[ap] = buddy.bdd_ithvar(aut.register_ap(ap)) aut.set_generalized_buchi(self.acc_num) aut.prop_state_acc(1) new_index = 0 for index, state in self.state_dict.items(): aut.new_state() state_map[index] = new_index new_index = new_index + 1 aut.set_init_state(state_map[self.getInitState()]) for edge in self.edge_list: acc = self.getStateAcc(edge.src) ap_calc_list = parse(edge.ap, ops, re_splitter) ap_stack = list() for token in ap_calc_list: if token == '!': ap_stack[-1] = -ap_stack[-1] elif token == '&': ap_stack[-2] = ap_stack[-1] & ap_stack[-2] ap_stack.pop() elif token == '|': ap_stack[-2] = ap_stack[-1] | ap_stack[-2] ap_stack.pop() elif token in self.ap_list: ap_stack.append(ap_list[token]) elif token == '0': ap_stack.append(buddy.bddfalse) elif token == '1': ap_stack.append(buddy.bddtrue) else: raise Exception('Unknown AP token %s in edge formula' % token) if len(ap_stack) != 1: raise Exception('Wrong edge AP formula format!') aut.new_edge(state_map[edge.src], state_map[edge.dst], ap_stack[0], acc) return aut, state_map
def __init__( self, prog, alphabets, buchi_aut, layer=None, layer_from=None, layer_to=None, save_to='plot.png', show=False, plot_method="matplotlib", color_by_axis=None, ): super().__init__() self.prog = prog self.buchi_aut = buchi_aut self.layer = layer self.layer_from = layer_from self.layer_to = layer_to self.save_to = save_to self.alphabet_sizes = {} self.color_by_axis = color_by_axis # only available for 3d self.show = show self.translation_cache = {} self.bdds = {} for var, aps in buchi_aut.var_map.items(): self.bdds[var] = [ buddy.bdd_ithvar(buchi_aut.aut.register_ap(ap)) for ap in aps ] self.prefix_word = spot.twa_word(buchi_aut.aut.get_dict()) self.prefix_word.cycle.append(buddy.bddtrue) for k in alphabets: self.alphabet_sizes[k] = alphabets[k] # fix an arbitrary order of the arguments self.dimensions = list(self.alphabet_sizes.keys()) if plot_method not in BuchiPlotter.PLOT_METHOD_MAP: raise Exception("unsupported plot method {}".format(plot_method)) dim = len(self.dimensions) if dim not in BuchiPlotter.PLOT_METHOD_MAP[plot_method]: raise Exception( "plot method {} cannot plot in dimension {}".format( plot_method, dim)) self.plot_method = BuchiPlotter.PLOT_METHOD_MAP[plot_method][dim]()
# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # Spot is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public # License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import spot import buddy bdict = spot.make_bdd_dict() k = spot.make_kripke_graph(bdict) p1 = buddy.bdd_ithvar(k.register_ap("p1")) p2 = buddy.bdd_ithvar(k.register_ap("p2")) cond1 = p1 & p2 cond2 = p1 & -p2 cond3 = -p1 & -p2 s2 = k.new_state(cond1) s1 = k.new_state(cond2) s3 = k.new_state(cond3) k.new_edge(s1, s2) k.new_edge(s2, s2) k.new_edge(s1, s3) k.new_edge(s3, s3) k.new_edge(s3, s2) k.set_init_state(s1) hoa = """HOA: v1
def pre_build(self, new_aut): for k, v in self.subs.items(): if type(v) is str: self.subs[k] = buddy.bdd_ithvar(new_aut.register_ap(v))
# (at your option) any later version. # # Spot is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public # License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import spot import buddy aut = spot.make_twa_graph(spot._bdd_dict) p1 = buddy.bdd_ithvar(aut.register_ap("p1")) p2 = buddy.bdd_ithvar(aut.register_ap("p2")) m = aut.set_buchi() aut.new_states(3) aut.set_init_state(0) aut.new_univ_edge(0, [1, 2], p1, m) aut.new_univ_edge(0, [0, 1], p2) aut.new_univ_edge(1, [0, 2, 1], p1 & p2) aut.new_edge(2, 2, p1 | p2) tr = [(s, [[x for x in aut.univ_dests(i)] for i in aut.out(s)]) for s in range(3)] print(tr)
# License for more details. # # You should have received a copy of the GNU General Public License # along with Spot; see the file COPYING. If not, write to the Free # Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. import spot import buddy import sys alloc = spot.bdd_allocator() alloc.allocate_variables(3) a = buddy.bdd_ithvar(0) b = buddy.bdd_ithvar(1) c = buddy.bdd_ithvar(2) w = -a & -b | -c & b | a & -b isop = spot.minato_isop(w) i = isop.next() l = [] while i != buddy.bddfalse: buddy.bdd_printset(i) print l.append(i) i = isop.next()