/**************************************************************
 *       rlbset.c - LBM Interpreter Relabeling Manipulation
 **************************************************************/
/***********************************************
 (C) Copyright 1993-1994; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************************
 $Log: rlbset.c,v $
 * Revision 1.3  1994/10/17  16:41:21  lotos
 * cosmetics
 *
 * Revision 1.2  1993/12/22  17:20:13  lotos
 * Changed a number of names in the interface
 * Added function  to work with instances of processes and their gates
 * CLOSING BASIC LOTOS VERSION OF LIBRARY!
 *
 * Revision 1.1  1993/10/16  10:52:13  lotos
 * Initial revision
 *
 **********************************************
 $Id: rlbset.c,v 1.3 1994/10/17 16:41:21 lotos Exp $
 **********************************************/

#include "swbus.h"

PUBLIC rlbset*
create_rlbset (actual, formal)
  gtelist actual;
  gtelist formal;
{
  rlbset *rlb;

  rlb = new_rlbset ();

  rlb->actual = INTdup (actual);
  rlb->formal = INTdup (formal);

  return rlb;
}

/* This function frees its arguments.
 * If you want them, pass a copy of them
 */
PUBLIC rlbset*
simp_relabel (fth, son)
  rlbset *fth;
  rlbset *son;
{
  int     pos;
  gtelist act = NULL;
  gtelist form = NULL;
  gtelist actson = NULL;
  gtelist actual = NULL;
  gtelist formal = NULL;
  rlbset *rlb = NULL;

  /* I'll try to explain this function. It takes two set of
   * relabelings, which will be concatenated. The first set
   * is called "fth" (older). The second is "son" (newer).
   * They represent the case of
   *            B = [a/m, b/n] [m/j n/k n/l] B1
   * The result will be
   *               B = [a/j b/k b/l] B1
   * In this case,
   *        fth->actual = {a, b}     son->actual = {m, n, n}
   *        fth->formal = {m, n}     son->formal = {j, k, l}
   * the result expected is
   *        actual = {a, b, b}  formal = {j, k, l}
   * Is this explanation enough ?
   */

  if ((fth == NULL) && (son == NULL))
    return NULL;
  if (fth == NULL)
    return son;
  if (son == NULL)
    return fth;

  for (act = fth->actual, form = fth->formal;
       act != NULL;
       act = INTtail (act), form = INTtail (form))
    if (INTIsIn (INThead (form), son->actual)) {
      /* gate is relabeled twice */
      for (actson = son->actual, pos = 1;
	   actson != NULL;
	   actson = INTtail (actson), pos++)
	if (INThead (form) == INThead (actson)) {
	  actual = INTcons (INThead (act), actual);
	  formal = INTcons (INTnth (pos, son->formal), formal);
	}
    }
    else { /* gate is no re-relabeled */
      actual = INTcons (INThead (act),  actual);
      formal = INTcons (INThead (form), formal);
    }
  rlb = create_rlbset (INTrev (actual), INTrev (formal));

  if (actual != NULL)
    fIL ((CLR_TYPE)actual);
  if (formal != NULL)
    fIL ((CLR_TYPE)formal);
  free_rlbset (fth);
  free_rlbset (son);

  return rlb;
}

PUBLIC rlbset*
rlbsetdup (rlb)
  rlbset *rlb;
{
  rlbset *aux;

  aux = new_rlbset ();

  aux->actual = INTdup (rlb->actual);
  aux->formal = INTdup (rlb->formal);
  return aux;
}

PUBLIC void
fdraw_rlbset (fp, S, rlb)
  FILE   *fp;
  spe    S;
  rlbset *rlb;
{
  fdraw_gatelist (fp, S, rlb->actual);
  fdraw_gatelist (fp, S, rlb->formal);
}

PUBLIC void
draw_rlbset (S, rlb)
  spe    S;
  rlbset *rlb;
{
  fdraw_rlbset (stdout, S, rlb);
}
