/***********************************
  (C) Copyright 1992-1993; dit/upm
  Distributed under the conditions stated in the
  TOPO General Public License (see file LICENSE)
  ***********************************/

/***********************************
  
  Santiago Pavon gomez
  
  7 March 1991
  
  Expansion Post processing
  
  25-6-1992 Santiago.
  The function to transform predicates with M-AND operators has been put
  inside comments.
  
  25-8-1993 David.
  New interleaved expansion post-processing.
  
  COMPILATION OPTIONS: The behaviour of this module can be modified
  by the following compilation flags:
  
  (none)
  
  ************************************/


#include "expostex.h"
#include "expre_br.h"
#include "badefca.h"
#include "baattr.h"
#include "limisc.h"
#include "batyperw.h"
#include "balotosf.h"
#include "batables.h"
#include "babool.h"


/******************************************************************
 *                                                                *
 *  RmAltStopInBeh: Explores b and removes the stop alternatives. *
 *                                                                *
 *******************************************************************/

/* Pre_Branch_Stop_RMP
 * Transforms ...[]B1[]stop[]B2[]... into ...[]B1[]B2...
 */
static BehTyp Pre_Branch_Stop_RMP( b )
     BehTyp b;
{
  int n, i;
  
  if ( LookTypeB(b) == AlternativeC ) {
    n = NumArgB(b);
    for ( i=1; i<=n; ) {
      if ( LookTypeB(b)==AlternativeC )
	if ( LookTypeB(LookArgB(b,i))==StopC ) {
	  FreeArgB( b, i );
	  n--;
	}    
	else
	  i++;   
      else
	i++;  
    }
  }
  return b;
}

/*----------------------------------------------------------------*/

static BehTyp TravBehRMAS( b )
     BehTyp b;
{
  int n, i;
  
  if ( VisitedB(b) )
    return b;
  if ( LookTypeB(b)==AlternativeC ) {
    PutCopy( b, -LookCopy(b) );    /* undo Visit changes */
    b = Pre_Branch_Stop_RMP( b );
    PutCopy( b, -LookCopy(b) );    /* redo Visit changes */
  }
  n = NumArgB(b);
  for (i=1 ; i<=n ; i++)
    PutArgB( b, TravBehRMAS(GetArgB(b,i)), i );
  return b;
}

/*----------------------------------------------------------------*/

/* RmAltStopInBeh
 * Explores the behaviour b and removes the alternatives of stops.
 */
BehTyp RmAltStopInBeh( b )
     BehTyp b; 
{
  Begin_VisitB();
  b   = TravBehRMAS(b);
  End_VisitB();
  return b;
}

/******************************************************************
 *                                                                *
 *                        Clear Beh                               *
 *                                                                *
 ******************************************************************/

/* ClearBeh
 * Post-processing applied to the expanded behaviour and duplicated processes
 * after the expansion or free_expansion
 * The auxiliary cells of type BehaviourC are removed from the tree.
 * Predicates are converted to LOTOS format.
 */
void ClearBeh ( ptr )
     BehTyp ptr;
{ 
  ITContListTyp itcl;
  PITContTyp    pit;
  BehTyp        aux,beh;
  int           cero = 0;
  
  while ( ptr != NULL )
    switch ( LookTypeB(ptr) )
      {
      case AlternativeC : 
	aux = LookB2(ptr);
	while ( aux!=NULL ) {
	  ClearBeh( LookB1(aux) );
	  aux = LookB2(aux);
	}
	ptr = LookB1(ptr);
	break;
	
      case BehaviourC : 
	if ( LookB1(ptr)==NULL ) {
	  GlueArgB( ptr, 2 );
	  ptr = NULL; 
	}
	else
	  GlueArgB( ptr, 1 );
	break;
	
      case GuardC:
      case GateC:
	/* PredToLOTOSPred ( ptr ); */
	ptr = LookB1( ptr );
	break;
	
      case IC:
	ptr = LookB1( ptr );
	break;
	
      case ProcessDefC:
      case ChoiceC:
	ptr = LookB1( ptr );
	break;
	
      case ProcessInstC:
	aux = ( LookArgB(ptr,1)==NULL ) ? NULL: GetArgB(ptr,1);
	beh  = LookArgB( GetP_def(LookNameB(ptr)), 1 );
	if ( LookTypeB(beh)==TerminationC ||
	    LookTypeB(beh)==ExitC ||
	    LookTypeB(beh)==StopC ){
	  expansion_flags = 0;
	  GlueB( ptr, Pre_Branch( ptr, &cero ) );
	}
	ptr = aux;
	break;
	
      case ExitC:
      case StopC:
	ptr = NULL;
	break;
	
      case ParallelC:
	if ( LookA(ptr,BHT1A) ){
	  FreeA(GetA(ptr,BHT1A));
	}
	if ( LookA(ptr,BHT2A) ){
	  FreeA(GetA(ptr,BHT2A));
	}
	ClearBeh( LookArgB(ptr,1) );
	ptr = LookArgB(ptr,2);
	break;
	
      case DisablingC:
      case InterleavedC:
	ClearBeh( LookArgB(ptr,1) );
	ptr = LookArgB(ptr,2);
	break;
	
/*      case ResumeSetC: */
      case ContSetC:
	if ( LookA(ptr,ITCLA) ){
	  UnshareA( ptr, ITCLA );
	  itcl = (ITContListTyp)LookAInfo(LookA(ptr,ITCLA));
	  for ( ; itcl!=NULL; itcl= Next_list(itcl) ) {
	    pit = (PITContTyp)LookInfo_list(itcl);
	    ClearBeh( LookBehITC(pit) );
	    /*
	    ClearITC(pit); */
	  }
	}
	ptr = NULL;
	break;
	
      case TerminationC:
	ptr = NULL;
	break;
	
      default:
	/* uncomplete iexpansion */
	ptr = NULL;
	/*
	Error("Post_expan.ClearBeh: Unexpected cell.");
	*/
      }
  
}

/*****************************************************************  
 * PClearBeh
 *
 * PostProcess after the parameterized expansion.
 * The parameterization is removed and the expressions are rewritten.
 * The duplicated process are processed with PClearProc
 * The main behaviour is procesed by PClearBeh
 *
 ******************************************************************/

/* 
 * Used processes
 */
static ListTyp lproc;

/*
 * continuation sets to be processed with PClearProc
 */
static ListTyp csl;

/*----------------------------------------------------------------*/


static boolean changeReplaceVarP;

static ExprTyp AuxReplaceVarP( e )
     ExprTyp e;
{
  ExprTyp p;
  int n,i;
  
  LASSERT(OwnersE(e)==0);
  if ( LookTypeE(e)==VariableC ) {
    if ( (p = GetPVarE(e)) != NULL ) {
      changeReplaceVarP = TRUE;
      FreeE( e );
      return AuxReplaceVarP( GetE(p) );
    }
    return e;
  }
  else {
    n = NumArgE(e);  
    for (i=1 ; i<=n ; i++) {
      PutArgE( e, AuxReplaceVarP(GetArgE(e,i)),i);
    }
    return e;
  }
}

/* ReplaceVarP
 * Replaces the variables with their parameterized values.
 * If "r" is TRUE then it rewrites "e".
 * The expression is not copied.
 */
static ExprTyp ReplaceVarP ( e , r )
     ExprTyp e;
     boolean r;
{
  LASSERT(OwnersE(e)==0);
  changeReplaceVarP = FALSE;
  e = AuxReplaceVarP(e);
  if (changeReplaceVarP && r)
    e = Rewrite(e);
  return e;
}

/*----------------------------------------------------------------*/

/*
 * List of defined formal variables
 */
static ListTyp list_var;

/* InsertVarVL
 * Inserts the formal variables parameter of the process p
 * into the list list_var.
 * As well for the variables defined in a choice.
 */
static void InsertVarVL( p )
     BehTyp p;
{
  PAttrTyp      a;
  ExprListTyp   el;
  
  LASSERT((LookTypeB(p)==ProcessDefC) || 
          (LookTypeB(p)==ChoiceC)     || 
          (LookTypeB(p)==EnablingC)   ||
          (LookTypeB(p)==TerminationC)       /* in continuation labels */
          );
  if ( (a = LookA(p,ELA)) != NULL ) {
    for ( el=(ExprListTyp)LookAInfo(a) ; el!=NULL ; el=Next_list(el) ){
      /*
	 correct and possible
	 v = LookNameE((ExprTyp)LookInfo_list(el));
	 LASSERT(!In_list((DataListTyp)v,list_var,EqInt));
	 */
      list_var = Insert_list((DataListTyp)LookNameE((ExprTyp)LookInfo_list(el))
                             ,list_var);
    }
  }
}

/*----------------------------------------------------------------*/

static boolean changeClearExprVnD;

static ExprTyp AuxClearExprVnD( e )
     ExprTyp e;
{
  ExprTyp p;
  int n,i;
  
  LASSERT(OwnersE(e)==0);
  if ( LookTypeE(e)==VariableC ) {
    if ( (p = GetPVarE(e)) != NULL ) {
      if ( In_list((DataListTyp)LookNameE(e),list_var,EqInt) ) {
	FreeE( p );
	return e;
      }
      else {
	changeClearExprVnD = TRUE;
	FreeE( e );
	return AuxClearExprVnD( GetE(p) );
      }
    }
    else
      return e;
  }
  else {
    n = NumArgE(e);  
    for (i=1 ; i<=n ; i++) {
      PutArgE( e, AuxClearExprVnD(GetArgE(e,i)),i);
    }
    return e;
  }
}

/* ClearExprVnD
 * Replaces in the expression e all the not-defined-in-list_var variables
 * by their parameterized value. Free the parameterized value of the rest.
 * If "r" is TRUE then it rewrites the expression.
 */
static ExprTyp ClearExprVnD( e,r )
     ExprTyp e;
     boolean r;
{
  LASSERT(OwnersE(e)==0);
  changeClearExprVnD = FALSE;
  e = AuxClearExprVnD(GetE(e));
  if (changeClearExprVnD && r)
    e = Rewrite(e);
  return e;
}

/*----------------------------------------------------------------*/

static void TravBehPCP( b )
     BehTyp b;
{
  int               i, n;
  PredicateTyp      p,paux;
  PredNodeTyp       pn;
  PAttrTyp          a;
  ExprTyp           e;
  VarAssignListTyp  val;
  OfferListTyp      ol;
  ExprListTyp       el;
  ITContListTyp     itcl,itclh,itclres;
  PITContTyp        pit;
  BehTyp            bi,lab,def,beh;
  int               cero = 0;
  char              evalp;
  
  while ( b!=NULL ) {
    if ( VisitedB( b ) )
      return;
    switch ( LookTypeB(b) )
      {
      case EnablingC:
	TravBehPCP( LookArgB(b,1) );
	InsertVarVL( b );
	b = LookArgB( b, 2 );
	break;
	
      case ChoiceC:
	InsertVarVL( b );
	bi = LookArgB( b, 1 );
	TravBehPCP( bi );
	if ( LookTypeB(bi)==StopC )
	  TrfStop( b );
	b = NULL;
	break;
	
      case ParallelC:
	if ( LookA(b,BHT1A) ){
	  FreeA(GetA(b,BHT1A));
	}
	if ( LookA(b,BHT2A) ){
	  FreeA(GetA(b,BHT2A));
	}
      case DisablingC:
	TravBehPCP( LookArgB(b,1) );
	b = LookArgB(b,2);
	break;
	
      case AlternativeC:
	n = NumArgB( b );
	for ( i=1 ; i<=n ; i++ ) 
	  TravBehPCP( LookArgB(b,i) );
	b = Pre_Branch_Stop_RMP( b );
	b = NULL;
	break;
	
      case BehaviourC : 
	if ( LookB1(b)==NULL ) 
	  GlueArgB( b, 2 );
	else
	  GlueArgB( b, 1 );
	break;
	
      case GuardC:
	UnshareA( b, PA );
	a = LookA( b, PA );
	p = (PredicateTyp)GetAInfo( a );
	for (paux=p ; paux!=NULL ; paux=Next_list(paux)) {
	  pn = (PredNodeTyp)LookInfo_list(paux);
	  pn->rewritten = ShareE(ClearExprVnD(UnshareE(pn->rewritten),TRUE));
	  if (pn->original!=NULL) 
	    pn->original = ShareE(ClearExprVnD(UnshareE(pn->original),FALSE));
	}
	evalp = Evaluate(&p);
	PutAInfo( a, (AttrValueTyp)p );
	if ( evalp=='t' ){
	  UnVisitB( b );
	  GlueArgB( b, 1 );
	}
	else if ( evalp=='f' ) {
	  TrfStop( b );
	  b = NULL;
	}
	else {
	  bi = LookArgB( b, 1 );
	  TravBehPCP( bi );
	  if ( LookTypeB(bi)==StopC )
	    TrfStop( b );
	  b = NULL;
	}
	break;
	
      case ProcessInstC:
	if ( LookArgB( b, 1 )!=NULL ) {
	  (void)GetArgB( b, 1 );
	}
	def   = GetP_def(LookNameB(b));
	lproc = Add_IfNotIn_list( (DataListTyp)def, lproc, EqInt );
	UnshareA( b, ELA );
	if ( (a = LookA(b,ELA))!=NULL ) {
	  for ( el = (ExprListTyp)LookAInfo(a);el!=NULL ; el=Next_list(el) ) {
	    e = UnshareE((ExprTyp)GetInfo_list( el ));
	    e = ClearExprVnD( e,TRUE );
	    PutInfo_list( el, (DataListTyp)ShareE(e) );
	  }
	}
	beh  = LookArgB( def, 1 );
	if ( LookTypeB(beh)==TerminationC ||
	    LookTypeB(beh)==ExitC ||
	    LookTypeB(beh)==StopC ){
	  expansion_flags = 0;
	  GlueB( b, Pre_Branch( b, &cero ) );
	}
	b = NULL;
	break;
	
      case PletC:
	UnshareA( b, VALA );
	if ( (a = LookA(b,VALA))!=NULL ) {
	  for ( val=(VarAssignListTyp)LookAInfo(a); val!=NULL;
	       val=Next_list(val) ) {
	    e = GetExprVAL( val );
	    e = ClearExprVnD( e,TRUE );
	    PutExprVAL( val, e );
	  }
	}
	b = NULL;
	break;
	
      case LetC:
	UnshareA(b,VALA);
	if ( (a = LookA(b,VALA)) != NULL ) {
	  for ( val = (VarAssignListTyp)LookAInfo(a); val!=NULL;
	       val = Next_list(val) ) {
	    e = GetExprVAL( val );
	    e = ClearExprVnD( e,TRUE );
	    PutExprVAL( val, e );
	    list_var = Insert_list( (DataListTyp)LookVarVAL(val), list_var );
	  }
	}
	b = LookArgB(b,1);
	break;
	
      case ExitC:
	UnshareA( b, OLA );
	if ( (a = LookA(b,OLA)) != NULL ) {
	  for ( ol=(OfferListTyp)LookAInfo(a); ol!=NULL; ol=MvNextOffer(ol) ){
	    if ( LookKindOffer(ol)==EXCLAMATION ) {
	      e = GetExprOffer( ol );
	      e = ClearExprVnD( e,TRUE );
	      PutExprOffer( ol, e );
	    }
	  }
	}
	b = NULL;
	break;
	
      case GateC: 
	UnshareA( b, PA );
	a = GetA( b, PA );
	if ( a != NULL ) {
	  p = (PredicateTyp)GetAInfo( a );
	  for (paux=p ; paux!=NULL ; paux=Next_list(paux)) {
	    pn = (PredNodeTyp)LookInfo_list(paux);
	    pn->rewritten = ShareE(ClearExprVnD(UnshareE(pn->rewritten),TRUE));
	    if (pn->original!=NULL) 
	      pn->original = ShareE(ClearExprVnD(UnshareE(pn->original),FALSE));
	  }
	  evalp = Evaluate(&p);
	  PutAInfo( a, (AttrValueTyp)p);
	  if ( evalp=='t' )
	    FreeA( a );
	  else if ( evalp=='f' ) {
	    FreeA( a );
	    TrfStop( b );
	  }
	  else 
	    PutA( b, a );
	}
	if ( LookTypeB(b)!=StopC ) {
	  /* PredToLOTOSPred ( b ); */
	  UnshareA( b, OLA );
	  if ( (a = LookA(b,OLA)) != NULL ) {
	    for ( ol=(OfferListTyp)LookAInfo(a); ol!=NULL;
		 ol=MvNextOffer(ol) ){
	      if ( LookKindOffer(ol)==EXCLAMATION ) {
		e = GetExprOffer( ol );
		e = ClearExprVnD( e,TRUE );
		PutExprOffer( ol, e );
	      }
	      else {
		list_var = Insert_list( (DataListTyp)LookNameE(LookExprOffer(ol)),
				       list_var
				       );
	      }
	    }
	  }
	}
	b = LookArgB( b, 1 );
	break;
	
      case IC:
	UnshareA( b, OLA );
	if ( (a = LookA(b,OLA)) != NULL ) {
	  for ( ol = (OfferListTyp)LookAInfo(a); ol!=NULL;
	       ol = MvNextOffer(ol) ){
	    e = GetExprOffer( ol );
	    e = ClearExprVnD( e,TRUE );
	    PutExprOffer( ol, e );
	  }
	}
	b = LookArgB( b, 1 );
	break;
	
      case RelabellingC:
      case GateChoiceC:
      case ParC:
      case HidingC:
	b = LookArgB( b, 1 );
	break;
	
      case StopC:
	b = NULL;
	break;
	
      case InterleavedC:
	TravBehPCP( LookArgB(b,1) );
	b = LookArgB(b,2);
	break;
	
      /* case ResumeSetC: */
      case ContSetC:
	if ( LookA(b,ITCLA)!=NULL ){
	  UnshareA( b, ITCLA );
	  itcl = (ITContListTyp)GetAInfo(a=LookA(b,ITCLA));
	  for ( itclres=Create_list(),itclh=itcl;
	       itcl!=NULL; itcl= Next_list(itcl) ) {
	    pit = (PITContTyp)GetInfo_list(itcl);
	    for ( lab=pit->label; lab!=NULL; lab=LookArgB(lab,1) )
	      InsertVarVL( lab );
	    TravBehPCP( LookBehITC(pit) );
	    if ( LookTypeB(pit->b)==StopC ){
	      FreeITC( pit );
	    }
	    else
	      itclres = Add_list((DataListTyp)pit, itclres );
	  }
	  Disp_list( itclh );
	  PutAInfo( a, (AttrValueTyp)itclres );
	}
	b = NULL;
	break;
	
      case TerminationC:
	UnshareA( b, ELA );
	if ( (a = LookA(b,ELA))!=NULL ) {
	  for ( el = (ExprListTyp)LookAInfo(a);el!=NULL ; el=Next_list(el) ) {
	    e = UnshareE((ExprTyp)GetInfo_list( el ));
	    e = ClearExprVnD( e,TRUE );
	    PutInfo_list( el, (DataListTyp)ShareE(e) );
	  }
	}
	b = NULL;
	break;
	
      default :
	Error("Post_Expan: PClearProc: Unexpected cell.");
      }
  }
}

/*----------------------------------------------------------------*/

/* PClearProc
 * PostProcess after the parameterized expansion.
 * The parameterized values replaces the undefined variables and 
 * the expressions are rewritten.
 * The duplicated processes are processed with PClearProc
 */
static void PClearProc( b )
     BehTyp b;
{
  list_var = Create_list();
  LASSERT(LookTypeB(b) == ProcessDefC);
  InsertVarVL( b );
  b = LookArgB( b, 1 );
  TravBehPCP( b );
  Disp_list( list_var );
}

/*----------------------------------------------------------------*/

/* PClearCSet
 * PostProcess after the parameterized expansion of a Continuation Set.
 * The parameterized values replaces the undefined variables and 
 * the expressions are rewritten.
 */
static void PClearCSet( b )
     BehTyp b;
{
  ITContListTyp     itcl,itclh,itclres;
  PITContTyp        pit;
  BehTyp            lab;
  PAttrTyp          a;
  
  LASSERT(LookTypeB(b) == ContSetC);
  
  if ( LookA(b,ITCLA)!=NULL ){
    UnshareA( b, ITCLA );
    itcl = (ITContListTyp)GetAInfo(a=LookA(b,ITCLA));
    for ( itclres=Create_list(),itclh=itcl;
	 itcl!=NULL; itcl= Next_list(itcl) ) {
      list_var = Create_list();
      pit = (PITContTyp)GetInfo_list(itcl);
      for ( lab=pit->label; lab!=NULL; lab=LookArgB(lab,1) )
	InsertVarVL( lab );
      TravBehPCP( LookBehITC(pit) );
      Disp_list( list_var );
      if ( LookTypeB(pit->b)==StopC ){
	FreeITC( pit );
      }
      else
	itclres = Add_list( (DataListTyp)pit, itclres );
    }
    Disp_list( itclh );
    PutAInfo( a, (AttrValueTyp)itclres );
  }
}

/*----------------------------------------------------------------*/

static void TravBehPCB( b )
     BehTyp b;
{
  int               i,n;
  PredicateTyp      p,paux;
  PredNodeTyp       pn;
  PAttrTyp          a;
  ExprTyp           e;
  VarAssignListTyp  val;
  OfferListTyp      ol;
  ExprListTyp       el;
  BehTyp            bi,def,beh;
  int               cero = 0;
  char              evalp;
  
  while ( b!=NULL ) {
    if ( VisitedB(b) )
      return;
    switch ( LookTypeB(b) )
      {
      case ParallelC:
	if ( LookA(b,BHT1A) ){
	  FreeA(GetA(b,BHT1A));
	}
	if ( LookA(b,BHT2A) ){
	  FreeA(GetA(b,BHT2A));
	}
      case DisablingC:
      case EnablingC:
	TravBehPCB( LookArgB(b,1) );
	b = LookArgB( b, 2 );
	break;
	
      case AlternativeC:
	n = NumArgB( b ); 
	for ( i=1; i<=n; i++ ) 
	  TravBehPCB( LookArgB(b,i) );
	b = Pre_Branch_Stop_RMP( b );
	b = NULL;
	break;
	
      case BehaviourC : 
	if ( LookB1(b)==NULL ) 
	  GlueArgB( b, 2 );
	else
	  GlueArgB( b, 1 );
	break;
	
      case GuardC:
	UnshareA( b, PA );
	a = LookA( b, PA );
	p = (PredicateTyp)GetAInfo( a );
	for (paux=p ; paux!=NULL ; paux=Next_list(paux)) {
	  pn = (PredNodeTyp)LookInfo_list(paux);
	  pn->rewritten = ShareE(ReplaceVarP(UnshareE(pn->rewritten),TRUE)); 
	  if (pn->original!=NULL) 
	    pn->original = ShareE(ReplaceVarP(UnshareE(pn->original),FALSE)); 
	}
	evalp = Evaluate(&p);
	PutAInfo( a, (AttrValueTyp)p );
	if (evalp=='t'){
	  UnVisitB( b );
	  GlueArgB( b, 1 );
	}
	else if ( evalp=='f' ) {
	  TrfStop( b );
	  b = NULL;
	}
	else {
	  bi = LookArgB( b, 1 );
	  TravBehPCB( bi );
	  if ( LookTypeB(bi)==StopC )
	    TrfStop( b );
	  b = NULL;
	}
	break;
	
      case ProcessInstC:
	if ( LookArgB(b,1)!=NULL ) {
	  (void) GetArgB(b,1);
	}
	def   = GetP_def(LookNameB(b));
	lproc = Add_IfNotIn_list( (DataListTyp)def, lproc, EqInt );
	UnshareA( b, ELA );
	if ( (a = LookA(b,ELA)) != NULL ) {
	  for ( el=(ExprListTyp)LookAInfo(a); el!=NULL; el=Next_list(el) ) {
	    e = UnshareE((ExprTyp)GetInfo_list( el ));
	    e = ReplaceVarP( e,TRUE );
	    PutInfo_list( el, (DataListTyp)ShareE(e) );
	  }
	}
	beh  = LookArgB( def, 1 );
	if ( LookTypeB(beh)==TerminationC ||
	    LookTypeB(beh)==ExitC ||
	    LookTypeB(beh)==StopC ){
	  expansion_flags = 0;
	  GlueB( b, Pre_Branch( b, &cero ) );
	}
	b = NULL;
	break;
	
      case PletC:
	UnshareA( b, VALA );
	if ( (a = LookA(b,VALA))!=NULL ) {
	  for ( val = (VarAssignListTyp)LookAInfo(a); val!=NULL;
	       val = Next_list(val)) {
	    e = GetExprVAL( val );
	    e = ReplaceVarP( e,TRUE );
	    PutExprVAL( val, e );
	  }
	}
	b = NULL;
	break;
	
      case LetC:
	UnshareA( b, VALA );
	if ( (a = LookA(b,VALA)) != NULL ) {
	  for ( val = (VarAssignListTyp)LookAInfo(a); val!=NULL;
	       val = Next_list(val) ) {
	    e = GetExprVAL( val );
	    e = ReplaceVarP( e,TRUE );
	    PutExprVAL( val, e );
	  }
	}
	b = LookArgB( b, 1 );
	break;
	
      case ExitC:
	UnshareA( b, OLA );
	if ( (a = LookA(b,OLA)) != NULL ) {
	  for ( ol=(OfferListTyp)LookAInfo(a); ol!=NULL; ol=MvNextOffer(ol) ) {
	    if ( LookKindOffer(ol)==EXCLAMATION ) {
	      e = GetExprOffer( ol );
	      e = ReplaceVarP( e,TRUE );
	      PutExprOffer( ol, e );
	    }
	  }
	}
	b = NULL;
	break;
	
      case GateC: 
	UnshareA( b, PA );
	a = GetA( b, PA );
	if ( a!=NULL ) {
	  p = (PredicateTyp)GetAInfo( a );
	  for (paux=p ; paux!=NULL ; paux=Next_list(paux)) {
	    pn = (PredNodeTyp)LookInfo_list(paux);
	    pn->rewritten = ShareE(ReplaceVarP(UnshareE(pn->rewritten),TRUE));
	    if (pn->original!=NULL) 
	      pn->original = ShareE(ReplaceVarP(UnshareE(pn->original),FALSE));
	  }
	  evalp = Evaluate(&p);
	  PutAInfo( a, (AttrValueTyp)p);
	  if ( evalp=='t' )
	    FreeA( a );
	  else if ( evalp=='f' ) {
	    FreeA( a );
	    TrfStop( b );
	  }
	  else 
	    PutA( b, a );
	}
	if ( LookTypeB(b)!=StopC ) {
	  UnshareA( b, OLA );
	  if ( (a = LookA(b,OLA)) != NULL ) {
	    for ( ol=(OfferListTyp)LookAInfo(a); ol!=NULL;
		 ol=MvNextOffer(ol) ){
	      if ( LookKindOffer(ol)==EXCLAMATION ) {
		e = GetExprOffer( ol );
		e = ReplaceVarP( e,TRUE );
		PutExprOffer( ol, e );
	      }
	    }
	  }
	}
	b = LookArgB(b,1);
	break;
	
      case IC:
	UnshareA( b, OLA );
	if ( (a = LookA(b,OLA)) != NULL ) {
	  for ( ol=(OfferListTyp)LookAInfo(a); ol!=NULL;
	       ol=MvNextOffer(ol) ){
	    e = GetExprOffer( ol );
	    e = ReplaceVarP( e,TRUE );
	    PutExprOffer( ol, e );
	  }
	}
	b = LookArgB(b,1);
	break;
	
      case ChoiceC:
	bi = LookArgB( b, 1 );
	TravBehPCB( bi );
	if ( LookTypeB(bi)==StopC )
	  TrfStop( b );
	b = NULL;
	break;
	
      case RelabellingC:
      case GateChoiceC:
      case ParC:
      case HidingC:
	b = LookArgB( b, 1 );
	break;
	
      case StopC:
	b = NULL;
	break;
	
      case InterleavedC:
	TravBehPCB( LookArgB(b,1) );
	b = LookArgB(b,2);
	break;
	
      case TerminationC:
	UnshareA( b, ELA );
	if ( (a = LookA(b,ELA))!=NULL ) {
	  for ( el = (ExprListTyp)LookAInfo(a);el!=NULL ; el=Next_list(el) ) {
	    e = UnshareE((ExprTyp)GetInfo_list( el ));
	    e = ReplaceVarP( e,TRUE );
	    PutInfo_list( el, (DataListTyp)ShareE(e) );
	  }
	}
	b = NULL;
	break;
	
      case ContSetC:
	csl = Insert_list( (DataListTyp)b, csl );
	b = NULL;
	break;
	
	
      default:
	Error("PClearBeh: Unexpected cell.");
      }
  }
}

/*----------------------------------------------------------------*/

/* PClearBeh
 * PostProcess after the parameterized expansion.
 * The parameterization is removed and the expressions are rewritten.
 * The duplicated process are processed with PClearProc
 */
void PClearBeh( b, lastproc )
     BehTyp        b;
     DescriptorTyp lastproc;
{
  DescriptorTyp i;
  BehTyp        p, d;
  
  Begin_VisitB();
  lproc = Create_list();
  csl   = Create_list();
  TravBehPCB( b );
  End_VisitB();
  for ( i=lastproc+1; i<=LastTableP(); i++ ) {
    Begin_VisitB();
    PClearProc( GetP_def(i) );
    End_VisitB();
  }
  
  for ( ; csl!=NULL; csl = Next_list(csl) ){
    Begin_VisitB();
    PClearCSet( (BehTyp)LookInfo_list(csl) );
    End_VisitB();
  }
  Disp_list(csl);
  
  for ( i=lastproc+1; i<=LastTableP(); i++ ) 
    if ( In_list((DataListTyp)(d=GetP_def(i)),lproc,EqInt)==FALSE ) {
      FreeAS( d );
      p = GetArgB( d, 1 );
      TrfStop( p );
      PutArgB( d, p, 1 );
    }
  Disp_list( lproc );
  
}


/*----------------------------------------------------------------*/


