⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adseliminatepseudostatenodes.c

📁 这个工具集提供以下结构化分析和UML分析中所用的图形化绘图工具:ER-diagrams, data and event flow diagrams and state-transition diagr
💻 C
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////////////// This file is part of Toolkit for Conceptual Modeling (TCM).// (c) copyright 2001, Universiteit Twente.// Author: Rik Eshuis (eshuis@cs.utwente.nl).//// TCM is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// TCM is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with TCM; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA// 02111-1307, USA.////////////////////////////////////////////////////////////////////////////////// Eliminate pseudo state nodes from graph structure by replacing edges// with hyperedges.#include <string.h>#include "atddecisionstatenode.h"#include "code.h"#include "atdiagram.h"#include "adseliminatepseudostatenodes.h"#include "limits.h"#include "bool.h"#include "graph.h"#include "atdtransitionedge.h"#include "outputfile.h"#include "../../dg/hyperedge.h"#include "adsclock.h"#include "adsclockconstraint.h"#include "adsedgelabelparse.h"#include "adsproperty.h"#include "adspropertyvaluation.h"#include "adsvariable.h"#include "adshyperedge.h"// some generic checks on activity graphs needed in order to make// sure that the elimination of pseudo state nodes can be conductedbool Elim::Check(Graph *g){  List <Subject *>  gnodes;  g->GetNodes(&gnodes); // the nodes of g  for (gnodes.first();!gnodes.done();gnodes.next()){    Subject *curnode;    curnode=gnodes.cur();    if (curnode->IsEdge()) {      error("There is an edge having an edge as source or target!\n");      return False;    }    if ((curnode->GetClassType()==Code::ATD_SYNCHRONIZATION_NODE) ||	(curnode->GetClassType()==Code::ATD_DECISION_STATE_NODE)){      List <Subject *> tempedges;      if (g->GetEdgesFrom(&tempedges,curnode)==0) {	error("There is a pseudo state node with no outgoing edges!\n");	return False;      }      List <Subject *> tempedges2;      if (g->GetEdgesTo(&tempedges2,curnode)==0) {	error("There is a pseudo state node with no incoming edges!\n");	return False;      }    }    if (curnode->GetClassType()==Code::ATD_INITIAL_STATE_NODE){      List <Subject *> tempedges;      // initial state should have no incoming edges      if (g->GetEdgesTo(&tempedges,curnode)>0) return False;     }    if (curnode->GetClassType()==Code::FINAL_STATE){      List <Subject *> tempedges;      // final state should have no outgoing edges      if (g->GetEdgesFrom(&tempedges,curnode)>0) return False;    }    if (curnode->GetClassType()==Code::ATD_DECISION_STATE_NODE){      List <Subject *> tempedges;      bool found=False;      // final state should have no outgoing edges      g->GetEdgesFrom(&tempedges,curnode);      if (tempedges.count()>1){	for (tempedges.first();!tempedges.done();tempedges.next()){	  if ((tempedges.cur()->GetName()->contains("[else]"))||(tempedges.cur()->GetName()->length()==0)){	    found=True;	  }	}	if (!found){	  error("There is a decision node with no [else] branch!\n");	  return False;	}      }          }  }  List <Subject *>  gedges;  g->GetEdges(&gedges); // the edges of g  for (gedges.first();!gedges.done();gedges.next()){    if (gedges.cur()->GetName()->contains("[else]")){      if (((Edge *)gedges.cur())->GetSubject1()->GetClassType()!=Code::ATD_DECISION_STATE_NODE){	error("There is a [else] branch that does not leave a decision node!\n");	return False;      }    }  }  if (g->CountNodes(Code::ATD_INITIAL_STATE_NODE)==0){    error("There is no initial node!\n");    return False;  }  return True;}// eliminate every OR node by// replacing every possible combination of an OR-entering hyperedge and an OR-exiting hyperedge by a new hyperedgebool Elim::ElimOrNodes(ADSHyperGraph *h){  List <Subject *> hnodes; // the nodes of activity machine h  h->GetNodes(&hnodes);    for (hnodes.first();!hnodes.done();hnodes.next()){    if (hnodes.cur()->GetClassType()==Code::ATD_DECISION_STATE_NODE){ // if OR node      List <Subject *> eto; // hyperedges entering the OR node      h->GetHyperEdgesTo(&eto,hnodes.cur());      List <Subject *> efrom; // hyperedges exiting the OR node      h->GetHyperEdgesFrom(&efrom,hnodes.cur());      for (eto.first();!eto.done();eto.next()){ // for every hyperedge entering the OR node ...	for (efrom.first();!efrom.done();efrom.next()){ // for every hyperedge exiting the OR node ...	  if (efrom.cur()==eto.cur()) { // cycle detected	    error("There is an or state node with a cycle\n");	    return False;	  }	  	  if (((ADSHyperEdge *)efrom.cur())->hasClockConstraint() && 	      ((ADSHyperEdge *)eto.cur())->hasClockConstraint()){ // two clock constraints for same hyperedge	    error("There are two segments in the hyperedge with a clock constraint\n");	    return False;	  }	  	  ADSHyperEdge *he =new ADSHyperEdge(h); // Create new hyperedge he for this combination of efrom.cur() and eto.cur()	  // keep track of the simple edges that belong to this hyperedge;	  // necessary to animate models and to give feedback etc, but not for execution 	  List <Subject *> ls; 	  ((ADSHyperEdge *)eto.cur())->GetEdges(&ls);	  he->AddEdges(ls);	  ls.empty();	  ((ADSHyperEdge *)efrom.cur())->GetEdges(&ls);	  he->AddEdges(ls);	  ls.empty();	  //	  //	  he->AddPseudoNode(hnodes.cur());	  string event;	  // initialise event with the event label of either eto.cur() or efrom.cur()	  if (((ADSHyperEdge *)eto.cur())->HasEmptyEvent())	    event=((ADSHyperEdge *)efrom.cur())->GetEvent();	  else if (((ADSHyperEdge *)efrom.cur())->HasEmptyEvent())	    event=((ADSHyperEdge *)eto.cur())->GetEvent();	  else {	    error("Two edges connected by diamond have an event label");	    return False;	  }	 	  string s1=((ADSHyperEdge *)efrom.cur())->GetGuard(); // guard of exiting edge	  string s2=((ADSHyperEdge *)eto.cur())->GetGuard(); // guard of entering edge	  string guard;	  if (s1=="") {	    guard=s2;	  }	  else 	    if (s2=="") 	      guard=s1;	    else{ // s1!="" && s2!=""			      s1.remove(0); // strip  [	      s1.remove();// strip  ]	      s2.remove(0); // strip [	      s2.remove(); // strip ]	      guard= "[("+ s2 + ")" + "&" + "(" + s1 + ")]";	    }	  he->SetLabel(event+guard);	  // fill he with properties	  List <Prop *> p1;	  ((ADSHyperEdge *)eto.cur())->GetPropList(p1);	  for (p1.first();!p1.done();p1.next()){	    he->AddProp(p1.cur());	  }	  List <Prop *> p2;	  ((ADSHyperEdge *)efrom.cur())->GetPropList(p2);	  for (p2.first();!p2.done();p2.next()){	    he->AddProp(p2.cur());	  }	  	  // fill he with variables	  List <ADSVar *> v1;	  ((ADSHyperEdge *)eto.cur())->GetVarList(v1);	  for (v1.first();!v1.done();v1.next()){	    he->AddVar(v1.cur());	  }	  List <ADSVar *> v2;	  ((ADSHyperEdge *)efrom.cur())->GetVarList(v2);	  for (v2.first();!v2.done();v2.next()){	    he->AddVar(v2.cur());	  }	      	  // fill he with `in' nodes	  List <Subject *> n1;	  ((ADSHyperEdge *)eto.cur())->GetInNodes(&n1);	  for (n1.first();!n1.done();n1.next()){	    he->AddInNode(n1.cur());	  }	  List <Subject *> n2;	  ((ADSHyperEdge *)efrom.cur())->GetInNodes(&n2);	  for (n2.first();!n2.done();n2.next()){	    he->AddInNode(n2.cur());	  }	  // fill he with `not in' nodes	  List <Subject *> n3;	  ((ADSHyperEdge *)eto.cur())->GetNotInNodes(&n3);	  for (n3.first();!n3.done();n3.next()){	    he->AddNotInNode(n3.cur());	  }	  List <Subject *> n4;	  ((ADSHyperEdge *)efrom.cur())->GetNotInNodes(&n4);	  for (n4.first();!n4.done();n4.next()){	    he->AddNotInNode(n4.cur());	  }	       	  //	  if ((((ADSHyperEdge *)efrom.cur())->GetClockConstraint()) && (((ADSHyperEdge *)eto.cur())->GetClockConstraint())){ 	    error("There are two clock constraints events in one hyperedge: I cannot deal with this (yet)\n");	    return False;	  }	  else{	    ClockConstraint *cnew=NULL;	    if (((ADSHyperEdge *)efrom.cur())->GetClockConstraint()){	      //cnew= new ClockConstraint(*(((ADSHyperEdge *)efrom.cur())->GetClockConstraint()));	      cnew=(((ADSHyperEdge *)efrom.cur())->GetClockConstraint());	    }	    if (((ADSHyperEdge *)eto.cur())->GetClockConstraint()){      	      // cnew= new ClockConstraint(*(((ADSHyperEdge *)eto.cur())->GetClockConstraint()));	    	      cnew= (((ADSHyperEdge *)eto.cur())->GetClockConstraint());	    }	    he->SetClockConstraint(cnew); //possibly NULL	  }	  //	  if ((((ADSHyperEdge *)efrom.cur())->GetSendEvent()) && (((ADSHyperEdge *)eto.cur())->GetSendEvent())){ 	    error("There are two send events in one hyperedge: I cannot deal with this (yet)\n");	    return False;	  }	  else{	    if (((ADSHyperEdge *)efrom.cur())->GetSendEvent()){	      he->SetSendEvent(((ADSHyperEdge *)efrom.cur())->GetSendEvent());	    }	    else he->SetSendEvent(((ADSHyperEdge *)eto.cur())->GetSendEvent()); //possibly NULL	  }	  // fill he with outgoing hyperedge	       	  List <Subject *> *sources;	  sources = ((ADSHyperEdge *)efrom.cur())->GetSubject1();	  for (sources->first();!sources->done();sources->next()){ 	    if (sources->cur()!=hnodes.cur()) 	      he->AddSubject1(sources->cur()); //new	  }	  	  List <Subject *> *targets;	  targets = ((ADSHyperEdge *)efrom.cur())->GetSubject2();	  for (targets->first();!targets->done();targets->next()){	    if (targets->cur()!=hnodes.cur())	      he->AddSubject2(targets->cur()); //new	  }	       	  // fill he with incoming hyperedge	  sources = ((ADSHyperEdge *)eto.cur())->GetSubject1();	  for (sources->first();!sources->done();sources->next()){ 	    if (sources->cur()!=hnodes.cur()) 	      he->AddSubject1(sources->cur()); //new	  }	  targets = ((ADSHyperEdge *)eto.cur())->GetSubject2();	  for (targets->first();!targets->done();targets->next()){	    if (targets->cur()!=hnodes.cur()) 	      he->AddSubject2(targets->cur()); //new	  }	  // check the resulting hyperedge	  if (!he->GetSubject1()->isSet()){ 	    error("There is a hyper edge whose source is no set!\n");	    delete he;	    return False;	  } 	  else if (!he->GetSubject2()->isSet()){ 	    error("There is a hyper edge whose target is no set!\n");	    delete he;	    return False;	  }	  if (!h->ExistsSimilarHyperEdge(he)) h->AddHyperEdge(he);	  else delete he;	}      }      h->RemoveNode((Node *)hnodes.cur());    }  }  return True;}// wrapper to call the parserbool Elim::ParseGuardLabel(const string *str) {  YY_BUFFER_STATE y = ::adsedgelabel_scan_string(str->getstr());  strcpy(::adsedgelabel_constraint, "");  bool b = !adsedgelabelparse();  adsedgelabel_delete_buffer(y);  return (b);} extern string replace(string s); // defined in adscks

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -