spot  2.11.6
aiger.hh
1 // -*- coding: utf-8 -*-
2 // Copyright (C) 2020-21 Laboratoire de Recherche et Développement
3 // de l'Epita (LRDE).
4 //
5 // This file is part of Spot, a model checking library.
6 //
7 // Spot is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // Spot is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 
20 #pragma once
21 
22 #include <iosfwd>
23 #include <spot/misc/common.hh>
24 #include <spot/misc/bddlt.hh>
25 #include <spot/twa/fwd.hh>
26 #include <spot/twa/bdddict.hh>
27 #include <spot/tl/formula.hh>
28 
29 #include <unordered_map>
30 #include <vector>
31 #include <set>
32 #include <memory>
33 #include <sstream>
34 
35 
36 namespace spot
37 {
38  // Forward for synthesis
39  struct mealy_like;
40 
41  class aig;
42 
43  typedef std::shared_ptr<aig> aig_ptr;
44  typedef std::shared_ptr<const aig> const_aig_ptr;
45 
58  class SPOT_API aig
59  {
60  protected:
61  const unsigned num_inputs_;
62  const unsigned num_outputs_;
63  const unsigned num_latches_;
64  const std::vector<std::string> input_names_;
65  const std::vector<std::string> output_names_;
66  unsigned max_var_;
67 
68  std::vector<unsigned> next_latches_;
69  std::vector<unsigned> outputs_;
70  std::vector<std::pair<unsigned, unsigned>> and_gates_;
71  bdd_dict_ptr dict_;
72  // Cache the function computed by each variable as a bdd.
73  // Bidirectional map
74  std::unordered_map<unsigned, bdd> var2bdd_;
75  std::unordered_map<int, unsigned> bdd2var_; //uses id
76  // First anonymous var marking the beginning of variables used
77  // as latches
78  int l0_;
79 
80  bdd all_ins_;
81  bdd all_latches_;
82 
83  // For simulation
84  std::vector<bool> state_;
85 
86  public:
87 
93  using safe_point = std::pair<unsigned, unsigned>;
94  using safe_stash =
95  std::tuple<std::vector<std::pair<unsigned, unsigned>>,
96  std::vector<std::pair<unsigned, bdd>>,
97  std::vector<bdd>>;
98 
103  aig(const std::vector<std::string>& inputs,
104  const std::vector<std::string>& outputs,
105  unsigned num_latches,
106  bdd_dict_ptr dict = make_bdd_dict());
107 
109  aig(unsigned num_inputs, unsigned num_outputs,
110  unsigned num_latches, bdd_dict_ptr dict = make_bdd_dict());
111 
112  ~aig()
113  {
114  dict_->unregister_all_my_variables(this);
115  }
116 
117  protected:
119  void register_new_lit_(unsigned v, const bdd &b);
120  void register_latch_(unsigned i, const bdd& b);
121  void register_input_(unsigned i, const bdd& b);
123  void unregister_lit_(unsigned v);
124 
127  void split_cond_(const bdd& b, char so_mode,
128  std::vector<bdd>& cond_parts);
129 
131  bdd accum_common_(const bdd& b) const;
132 
134  unsigned cube2var_(const bdd& b, const int use_split_off);
135 
136  public:
137 
146 
154  safe_stash roll_back_(safe_point sp,
155  bool do_stash = false);
160  void reapply_(safe_point sp, const safe_stash& ss);
161 
163  unsigned num_outputs() const
164  {
165  return num_outputs_;
166  }
169  const std::vector<unsigned>& outputs() const
170  {
171  SPOT_ASSERT(std::none_of(outputs_.begin(), outputs_.end(),
172  [](unsigned o){return o == -1u; }));
173  return outputs_;
174  }
176  const std::vector<std::string>& output_names() const
177  {
178  return output_names_;
179  }
180 
182  unsigned num_inputs() const
183  {
184  return num_inputs_;
185  }
187  const std::vector<std::string>& input_names() const
188  {
189  return input_names_;
190  }
191 
193  unsigned num_latches() const
194  {
195  return num_latches_;
196  }
200  const std::vector<unsigned>& next_latches() const
201  {
202  SPOT_ASSERT(std::none_of(next_latches_.begin(), next_latches_.end(),
203  [](unsigned o){return o == -1u; }));
204  return next_latches_;
205  };
206 
208  unsigned num_gates() const
209  {
210  return and_gates_.size();
211  };
213  const std::vector<std::pair<unsigned, unsigned>>& gates() const
214  {
215  return and_gates_;
216  };
217 
219  unsigned max_var() const
220  {
221  return max_var_;
222  };
223 
225  unsigned input_var(unsigned i, bool neg = false) const
226  {
227  SPOT_ASSERT(i < num_inputs_);
228  return (1 + i) * 2 + neg;
229  }
231  bdd input_bdd(unsigned i, bool neg = false) const
232  {
233  return aigvar2bdd(input_var(i, neg));
234  }
235 
237  unsigned latch_var(unsigned i, bool neg = false) const
238  {
239  SPOT_ASSERT(i < num_latches_);
240  return (1 + num_inputs_ + i) * 2 + neg;
241  }
243  bdd latch_bdd(unsigned i, bool neg = false) const
244  {
245  return aigvar2bdd(latch_var(i, neg));
246  }
247 
249  unsigned gate_var(unsigned i, bool neg = false) const
250  {
251  SPOT_ASSERT(i < num_gates());
252  return (1 + num_inputs_ + num_latches_ + i) * 2 + neg;
253  }
255  bdd gate_bdd(unsigned i, bool neg = false) const
256  {
257  return aigvar2bdd(gate_var(i, neg));
258  }
259 
262  bdd aigvar2bdd(unsigned v, bool neg = false) const
263  {
264  return neg ? bdd_not(var2bdd_.at(v)) : var2bdd_.at(v);
265  }
266 
269  unsigned bdd2aigvar(const bdd& b) const
270  {
271  return bdd2var_.at(b.id());
272  }
273 
275  unsigned bdd2INFvar(const bdd& b);
276 
278  unsigned bdd2ISOPvar(const bdd& b, const int use_split_off = 0);
279 
297  unsigned encode_bdd(const std::vector<bdd>& c_alt,
298  char method = 1, bool use_dual = false,
299  int use_split_off = 0);
300 
302  unsigned encode_bdd(const bdd& b,
303  char method = 1, bool use_dual = false,
304  int use_split_off = 0);
305 
307  void set_output(unsigned i, unsigned v);
308 
310  void set_next_latch(unsigned i, unsigned v);
311 
312  static constexpr unsigned aig_true() noexcept
313  {
314  return 1;
315  };
316 
317  static constexpr unsigned aig_false() noexcept
318  {
319  return 0;
320  };
321 
323  unsigned aig_not(unsigned v);
324 
326  unsigned aig_and(unsigned v1, unsigned v2);
327 
331  unsigned aig_and(std::vector<unsigned>& vs);
332 
334  unsigned aig_or(unsigned v1, unsigned v2);
335 
339  unsigned aig_or(std::vector<unsigned>& vs);
340 
342  unsigned aig_pos(unsigned v);
343 
350  void encode_all_bdds(const std::vector<bdd>& all_bdd);
351 
359  static aig_ptr
360  parse_aag(const std::string& aig_file,
361  bdd_dict_ptr dict = make_bdd_dict());
362 
363  static aig_ptr
364  parse_aag(const char* data,
365  const std::string& filename,
366  bdd_dict_ptr dict = make_bdd_dict());
367 
368  static aig_ptr
369  parse_aag(std::istream& iss,
370  const std::string& filename,
371  bdd_dict_ptr dict = make_bdd_dict());
372 
377  twa_graph_ptr as_automaton(bool keepsplit = false) const;
378 
387  const std::vector<bool>& circ_state() const
388  {
389  SPOT_ASSERT(state_.size() == max_var_ + 2
390  && "State vector does not have the correct size.\n"
391  "Forgot to initialize?");
392  return state_;
393  }
394 
396  bool circ_state_of(unsigned var) const
397  {
398  SPOT_ASSERT(var <= max_var_ + 1
399  && "Variable out of range");
400  return circ_state()[var];
401  }
402 
405  void circ_init();
406 
413  void circ_step(const std::vector<bool>& inputs);
414 
415  };
416 
439  SPOT_API aig_ptr
440  mealy_machine_to_aig(const const_twa_graph_ptr& m, const char* mode);
441  SPOT_API aig_ptr
442  mealy_machine_to_aig(const twa_graph_ptr& m, const char *mode,
443  const std::vector<std::string>& ins,
444  const std::vector<std::string>& outs);
445 
446  SPOT_API aig_ptr
447  mealy_machine_to_aig(const mealy_like& m, const char* mode);
448  SPOT_API aig_ptr
449  mealy_machine_to_aig(mealy_like& m, const char *mode,
450  const std::vector<std::string>& ins,
451  const std::vector<std::string>& outs);
453 
468  SPOT_API aig_ptr
469  mealy_machines_to_aig(const std::vector<const_twa_graph_ptr>& m_vec,
470  const char* mode);
471  SPOT_API aig_ptr
472  mealy_machines_to_aig(const std::vector<mealy_like>& m_vec,
473  const char* mode);
474  SPOT_API aig_ptr
475  mealy_machines_to_aig(const std::vector<const_twa_graph_ptr>& m_vec,
476  const char* mode,
477  const std::vector<std::string>& ins,
478  const std::vector<std::vector<std::string>>& outs);
479  SPOT_API aig_ptr
480  mealy_machines_to_aig(const std::vector<mealy_like>& m_vec,
481  const char* mode,
482  const std::vector<std::string>& ins,
483  const std::vector<std::vector<std::string>>& outs);
485 
488  SPOT_API std::ostream&
489  print_aiger(std::ostream& os, const_aig_ptr circuit);
490 
526  SPOT_API std::ostream&
527  print_aiger(std::ostream& os, const const_twa_graph_ptr& aut,
528  const char* mode);
529 }
A class representing AIG circuits.
Definition: aiger.hh:59
bdd gate_bdd(unsigned i, bool neg=false) const
Get the bdd associated to the ith gate.
Definition: aiger.hh:255
unsigned encode_bdd(const std::vector< bdd > &c_alt, char method=1, bool use_dual=false, int use_split_off=0)
Add a bdd to the circuit Assumes that all bdd's given in c_alt fulfill the same purpose,...
bdd aigvar2bdd(unsigned v, bool neg=false) const
Get the bdd associated to a variable.
Definition: aiger.hh:262
static aig_ptr parse_aag(const std::string &aig_file, bdd_dict_ptr dict=make_bdd_dict())
Create a circuit from an aag file with restricted syntax.
twa_graph_ptr as_automaton(bool keepsplit=false) const
Transform the circuit onto an equivalent monitor.
void reapply_(safe_point sp, const safe_stash &ss)
Reapply to stored changes on top of a safe_point.
std::pair< unsigned, unsigned > safe_point
Mark the beginning of a test tranlation.
Definition: aiger.hh:93
unsigned gate_var(unsigned i, bool neg=false) const
Get the variable associated to the ith gate.
Definition: aiger.hh:249
const std::vector< std::pair< unsigned, unsigned > > & gates() const
Access the underlying container.
Definition: aiger.hh:213
void unregister_lit_(unsigned v)
Remove a literal from both maps.
unsigned aig_and(unsigned v1, unsigned v2)
Compute AND of v1 and v2.
unsigned num_gates() const
Get the total number of and gates.
Definition: aiger.hh:208
safe_point get_safe_point_() const
Safe the current state of the circuit.
const std::vector< unsigned > & next_latches() const
Get the variables associated to the state of the latches in the next iteration.
Definition: aiger.hh:200
unsigned aig_pos(unsigned v)
Returns the positive form of the given variable.
const std::vector< std::string > & output_names() const
Get the set of output names.
Definition: aiger.hh:176
unsigned bdd2aigvar(const bdd &b) const
Get the variable associated to a bdd.
Definition: aiger.hh:269
unsigned num_inputs() const
Get the number of inputs.
Definition: aiger.hh:182
void circ_init()
(Re)initialize the stepwise evaluation of the circuit. This sets all latches to 0 and clears the outp...
bdd input_bdd(unsigned i, bool neg=false) const
Get the bdd associated to the ith input.
Definition: aiger.hh:231
unsigned input_var(unsigned i, bool neg=false) const
Get the variable associated to the ith input.
Definition: aiger.hh:225
unsigned encode_bdd(const bdd &b, char method=1, bool use_dual=false, int use_split_off=0)
Just like the vector version but with no alternatives given.
aig(unsigned num_inputs, unsigned num_outputs, unsigned num_latches, bdd_dict_ptr dict=make_bdd_dict())
Constructing the circuit with generic names.
unsigned aig_and(std::vector< unsigned > &vs)
Computes the AND of all vars.
unsigned num_outputs() const
Get the number of outputs.
Definition: aiger.hh:163
aig(const std::vector< std::string > &inputs, const std::vector< std::string > &outputs, unsigned num_latches, bdd_dict_ptr dict=make_bdd_dict())
Constructing an "empty" aig, knowing only about the necessary inputs, outputs and latches....
unsigned cube2var_(const bdd &b, const int use_split_off)
Translate a cube into gates, using split-off optionally.
unsigned num_latches() const
Get the number of latches in the circuit.
Definition: aiger.hh:193
bdd accum_common_(const bdd &b) const
Split-off common sub-expressions as cube.
void set_output(unsigned i, unsigned v)
Associate the ith output to the variable v.
unsigned bdd2INFvar(const bdd &b)
Add a bdd to the circuit using if-then-else normal form.
void set_next_latch(unsigned i, unsigned v)
Associate the ith latch state after update to the variable v.
unsigned aig_not(unsigned v)
Negate a variable.
const std::vector< bool > & circ_state() const
Gives access to the current state of the circuit.
Definition: aiger.hh:387
safe_stash roll_back_(safe_point sp, bool do_stash=false)
roll_back to the saved point.
unsigned latch_var(unsigned i, bool neg=false) const
Get the variable associated to the ith latch.
Definition: aiger.hh:237
void circ_step(const std::vector< bool > &inputs)
Performs the next discrete step of the circuit, based on the inputs.
unsigned aig_or(unsigned v1, unsigned v2)
Computes the OR of v1 and v2.
const std::vector< std::string > & input_names() const
Get the set of input names.
Definition: aiger.hh:187
const std::vector< unsigned > & outputs() const
Get the variables associated to the outputs.
Definition: aiger.hh:169
bdd latch_bdd(unsigned i, bool neg=false) const
Get the bdd associated to the ith latch.
Definition: aiger.hh:243
unsigned aig_or(std::vector< unsigned > &vs)
Computes the or of all vars.
void encode_all_bdds(const std::vector< bdd > &all_bdd)
Instead of successively adding bdds to the circuit, one can also pass a vector of all bdds needed to ...
unsigned bdd2ISOPvar(const bdd &b, const int use_split_off=0)
Add a bdd to the circuit using isop normal form.
void register_new_lit_(unsigned v, const bdd &b)
Register a new literal in both maps.
bool circ_state_of(unsigned var) const
Access to the state of a specific variable.
Definition: aiger.hh:396
void split_cond_(const bdd &b, char so_mode, std::vector< bdd > &cond_parts)
Internal function that split a bdd into a conjunction hoping to increase reusage of gates.
unsigned max_var() const
Maximal variable index currently appearing in the circuit.
Definition: aiger.hh:219
LTL/PSL formula interface.
aig_ptr mealy_machine_to_aig(const const_twa_graph_ptr &m, const char *mode)
Convert a mealy (like) machine into an aig relying on the transformation described by mode.
aig_ptr mealy_machines_to_aig(const std::vector< const_twa_graph_ptr > &m_vec, const char *mode)
Convert multiple mealy machines into an aig relying on the transformation described by mode.
std::ostream & print_aiger(std::ostream &os, const_aig_ptr circuit)
Print the aig to stream in AIGER format.
Definition: automata.hh:27
A struct that represents different types of mealy like objects.
Definition: synthesis.hh:196

Please direct any question, comment, or bug report to the Spot mailing list at spot@lrde.epita.fr.
Generated on Fri Feb 27 2015 10:00:07 for spot by doxygen 1.9.1