/****************************************************************************
**
*A  immediate_descendant.c      ANUPQ source                   Eamonn O'Brien
**
*Y  Copyright 1995-2001,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
*Y  Copyright 1995-2001,  School of Mathematical Sciences, ANU,     Australia
**
*/

#include "pq_defs.h"
#include "pcp_vars.h"
#include "pga_vars.h"
#include "exp_vars.h"
#include "constants.h"
#include "pq_functions.h"

/* if immediate descendant is capable or terminal flag
   is set, save its covering group to descendant_file and
   compute required central automorphisms */

int ***immediate_descendant(FILE *descendant_file,
                            struct pga_vars *pga,
                            struct pcp_vars *pcp)
{
   register int *y = y_address;

   int ***central;
   int **auts;
   struct exp_vars exp_flag;

   /* compute the p-covering group of the descendant */

   /* if metabelian law is to be enforced, set pcp flag true */
   if (pga->metabelian)
      pcp->metabelian = TRUE;

   pcp->multiplicator = TRUE;
   next_class(FALSE, auts, auts, pcp);
   if (pcp->overflow)
      exit(FAILURE);
   pcp->multiplicator = FALSE;

   /* enforce an exponent law, if any */
   if (pga->exponent_law) {
      pcp->extra_relations = pga->exponent_law;
      initialise_exponent(&exp_flag, pcp);
      extra_relations(&exp_flag, pcp);
      eliminate(0, pcp);
   }

   pga->capable = (pcp->newgen != 0);

   /* pga->capable = FALSE;
   pga->terminal = FALSE;
   */

   pcp->multiplicator_rank = pcp->lastg - y[pcp->clend + pcp->cc - 1];

   /* possible that nucleus is trivial but presentation
      for p-covering group present */
   if (pga->terminal && pcp->newgen == 0 && pcp->complete == FALSE) {
      last_class(pcp);
      pcp->complete = TRUE;
   }

   /*
      if (pga->trace || (pga->capable && pga->print_automorphisms
                         && pga->final_stage && !pga->print_group)) {
         printf ("------------------------------------------\n");
         printf ("Immediate descendant %s\n", pcp->ident);
      }
   */

   if (pga->print_nuclear_rank)
      printf("Group %s has nuclear rank %d\n", pcp->ident, pcp->newgen);

   if (pga->print_multiplicator_rank)
      printf("Group %s has %d-multiplicator rank %d\n",
             pcp->ident,
             pcp->p,
             pcp->lastg - y[pcp->clend + pcp->cc - 1]);

   /* if descendant is capable or terminal is true,
      compute central automorphisms */
   if (pga->capable || pga->terminal) {
      /* save group description to file -- if group is capable, save
         p-covering group presentation, else save that of group */
      save_pcp(descendant_file, pcp);

      set_values(pga, pcp);

      /* revert to last class for automorphism group calculations */
      if (!pcp->complete)
         last_class(pcp);

      /* determine the required central outer automorphisms */
      central = central_automorphisms(pga, pcp);
      if (pga->print_automorphisms)
         print_auts(pga->nmr_centrals, pga->ndgen, central, pcp);
   }

   return central;
}
