carl  24.04
Computer ARithmetic Library
SymmetryFinder.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <carl-common/config.h>
4 #include "../formula/Formula.h"
5 
6 #include <bliss/graph.hh>
7 
8 #include <map>
9 
10 namespace carl {
11 namespace formula {
12 namespace symmetry {
13 
14 /**
15  * Special colors for structure nodes.
16  * - If: condition from ite
17  * - Then: first case from ite
18  * - Else: second case from ite
19  * - VarExp: pair of variable and exponent in terms
20  */
21 enum class SpecialColors { If, Then, Else, VarExp };
22 
23 /**
24  * Provides unique ids (colors) for all kinds of different objects in the formula:
25  * variable types, relations, formula types, numbers, special colors and indexes.
26  */
27 template<typename Number>
29 public:
30 private:
31  unsigned nextID = 0;
32  std::map<carl::VariableType, unsigned> mVT;
33  std::map<carl::Relation, unsigned> mRel;
34  std::map<carl::FormulaType, unsigned> mFT;
35  std::map<Number, unsigned> mConst;
36  std::map<SpecialColors, unsigned> mSpecial;
37  std::map<std::size_t, unsigned> mIndexes;
38 
39  template<typename T>
40  unsigned findOrInsert(std::map<T,unsigned>& container, const T& value) {
41  auto it = container.emplace(value, nextID);
42  if (it.second) nextID++;
43  return it.first->second;
44  }
45 public:
46  unsigned next() const {
47  return nextID;
48  }
50  return findOrInsert(mVT, v);
51  }
52  unsigned operator()(carl::Relation v) {
53  return findOrInsert(mRel, v);
54  }
56  return findOrInsert(mFT, v);
57  }
58  unsigned operator()(const Number& v) {
59  return findOrInsert(mConst, v);
60  }
61  unsigned operator()(SpecialColors v) {
62  return findOrInsert(mSpecial, v);
63  }
64  unsigned operator()(std::size_t v) {
65  return findOrInsert(mIndexes, v);
66  }
67 };
68 
69 struct Permutation {
70  std::vector<std::vector<unsigned>> data;
71 };
72 
73 void addGenerator(void* p, const unsigned int n, const unsigned int* aut) {
74  static_cast<Permutation*>(p)->data.emplace_back(aut, aut+n);
75 }
76 
77 template<typename Poly>
78 class GraphBuilder {
79  using Number = typename Poly::NumberType;
80  bliss::Digraph mGraph;
82  std::map<carl::Variable,unsigned> mVariableIDs;
83  std::vector<carl::Variable> mVariables;
84 
85  void gatherVariables(const Formula<Poly>& f) {
86  assert(mColor.next() == 0);
87  carlVariables vars;
88  carl::variables(f,vars);
89  for (const auto& v: vars) {
90  auto res = mVariableIDs.emplace(v, mGraph.add_vertex(mColor(v.type())));
91  assert(res.first->second == mVariables.size());
92  mVariables.emplace_back(v);
93  }
94  }
95  unsigned addTerm(const Term<Number>& t) {
96  unsigned vert = mGraph.add_vertex(mColor(t.coeff()));
97  if (t.monomial()) {
98  for (const auto& ve: *t.monomial()) {
99  for (std::size_t i = 0; i < ve.second; ++i) {
100  unsigned tmp = mGraph.add_vertex(mColor(SpecialColors::VarExp));
101  mGraph.add_edge(vert, tmp);
102  mGraph.add_edge(tmp, mVariableIDs[ve.first]);
103  }
104  }
105  }
106  return vert;
107  }
108  unsigned addConstraint(const Constraint<Poly>& c) {
109  unsigned vert = mGraph.add_vertex(mColor(c.relation()));
110  for (const auto& term: c.lhs()) {
111  mGraph.add_edge(vert, addTerm(term));
112  }
113  return vert;
114  }
115  unsigned addFormula(const Formula<Poly>& f) {
116  unsigned vert = mGraph.add_vertex(mColor(f.type()));
117  switch (f.type()) {
118  case carl::FormulaType::ITE: {
119  unsigned ifvert = mGraph.add_vertex(mColor(SpecialColors::If));
120  mGraph.add_edge(vert, ifvert);
121  mGraph.add_edge(ifvert, addFormula(f.condition()));
122  unsigned thenvert = mGraph.add_vertex(mColor(SpecialColors::Then));
123  mGraph.add_edge(vert, thenvert);
124  mGraph.add_edge(thenvert, addFormula(f.first_case()));
125  unsigned elsevert = mGraph.add_vertex(mColor(SpecialColors::Else));
126  mGraph.add_edge(vert, elsevert);
127  mGraph.add_edge(elsevert, addFormula(f.second_case()));
128  break;
129  }
134  break;
136  mGraph.add_edge(vert, mVariableIDs[f.boolean()]);
137  break;
139  mGraph.add_edge(vert, addFormula(f.subformula()));
140  break;
142  {
143  std::size_t cur = 1;
144  for (const auto& sf: f.subformulas()) {
145  unsigned idvert = mGraph.add_vertex(mColor(cur));
146  mGraph.add_edge(vert, idvert);
147  mGraph.add_edge(idvert, addFormula(sf));
148  cur++;
149  }
150  break;
151  }
156  for (const auto& sf: f.subformulas()) {
157  mGraph.add_edge(vert, addFormula(sf));
158  }
159  break;
161  mGraph.add_edge(vert, addConstraint(f.constraint()));
162  break;
167  break;
168  }
169  return vert;
170  }
171 public:
173  gatherVariables(f);
174  addFormula(f);
175  }
177  bliss::Stats stats;
178  Permutation p;
179  mGraph.find_automorphisms(stats, &addGenerator, &p);
180  Symmetries varsymms;
181  for (const auto& s: p.data) {
182  bool foundChange = false;
183  Symmetry tmp(mVariables.size());
184  for (unsigned i = 0; i < mVariables.size(); ++i) {
185  assert(s[i] < mVariables.size());
186  tmp[i] = std::make_pair(mVariables[i], mVariables[s[i]]);
187  if (s[i] != i) foundChange = true;
188  }
189  if (foundChange) {
190  varsymms.emplace_back(tmp);
191  }
192  }
193  return varsymms;
194  }
195 };
196 
197 }
198 }
199 }
carl is the main namespace for the library.
FormulaType
Represent the type of a formula to allow faster/specialized processing.
@ CONSTRAINT
@ BITVECTOR
@ VARCOMPARE
@ VARASSIGN
VariableType
Several types of variables are supported.
Definition: Variable.h:28
Relation
Definition: Relation.h:20
void variables(const BasicConstraint< Pol > &c, carlVariables &vars)
std::vector< std::pair< Variable, Variable > > Symmetry
A symmetry represents a bijection on a set of variables.
Definition: symmetry.h:14
std::vector< Symmetry > Symmetries
Represents a list of symmetries.
Definition: symmetry.h:19
void addGenerator(void *p, const unsigned int n, const unsigned int *aut)
SpecialColors
Special colors for structure nodes.
Represents a single term, that is a numeric coefficient and a monomial.
Definition: Term.h:23
Coefficient & coeff()
Get the coefficient.
Definition: Term.h:80
Monomial::Arg & monomial()
Get the monomial.
Definition: Term.h:91
Represent a polynomial (in)equality against zero.
Definition: Constraint.h:62
Relation relation() const
Definition: Constraint.h:116
const Pol & lhs() const
Definition: Constraint.h:109
const Formula & subformula() const
Definition: Formula.h:327
carl::Variable::Arg boolean() const
Definition: Formula.h:436
const Constraint< Pol > & constraint() const
Definition: Formula.h:410
const Formulas< Pol > & subformulas() const
Definition: Formula.h:400
const Formula & first_case() const
Definition: Formula.h:363
const Formula & second_case() const
Definition: Formula.h:372
FormulaType type() const
Definition: Formula.h:254
const Formula & condition() const
Definition: Formula.h:354
Provides unique ids (colors) for all kinds of different objects in the formula: variable types,...
std::map< carl::FormulaType, unsigned > mFT
unsigned operator()(carl::Relation v)
std::map< std::size_t, unsigned > mIndexes
std::map< SpecialColors, unsigned > mSpecial
std::map< Number, unsigned > mConst
unsigned operator()(const Number &v)
unsigned findOrInsert(std::map< T, unsigned > &container, const T &value)
std::map< carl::Relation, unsigned > mRel
unsigned operator()(SpecialColors v)
unsigned operator()(carl::FormulaType v)
unsigned operator()(carl::VariableType v)
std::map< carl::VariableType, unsigned > mVT
std::vector< std::vector< unsigned > > data
std::vector< carl::Variable > mVariables
unsigned addTerm(const Term< Number > &t)
typename Poly::NumberType Number
unsigned addFormula(const Formula< Poly > &f)
ColorGenerator< Number > mColor
void gatherVariables(const Formula< Poly > &f)
std::map< carl::Variable, unsigned > mVariableIDs
GraphBuilder(const Formula< Poly > &f)
unsigned addConstraint(const Constraint< Poly > &c)