clingo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
safetycheck.hh
Go to the documentation of this file.
1 // {{{ GPL License
2 
3 // This file is part of gringo - a grounder for logic programs.
4 // Copyright (C) 2013 Roland Kaminski
5 
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 // }}}
20 
21 #ifndef _GRINGO_SAFETYCHECK_HH
22 #define _GRINGO_SAFETYCHECK_HH
23 
24 #include <vector>
25 #include <forward_list>
26 #include <unordered_map>
27 
28 namespace Gringo {
29 
30 // {{{ declaration of SafetyChecker<Ent, Var>
31 
32 template <class Var, class Ent>
33 struct SafetyChecker {
34  struct EntNode;
35  struct VarNode {
36  template <class... T>
37  VarNode(T&&... args);
38  bool bound = false;
39  std::vector<EntNode*> provides;
41  };
42 
43  struct EntNode {
44  template <class... T>
45  EntNode(T&&... args);
46  std::vector<VarNode*> provides;
47  unsigned depends = 0;
48  Ent data;
49  };
50 
51  typedef std::vector<EntNode*> EntVec;
52  typedef std::vector<VarNode*> VarVec;
53 
54  SafetyChecker();
55  SafetyChecker(SafetyChecker const &) = delete;
57 
58  template <class... T>
59  VarNode &insertVar(T&&... args);
60  template <class... T>
61  EntNode &insertEnt(T&&... args);
62 
65  void insertEdge(VarNode &x, EntNode &y);
68  void insertEdge(EntNode &x, VarNode &y);
69 
70  void init(EntVec &open);
71  void propagate(EntNode *x, EntVec &open, VarVec *bound = nullptr);
72  template <class Pred = std::less<Ent>>
73  EntVec order(Pred pred = Pred());
74  VarVec open();
75 
76  std::forward_list<EntNode> entNodes_;
77  std::forward_list<VarNode> varNodes_;
78 };
79 
80 // }}}
81 
82 // {{{ definition of SafetyChecker<Var, Ent>::VarNode
83 
84 template <class Var, class Ent>
85 template <class... T>
87  : data(std::forward<T>(args)...)
88 {
89 }
90 
91 // }}}
92 // {{{ definition of SafetyChecker<Var, Ent>::EntNode
93 
94 template <class Var, class Ent>
95 template <class... T>
97  : data(std::forward<T>(args)...)
98 {
99 }
100 
101 // }}}
102 // {{{ definition of SafetyChecker<Var, Ent>
103 
104 template <class Var, class Ent>
106 
107 template <class Var, class Ent>
109 
110 template <class Var, class Ent>
112  x.provides.emplace_back(&y);
113  y.depends++;
114 }
115 
116 template <class Var, class Ent>
118  x.provides.emplace_back(&y);
119 }
120 
121 template <class Var, class Ent>
122 template <class... T>
124  varNodes_.emplace_front(std::forward<T>(args)...);
125  return varNodes_.front();
126 }
127 
128 template <class Var, class Ent>
129 template <class... T>
131  entNodes_.emplace_front(std::forward<T>(args)...);
132  return entNodes_.front();
133 }
134 
135 template <class Var, class Ent>
136 template <class Pred>
138  EntVec open;
139  init(open);
140  std::vector<EntNode*> done;
141  while (!open.empty()) {
142  for (auto it = open.begin(), end = open.end() - 1; it != end; ++it) {
143  if (pred((*it)->data, open.back()->data)) { std::swap(open.back(), *it); }
144  }
145  auto x = open.back();
146  open.pop_back();
147  propagate(x, open);
148  done.emplace_back(x);
149  }
150  return done;
151 }
152 
153 template <class Var, class Ent>
155  for (auto &x : entNodes_) {
156  if (!x.depends) { open.emplace_back(&x); }
157  }
158 }
159 
160 template <class Var, class Ent>
162  for (auto &y : x->provides) {
163  if (!y->bound) {
164  y->bound = true;
165  if (bound) { bound->emplace_back(y); }
166  for (auto &z : y->provides) {
167  if (!--z->depends) { open.emplace_back(z); }
168  }
169  }
170  }
171 }
172 
173 template <class Var, class Ent>
175  VarVec open;
176  for (auto &x : varNodes_) {
177  if (!x.bound) { open.emplace_back(&x); }
178  }
179  return open;
180 }
181 
182 // }}}
183 
184 } // namespace Gringo
185 
186 #endif // _GRINGO_SAFETYCHECK_HH
void init(EntVec &open)
Definition: safetycheck.hh:154
EntVec order(Pred pred=Pred())
EntNode(T &&...args)
Definition: safetycheck.hh:96
std::vector< EntNode * > EntVec
Definition: safetycheck.hh:51
Definition: safetycheck.hh:35
ULit pred(NAF naf, UTerm &&arg)
Definition: lit_helper.hh:69
unsigned depends
Definition: safetycheck.hh:47
VarNode & insertVar(T &&...args)
void propagate(EntNode *x, EntVec &open, VarVec *bound=nullptr)
Definition: safetycheck.hh:161
EntNode & insertEnt(T &&...args)
void swap(Literal &l, Literal &r)
Definition: literal.h:188
uint32 Var
A variable is currently nothing more but an integer in the range [0..varMax).
Definition: literal.h:42
std::vector< VarNode * > VarVec
Definition: safetycheck.hh:52
Definition: safetycheck.hh:43
void insertEdge(VarNode &x, EntNode &y)
Definition: safetycheck.hh:111
std::vector< EntNode * > provides
Definition: safetycheck.hh:39
Ent data
Definition: safetycheck.hh:48
std::forward_list< VarNode > varNodes_
Definition: safetycheck.hh:77
bool bound
Definition: safetycheck.hh:38
Bound & bound
Definition: output.cc:122
std::forward_list< EntNode > entNodes_
Definition: safetycheck.hh:76
VarVec open()
Definition: safetycheck.hh:174
VarNode(T &&...args)
Definition: safetycheck.hh:86
int x
Definition: utility.cc:65
std::vector< VarNode * > provides
Definition: safetycheck.hh:46
Definition: safetycheck.hh:33
Var data
Definition: safetycheck.hh:40
int end
Definition: literals.cc:62