Doxygen Generated Documentation of Ben-Jose Trainable SAT Solver Library
binder.h
1 
2 
3 /*************************************************************
4 
5 This file is part of ben-jose.
6 
7 ben-jose is free software: you can redistribute it and/or modify
8 it under the terms of the version 3 of the GNU General Public
9 License as published by the Free Software Foundation.
10 
11 ben-jose 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 ben-jose. If not, see <http://www.gnu.org/licenses/>.
18 
19 ------------------------------------------------------------
20 
21 Copyright (C) 2007-2012, 2014-2016. QUIROGA BELTRAN, Jose Luis.
22 Id (cedula): 79523732 de Bogota - Colombia.
23 See https://github.com/joseluisquiroga/ben-jose
24 
25 ben-jose is free software thanks to The Glory of Our Lord
26  Yashua Melej Hamashiaj.
27 Our Resurrected and Living, both in Body and Spirit,
28  Prince of Peace.
29 
30 ------------------------------------------------------------
31 
32 binder.h
33 
34 binder class and related.
35 
36 --------------------------------------------------------------*/
37 
38 #ifndef BINDER_H
39 #define BINDER_H
40 
41 #include "tools.h"
42 
43 #define BINDER_CK(prm) DBG_CK(prm)
44 
45 //=================================================================
46 // binder
47 
48 class binder {
49 public:
50  static
51  char* CL_NAME;
52 
53  virtual
54  char* get_cls_name(){
55  return binder::CL_NAME;
56  }
57 
58  binder* bn_left;
59  binder* bn_right;
60 
61  binder(){
62  init_binder();
63  }
64 
65  ~binder(){
66  }
67 
68  void init_binder(){
69  bn_left = this;
70  bn_right = this;
71  }
72 
73  bool is_alone(){
74  return ((bn_left == this) && (bn_right == this));
75  }
76 
77  virtual
78  void let_go(){
79  bn_left->bn_right = bn_right;
80  bn_right->bn_left = bn_left;
81  bn_left = this;
82  bn_right = this;
83  }
84 
85  bool ck_binder(){
86  BINDER_CK(bn_right->bn_left == this);
87  BINDER_CK(bn_left->bn_right == this);
88  return true;
89  }
90 
91  void bind_to_my_right(binder& the_rgt){
92  BINDER_CK(the_rgt.is_alone());
93  BINDER_CK(ck_binder());
94 
95  the_rgt.bn_right = bn_right;
96  the_rgt.bn_left = this;
97  bn_right->bn_left = &the_rgt;
98  bn_right = &the_rgt;
99 
100  BINDER_CK(the_rgt.ck_binder());
101  BINDER_CK(ck_binder());
102  }
103 
104  void bind_to_my_left(binder& the_lft){
105  BINDER_CK(the_lft.is_alone());
106  BINDER_CK(ck_binder());
107 
108  the_lft.bn_left = bn_left;
109  the_lft.bn_right = this;
110  bn_left->bn_right = &the_lft;
111  bn_left = &the_lft;
112 
113  BINDER_CK(the_lft.ck_binder());
114  BINDER_CK(ck_binder());
115  }
116 
117  bool is_grip();
118  bool is_leftmost();
119  bool is_rightmost();
120 
121  bool is_last_in_grip(){
122  return (is_leftmost() && is_rightmost());
123  }
124 };
125 
126 //=================================================================
127 // grip
128 
129 class grip : public binder {
130 public:
131  static
132  char* CL_NAME;
133 
134  virtual
135  char* get_cls_name(){
136  return grip::CL_NAME;
137  }
138 
139  virtual
140  void let_go(){
141  BINDER_CK(false);
142  }
143 
144  bool is_single(){
145  return (! is_alone() && (bn_left == bn_right));
146  }
147 
148  bool is_multiple(){
149  return (! is_alone() && ! is_single());
150  }
151 
152  void move_all_to_my_right(grip& grp){
153  if(grp.is_alone()){
154  return;
155  }
156 
157  BINDER_CK(ck_binder());
158 
159  binder* new_rgt = grp.bn_right;
160  binder* new_mid = grp.bn_left;
161  binder* old_rgt = bn_right;
162 
163  grp.bn_right = &grp;
164  grp.bn_left = &grp;
165 
166  bn_right = new_rgt;
167  bn_right->bn_left = this;
168 
169  new_mid->bn_right = old_rgt;
170  new_mid->bn_right->bn_left = new_mid;
171 
172  BINDER_CK(grp.is_alone());
173  BINDER_CK(new_rgt->ck_binder());
174  BINDER_CK(new_mid->ck_binder());
175  BINDER_CK(old_rgt->ck_binder());
176  BINDER_CK(ck_binder());
177  }
178 
179  void move_all_to_my_left(grip& grp){
180  if(grp.is_alone()){
181  return;
182  }
183 
184  BINDER_CK(ck_binder());
185 
186  binder* new_lft = grp.bn_left;
187  binder* new_mid = grp.bn_right;
188  binder* old_lft = bn_left;
189 
190  grp.bn_right = &grp;
191  grp.bn_left = &grp;
192 
193  bn_left = new_lft;
194  bn_left->bn_right = this;
195 
196  new_mid->bn_left = old_lft;
197  new_mid->bn_left->bn_right = new_mid;
198 
199  BINDER_CK(grp.is_alone());
200  BINDER_CK(new_lft->ck_binder());
201  BINDER_CK(new_mid->ck_binder());
202  BINDER_CK(old_lft->ck_binder());
203  BINDER_CK(ck_binder());
204  }
205 
206  void let_all_go(){
207  while(! is_alone()){
208  bn_right->let_go();
209  }
210  }
211 
212  void forced_let_go(){
213  binder::let_go();
214  }
215 
216  template<class obj_t1>
217  void append_all_as(row<obj_t1*>& rr, bool clr = false);
218 };
219 
220 inline
221 bool
222 binder::is_grip(){
223  bool is_g = (get_cls_name() == grip::CL_NAME);
224  return is_g;
225 }
226 
227 inline
228 bool
229 binder::is_leftmost(){
230  BINDER_CK(! is_grip());
231  return bn_left->is_grip();
232 }
233 
234 inline
235 bool
236 binder::is_rightmost(){
237  BINDER_CK(! is_grip());
238  return bn_right->is_grip();
239 }
240 
241 //=================================================================
242 // receptor
243 
244 template<class obj_t1>
245 class receptor : public binder {
246 public:
247  virtual
248  char* get_cls_name(){
249  return obj_t1::CL_NAME;
250  }
251 
252  obj_t1* re_me;
253 
254  receptor(){
255  init_receptor();
256  }
257 
258  ~receptor(){
259  }
260 
261  void init_receptor(){
262  re_me = NULL_PT;
263  }
264 
265  receptor(obj_t1& tgt){
266  re_me = &tgt;
267  }
268 
269  receptor(obj_t1* tgt){
270  re_me = tgt;
271  }
272 
273  operator obj_t1* () {
274  return re_me;
275  }
276 
277  operator obj_t1& () {
278  BINDER_CK(re_me != NULL_PT);
279  return *re_me;
280  }
281 };
282 
283 //=================================================================
284 // TEMPLATE DEFS
285 
286 template<class obj_t1>
287 obj_t1&
288 rcp_as(binder* bdr){
289  BINDER_CK(bdr != NULL_PT);
290  BINDER_CK(bdr->get_cls_name() == obj_t1::CL_NAME);
291 
292  receptor<obj_t1>& rcp = *((receptor<obj_t1>*)(bdr));
293  BINDER_CK(rcp.re_me != NULL_PT);
294 
295  obj_t1& obj_1 = rcp;
296  return obj_1;
297 }
298 
299 
300 template<class obj_t1>
301 void
302 grip::append_all_as(row<obj_t1*>& rr, bool clr){
303  if(clr){
304  rr.clear();
305  }
306 
307  binder* fst_bdr = bn_right;
308  binder* lst_bdr = this;
309  for(binder* bdr_1 = fst_bdr; bdr_1 != lst_bdr; bdr_1 = bdr_1->bn_right){
310  obj_t1& ob_1 = rcp_as<obj_t1>(bdr_1);
311  rr.push(&ob_1);
312  }
313 }
314 
315 
316 #endif // BINDER_H
317 
318