#include "cdabs.h" // This File contains routines to check whether 2 adjacencies are similar void Adjacency_Nlist::similar(Adjacency* adj,Adjacency_Nlist* anl) { Adjacency_list_iterator next_arg(*this); Adjacency_ each_arg; while (each_arg = next_arg()) if (each_arg->similar(adj,anl,this)) return; /* similar found */ } int Adjacency::similar(Adjacency* adj,Adjacency_Nlist* anl1,Adjacency_Nlist* anl2) { if (strcmp(this->ns_type(),adj->ns_type())) return (FALSE); /* Different types - can't be similar */ if (!(source->same_name(adj->get_source()))) return(FALSE); /* different names - can't be similar */ extern Adjacency_Nlist* new_anl; Neighbors* new_ns; if (new_ns = ns->similar(adj->get_ns(),anl1,anl2)) { Adjacency* new_adj = new Adjacency(); new_adj->set_ns(new_ns); new_adj->set_source(source); new_anl->append(new_adj); /* appending a new adjacency */ return (TRUE); } else return (FALSE); } Term* Adjacency::sim_alt(Adjacency* adj,Adjacency_Nlist* anl1,Adjacency_Nlist* anl2) // Function to find out the common children between 2 Alternate classes { Vertex* new_vertex = ((Vertex*)adj->get_source()->g_copy())->cat((Vertex*)source->g_copy()); Normal* ret_term = new Normal(); ret_term->set_vertex(new_vertex); extern Adjacency_Nlist* new_anl; if (new_anl->get_adj(new_vertex)) /* already found out */ return (ret_term); Neighbors* new_ns; if (new_ns = ns->similar(adj->get_ns(),anl1,anl2)) { Adjacency* new_adj = new Adjacency(); new_adj->set_ns(new_ns); new_adj->set_source(new_vertex); new_anl->append(new_adj); return (ret_term); } else return ((Term*)NULL); } int Vertex::same_name(Vertex* vertex) // Checks whether the 2 vertices have the same name { return(vertex_name->g_equal(vertex->get_vertex_name())); } Neighbors* Neighbors::similar( Neighbors*, Adjacency_Nlist*, Adjacency_Nlist* ) { return ((Neighbors*)NULL); } Neighbors* Repetit_n::similar(Neighbors* n,Adjacency_Nlist* anl1,Adjacency_Nlist* anl2) { return (sandwiched->similar(n, anl1, anl2)); } Neighbors* Neighbors_wc::similar(Neighbors*,Adjacency_Nlist*,Adjacency_Nlist*) { return ((Neighbors*)NULL); } Neighbors* Alternat_ns::similar(Neighbors* n,Adjacency_Nlist* anl1,Adjacency_Nlist* anl2) { Term_Bar_list* ret_tbl; if (ret_tbl = this->get_alternat_ns()->similar(((Alternat_ns*)n)->get_alternat_ns(),anl1,anl2)) { Alternat_ns* ret_alns = new Alternat_ns(); ret_alns->set_alternat_ns(ret_tbl); ret_alns->set_construct_ns(new Any_vertex_List()); return (ret_alns);} else return ((Neighbors*)NULL); } Neighbors* Construct_ns::similar(Neighbors* n,Adjacency_Nlist* anl1,Adjacency_Nlist* anl2) { Construct_ns* ret_cns = new Construct_ns(); Any_vertex_List* ret_avl; if (ret_avl = this->get_construct_ns()->similar(((Construct_ns*)n)->get_construct_ns(),anl1,anl2)) { ret_cns->set_construct_ns(ret_avl); return (ret_cns);} else return ((Neighbors*)NULL); } Any_vertex_List* Any_vertex_List::similar( Any_vertex_List* avl, Adjacency_Nlist* anl1, Adjacency_Nlist* anl2) { Any_vertex_List* ret_avl = new Any_vertex_List(); if ((this->list_length() == 0) && (avl->list_length() == 0)) return (ret_avl); Any_vertex_list_iterator next_arg(*this); Any_vertex_ each_arg; Any_vertex_ each_arg1; while (each_arg = next_arg()) if (each_arg1 = each_arg->sim_in_list(avl,anl1,anl2)) ret_avl->append(each_arg1); return (ret_avl); } Any_vertex* Any_vertex::sim_in_list( Any_vertex_List*, Adjacency_Nlist*, Adjacency_Nlist* ) /* Checks to see if the given vertex has a similar one in the list */ { return NULL; } Any_vertex* Regular_syntax::sim_in_list( Any_vertex_List*, Adjacency_Nlist*, Adjacency_Nlist*) { return ((Any_vertex*)NULL); /* Not considering these */ } Any_vertex* Inherit_term::sim_in_list( Any_vertex_List*, Adjacency_Nlist*, Adjacency_Nlist*) { return ((Any_vertex*)NULL); /* Not considering these */ } Any_vertex* Optional_term::sim_in_list( Any_vertex_List* avl, Adjacency_Nlist* anl1, Adjacency_Nlist* anl2) { Opt_labeled_term* opt_term = this->get_inner(); char* type1 = (char *)opt_term->get_type(); Any_vertex_list_iterator next_arg(*avl); Any_vertex_ each_arg; Any_vertex_ each_arg1; while (each_arg = next_arg()) {char* type2 = (char *)each_arg->get_type(); if (each_arg->is_optional()) // both are optional - return optional { Opt_labeled_term* opt_term1 = each_arg->get_inner(); if (!(strcmp(type1,opt_term1->get_type()))) if (each_arg1 = opt_term->similar(opt_term1,anl1,anl2)) { Optional_term* ret_opt = new Optional_term(); Opt_labeled_term_Sandwich* ret_sand = new Opt_labeled_term_Sandwich(); ret_sand->set_first(new Syntax_vertex_List()); ret_sand->set_second(new Syntax_vertex_List()); ret_sand->set_inner((Opt_labeled_term*)each_arg1); ret_opt->set_opt(ret_sand); return (ret_opt);} } if (!(strcmp(type1,type2))) // One is optional - return if this is similar to the required one if (each_arg1 = opt_term->similar(each_arg,anl1,anl2)) return (each_arg1); } return ((Any_vertex*)NULL); } Any_vertex* Opt_labeled_term::sim_in_list( Any_vertex_List* avl, Adjacency_Nlist* anl1, Adjacency_Nlist* anl2) { Any_vertex_list_iterator next_arg(*avl); Any_vertex_ each_arg; Any_vertex_ each_arg1; char* type1 = (char*)this->get_type(); while (each_arg = next_arg()) {char* type2 = (char*)each_arg->get_type(); if (!(strcmp(type1,type2))) /* must be of same type to be similar */ if (each_arg1 = this->similar(each_arg,anl1,anl2)) return (each_arg1); if (each_arg->is_optional()) { Opt_labeled_term* opt_term = each_arg->get_inner(); if (!(strcmp(type1,opt_term->get_type()))) if (each_arg1 = this->similar(opt_term,anl1,anl2)) return (each_arg1);} } return ((Any_vertex*)NULL); } Any_vertex* Inherit_term::similar( Any_vertex*, Adjacency_Nlist*, Adjacency_Nlist* ) { return ((Any_vertex*)NULL); } Any_vertex* Regular_syntax::similar( Any_vertex*, Adjacency_Nlist*, Adjacency_Nlist*) { return ((Any_vertex*)NULL); } Any_vertex* Opt_labeled_term::similar( Any_vertex*, Adjacency_Nlist*, Adjacency_Nlist* ) { return ((Any_vertex*)NULL); } Any_vertex* Labeled::similar( Any_vertex* each_arg, Adjacency_Nlist* anl1, Adjacency_Nlist* anl2 ) { if (this->get_label_name()->g_equal(((Labeled*)each_arg)->get_label_name())) /*labels must match */ {Labeled* ret_lab = new Labeled(); ret_lab->set_label_name(((Labeled*)this)->get_label_name()); Term* ret_term; if (ret_term = this->get_vertex()->similar(((Opt_labeled_term*)each_arg)->get_vertex(),anl1,anl2)) {ret_lab->set_vertex(ret_term); return (ret_lab);} return ((Any_vertex*)NULL);} return ((Any_vertex*)NULL); } Any_vertex* Regular::similar( Any_vertex* each_arg, Adjacency_Nlist* anl1, Adjacency_Nlist* anl2) { if (!(this->get_vertex()->same_name(((Regular*)each_arg)->get_vertex()))) // names must match - since the name is considered as a label return ((Any_vertex*)NULL); Regular* ret_reg = new Regular(); Term* ret_term; if (ret_term = this->get_vertex()->similar(((Opt_labeled_term*)each_arg)->get_vertex(),anl1,anl2)) {ret_reg->set_vertex(ret_term); return (ret_reg);} return ((Any_vertex*)NULL); } int Term::same_name(Term* term) { return (vertex->same_name(term->get_vertex())); } Term_Bar_list* Term_Bar_list::similar( Term_Bar_list* tbl, Adjacency_Nlist* anl1, Adjacency_Nlist* anl2) { Term_Bar_list* ret_tbl = new Term_Bar_list(); Term_list_iterator next_arg(*this); Term_ each_arg; while (each_arg = next_arg()) ret_tbl = each_arg->sim_in_list(tbl,anl1,anl2,ret_tbl); if (ret_tbl->list_length() == 0) return ((Term_Bar_list*) NULL); return (ret_tbl); } Term_Bar_list* Term::sim_in_list( Term_Bar_list* tbl, Adjacency_Nlist* anl1, Adjacency_Nlist* anl2, Term_Bar_list* ret_tbl) /* Checks to see if the given term has a similar one in the list */ { Term_list_iterator next_arg(*tbl); Term_ each_arg; while (each_arg = next_arg()) {Term* ret_term; if (ret_term = this->similar(each_arg,anl1,anl2)) ret_tbl->append(ret_term);} return (ret_tbl); } Term* Term::similar(Term* term, Adjacency_Nlist* anl1,Adjacency_Nlist* anl2) { Adjacency* adj1; if (!(adj1 = anl1->get_adj(term->get_vertex()))) /* Since not in the adjacency list must be a terminal class */ if (this->same_name(term)) return (this); /* same terminal class */ else return ((Term*)NULL); /* different terminal classes */ Adjacency* adj2; if (!(adj2 = anl2->get_adj(this->get_vertex()))) return ((Term*)NULL); /* this is a terminal class - not the other*/ char* type1 = adj1->ns_type(); char* type2 = adj2->ns_type(); if (strcmp(type1,type2)) /* different classes */ { int gen = adj2->generalize(adj1,anl1,anl2); if (gen == SUP) /* this class generalizes the other */ return (term); else if (gen == SUB) /* this class specializes the other */ return (this);} else if (!(adj1->is_alns())) { if (adj1->get_source()->same_name(adj2->get_source())) // same construction or repetition class return (this);} else { Normal* ret_normal = new Normal(); // check to see the commonality between the 2 alternation classes if (ret_normal = ((Normal*)adj2->sim_alt(adj1,anl1,anl2))) return (ret_normal);} return ((Term*)NULL); } Neighbors* Kernel_Sandwich::similar( Neighbors* n, Adjacency_Nlist* anl1, Adjacency_Nlist* anl2) { return (inner->similar(n,anl1,anl2)); } Neighbors* Kernel::similar( Neighbors* n, Adjacency_Nlist* anl1, Adjacency_Nlist* anl2) { Term* this_term = repeated->get_inner(); /* get the repeated term */ Term* n_term = n->get_rep(); /* get the repeated term */ Term* ret_term; if (ret_term = this_term->similar(n_term,anl1,anl2)) // the terms are similar - return a repetition class { Kernel* ret_kernel = new Kernel(); Term_Sandwich* term_sand = new Term_Sandwich(); term_sand->set_first(new Syntax_vertex_List()); term_sand->set_second(new Syntax_vertex_List()); term_sand->set_inner(ret_term); ret_kernel->set_repeated(term_sand); if (nonempty && n->ne()) // both are non-empty - return a non-empty repetition class ret_kernel->set_nonempty(ret_term); Kernel_Sandwich* kernel_sand = new Kernel_Sandwich(); kernel_sand->set_first(new Syntax_vertex_List()); kernel_sand->set_second(new Syntax_vertex_List()); kernel_sand->set_inner(ret_kernel); Repetit_n* ret_n = new Repetit_n(); ret_n->set_sandwiched(kernel_sand); return(ret_n);} return ((Neighbors*)NULL); }