Generated on Sun Aug 26 2012 08:42:35 for Gecode by doxygen 1.8.1.1
ast.hh
Go to the documentation of this file.
1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 /*
3  * Main authors:
4  * Guido Tack <tack@gecode.org>
5  *
6  * Copyright:
7  * Guido Tack, 2007
8  *
9  * Last modified:
10  * $Date: 2012-02-22 16:04:20 +1100 (Wed, 22 Feb 2012) $ by $Author: tack $
11  * $Revision: 12537 $
12  *
13  * This file is part of Gecode, the generic constraint
14  * development environment:
15  * http://www.gecode.org
16  *
17  * Permission is hereby granted, free of charge, to any person obtaining
18  * a copy of this software and associated documentation files (the
19  * "Software"), to deal in the Software without restriction, including
20  * without limitation the rights to use, copy, modify, merge, publish,
21  * distribute, sublicense, and/or sell copies of the Software, and to
22  * permit persons to whom the Software is furnished to do so, subject to
23  * the following conditions:
24  *
25  * The above copyright notice and this permission notice shall be
26  * included in all copies or substantial portions of the Software.
27  *
28  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35  *
36  */
37 
38 #ifndef __GECODE_FLATZINC_AST_HH__
39 #define __GECODE_FLATZINC_AST_HH__
40 
41 #include <vector>
42 #include <string>
43 #include <iostream>
44 #include <cstdlib>
45 
51 namespace Gecode { namespace FlatZinc { namespace AST {
52 
53  class Call;
54  class Array;
55  class Atom;
56  class SetLit;
57 
60  private:
61  std::string _what;
62  public:
63  TypeError() : _what("") {}
64  TypeError(std::string what) : _what(what) {}
65  std::string what(void) const { return _what; }
66  };
67 
72  public:
74  virtual ~Node(void);
75 
77  void append(Node* n);
78 
80  bool hasAtom(const std::string& id);
82  bool isInt(int& i);
84  bool isCall(const std::string& id);
86  Call* getCall(void);
88  bool hasCall(const std::string& id);
90  Call* getCall(const std::string& id);
92  Array* getArray(void);
94  Atom* getAtom(void);
96  int getIntVar(void);
98  int getBoolVar(void);
100  int getSetVar(void);
101 
103  int getInt(void);
105  bool getBool(void);
107  double getFloat(void);
109  SetLit *getSet(void);
110 
112  std::string getString(void);
113 
115  bool isIntVar(void);
117  bool isBoolVar(void);
119  bool isSetVar(void);
121  bool isInt(void);
123  bool isBool(void);
125  bool isString(void);
127  bool isArray(void);
129  bool isSet(void);
131  bool isAtom(void);
132 
134  virtual void print(std::ostream&) = 0;
135  };
136 
139  public:
140  bool b;
141  BoolLit(bool b0) : b(b0) {}
142  virtual void print(std::ostream& os) {
143  os << "b(" << (b ? "true" : "false") << ")";
144  }
145  };
148  public:
149  int i;
150  IntLit(int i0) : i(i0) {}
151  virtual void print(std::ostream& os) {
152  os << "i("<<i<<")";
153  }
154  };
157  public:
158  double d;
159  FloatLit(double d0) : d(d0) {}
160  virtual void print(std::ostream& os) {
161  os << "f("<<d<<")";
162  }
163  };
166  public:
167  bool interval;
168  int min; int max;
169  std::vector<int> s;
170  SetLit(void) {}
171  SetLit(int min0, int max0) : interval(true), min(min0), max(max0) {}
172  SetLit(const std::vector<int>& s0) : interval(false), s(s0) {}
173  bool empty(void) const {
174  return ( (interval && min>max) || (!interval && s.size() == 0));
175  }
176  virtual void print(std::ostream& os) {
177  os << "s()";
178  }
179  };
180 
182  class GECODE_VTABLE_EXPORT Var : public Node {
183  public:
184  int i;
185  Var(int i0) : i(i0) {}
186  };
189  public:
190  BoolVar(int i0) : Var(i0) {}
191  virtual void print(std::ostream& os) {
192  os << "xb("<<i<<")";
193  }
194  };
196  class GECODE_VTABLE_EXPORT IntVar : public Var {
197  public:
198  IntVar(int i0) : Var(i0) {}
199  virtual void print(std::ostream& os) {
200  os << "xi("<<i<<")";
201  }
202  };
205  public:
206  FloatVar(int i0) : Var(i0) {}
207  virtual void print(std::ostream& os) {
208  os << "xf("<<i<<")";
209  }
210  };
212  class GECODE_VTABLE_EXPORT SetVar : public Var {
213  public:
214  SetVar(int i0) : Var(i0) {}
215  virtual void print(std::ostream& os) {
216  os << "xs("<<i<<")";
217  }
218  };
219 
221  class GECODE_VTABLE_EXPORT Array : public Node {
222  public:
223  std::vector<Node*> a;
224  Array(const std::vector<Node*>& a0)
225  : a(a0) {}
227  : a(1) { a[0] = n; }
228  Array(int n=0) : a(n) {}
229  virtual void print(std::ostream& os) {
230  os << "[";
231  for (unsigned int i=0; i<a.size(); i++) {
232  a[i]->print(os);
233  if (i<a.size()-1)
234  os << ", ";
235  }
236  os << "]";
237  }
238  ~Array(void) {
239  for (int i=a.size(); i--;)
240  delete a[i];
241  }
242  };
243 
245  class GECODE_VTABLE_EXPORT Call : public Node {
246  public:
247  std::string id;
249  Call(const std::string& id0, Node* args0)
250  : id(id0), args(args0) {}
251  ~Call(void) { delete args; }
252  virtual void print(std::ostream& os) {
253  os << id << "("; args->print(os); os << ")";
254  }
255  Array* getArgs(unsigned int n) {
256  Array *a = args->getArray();
257  if (a->a.size() != n)
258  throw TypeError("arity mismatch");
259  return a;
260  }
261  };
262 
265  public:
266  Node* a;
268  ArrayAccess(Node* a0, Node* idx0)
269  : a(a0), idx(idx0) {}
270  ~ArrayAccess(void) { delete a; delete idx; }
271  virtual void print(std::ostream& os) {
272  a->print(os);
273  os << "[";
274  idx->print(os);
275  os << "]";
276  }
277  };
278 
280  class GECODE_VTABLE_EXPORT Atom : public Node {
281  public:
282  std::string id;
283  Atom(const std::string& id0) : id(id0) {}
284  virtual void print(std::ostream& os) {
285  os << id;
286  }
287  };
288 
291  public:
292  std::string s;
293  String(const std::string& s0) : s(s0) {}
294  virtual void print(std::ostream& os) {
295  os << "s(\"" << s << "\")";
296  }
297  };
298 
299  inline
300  Node::~Node(void) {}
301 
302  inline void
303  Node::append(Node* newNode) {
304  Array* a = dynamic_cast<Array*>(this);
305  if (!a)
306  throw TypeError("array expected");
307  a->a.push_back(newNode);
308  }
309 
310  inline bool
311  Node::hasAtom(const std::string& id) {
312  if (Array* a = dynamic_cast<Array*>(this)) {
313  for (int i=a->a.size(); i--;)
314  if (Atom* at = dynamic_cast<Atom*>(a->a[i]))
315  if (at->id == id)
316  return true;
317  } else if (Atom* a = dynamic_cast<Atom*>(this)) {
318  return a->id == id;
319  }
320  return false;
321  }
322 
323  inline bool
324  Node::isCall(const std::string& id) {
325  if (Call* a = dynamic_cast<Call*>(this)) {
326  if (a->id == id)
327  return true;
328  }
329  return false;
330  }
331 
332  inline Call*
334  if (Call* a = dynamic_cast<Call*>(this))
335  return a;
336  throw TypeError("call expected");
337  }
338 
339  inline bool
340  Node::hasCall(const std::string& id) {
341  if (Array* a = dynamic_cast<Array*>(this)) {
342  for (int i=a->a.size(); i--;)
343  if (Call* at = dynamic_cast<Call*>(a->a[i]))
344  if (at->id == id) {
345  return true;
346  }
347  } else if (Call* a = dynamic_cast<Call*>(this)) {
348  return a->id == id;
349  }
350  return false;
351  }
352 
353  inline bool
354  Node::isInt(int& i) {
355  if (IntLit* il = dynamic_cast<IntLit*>(this)) {
356  i = il->i;
357  return true;
358  }
359  return false;
360  }
361 
362  inline Call*
363  Node::getCall(const std::string& id) {
364  if (Array* a = dynamic_cast<Array*>(this)) {
365  for (int i=a->a.size(); i--;)
366  if (Call* at = dynamic_cast<Call*>(a->a[i]))
367  if (at->id == id)
368  return at;
369  } else if (Call* a = dynamic_cast<Call*>(this)) {
370  if (a->id == id)
371  return a;
372  }
373  throw TypeError("call expected");
374  }
375 
376  inline Array*
378  if (Array* a = dynamic_cast<Array*>(this))
379  return a;
380  throw TypeError("array expected");
381  }
382 
383  inline Atom*
385  if (Atom* a = dynamic_cast<Atom*>(this))
386  return a;
387  throw TypeError("atom expected");
388  }
389 
390  inline int
392  if (IntVar* a = dynamic_cast<IntVar*>(this))
393  return a->i;
394  throw TypeError("integer variable expected");
395  }
396  inline int
398  if (BoolVar* a = dynamic_cast<BoolVar*>(this))
399  return a->i;
400  throw TypeError("bool variable expected");
401  }
402  inline int
404  if (SetVar* a = dynamic_cast<SetVar*>(this))
405  return a->i;
406  throw TypeError("set variable expected");
407  }
408  inline int
409  Node::getInt(void) {
410  if (IntLit* a = dynamic_cast<IntLit*>(this))
411  return a->i;
412  throw TypeError("integer literal expected");
413  }
414  inline bool
416  if (BoolLit* a = dynamic_cast<BoolLit*>(this))
417  return a->b;
418  throw TypeError("bool literal expected");
419  }
420  inline double
422  if (FloatLit* a = dynamic_cast<FloatLit*>(this))
423  return a->d;
424  throw TypeError("float literal expected");
425  }
426  inline SetLit*
427  Node::getSet(void) {
428  if (SetLit* a = dynamic_cast<SetLit*>(this))
429  return a;
430  throw TypeError("set literal expected");
431  }
432  inline std::string
434  if (String* a = dynamic_cast<String*>(this))
435  return a->s;
436  throw TypeError("string literal expected");
437  }
438  inline bool
440  return (dynamic_cast<IntVar*>(this) != NULL);
441  }
442  inline bool
444  return (dynamic_cast<BoolVar*>(this) != NULL);
445  }
446  inline bool
448  return (dynamic_cast<SetVar*>(this) != NULL);
449  }
450  inline bool
451  Node::isInt(void) {
452  return (dynamic_cast<IntLit*>(this) != NULL);
453  }
454  inline bool
455  Node::isBool(void) {
456  return (dynamic_cast<BoolLit*>(this) != NULL);
457  }
458  inline bool
459  Node::isSet(void) {
460  return (dynamic_cast<SetLit*>(this) != NULL);
461  }
462  inline bool
464  return (dynamic_cast<String*>(this) != NULL);
465  }
466  inline bool
468  return (dynamic_cast<Array*>(this) != NULL);
469  }
470  inline bool
471  Node::isAtom(void) {
472  return (dynamic_cast<Atom*>(this) != NULL);
473  }
474 
475  inline Node*
477  if (Array* a = dynamic_cast<Array*>(n)) {
478  if (a->a.size() == 1) {
479  Node *ret = a->a[0];
480  a->a[0] = NULL;
481  delete a;
482  return ret;
483  }
484  }
485  return n;
486  }
487 
488 }}}
489 
490 #endif
491 
492 // STATISTICS: flatzinc-any