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

/***********************************
  
  David Larrabeiti Lopez
  
  24-02-91
  
  
  Hide_Expand
  
  Hiding operator one-level expansion.
  
  hide GSet in b
  
  where b is any behaviour.
  
  COMPILATION OPTIONS: The behaviour of this module can be modified
  by the following compilation flags:
  
  (none)
  
  ************************************/

#include "limisc.h"
#include "licell.h"
#include "badefca.h"
#include "balotosf.h"
#include "baattr.h"
#include "expre_br.h"
#include "eximmed.h"
#include "exsucces.h"

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

static BehTyp MkChoice( ol )
     OfferListTyp ol;
{
  BehTyp choice;
  ExprListTyp el;
  
  el = Create_list();
  for ( ; ol!=NULL; ol=MvNextOffer(ol) )
    if ( LookKindOffer(ol)==QUESTION )
      el = AddEL( CopyE(LookExprOffer(ol)), el );  /*mse*/
  
  choice = MakeB( 0, ChoiceC );
  PutA( choice, MakeA( (AttrValueTyp)el, ELA ) );
  FreeOL( ol );
  
  return choice;
}

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

static BehTyp H_E( b , gs, i_rm_depth )
     BehTyp     b;
     GateSetTyp gs;
     int        *i_rm_depth;
{
  BehTyp           out,hide,hide2,choice,guard,iact,bi;
  PAttrTyp         ola,gsa,rfla,sla,sta;
  GateSetTyp       gs2,gs2bk,dif,inter;
  OfferListTyp     ol;
  RelabFuncListTyp rfl;
  int              numArg,i;
#ifdef TIME 
  PAttrTyp   ta;
#endif 

  switch ( LookTypeB(b) )
    { case GateC:
	choice = NULL;
	guard  = NULL;
	hide   = MakeB( 0, HidingC );
	PutA( hide, MakeA( (AttrValueTyp)CopyGS(gs), GSA ) );
	if ( GateInGS( LookNameB(b), gs ) ) {
	  bi   = GetArgB( b, 1 );
	  if ( IS_WEAK_EQUIV_EXP )
	    iact = MakeB( 0 , IC );
	  else
	    iact = MakeB( LookNameB(b) , IC );
#ifdef TIME 
	  if ( LookA(b,TA)!=NULL ){
	    ta =  CopyA( LookA(b,TA));
	    PutA( iact, ta );
	  }
#endif 
	  if ( LookA(b,OLA)!=NULL ) {
	    ola = CopyA( LookA(b,OLA) );
	    ol  = (OfferListTyp)LookAInfo( ola );
	    if ( IsThereQuestionOL(ol) )
	      choice = MkChoice( ol );
	    if ( IS_WEAK_EQUIV_EXP )
	      FreeA( ola );
	    else {
	      Convert_to_AdmirationOL((OfferListTyp)LookAInfo(ola));
	      PutA( iact, ola );
	    }
	  }
	  
	  if ( LookA(b,PA)!=NULL ) {
	    guard = MakeB( 0, GuardC );   /*mse*/
	    PutA(guard,GetA( b, PA ));
	  }
	  
	  if ( IS_STEP_EXP ) {
	    if ( (sla = LookA(b,SSLA))!=NULL ) {
	      PutA( iact, sla );
	    }
	    if ( (sta = LookA(b,STA))!=NULL ) {
	      PutA( iact, sta );
	    }
	  }
	  
	  out = ConcatUB(ConcatUB(ConcatUB(ConcatUB(
						    choice,
						    guard),
					   iact),
				  hide),
			 bi);
	  FreeB( b );
	}
	else {
	  bi = GetArgB( b, 1 );
	  PutArgB( b, hide, 1 );
	  PutArgB( hide, bi, 1 );
	  out = b;
	}
	break;
	
      case IC:
	hide = MakeB( 0, HidingC );
	PutA( hide, MakeA( (AttrValueTyp)CopyGS(gs), GSA ) );
	bi = GetArgB( b, 1 );
	PutArgB( b, hide, 1 );
	PutArgB( hide, bi, 1 );
	out = b;
	break;
	
      case AlternativeC:
	numArg = NumArgB(b);
	for ( i=1; i<=numArg; i++ )
	  PutArgB( b, H_E( GetArgB( b, i ), gs, i_rm_depth ), i );
	out = b;
	break;
	
      case ExitC:
      case StopC:
	out = b;
	break;
	
      case GuardC:
      case ChoiceC:
	PutArgB( b, H_E( GetArgB( b, 1 ), gs, i_rm_depth ), 1 );
	out = b;
	break;
	
      case HidingC:
	UnshareA( b, GSA );
	gsa = GetA( b, GSA );
	gs2 = (GateSetTyp)GetAInfo( gsa );
	gs2 = JunctionGS( gs, gs2bk=gs2 );
	PutAInfo( gsa, (AttrValueTyp)gs2 );
	PutA( b, gsa );
	FreeGS( gs2bk );
	out = Hide_Expand( b, i_rm_depth );
	break;
	
      case RelabellingC:
	UnshareA( b, RFLA );
	rfla  = LookA( b, RFLA );
	rfl   = (RelabFuncListTyp)GetAInfo( rfla );
	/*
	   rng   = RangeRFL( rfl );
	   dif   = DiffGS( gs, rng );
	   img   = ImageRFL(rfl);
	   inter = IntersGS( img, gs );
	   inv   = InvApplyRFL( rfl, inter );
	   gs2   = JunctionGS( dif, inv );
	   FreeGS( rng );
	   FreeGS( dif );
	   FreeGS( img );
	   FreeGS( inter );
	   FreeGS( inv );
	   */
	gs2 = InvApplyRFL( rfl, gs );
	
	rfl = SimplifyRFL( rfl, gs2 );
	PutAInfo( rfla, (AttrValueTyp)rfl );
	bi = GetArgB(b,1);
	if ( rfl == NULL ) {  /* => gs2 not empty */
	  FreeB(b);
	  out = H_E( bi, gs2, i_rm_depth );
	}
	else {
	  if ( !IsEmptyGS(gs2) )
	    if (IS_TEST_EQUIV_EXP) {
	      RelabUpdateSuccessStack(rfl);
	      PutArgB( b, H_E( bi, gs2, i_rm_depth ), 1 );
	      PopSuccessStack();
	    }
	    else
	      PutArgB( b, H_E( bi, gs2, i_rm_depth ), 1 );
	  else
	    AddArgB( b, bi );
	  out = b;
	}
	FreeGS(gs2);
	break;
	
      case ParallelC:
	if ( IS_WEAK_EQUIV_EXP && LookNameB(b)!=FULL_SYNC ) {
	  if ( LookNameB(b)==INTER_SYNC ) {
	    dif   = CopyGS(gs);
	    inter = NewGS();
	  }
	  else {
	    gs2   = (GateSetTyp)LookAInfo(LookA(b,GSA));
	    dif   = DiffGS( gs, gs2 );
	    inter = IntersGS( gs, gs2 );
	  }
	  if ( !IsEmptyGS( dif ) ){
	    b    = GetOperB(b);
	    hide = MakeB( 0, HidingC );
	    PutA( hide, MakeA((AttrValueTyp)dif,GSA) );
	    hide2 = CopyB( hide );
	    bi = GetArgB( b, 1 );
	    PutArgB( b, hide, 1 );
	    AddArgB( hide, bi );
	    bi = GetArgB( b, 2 );
	    PutArgB( b, hide2, 2 );
	    AddArgB( hide2, bi );
	  }
	  else
	    FreeGS(dif);
	}
	else
	  inter = CopyGS(gs);
	
	if (IS_SHARED_EXP){
	  Pre_Processing_2( b, i_rm_depth );
	}
	else {
	  if (IS_TEST_EQUIV_EXP) {
	    HideUpdateSuccessStack(inter);
	    b = Pre_Processing( b, i_rm_depth );
            PopSuccessStack();
	  }
	  else
	    b = Pre_Processing( b, i_rm_depth );
	}
	if ( !IsEmptyGS(inter) )
	  out = H_E( b, inter, i_rm_depth );
	else
	  out = b;
	FreeGS( inter );
	break;
	
	
      case DisablingC:
      case EnablingC:
	if ( IS_WEAK_EQUIV_EXP ) {     /* hide A in B1>>B2 = (hide A in B1)  */
	  LASSERT(!IsEmptyGS(gs));     /*                    >> hide A in B2 */
	  gs2  = CopyGS(gs);
	  b    = GetOperB(b);
	  hide = MakeB( 0, HidingC );
	  PutA( hide, MakeA((AttrValueTyp)gs2,GSA) );
	  hide2 = CopyB( hide );
	  bi = GetArgB( b, 1 );
	  PutArgB( b, hide, 1 );
	  AddArgB( hide, bi );
	  bi = GetArgB( b, 2 );
	  PutArgB( b, hide2, 2 );
	  AddArgB( hide2, bi );
	  if (IS_SHARED_EXP){
	    Pre_Processing_2( b, i_rm_depth );
	    out = b;
	  }
	  else
	    if (IS_TEST_EQUIV_EXP) {
	      HideUpdateSuccessStack(gs);
	      out = Pre_Processing( b, i_rm_depth );
	      PopSuccessStack();
	    }
	    else
	      out = Pre_Processing( b, i_rm_depth );
	  break;
	}
	/* else 
	   go on .... */
	
      default:
	if (IS_SHARED_EXP){
	  Pre_Processing_2( b, i_rm_depth );
	  out = H_E( b , gs, i_rm_depth );
	}
	else
	  if (IS_TEST_EQUIV_EXP) {
	    HideUpdateSuccessStack(gs);
	    out = H_E( Pre_Processing( b, i_rm_depth ), gs, i_rm_depth );
            PopSuccessStack();
	  }
	  else
	    out = H_E( Pre_Processing( b, i_rm_depth ), gs, i_rm_depth );
	break;
      }
  return out;
}

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

/* Hide_Expand
 * Processing of the Hiding operator hide.
 *
 *     hide = hide GSet in b
 *
 * where b is any behaviour.
 */
BehTyp Hide_Expand( hide, i_rm_depth )
     BehTyp hide;
     int    *i_rm_depth;
{
  BehTyp out;
  GateSetTyp gs;
  
  LASSERT( LookTypeB(hide)==HidingC );
  
  gs  = (GateSetTyp)LookAInfo( LookA( hide, GSA ) );
  out = H_E( GetArgB( hide, 1 ), gs, i_rm_depth );
  FreeB( hide );
  
  return out;
  
}

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