Index: src/dgp/boubble.hh
===================================================================
--- src/dgp/boubble.hh	(revision e7de6cc88c605c4f810cbc852e843294b4b0e8ac)
+++ src/dgp/boubble.hh	(revision e7de6cc88c605c4f810cbc852e843294b4b0e8ac)
@@ -0,0 +1,223 @@
+#ifndef _BOUBBLE_HH_
+#define _BOUBBLE_HH_
+
+#include <list>
+#include <iostream>
+#include <sstream>
+
+#include "thesymbols.hh"
+
+
+enum Dir {UP=0,DOWN=1,AT_TARGET=2};
+
+// class BoubbleAction
+// {
+// public:
+//   void apply() {};
+// private:
+  
+// };
+
+
+
+class Boubble
+{
+public:
+  Boubble(list<Role> u, list<Role> d, LongRel l, int s=-1);
+  Boubble(const char* pathstr, const char* l, int s=-1);
+
+  Dir dir();
+  LongRel rel();
+  int src();
+  void src(int s);
+
+  Role next();
+
+  Boubble* step(Role r, Dir d);
+  
+  bool is_at_target();
+
+  bool operator==(Boubble const& b) const;
+  bool operator!=(Boubble const& b) const;
+  bool operator<(Boubble const& b) const;
+
+  void as_cstr(char* s);
+  friend std::ostream& operator<<(std::ostream&, const Boubble&);
+
+private:
+
+  int                  _src;
+  list<Role>           _upath;
+  list<Role>           _dpath;
+  LongRel              _rel;
+
+};
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+Boubble::Boubble(list<Role> u, list<Role> d, LongRel l, int s) : _upath(u), _dpath(d), _rel(l), _src(s) {}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+Boubble::Boubble(const char* pathstr, const char* l, int s)
+{
+  Dir dir = UP;
+  const char* p = pathstr;
+  while(*p)
+    {
+      if(*p=='^') { dir = DOWN; p++; }
+      else if(isalpha(*p))
+	{
+	  char buf[80];
+	  sscanf(p,"%[a-zA-Z0-9_]",buf);
+	  dir == UP ? _upath.push_back(Role(buf)) : _dpath.push_back(Role(buf));
+	  p += strlen(buf);
+	}
+      else
+	p++;
+    }
+  
+  _rel = LongRel(l);
+  _src = s;
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+Dir Boubble::dir()
+{ 
+  if(!_upath.empty())
+    return UP;
+  else if(!_dpath.empty())
+    return DOWN;
+  else return AT_TARGET;
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+LongRel Boubble::rel()
+{ return _rel; }
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+int Boubble::src()
+{ return _src; }
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+void Boubble::src(int s)
+{ _src=s; }
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+Role Boubble::next()
+{ 
+  if(!_upath.empty())
+    return _upath.front();
+  else if(!_dpath.empty())
+    return _dpath.front();
+  else return Role("NULL"); 
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+Boubble* Boubble::step(Role r, Dir d)
+{
+  if(d==UP && !_upath.empty() && _upath.front() == r)
+    {
+      Boubble* newboubble = new Boubble(_upath,_dpath,_rel,_src);
+      newboubble->_upath.pop_front();
+      return newboubble;
+    }
+  
+  if(d==DOWN && _upath.empty() && !_dpath.empty())
+    {
+      Boubble* newboubble = new Boubble(_upath,_dpath,_rel,_src);
+      newboubble->_dpath.pop_front();
+      return newboubble;
+    }
+  return NULL;
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+bool Boubble::is_at_target()
+{ return _upath.empty() && _dpath.empty(); }
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+bool Boubble::operator==(Boubble const& b) const
+{
+  return _src==b._src && _upath==b._upath && _dpath==b._dpath && _rel==b._rel;
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+bool Boubble::operator!=(Boubble const& b) const
+{
+  return !(*this==b);
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+bool Boubble::operator<(Boubble const& b) const
+{
+  if(_src < b._src) return true;
+  if(_rel < b._rel) return true;
+  if(this < &b) return true;
+  return false;
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+std::ostream& operator<<(std::ostream& o, const Boubble& b)
+{
+  o << "[";
+
+  o << b._src << "|";
+
+  bool cont=false;
+  for(list<Role>::const_iterator i = b._upath.begin(); i != b._upath.end(); ++i)
+    {
+      if(cont) o << ',';
+      o << i->str();
+      cont = true;
+    }
+  o << '^';
+  cont=false;
+  for(list<Role>::const_iterator i = b._dpath.begin(); i != b._dpath.end(); ++i)
+    {
+      if(cont) o << ',';
+      o << i->str();
+      cont = true;
+    }
+  o << ':';
+  o << b._rel.str();
+  o << "]";
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+void Boubble::as_cstr(char* s)
+{
+  stringstream oss;
+  oss << *this;
+  strcpy(s,oss.str().c_str());
+}
+
+//====================================================================================================
+
+#endif
