#include "dgp0.hh" #include "global.hh" extern Grammar grammar; extern MGraph mgraph; extern SGraph sgraph; extern bool debug; list nodelist; list::iterator processed; //==================================================================================================== void set_initial_constraints(int node) { sgraph[node].prop.forbidden.reset(); sgraph[node].prop.required=grammar.is_obl(sgraph.cat(node)); sgraph[node].prop.attached.reset(); sgraph[node].prop.flags=grammar.initial_flags(sgraph.cat(node)); } //---------------------------------------------------------------------------------------------------- bool changing_constraints(int head, Role role) { return grammar.is_sgl(role) || sgraph[head].prop.required[role]; } //==================================================================================================== NodeProp compute_head_prop(NodeProp headprop, const Link& link, list bs, FlagSet& depflags) { NodeProp ret=headprop; if(grammar.is_sgl(link.role)) { ret.forbidden.set(link.role); ret.attached.set(link.role); } ret.required.reset(link.role); ret.required |= (grammar.constr_include(link.role) & ~ret.attached); ret.forbidden |= grammar.constr_exclude(link.role); ret.boubbles=bs; ret.flags |= ( depflags & grammar.pass_flags(link.role) ); if(link.props[Prop("INIT")]) ret.init_attached=true; if(link.props[Prop("FIN")]) ret.fin_attached=true; return ret; } //---------------------------------------------------------------------------------------------------- NodeProp compute_dep_prop(NodeProp depprop, const Link& link, list bs) { NodeProp ret=depprop; ret.boubbles=bs; return ret; } //==================================================================================================== int find_existing_node(int mnodeind, NodeProp p, bitset& newheadLH, bitset& newheadLV) { MNode& mnode = mgraph[mnodeind]; for(vector::iterator ps=mnode.snodes.begin(); ps!=mnode.snodes.end(); ++ps) if(sgraph[*ps].prop==p && sgraph[*ps].LH==newheadLH && sgraph[*ps].LV==newheadLV) return *ps; return -1; } //==================================================================================================== list receive_boubbles(int node, Role role, Dir dir) { list ret; for(list::iterator b = sgraph[node].prop.boubbles.begin(); b!=sgraph[node].prop.boubbles.end(); b++) { Boubble* new_boubble = (*b)->step(role,dir); if(new_boubble) ret.push_back(new_boubble); } return ret; } //---------------------------------------------------------------------------------------------------- list collect_head_boubbles(int head, int dep, Role role) { list new_boubbles = grammar.trigger_boubbles(sgraph.cat(dep),role,UP); for(list::iterator b = new_boubbles.begin(); b != new_boubbles.end(); b++) (*b)->src(dep); list received_boubbles = receive_boubbles(dep,role,UP); new_boubbles.insert(new_boubbles.begin(),received_boubbles.begin(),received_boubbles.end()); return new_boubbles; } //---------------------------------------------------------------------------------------------------- list collect_dep_boubbles(int head, int dep, Role role) { list new_boubbles = grammar.trigger_boubbles(sgraph.cat(head), role, DOWN); for(list::iterator b = new_boubbles.begin(); b != new_boubbles.end(); b++) (*b)->src(head); list received_boubbles = receive_boubbles(head,role,DOWN); new_boubbles.insert(new_boubbles.begin(),received_boubbles.begin(),received_boubbles.end()); return new_boubbles; } //==================================================================================================== int create_new_head_node_left(list::iterator h, NodeProp& newheadprop, bitset& newheadLH, bitset& newheadLD, bitset& newheadLV) { int newheadind = sgraph.clone(*h,newheadprop); list::iterator nextit=h; ++nextit; nodelist.insert(nextit,newheadind); sgraph[newheadind].LH=newheadLH; sgraph[newheadind].LD = newheadLD; sgraph[newheadind].in_LH=true; sgraph[newheadind].LV.reset(); if(debug) sgraph.print_node_debug(stderr,"C ",newheadind,*h); return newheadind; } int create_new_dep_node_left(list::iterator d, NodeProp& prop, bitset& LH, bitset& LD, bitset& LV) { int newind = sgraph.clone(*d,prop); list::iterator nextit=d; ++nextit; nodelist.insert(nextit,newind); sgraph[newind].LH.reset(); sgraph[newind].LD=LD; sgraph[newind].in_LH=false; //??????? sgraph[newind].LV.reset(); if(debug) sgraph.print_node_debug(stderr,"C ",newind,*d); return newind; } int create_new_head_node_right(list::iterator h, NodeProp& newheadprop, bitset& newheadLH, bitset& newheadLD, bitset& newheadLV) { int newheadind = sgraph.clone(*h,newheadprop); list::iterator nextit=h; ++nextit; nodelist.insert(nextit,newheadind); sgraph[newheadind].LH=newheadLH; sgraph[newheadind].LD=newheadLD; sgraph[newheadind].in_LH=false; sgraph[newheadind].LV=newheadLV; if(debug) sgraph.print_node_debug(stderr,"C ",newheadind,*h); return newheadind; } int create_new_dep_node_right(list::iterator d, NodeProp& prop, bitset& LH, bitset& LD, bitset& LV) { int newind = sgraph.clone(*d,prop); list::iterator nextit=d; ++nextit; nodelist.insert(nextit,newind); sgraph[newind].LH=LH; sgraph[newind].LD=LD; sgraph[newind].in_LH=true; //??????? sgraph[newind].LV.reset(); if(debug) sgraph.print_node_debug(stderr,"C ",newind,*d); return newind; } //==================================================================================================== void connect_left(list::iterator h, list::iterator d, const Link& l, list& new_head_boubbles, list& new_dep_boubbles) { NodeProp &oldheadprop = sgraph[*h].prop; NodeProp &olddepprop = sgraph[*d].prop; NodeProp newheadprop = compute_head_prop(oldheadprop,l,new_head_boubbles,olddepprop.flags); int newheadind; if(oldheadprop==newheadprop) newheadind = *h; else { bitset newheadLH = sgraph[*h].LH; bitset newheadLV = sgraph[*d].LV; bitset newheadLD = sgraph[*h].LD; newheadind = find_existing_node(sgraph[*h].mnode, newheadprop, newheadLH, newheadLV); if( newheadind >= 0 ) sgraph[newheadind].LD |= newheadLD; else newheadind = create_new_head_node_left(h,newheadprop,newheadLH,newheadLD,newheadLV); } NodeProp newdepprop = compute_dep_prop(olddepprop,l,new_dep_boubbles); int newdepind; if(olddepprop==newdepprop) newdepind = *d; else { bitset newdepLH = sgraph[*d].LH; bitset newdepLV = sgraph[*d].LV; bitset newdepLD = sgraph[*d].LD; newdepind = find_existing_node(sgraph[*d].mnode, newdepprop, newdepLH, newdepLV); if( newdepind >= 0 ) sgraph[newdepind].LD |= newdepLD; // TYLKO DLA LD else newdepind = create_new_dep_node_left(d,newdepprop,newdepLH,newdepLD,newdepLV); } sgraph[newheadind].deps.push_back(Arc(newdepind,l.role,*h,*d)); if(sgraph[*d].saturated()) sgraph[newheadind].LV |= sgraph[*d].LV; sgraph[newheadind].LD.set(*d); if(sgraph[*d].saturated()) sgraph[newheadind].LD |= sgraph[*d].LD; if(debug) sgraph.print_arc(stderr,newheadind,*d,l.role,0); if(debug) sgraph.print_node_debug(stderr,"U ",newheadind,*h); if(debug) sgraph.print_node_debug(stderr,"U ",*d,*d); } //---------------------------------------------------------------------------------------------------- void connect_right(list::iterator h, list::iterator d, const Link& l, list& new_head_boubbles, list& new_dep_boubbles) { NodeProp &oldheadprop = sgraph[*h].prop; NodeProp newheadprop = compute_head_prop(oldheadprop,l,new_head_boubbles, sgraph[*d].prop.flags); int newheadind; if(oldheadprop==newheadprop) newheadind = *h; else { bitset newheadLH = sgraph[*h].LH; bitset newheadLV = sgraph[*h].LV; bitset newheadLD = sgraph[*h].LD; newheadind = find_existing_node(sgraph[*h].mnode, newheadprop, newheadLH, newheadLV); if( newheadind >= 0 ) sgraph[newheadind].LD |= newheadLD; // TYLKO DLA LD else newheadind = create_new_head_node_right(h,newheadprop,newheadLH,newheadLD,newheadLV); } NodeProp &olddepprop = sgraph[*d].prop; NodeProp newdepprop = compute_dep_prop(olddepprop,l,new_dep_boubbles); int newdepind; if(olddepprop==newdepprop) newdepind = *d; else { bitset newdepLH = sgraph[*d].LH; bitset newdepLV = sgraph[*d].LV; bitset newdepLD = sgraph[*d].LD; newdepind = find_existing_node(sgraph[*d].mnode, newdepprop, newdepLH, newdepLV); if( newdepind >= 0 ) sgraph[newdepind].LD |= newdepLD; // TYLKO DLA LD else newdepind = create_new_dep_node_right(d,newdepprop,newdepLH,newdepLD,newdepLV); } sgraph[newdepind].heads.push_back(Arc(newheadind,l.role,*h,*d)); sgraph[newdepind].LH.set(newheadind); // sgraph[*d].prop.merge_boubbles(new_dep_boubbles); if(sgraph[newheadind].saturated()) sgraph[newdepind].LH |= sgraph[newheadind].LH; if(debug) sgraph.print_arc(stderr,newheadind,newdepind,l.role,1); if(debug) sgraph.print_node_debug(stderr,"U ",newheadind,*h); if(debug) sgraph.print_node_debug(stderr,"U ",newdepind,*d); } //==================================================================================================== // sprawdza czy te, spo¶ród b±bli, które dotarły do celu node // daj± wynik prawdziwy, dodatkowo - usuwa je z listy boubbles bool check_boubbles_at_target(list& boubbles, int node) { list::iterator last; // ostatnio sprawdzany b±bel bool remove=false; // czy usun±ć ostatnio sprawdzany b±bel for(list::iterator b = boubbles.begin(); b != boubbles.end(); b = remove ? boubbles.erase(b) : ++b ) if( (*b)->is_at_target() ) if( grammar.check_longrel(sgraph.cat((*b)->src()), sgraph.cat(node), (*b)->rel()) ) remove=true; else return false; else remove=false; return true; } // bool check_boubbles_at_target(list boubbles, int node) // { // for(list::iterator b = boubbles.begin(); b != boubbles.end(); ++b ) // if( (*b)->is_at_target() && !grammar.check_longrel(sgraph.cat((*b)->src()), sgraph.cat(node), (*b)->rel()) ) // return false; // return true; // } //==================================================================================================== void try_connect_dependents(list::iterator j) { for(list::iterator i(j); i!=nodelist.begin(); --i) if(sgraph.visible(*i,*j) && sgraph.saturated(*i)) { if(debug) {fprintf(stderr,"## %d <-- %d ... ",*i,*j); } list ji_links = grammar.connectable2( sgraph.cat(*j), sgraph.cat(*i), sgraph[*j].prop.flags, sgraph[*i].prop.flags); // ref do Roles!!! list::iterator ri = ji_links.begin(); if(ri == ji_links.end()) { if(debug) fprintf(stderr,"no roles\n"); } else { for(; ri != ji_links.end(); ++ri ) if(!grammar.check_constr2(sgraph[*j].prop,sgraph[*i].prop,0,**ri )) { if(debug) fprintf(stderr,"constraints failed\n"); } else { list new_head_boubbles = collect_head_boubbles(*j,*i,(*ri)->role); list new_dep_boubbles = collect_dep_boubbles(*j,*i,(*ri)->role); if( !(check_boubbles_at_target(new_head_boubbles,*j) && check_boubbles_at_target(new_dep_boubbles,*i)) ) { if(debug) fprintf(stderr,"boubbles failed\n"); } else { if(debug) fprintf(stderr,"success\n"); connect_left( j, i, **ri, new_head_boubbles, new_dep_boubbles); } } } } } //---------------------------------------------------------------------------------------------------- void try_connect_heads(list::iterator j) { for(list::iterator i(j); i!=nodelist.begin(); --i) if(sgraph.visible(*i,*j)) { if(debug) fprintf(stderr, "## %d --> %d ... ",*i,*j); list ij_links = grammar.connectable2( sgraph.cat(*i), sgraph.cat(*j), sgraph[*i].prop.flags, sgraph[*j].prop.flags ); list::iterator ri = ij_links.begin(); if(ri == ij_links.end()) { if(debug) fprintf(stderr,"no roles\n"); } else { for(; ri != ij_links.end(); ++ri ) if( !grammar.check_constr2( sgraph[*i].prop, sgraph[*j].prop, 1, **ri ) ) { if(debug) fprintf(stderr,"constraints failed\n"); } else { list new_head_boubbles = collect_head_boubbles(*i,*j,(*ri)->role); list new_dep_boubbles = collect_dep_boubbles(*i,*j,(*ri)->role); if( !(check_boubbles_at_target(new_head_boubbles,*i) && check_boubbles_at_target(new_dep_boubbles,*j)) ) { if(debug) fprintf(stderr,"boubbles failed\n"); } else { if(debug) fprintf(stderr,"success\n"); connect_right( i, j, **ri, new_head_boubbles, new_dep_boubbles ); } } } } } //==================================================================================================== void reverse_links() { list::iterator i = nodelist.begin(); for(++i; i!=nodelist.end(); ++i) { for(vector::iterator da=sgraph[*i].deps.begin()--; da!=sgraph[*i].deps.end(); ++da) sgraph[da->dst].heads.push_back(Arc(*i,da->role,da->headanc,da->depanc)); for(vector::iterator ha=sgraph[*i].heads.begin(); ha!=sgraph[*i].heads.end(); ++ha) sgraph[ha->dst].deps.push_back(Arc(*i,ha->role,ha->headanc,ha->depanc)); } } //==================================================================================================== void dgp1() { nodelist.clear(); nodelist.push_back(0); // BOS processed=nodelist.begin(); for(int m=0; m::iterator cursor=processed; while(++cursor != nodelist.end()) { try_connect_dependents(cursor); try_connect_heads(cursor); processed=cursor; } } reverse_links(); }