Generated on Sat May 25 2013 18:00:32 for Gecode by doxygen 1.8.3.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-03-30 05:58:02 +0200 (Fri, 30 Mar 2012) $ by $Author: tack $
11  * $Revision: 12665 $
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 isFloat(double& i);
86  bool isCall(const std::string& id);
88  Call* getCall(void);
90  bool hasCall(const std::string& id);
92  Call* getCall(const std::string& id);
94  Array* getArray(void);
96  Atom* getAtom(void);
98  int getIntVar(void);
100  int getBoolVar(void);
102  int getFloatVar(void);
104  int getSetVar(void);
105 
107  int getInt(void);
109  bool getBool(void);
111  double getFloat(void);
113  SetLit *getSet(void);
114 
116  std::string getString(void);
117 
119  bool isIntVar(void);
121  bool isBoolVar(void);
123  bool isSetVar(void);
125  bool isFloatVar(void);
127  bool isInt(void);
129  bool isFloat(void);
131  bool isBool(void);
133  bool isString(void);
135  bool isArray(void);
137  bool isSet(void);
139  bool isAtom(void);
140 
142  virtual void print(std::ostream&) = 0;
143  };
144 
147  public:
148  bool b;
149  BoolLit(bool b0) : b(b0) {}
150  virtual void print(std::ostream& os) {
151  os << "b(" << (b ? "true" : "false") << ")";
152  }
153  };
156  public:
157  int i;
158  IntLit(int i0) : i(i0) {}
159  virtual void print(std::ostream& os) {
160  os << "i("<<i<<")";
161  }
162  };
165  public:
166  double d;
167  FloatLit(double d0) : d(d0) {}
168  virtual void print(std::ostream& os) {
169  os << "f("<<d<<")";
170  }
171  };
174  public:
175  bool interval;
176  int min; int max;
177  std::vector<int> s;
178  SetLit(void) {}
179  SetLit(int min0, int max0) : interval(true), min(min0), max(max0) {}
180  SetLit(const std::vector<int>& s0) : interval(false), s(s0) {}
181  bool empty(void) const {
182  return ( (interval && min>max) || (!interval && s.size() == 0));
183  }
184  virtual void print(std::ostream& os) {
185  os << "s()";
186  }
187  };
188 
190  class GECODE_VTABLE_EXPORT Var : public Node {
191  public:
192  int i;
193  Var(int i0) : i(i0) {}
194  };
197  public:
198  BoolVar(int i0) : Var(i0) {}
199  virtual void print(std::ostream& os) {
200  os << "xb("<<i<<")";
201  }
202  };
204  class GECODE_VTABLE_EXPORT IntVar : public Var {
205  public:
206  IntVar(int i0) : Var(i0) {}
207  virtual void print(std::ostream& os) {
208  os << "xi("<<i<<")";
209  }
210  };
213  public:
214  FloatVar(int i0) : Var(i0) {}
215  virtual void print(std::ostream& os) {
216  os << "xf("<<i<<")";
217  }
218  };
220  class GECODE_VTABLE_EXPORT SetVar : public Var {
221  public:
222  SetVar(int i0) : Var(i0) {}
223  virtual void print(std::ostream& os) {
224  os << "xs("<<i<<")";
225  }
226  };
227 
229  class GECODE_VTABLE_EXPORT Array : public Node {
230  public:
231  std::vector<Node*> a;
232  Array(const std::vector<Node*>& a0)
233  : a(a0) {}
235  : a(1) { a[0] = n; }
236  Array(int n=0) : a(n) {}
237  virtual void print(std::ostream& os) {
238  os << "[";
239  for (unsigned int i=0; i<a.size(); i++) {
240  a[i]->print(os);
241  if (i<a.size()-1)
242  os << ", ";
243  }
244  os << "]";
245  }
246  ~Array(void) {
247  for (int i=a.size(); i--;)
248  delete a[i];
249  }
250  };
251 
253  class GECODE_VTABLE_EXPORT Call : public Node {
254  public:
255  std::string id;
257  Call(const std::string& id0, Node* args0)
258  : id(id0), args(args0) {}
259  ~Call(void) { delete args; }
260  virtual void print(std::ostream& os) {
261  os << id << "("; args->print(os); os << ")";
262  }
263  Array* getArgs(unsigned int n) {
264  Array *a = args->getArray();
265  if (a->a.size() != n)
266  throw TypeError("arity mismatch");
267  return a;
268  }
269  };
270 
273  public:
274  Node* a;
276  ArrayAccess(Node* a0, Node* idx0)
277  : a(a0), idx(idx0) {}
278  ~ArrayAccess(void) { delete a; delete idx; }
279  virtual void print(std::ostream& os) {
280  a->print(os);
281  os << "[";
282  idx->print(os);
283  os << "]";
284  }
285  };
286 
288  class GECODE_VTABLE_EXPORT Atom : public Node {
289  public:
290  std::string id;
291  Atom(const std::string& id0) : id(id0) {}
292  virtual void print(std::ostream& os) {
293  os << id;
294  }
295  };
296 
299  public:
300  std::string s;
301  String(const std::string& s0) : s(s0) {}
302  virtual void print(std::ostream& os) {
303  os << "s(\"" << s << "\")";
304  }
305  };
306 
307  inline
308  Node::~Node(void) {}
309 
310  inline void
311  Node::append(Node* newNode) {
312  Array* a = dynamic_cast<Array*>(this);
313  if (!a)
314  throw TypeError("array expected");
315  a->a.push_back(newNode);
316  }
317 
318  inline bool
319  Node::hasAtom(const std::string& id) {
320  if (Array* a = dynamic_cast<Array*>(this)) {
321  for (int i=a->a.size(); i--;)
322  if (Atom* at = dynamic_cast<Atom*>(a->a[i]))
323  if (at->id == id)
324  return true;
325  } else if (Atom* a = dynamic_cast<Atom*>(this)) {
326  return a->id == id;
327  }
328  return false;
329  }
330 
331  inline bool
332  Node::isCall(const std::string& id) {
333  if (Call* a = dynamic_cast<Call*>(this)) {
334  if (a->id == id)
335  return true;
336  }
337  return false;
338  }
339 
340  inline Call*
342  if (Call* a = dynamic_cast<Call*>(this))
343  return a;
344  throw TypeError("call expected");
345  }
346 
347  inline bool
348  Node::hasCall(const std::string& id) {
349  if (Array* a = dynamic_cast<Array*>(this)) {
350  for (int i=a->a.size(); i--;)
351  if (Call* at = dynamic_cast<Call*>(a->a[i]))
352  if (at->id == id) {
353  return true;
354  }
355  } else if (Call* a = dynamic_cast<Call*>(this)) {
356  return a->id == id;
357  }
358  return false;
359  }
360 
361  inline bool
362  Node::isInt(int& i) {
363  if (IntLit* il = dynamic_cast<IntLit*>(this)) {
364  i = il->i;
365  return true;
366  }
367  return false;
368  }
369 
370  inline bool
371  Node::isFloat(double& d) {
372  if (FloatLit* fl = dynamic_cast<FloatLit*>(this)) {
373  d = fl->d;
374  return true;
375  }
376  return false;
377  }
378 
379  inline Call*
380  Node::getCall(const std::string& id) {
381  if (Array* a = dynamic_cast<Array*>(this)) {
382  for (int i=a->a.size(); i--;)
383  if (Call* at = dynamic_cast<Call*>(a->a[i]))
384  if (at->id == id)
385  return at;
386  } else if (Call* a = dynamic_cast<Call*>(this)) {
387  if (a->id == id)
388  return a;
389  }
390  throw TypeError("call expected");
391  }
392 
393  inline Array*
395  if (Array* a = dynamic_cast<Array*>(this))
396  return a;
397  throw TypeError("array expected");
398  }
399 
400  inline Atom*
402  if (Atom* a = dynamic_cast<Atom*>(this))
403  return a;
404  throw TypeError("atom expected");
405  }
406 
407  inline int
409  if (IntVar* a = dynamic_cast<IntVar*>(this))
410  return a->i;
411  throw TypeError("integer variable expected");
412  }
413  inline int
415  if (BoolVar* a = dynamic_cast<BoolVar*>(this))
416  return a->i;
417  throw TypeError("bool variable expected");
418  }
419  inline int
421  if (FloatVar* a = dynamic_cast<FloatVar*>(this))
422  return a->i;
423  throw TypeError("integer variable expected");
424  }
425  inline int
427  if (SetVar* a = dynamic_cast<SetVar*>(this))
428  return a->i;
429  throw TypeError("set variable expected");
430  }
431  inline int
432  Node::getInt(void) {
433  if (IntLit* a = dynamic_cast<IntLit*>(this))
434  return a->i;
435  throw TypeError("integer literal expected");
436  }
437  inline bool
439  if (BoolLit* a = dynamic_cast<BoolLit*>(this))
440  return a->b;
441  throw TypeError("bool literal expected");
442  }
443  inline double
445  if (FloatLit* a = dynamic_cast<FloatLit*>(this))
446  return a->d;
447  throw TypeError("float literal expected");
448  }
449  inline SetLit*
450  Node::getSet(void) {
451  if (SetLit* a = dynamic_cast<SetLit*>(this))
452  return a;
453  throw TypeError("set literal expected");
454  }
455  inline std::string
457  if (String* a = dynamic_cast<String*>(this))
458  return a->s;
459  throw TypeError("string literal expected");
460  }
461  inline bool
463  return (dynamic_cast<IntVar*>(this) != NULL);
464  }
465  inline bool
467  return (dynamic_cast<BoolVar*>(this) != NULL);
468  }
469  inline bool
471  return (dynamic_cast<SetVar*>(this) != NULL);
472  }
473  inline bool
475  return (dynamic_cast<FloatVar*>(this) != NULL);
476  }
477  inline bool
478  Node::isInt(void) {
479  return (dynamic_cast<IntLit*>(this) != NULL);
480  }
481  inline bool
482  Node::isBool(void) {
483  return (dynamic_cast<BoolLit*>(this) != NULL);
484  }
485  inline bool
487  return (dynamic_cast<FloatLit*>(this) != NULL);
488  }
489  inline bool
490  Node::isSet(void) {
491  return (dynamic_cast<SetLit*>(this) != NULL);
492  }
493  inline bool
495  return (dynamic_cast<String*>(this) != NULL);
496  }
497  inline bool
499  return (dynamic_cast<Array*>(this) != NULL);
500  }
501  inline bool
502  Node::isAtom(void) {
503  return (dynamic_cast<Atom*>(this) != NULL);
504  }
505 
506  inline Node*
508  if (Array* a = dynamic_cast<Array*>(n)) {
509  if (a->a.size() == 1) {
510  Node *ret = a->a[0];
511  a->a[0] = NULL;
512  delete a;
513  return ret;
514  }
515  }
516  return n;
517  }
518 
519 }}}
520 
521 #endif
522 
523 // STATISTICS: flatzinc-any