/***********************************
  (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************
 $Log: ecuaciones.c,v $
 * Revision 1.9  1993/01/18  18:12:15  lotos
 * distribution issues
 *
 * Revision 1.8  1992/10/14  17:43:44  lotos
 * forget about ophuscation
 *
 * Revision 1.7  1992/09/02  15:44:55  lotos
 * new option to remove externa annotations
 * new option to print and label the equations
 * new debugging options: save modified CAST
 * overall debugging and improvements
 *
 * Revision 1.6  92/05/06  18:50:47  lotos
 * no se
 * 
 * Revision 1.5  92/01/14  15:25:20  lotos
 * distribution issues
 * 
 * Revision 1.4  92/01/13  19:24:50  lotos
 * adaptec to ophuscate
 * 
 * Revision 1.3  91/11/20  13:17:25  lotos
 * parse attribute added
 * 
 * Revision 1.2  91/10/02  16:49:40  lotos
 * color sort is now in the AT
 * 
 * Revision 1.1  91/02/06  20:15:43  lotos
 * Initial revision
 * 
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: ecuaciones.c,v 1.9 1993/01/18 18:12:15 lotos Exp $";
#endif

/***********************************************************************

     "ecuaciones.o": modulo para el manejo de ecuaciones en el AST.

***********************************************************************/

#include <stdio.h>
#include "idle.h"
#include "tabop.h"
#include "LDM.h"
#include "ecuaciones.h"


TNODE *OpRaizMEc(NodoRaizMEc)
/* Devuelve un puntero a la operacion raiz de un miembro de una ec. */
TNODE *NodoRaizMEc;	/* Puntero al nodo raiz del miembro. */
{
  aborta_si(NodoRaizMEc == NULL ||
	    NodoRaizMEc->type != tvalue_expression ||
	    gt_ft(NodoRaizMEc)->type != tsimple_equation)
  return NodoRaizMEc;
}

int NumArgOp(IdOp)
/* Devuelve el numero de argumentos de una operacion. */
TNODE *IdOp;	/* Puntero al nodo con la operacion. */
{ TNODE *p;
  int i;

  aborta_si(NoEstaEnEc(IdOp))
  for (p= gt_fs(IdOp), i= 0; p != NULL; p= gt_rb(p), ++i)
    ;
  return i;
}

TNODE *PrimArgOp(IdOp)
/* Devuelve un puntero al primer argumento de una operacion. */
TNODE *IdOp;	/* Puntero al nodo con la operacion. */
{
  aborta_si(NoEstaEnEc(IdOp))
  return gt_fs(IdOp);
}

TNODE *UltArgOp(IdOp)
/* Devuelve un puntero al ultimo argumento de una operacin. */
TNODE *IdOp;	/* Puntero al nodo con la operacion. */
{
  aborta_si(NoEstaEnEc(IdOp))
  return gt_ls(IdOp);
}

TNODE *SigArgOp(IdArg)
/* Devuelve un puntero al siguiente argumento de una operacion. */
TNODE *IdArg;	/* Puntero al nodo con el argumento de referencia. */
{
  aborta_si(NoEstaEnEc(IdArg))
  if (gt_ft(IdArg)->type == tsimple_equation)
    return NULL;
  else
    return gt_rb(IdArg);
}

TNODE *AntArgOp(IdArg)
/* Devuelve un puntero al anterior argumento de una operacion. */
TNODE *IdArg;	/* Puntero al nodo con el argumento de referencia. */
{
  aborta_si(NoEstaEnEc(IdArg))
  if (gt_ft(IdArg)->type == tsimple_equation)
    return NULL;
  else
    return gt_lb(IdArg);
}

TNODE *OpArg(IdArg)
/* Devuelve un puntero a la operacion con el argumento indicado. */
TNODE *IdArg;	/* Puntero al nodo con el argumento. */
{ TNODE *p;

  aborta_si(NoEstaEnEc(IdArg))
  p= gt_ft(IdArg);
  if (p->type == tsimple_equation)
    return NULL;
  else
    return p;
}

TNODE *RaizExp(OpRaiz)
/* Devuelve el nodo raiz de una expresion. */
TNODE *OpRaiz;	/* Puntero a la operacion raiz de la expresion. */
{
  aborta_si(NoEstaEnEc(OpRaiz))
  return OpRaiz;
}

TNODE *CreaIdVar(IdOp)
/* Crea un nodo identificador de variable a partir de una operacion. */
TNODE *IdOp;	/* Puntero a un nodo con la operacion. */
{ TNODE *IdVar;
  static int m= -1;
  int n;

  aborta_si(NoEstaEnEc(IdOp) ||
	    idclass(idref(IdOp)) != opn_id)
  IdVar= new_node(tvalue_expression);
  if (m < 0)
  { m= STadd(NEW_VARIABLE_IDENTIFIER, stbl_ptr(LL), TRUE);
    aborta_si(m < 0)
  }
  n= ATinc(stbl_ptr(AT));
  RegIdTab();
  aborta_si(UltIdTab() != n)
  add_grn(IdVar, 0);
  add_class(IdVar, 0);
  add_line(IdVar, ask_line(IdOp));
  add_idref(IdVar, n);
  add_idclass(n, value_id);
  add_lexv(n, m);
  add_sort(n, sort(idref(IdOp)));
  add_ui(n, 0);
  return IdVar;
}

void ModIdVar(IdVar)
/* Modifica un nodo identificador de variable para que esta sea otra. */
TNODE *IdVar;	/* Puntero a un nodo con la variable. */
{ int n;

  aborta_si(NoEstaEnEc(IdVar) ||
	    idclass(idref(IdVar)) != value_id)
  n= ATcp(stbl_ptr(AT), idref(IdVar), TRUE);
  RegIdTab();
  aborta_si(UltIdTab() != n)
  del_idref(IdVar);
  add_idref(IdVar, n);
  del_ui(n);
  add_ui(n, 0);
}

TNODE *CreaExpVar(IdVar)
/* Crea una expresion con una variable. */
TNODE *IdVar;		/* Puntero al nodo con la variable. */
{
  aborta_si(IdVar == NULL ||
	    IdVar->type != tvalue_expression ||
	    idclass(idref(IdVar)) != value_id ||
	    !t_root(IdVar) ||
	    !t_brother(IdVar))
  return IdVar;
}

TNODE *SustExp(ExpOrig, ExpSust)
/* Sustituye una expresion dentro de una ecuacion por otra. */
TNODE *ExpOrig;		/* Puntero a la expresion original. */
TNODE *ExpSust;		/* Puntero a la expresion sustituta. */
{
  aborta_si(NoEsExp(ExpOrig) ||
	    t_root(ExpOrig))
  aborta_si(NoEsExp(ExpSust) ||
	    !t_root(ExpSust) ||
	    !t_brother(ExpSust))
  ln_rb(ExpOrig, ExpSust);
  cut_tree(ExpOrig);
  return ExpOrig;
}

static TNODE *CreaMiemEc(Exp)
/* Crea un miembro de una ecuacion a partir de una expresion. */
TNODE *Exp;		/* Puntero la expresion. */
{
  aborta_si(NoEsExp(Exp) ||
	    !t_root(Exp) ||
	    !t_brother(Exp))
  return Exp;
}

TNODE *CreaPrem(MiemIz, MiemDcho)
/* Crea una premisa a partir de sus miembros. */
TNODE *MiemIz;		/* Puntero la raiz del miembro izquierdo. */
TNODE *MiemDcho;	/* Puntero la raiz del miembro derecho. */
{ TNODE *Prem;

  aborta_si(NoEsExp(MiemIz) ||
	    !t_root(MiemIz) ||
	    !t_brother(MiemIz))
  aborta_si(NoEsExp(MiemDcho) ||
	    !t_root(MiemDcho) ||
	    !t_brother(MiemDcho))
  Prem= new_node(tsimple_equation);
  MiemIz= CreaMiemEc(MiemIz);
  MiemDcho= CreaMiemEc(MiemDcho);
  (void) lnsons(Prem, MiemIz);
  lnrnode(MiemIz, MiemDcho);
  return Prem;
}

static void _InsLisPremEc(NodoRaizPrem, PrimPrem)
/* Inserta una lista de premisas en una ecuacion (en primer lugar). */
TNODE *NodoRaizPrem;	/* Puntero al nodo raiz de las premisas. */
TNODE *PrimPrem;	/* Puntero a la primera premisa de la lista. */
{ TNODE *SegPrem;	/* Puntero a la segunda premisa de la lista. */

  aborta_si(NodoRaizPrem == NULL ||
	    NodoRaizPrem->type != tpremisses ||
	    PrimPrem == NULL ||
	    PrimPrem->type != tsimple_equation ||
	    !t_root(PrimPrem))
  SegPrem= gt_rb(PrimPrem);
  if (SegPrem != NULL)
    _InsLisPremEc(NodoRaizPrem, SegPrem);
  (void) lnnson(NodoRaizPrem, PrimPrem, 1);
}

void InsLisPremEc(NodoRaizEc, LisPrem)
/* Inserta una lista de premisas en una ecuacion (en primer lugar). */
TNODE *NodoRaizEc;	/* Puntero al nodo raiz de la ecuacion. */
TNODE *LisPrem;		/* Lista de premisas a insertar. */
{ TNODE *NodoRaizPrem;	/* Puntero al nodo raiz de las premisas. */

  aborta_si(NodoRaizEc == NULL ||
	    NodoRaizEc->type != tequation ||
	    LisPrem == NULL)
  NodoRaizPrem= gt_fs(NodoRaizEc);
  if (NodoRaizPrem->type != tpremisses)
  { /* Se anade un nodo <premisses>. */
    NodoRaizPrem= new_node(tpremisses);
    (void) lnnson(NodoRaizEc, NodoRaizPrem, 1);
  }
  _InsLisPremEc(NodoRaizPrem, LisPrem);
}
