Index: src/dgp/grammar.hh
===================================================================
--- src/dgp/grammar.hh	(revision 5f4d9c3b32eea7b6643a751aa75bdb05b7d41576)
+++ src/dgp/grammar.hh	(revision e7de6cc88c605c4f810cbc852e843294b4b0e8ac)
@@ -10,13 +10,51 @@
 #include "thesymbols.hh"
 #include "sgraph.hh"
-
-
-class Link
-{
+#include "boubble.hh"
+
+using namespace std;
+
+//enum PROP { INIT=0, FIN=1 };
+//typedef bitset<16> PropSet;
+
+const PropSet EmptyPropSet = PropSet();
+
+const FlagSet EmptyFlagSet = FlagSet();
+
+//====================================================================================================
+// class Link
+//====================================================================================================
+
+struct Link
+{
+  Link(Role r, Flag dfplus="NULL", Flag dfminus="NULL") : role(r), dflagplus(dfplus), dflagminus(dfminus) { }
+  Link(Role r, PropSet ps=EmptyPropSet, Flag hfp="NULL", Flag hfm="NULL", Flag dfp="NULL", Flag dfm="NULL")
+    : role(r), props(ps), hflagplus(hfp), hflagminus(hfm), dflagplus(dfp), dflagminus(dfm) { }
+  //Link(Role r) : role(r), dflagplus("NULL") { }
+
   Role role;
-  FlagSet hflags;
-  FlagSet dflags;
+  Flag hflagplus;
+  Flag hflagminus;
+  Flag dflagplus;
+  Flag dflagminus;
+  PropSet props;
+
+  bool operator<(const Link& l) const 
+  {
+    if(role < l.role) return true;
+    if(hflagplus < l.hflagplus) return true;
+    if(hflagminus < l.hflagminus) return true;
+    if(dflagplus < l.dflagplus) return true;
+    if(dflagminus < l.dflagminus) return true;
+    if(props.to_ulong() < l.props.to_ulong()) return true;
+    return false;
+  }
+
 };
 
+typedef set<Link> Links;
+
+//====================================================================================================
+// class Grammar
+//====================================================================================================
 
 class Grammar
@@ -25,55 +63,182 @@
  public:
 
-  //  enum CONSTR { SGL, OBL, LEFT, RIGHT, INIT, NONINIT, FIN, NONFIN };
-
-  Grammar() : types_sz(0), cats_sz(0), flags_sz(0) {} ;
+  static const int RESIZE_DELTA=16;
+
+  Grammar() {} ;
+
+  Roles&  connectable(Cat h, Cat d);
+  Roles   connectable(Cat h, Cat d, FlagSet f, FlagSet df);
+
+  list<const Link*> connectable2(Cat h, Cat d, FlagSet hfs, FlagSet dfs);
+
+  bool    check_constr(NodeProp& hprop, NodeProp& dprop, int dir, Role role);
+  bool    check_constr2(NodeProp& hprop, NodeProp& dprop, int dir, const Link& link);
+
+  bool    check_longrel(Cat hcat, Cat dcat, LongRel rel);
+  bool    is_sgl(Role r);
+  RoleSet is_obl(Cat c);
+ 
+  RoleSet& constr_include(Role r) { return include[r]; };
+  RoleSet& constr_exclude(Role r) { return exclude[r]; };
   
-  int types_sz;
-  int cats_sz;
-  int flags_sz;
-
-  vector< vector< Roles > >    connect;
+  FlagSet initial_flags(Cat c) { return set[c]; }
+  FlagSet pass_flags(Role r)   { return pass[r]; }
+
+  list<Boubble*>    trigger_boubbles(Cat c, Role r, Dir d);
+
+  bool    read(FILE* f);
+  void    write(ostream& os);
+  void    write(FILE* f);
+
+private:
+
   RoleSet                      sgl;
-  vector< RoleSet >            obl;
+  vector< RoleSet >            obl;      //[Cat]
   RoleSet                      left;
   RoleSet                      right;
-  vector< RoleSet >            lt;
-  vector< RoleSet >            gt;
-
-
-  //  vector< vector< vector<
-  vector< FlagSet >            set;
-  vector< FlagSet >            pass;
-
-  bool read(FILE* f);
-  void write(FILE* f);
+  RoleSet                      init;
+  RoleSet                      fin;
+  FlagSet                      initf;
+  FlagSet                      finf;
+
+  vector< RoleSet >            lt;       //[Role]
+  vector< RoleSet >            gt;       //[Role]
+
+  vector< FlagSet >            set;      //[Cat]
+  //  vector< FlagSet >            rset;     //[Role]
+  vector< FlagSet >            pass;     //[Role]
+
+  vector< vector< Roles > >    connect;  //[Cat][Cat]
+
+  vector< vector< Links > >    connect1; //[Cat][Cat]
+
+  vector< RoleSet >            include;  //[Role]
+  vector< RoleSet >            exclude;  //[Role]
+
+  vector< vector< LongRels > > longrel;  //[Cat][Cat]
+
+  list< Boubble* >              boubbles;
+  
+  vector< vector< list<Boubble*> > >   uptrigger;//[Cat][Role]
+  vector< vector< list<Boubble*> > >   dntrigger;//[Cat][Role]
 
   void add_category(const char* s);
   void add_type(const char* s);
-  void add_flag(const char* s);
-
-  void set_sgl(Role r)           { sgl.set(r); }
-  void set_obl(Cat c, Role r)    { obl[c].set(r); }
-  void set_left(Role r)          { left.set(r); }
-  void set_right(Role r)         { right.set(r); }
-  void set_order(Role r, Role s) { lt[s].set(r); }
-  void set_connect(Cat c, Cat d, Role r)   { connect[c][d].insert(r); }
+  void add_flag(const char* s)                   { Flag::add(s); }
+  void add_long(const char* l, const char* p)    { LongRel::add(l); boubbles.push_back( new Boubble(p,l) ); }
+  void add_triggers(Cat h, Cat d, LongRel l);
+
+  void set_sgl(Role r)                     { sgl.set(r); }
+  void set_obl(Cat c, Role r)              { obl[c].set(r); }
+  void set_left(Role r)                    { left.set(r); }
+  void set_right(Role r)                   { right.set(r); }
+  void set_init(Role r)                    { init.set(r); }
+  void set_fin(Role r)                     { fin.set(r); }
+  void set_initf(Flag f)                   { initf.set(f); }
+  void set_finf(Flag f)                    { finf.set(f); }
+  void set_order(Role r, Role s)           { lt[s].set(r); }
+
+  //  void set_connect(Cat c, Cat d, Role r)   { connect[c][d].insert(r); }
+  //  void set_connect(Cat c, Cat d, Flag f, Role r)   { connect1[c][d].insert(Link(r,f)); }
+
+  void set_connect(Cat h, Flag hfp, Flag hfm, Cat d, Flag dfp, Flag dfm, Role r, PropSet ps )   { connect1[h][d].insert(Link(r,ps,hfp,hfm,dfp,dfm)); }
+
+  void set_include(Role r, Role s)         { include[r].set(s); }
+  void set_exclude(Role r, Role s)         { exclude[r].set(s); }
+  void set_longrel(Cat c, Cat d, LongRel l){ longrel[c][d].insert(l); }
+  void set_set(Cat c, Flag f)              { set[c].set(f); }
+  void set_pass(Role r, Flag f)            { pass[r].set(f); }
   void set_lt(Role r, Role s);
   void compute_gt();
-
-
-  bool check_constr(NodeProp& hprop, NodeProp& dprop, int dir, Role role);
+  void compute_triggers();
+  bool contains_boubble(const list<Boubble*> boubble_list, Boubble* bp) const;
 
 };
 
-inline bool Grammar::check_constr(NodeProp& hprop, NodeProp& dprop, int dir, Role role)
+//----------------------------------------------------------------------------------------------------
+
+inline
+Roles&  Grammar::connectable(Cat h, Cat d)
+{
+  return connect[h][d];
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+Roles Grammar::connectable(Cat h, Cat d, FlagSet hfs, FlagSet dfs)  // ZBYT WOLNE!!!!!!!!!!!!!!!!!!!!!!!!!! (-> Roles&)
+{
+  Roles ret;
+  for(Links::const_iterator l = connect1[h][d].begin(); l != connect1[h][d].end(); l++)
+    if( (l->hflagplus==0 || hfs[l->hflagplus]) && (l->hflagminus==0 || !hfs[l->hflagminus]) )
+      if( (l->dflagplus==0 || dfs[l->dflagplus]) && (l->dflagminus==0 || !dfs[l->dflagminus]) )
+	ret.insert(l->role);
+  return ret;
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+list<const Link*> Grammar::connectable2(Cat h, Cat d, FlagSet hfs, FlagSet dfs)  // ZBYT WOLNE!!!!!!!!!!!!!!!!!!!!!!!!!! (-> Roles&)
+{
+  list<const Link*> ret;
+  for(Links::const_iterator l = connect1[h][d].begin(); l != connect1[h][d].end(); l++)
+    if( (l->hflagplus==0 || hfs[l->hflagplus]) && (l->hflagminus==0 || !hfs[l->hflagminus]) )
+      if( (l->dflagplus==0 || dfs[l->dflagplus]) && (l->dflagminus==0 || !dfs[l->dflagminus]) )
+	ret.push_back(&(*l));
+  return ret;
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+bool Grammar::check_constr(NodeProp& hprop, NodeProp& dprop, int dir, Role role)    // dir: 0-left 1-right
 {
   return 
     !hprop.forbidden[role] &&
-    ( !right[role] || dir==1 ) &&
-    ( !left[role] || dir==0 )
+    ( dir==1 || !right[role] ) &&
+    ( dir==0 || !left[role]  ) &&
+    ( dir==1 || (hprop.attached&init).none() ) &&
+    ( dir==0 || (hprop.attached&fin).none() )
     ;
 }
 
+//----------------------------------------------------------------------------------------------------
+
+inline
+bool Grammar::check_constr2(NodeProp& hprop, NodeProp& dprop, int dir, const Link& link)    // dir: 0-left 1-right
+{
+  return 
+    !hprop.forbidden[link.role] &&
+    ( dir==1 || !right[link.role] ) &&
+    ( dir==0 || !left[link.role]  ) &&
+    ( dir!=0 || !hprop.init_attached ) &&
+    ( dir!=1 || !hprop.fin_attached )
+    ;
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline
+bool Grammar::check_longrel(Cat hcat, Cat dcat, LongRel rel)
+{
+  return longrel[hcat][dcat].find(rel) != longrel[hcat][dcat].end();
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline bool Grammar::is_sgl(Role r)
+{
+  return sgl[r];
+}
+
+//----------------------------------------------------------------------------------------------------
+
+inline RoleSet Grammar::is_obl(Cat c)
+{
+  return obl[c];
+}
+
+//====================================================================================================
 
 #endif
