/////////////////////////////////////////////////////////////////////// // // $Log: checkRestrictions.pp,v $ // Revision 5.5.1.6 1994/09/23 15:52:34 demeter // fixed short cut checking // // Revision 5.5.1.5 1994/09/21 15:45:04 demeter // *** empty log message *** // // Revision 5.5.1.4 1994/09/16 13:56:45 demeter // *** empty log message *** // // Revision 5.5.1.3 1994/08/30 03:28:40 demeter // *** empty log message *** // // Revision 5.5.1.2 1994/08/27 01:21:05 demeter // add merge and join // // Revision 5.5.1.1 1994/08/24 19:30:55 demeter // *** empty log message *** // // Revision 5.5 1994/08/24 19:30:54 demeter // *** empty log message *** // // Revision 5.4.1.5 1994/02/25 22:19:57 demeter // typoes corrections // // Revision 5.4.1.4 1994/02/25 21:39:20 demeter // restriction checking // , // // Revision 5.4.1.3 1994/02/24 20:52:39 demeter // reimplement object transportation -- cun // // Revision 5.4.1.2 1994/02/24 18:50:45 demeter // initial file // // /////////////////////////////////////////////////////////////////////// (@ void computeTransitiveClosure(int n,int n2,char *matrix0) { char *matrix1 = new char[n2]; int i,j,k,t; t = 0; for (k = 0; k < n; k++) { for (i = 0; i < n; i++) for (j = 0; j < n; j++) { if (t) { if (matrix1[i*n+j] || (matrix1[i*n+k] && matrix1[k*n+j])) matrix0[i*n+j] = 1; else matrix0[i*n+j] = 0; } else { if (matrix0[i*n+j] || (matrix0[i*n+k] && matrix0[k*n+j])) matrix1[i*n+j] = 1; else matrix1[i*n+j] = 0; } } if (t) t = 0; else t = 1; } if (!t) { for (i = 0; i < n2; i++) matrix0[i] = matrix1[i]; } delete matrix1; } @) *operation* void checkCustomizerRestrictions(Cd_graph* schema,Propagation_schema *ps, int flag) // flag: 0 traversal // 1 transportation *wrapper* Cd_graph *prefix* (@ // the current object is a propagation graph // schema is the class graph // the subclass invariance //cout << toolname << ": checking the Subclass Invariance Restriction ..." << endl; this->checkSubclassInvarianceRestriction(schema,ps,flag); // If there is an outgoing construction edge edge from an alternation vertex // the vertex must have at least one outgoing alternation edge unless it is // a target vertex this->checkInheritanceRestriction(ps); @) *operation* void checkSubclassInvarianceRestriction(Cd_graph* schema,Propagation_schema *ps, int flag) *wrapper* Cd_graph *prefix* (@ int n = this->get_adjacencies()->list_length(); int n2 = n*n; int i,j,k; char *smatrix = new char[n2]; // subclass rel. on class graph char *pmatrix = new char[n2]; // subclass rel. on propagation graph. char *adjmatrix = new char[n2]; // adjacent char **snames = new char*[n]; // class graph char **pnames = new char*[n]; // propagation graph char *sourcenames = new char[n]; for (i = 0; i < n2; i++) { smatrix[i] = 0; pmatrix[i] = 0; adjmatrix[i] = 0; } for (i = 0; i < n; i++) { snames[i] = 0; sourcenames[i] = 0; } this->createNamelist(n,snames); for (i = 0; i < n; i++) pnames[i] = snames[i]; ps->get_paths()->createNamelist(n,pnames); this->markSubclassEdges(n,snames,smatrix); ps->markSubclassEdges(n,snames,pmatrix); computeTransitiveClosure(n,n2,smatrix); computeTransitiveClosure(n,n2,pmatrix); ps->get_source_port()->createSourcelist(n,snames,sourcenames); ps->markComposEdges(adjmatrix,n,snames,1); for (i = 0; i < n; i++) for (j = 0; j < n; j++) { if (smatrix[i*n+j] && !pmatrix[i*n+j]) { if (pnames[i] && pnames[j]) { for (k = 0; k < n; k++) if (adjmatrix[k,i]) break; if (k == n && !sourcenames[i]) continue; if (flag) derror('e',1, form(" the Subclass Invariance Restriction violated. From class '%s' to class '%s' there is an alternation path in the traversal graph but not in the transportation graph.",pnames[i],pnames[j])); else derror('e',1, form(" the Subclass Invariance Restriction violated. From class '%s' to class '%s' there is an alternation path in the class graph but not in the traversal graph.",pnames[i],pnames[j])); exit(-1); } } } delete smatrix; delete adjmatrix; delete pmatrix; for (j = 0; j < n; j++) { delete snames[j]; delete pnames[j]; } delete snames; delete sourcenames; delete pnames; @) *operation* void markSubclassEdges(int n, char **names, char* matrix) *wrapper* Propagation_schema (@ paths->markSubclassEdges(n,names,matrix); @) *wrapper* Cd_graph (@ adjacencies->markSubclassEdges(n,names,matrix); @) *wrapper* Adjacency_Nlist *prefix* (@ Adjacency_list_iterator next(*this); Adjacency* each; while (each = next()) { each->markSubclassEdges(n,names,matrix); } @) *wrapper* Adjacency *prefix* (@ int r; for (int i = 0; i < n; i++) if (strcmp(names[i],source->get_vertex_name()->get_val())==0) { r = i; break; } ns->markSubclassEdges(n,names,matrix,r); @) *operation* void markSubclassEdges(int n, char **names, char* matrix, int r) *wrapper* Neighbors (@ @) *wrapper* Neighbors_wc (@ @) *wrapper* Alternat_ns (@ if (alternat_ns) alternat_ns->markSubclassEdges(n,names,matrix,r); @) *wrapper* Term_Barlist (@ Term_list_iterator next(*this); Term* each; while (each = next()) each->markSubclassEdges(n,names,matrix,r); @) *wrapper* Term (@ int c; for (int i = 0; i < n; i++) if (strcmp(names[i],vertex->get_vertex_name()->get_val())==0) { c = i; break; } matrix[ r*n + c ] = 1; @) *operation* void createSourcelist(int n, char** names, char* snames) *wrapper* Vertex_selector *prefix* (@ @) *wrapper* Vertex_set (@ @) *wrapper* Vertex_set_sim (@ terms->createSourcelist(n, names,snames); @) *wrapper* Fixed_term_Commalist (@ Fixed_term_list_iterator next(*this); Fixed_term* each; while (each = next()) each->createSourcelist(n, names,snames); @) *wrapper* Fixed_term (@ vertex->createSourcelist(n, names,snames); @) *wrapper* Term (@ int i; for (i = 0; i < n; i++) if (strcmp(names[i],vertex->get_vertex_name()->get_val())== 0) break; snames[i] = 1; @) *operation* void createNamelist(int n, char **names) *wrapper* Cd_graph (@ adjacencies->createNamelist(n,names); @) *wrapper* Adjacency_Nlist *prefix* (@ int c = 0; Adjacency_list_iterator next(*this); Adjacency* each; while (each = next()) { while (names[c]) if (strcmp(names[c],each->get_source()->get_vertex_name()->get_val())==0) break; else { names[c] = 0; c++; } each->createNamelist(n,names,c); c++; } for (int i = c; i < n; i++) names[i] = 0; @) *operation* void createNamelist(int n, char **names, int c) *wrapper* Adjacency *prefix* (@ source->createNamelist(n, names, c); @) *wrapper* Vertex *prefix* (@ char *vname = vertex_name->get_val(); int vlen = strlen(vname); names[c] = new char[vlen+1]; sprintf(names[c],"%s",vname); @) *operation* void checkTransportationRestrictions(Cd_graph* schema, Propagation_schema *ps, Vertex_selector* travSources, Vertex_selector* tranSources) *wrapper* Cd_graph *prefix* (@ this->checkCustomizerRestrictions(schema,ps,1); // design rules checking // * sources of tranversal and transportation should not have // incoming transported edges // * no-sources not having traversal only edges adjacencies->checkTransportationRestrictions(schema,ps,travSources,tranSources); @) *wrapper* Adjacency_Nlist *prefix* (@ Adjacency_list_iterator next(*this); Adjacency* each; while (each = next()) each->checkTransportationRestrictions(schema,ps,travSources,tranSources); @) *wrapper* Adjacency *prefix* (@ static DemString * markc = new DemString("call"); int r = 0; if (superclasses) { Vertex_list_iterator next(*superclasses); Vertex* each; while (each = next()) { if (!markc->g_equal(each->get_call())) { Adjacency_list_iterator nexta(*schema->get_adjacencies()); Adjacency* eacha; while (eacha = nexta()) if (eacha->get_source()->equal(each)) break; assert(eacha); if (!eacha->noInhConsCallEdges()) { derror('e',1, form(" the Inheritance Restriction is violated. Inheritance edge ':> %s,%s' which is in the traversal graph but not in the transportation graph is not allowed, since '%s' has outgoing transporation edges which are inheritance/construction edges.", source->get_vertex_name()->get_val(), each->get_vertex_name()->get_val(), each->get_vertex_name()->get_val())); exit(-1); } } } } ns->checkTransportationRestrictions(schema,travSources,tranSources,source); @) *operation* void checkTransportationRestrictions(Cd_graph* schema, Vertex_selector* travSources, Vertex_selector* tranSources, Vertex* source) *wrapper* Neighbors *prefix* (@ @) *wrapper* Neighbors_wc *prefix* (@ @) *wrapper* Construct_ns *prefix* (@ this->get_construct_ns()-> checkTransportationRestrictions(schema,travSources,tranSources,source); @) *wrapper* Alternat_ns *prefix* (@ this->get_construct_ns()-> checkTransportationRestrictions(schema,travSources,tranSources,source); if (alternat_ns) alternat_ns-> checkTransportationRestrictions(schema,travSources,tranSources,source); @) *wrapper* Repetit_n *prefix* (@ if (sandwiched) sandwiched-> checkTransportationRestrictions(schema,travSources,tranSources,source); @) *wrapper* Any_vertex_List *prefix* (@ Any_vertex_list_iterator next(*this); Any_vertex* each; while (each = next()) each->checkTransportationRestrictions(schema,travSources,tranSources,source); @) *wrapper* Any_vertex *prefix* (@ @) *wrapper* Optional_term *prefix* (@ opt->checkTransportationRestrictions(schema,travSources,tranSources,source); @) *wrapper* Opt_labeled_term_Sandwich *prefix* (@ inner->checkTransportationRestrictions(schema,travSources,tranSources,source); @) *wrapper* Opt_labeled_term *prefix* (@ @) *wrapper* Labeled *prefix* (@ static DemString * markc = new DemString("call"); static DemString * marka = new DemString("propagate"); int r = 0; if (markc->g_equal(this->get_call())) { r = 0; travSources->contains(this->get_vertex()->get_vertex(),r); if (r) { derror('e',1, form(" the Traversal Source Restriction is violated. The transportation construction edge '-> %s,%s,%s' is not allowed, since '%s' is a traversal source.", source->get_vertex_name()->get_val(), this->get_label_name()->get_val(), this->get_vertex()->get_vertex()->get_vertex_name()->get_val(), this->get_vertex()->get_vertex()->get_vertex_name()->get_val())); exit(-1); } r = 0; tranSources->contains(this->get_vertex()->get_vertex(),r); if (r) { derror('e',1, form(" the Traversal Source Restriction is violated. The transportation construction edge '-> %s,%s,%s' is not allowed, since '%s' is a transportation source.", source->get_vertex_name()->get_val(), this->get_label_name()->get_val(), this->get_vertex()->get_vertex()->get_vertex_name()->get_val(), this->get_vertex()->get_vertex()->get_vertex_name()->get_val())); exit(-1); } } else { Adjacency_list_iterator nexta(*schema->get_adjacencies()); Adjacency* eacha; while (eacha = nexta()) if (eacha->get_source()->equal(this->get_vertex()->get_vertex())) break; assert(eacha); if (marka->g_equal(eacha->get_propagate())) { r = 0; tranSources->contains(eacha->get_source(),r); if (!r) { derror('e',1, form(" the Transportation Source Restriction is violated. The construction edge '-> %s,%s,%s' which is in the traversal graph but not in the transportation graph is not allowed, since '%s' is in the transporation graph but not a transportation source.", source->get_vertex_name()->get_val(), this->get_label_name()->get_val(), this->get_vertex()->get_vertex()->get_vertex_name()->get_val(), this->get_vertex()->get_vertex()->get_vertex_name()->get_val())); exit(-1); } } } @) *wrapper* Regular *prefix* (@ derror('i',1," unexpected visit at Regular::checkTransportationRestrictions\n"); exit(-1); @) *wrapper* Term_Barlist *prefix* (@ static DemString * markc = new DemString("call"); static DemString * marka = new DemString("propagate"); Term_list_iterator next(*this); Term* each; int r = 0; while (each = next()) { if (markc->g_equal(each->get_call())) { r = 0; travSources->contains(each->get_vertex(),r); if (r) { derror('e',1, form(" the Traversal Source Restriction is violated. The transportation alternation edge '=> %s,%s' is not allowed, since '%s' is a traversal source.", source->get_vertex_name()->get_val(), each->get_vertex()->get_vertex_name()->get_val(), each->get_vertex()->get_vertex_name()->get_val())); exit(-1); } r = 0; tranSources->contains(each->get_vertex(),r); if (r) { derror('e',1, form(" the Transportation Source Restriction is violated. The transportation alternation edge '=> %s,%s' is not allowed, since '%s' is a transportation source.", source->get_vertex_name()->get_val(), each->get_vertex()->get_vertex_name()->get_val(), each->get_vertex()->get_vertex_name()->get_val())); exit(-1); } } else { Adjacency_list_iterator nexta(*schema->get_adjacencies()); Adjacency* eacha; while (eacha = nexta()) if (eacha->get_source()->equal(each->get_vertex())) break; assert(eacha); if (marka->g_equal(eacha->get_propagate())) { r = 0; tranSources->contains(eacha->get_source(),r); if (!r) { derror('e',1, form(" the Transportation Source Restriction is violated. The alternation edge '=> %s,%s' which is in the traversal graph but not in the transportation graph is not allowed, since '%s' is in the transporation graph but not a transportation source.", source->get_vertex_name()->get_val(), each->get_vertex()->get_vertex_name()->get_val(), each->get_vertex()->get_vertex_name()->get_val())); exit(-1); } } } } @) *wrapper* Kernel_Sandwich *prefix* (@ inner->checkTransportationRestrictions(schema,travSources,tranSources,source); @) *wrapper* Kernel *prefix* (@ repeated->checkTransportationRestrictions(schema,travSources,tranSources,source); @) *wrapper* Term_Sandwich *prefix* (@ inner->checkTransportationRestrictions(schema,travSources,tranSources,source); @) *wrapper* Term *prefix* (@ @) *wrapper* CppTerm *prefix* (@ derror('i',1," unexpected visit at CppTerm::checkTransportationRestrictions\n"); exit(-1); @) *wrapper* Normal *prefix* (@ static DemString * markc = new DemString("call"); static DemString * marka = new DemString("propagate"); int r = 0; if (markc->g_equal(this->get_call())) { r = 0; travSources->contains(this->get_vertex(),r); if (r) { derror('e',1, form(" the Traversal Source Restriction is violated. The transportation repetition edge '-> %s,%s' is not allowed, since '%s' is a traversal source.", source->get_vertex_name()->get_val(), this->get_vertex()->get_vertex_name()->get_val(), this->get_vertex()->get_vertex_name()->get_val())); exit(-1); } r = 0; tranSources->contains(this->get_vertex(),r); if (r) { derror('e',1, form(" the Transportation Source Restriction is violated. The transportation repetition edge '~> %s,%s' is not allowed, since '%s' is a transportation source.", source->get_vertex_name()->get_val(), this->get_vertex()->get_vertex_name()->get_val(), this->get_vertex()->get_vertex_name()->get_val())); exit(-1); } } else { Adjacency_list_iterator nexta(*schema->get_adjacencies()); Adjacency* eacha; while (eacha = nexta()) if (eacha->get_source()->equal(this->get_vertex())) break; assert(eacha); if (marka->g_equal(eacha->get_propagate())) { r = 0; tranSources->contains(eacha->get_source(),r); if (!r) { derror('e',1, form(" the Transportation Source Restriction is violated. The repetition edge '~> %s,%s' which is in the traversal graph but not in the transportation graph is not allowed, since '%s' is in the transporation graph but not a transportation source.", source->get_vertex_name()->get_val(), this->get_vertex()->get_vertex_name()->get_val(), this->get_vertex()->get_vertex_name()->get_val())); exit(-1); } } } @) *operation* int noInhConsCallEdges() *init* (@ 1 @) *wrapper* Adjacency *prefix* (@ static DemString * markc = new DemString("call"); int r = 0; if (superclasses) { Vertex_list_iterator next(*superclasses); Vertex* each; while (each = next()) { if (markc->g_equal(each->get_call())) { return_val = 0; return; } } } return_val = ns->noInhConsCallEdges(); @) *wrapper* Neighbors *prefix* (@ @) *wrapper* Neighbors_wc *prefix* (@ return_val = this->get_construct_ns()->noInhConsCallEdges(); @) *wrapper* Any_vertex_List *prefix* (@ Any_vertex_list_iterator next(*this); Any_vertex* each; while (each = next()) if (!each->noInhConsCallEdges()) { return_val = 0; return; } @) *wrapper* Any_vertex *prefix* (@ @) *wrapper* Optional_term *prefix* (@ return_val = opt->noInhConsCallEdges(); @) *wrapper* Opt_labeled_term_Sandwich *prefix* (@ return_val = inner->noInhConsCallEdges(); @) *wrapper* Opt_labeled_term *prefix* (@ static DemString * markc = new DemString("call"); if (markc->g_equal(this->get_call())) return_val = 0; @) ///////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////// *operation* void markComposEdges(char* matrix, int n, char **names,int v) *wrapper* Propagation_schema (@ paths->markComposEdges(matrix, n, names, v); @) *wrapper* Cd_graph (@ adjacencies->markComposEdges(this,matrix,n,names,v); @) *operation* void markComposEdges( Cd_graph* schema, char* matrix, int n, char **names,int v) *wrapper* Adjacency_Nlist *prefix* (@ Adjacency_list_iterator next(*this); Adjacency* each; while (each = next()) { each->markComposEdges(schema,matrix,n,names,v); } @) *wrapper* Adjacency *prefix* (@ int r; for (int i = 0; i < n; i++) if (strcmp(names[i],source->get_vertex_name()->get_val())==0) { r = i; break; } ns->markComposEdges(schema,matrix,n,names,r,v); if (superclasses) superclasses->markComposEdges(schema,matrix,n,names,r,v); @) *operation* void markComposEdgesInh (Cd_graph* schema,char* matrix, int n, char **names,int r,int v) *wrapper* Adjacency *prefix* (@ ns->markComposEdgesInh(schema,matrix,n,names,r,v); if (superclasses) superclasses->markComposEdges(schema,matrix,n,names,r,v); @) *wrapper* Neighbors *prefix* (@ @) *wrapper* Neighbors_wc *prefix* (@ this->get_construct_ns()->markComposEdges(schema,matrix,n,names,r,v); @) *operation* void markComposEdges( Cd_graph* schema, char* matrix, int n, char **names, int r,int v) *wrapper* Vertex_List *prefix* (@ Vertex_list_iterator nextv(*this); Vertex* eachv; while (eachv = nextv()) { Adjacency_list_iterator nexta(*schema->get_adjacencies()); Adjacency* eacha; while (eacha = nexta()) { if (eacha->get_source()->equal(eachv)) break; } assert(eacha); eacha->markComposEdgesInh(schema,matrix,n,names,r,v); } @) *wrapper* Neighbors *prefix* (@ @) *wrapper* Neighbors_wc *prefix* (@ this->get_construct_ns()->markComposEdges(schema,matrix,n,names,r,v); @) *wrapper* Repetit_n *prefix* (@ if (this->get_sandwiched()) this->get_sandwiched()->markComposEdges(schema,matrix,n,names,r,v); @) *wrapper* Alternat_ns *prefix* (@ if (alternat_ns) alternat_ns->markComposEdges(schema,matrix,n,names,r,v); @) *wrapper* Term_Barlist *prefix* (@ Term_list_iterator next(*this); Term* each; while (each = next()) each->markComposEdges(schema,matrix,n,names,r,v); @) *wrapper* Kernel_Sandwich *prefix* (@ inner->markComposEdges(schema,matrix,n,names,r,v); @) *wrapper* Kernel (@ repeated->markComposEdges(schema,matrix,n,names,r,v); @) *wrapper* Term_Sandwich *prefix* (@ inner->markComposEdges(schema,matrix,n,names,r,v); @) *wrapper* Any_vertex_List *prefix* (@ Any_vertex_list_iterator next(*this); Any_vertex* each; while (each = next()) each->markComposEdges(schema,matrix,n,names,r,v); @) *wrapper* Any_vertex *prefix* (@ @) *wrapper* Opt_labeled_term *prefix* (@ vertex->markComposEdges(schema,matrix,n,names,r,v); @) *wrapper* Optional_term *prefix* (@ opt->markComposEdges(schema,matrix,n,names,r,v); @) *wrapper* Opt_labeled_term_Sandwich *prefix* (@ inner->markComposEdges(schema,matrix,n,names,r,v); @) *wrapper* Term *prefix* (@ int c; for (int i = 0; i < n; i++) if (strcmp(names[i],vertex->get_vertex_name()->get_val())==0) { c = i; break; } if (matrix[ r*n + c ] == 1) matrix[ r*n + c ] = 3; else matrix[ r*n + c ] = v; @)