/* Miscellaneous MOID routines.
   Copyright (C) 2001-2023 J. Marcel van der Veer.
   Copyright (C) 2025 Jose E. Marchesi.

   Original implementation by J. Marcel van der Veer.
   Adapted for GCC by Jose E. Marchesi.

   GCC is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GCC is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   License for more details.

   You should have received a copy of the GNU General Public License
   along with GCC; see the file COPYING3.  If not see
   <http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "options.h"

#include "a68.h"

/*
 * MODE checker routines.
 */

/* Absorb nested series modes recursively.  */

void
a68_absorb_series_pack (MOID_T **p)
{
  bool siga;

  do
    {
      PACK_T *z = NO_PACK;

      siga = false;
      for (PACK_T *t = PACK (*p); t != NO_PACK; FORWARD (t))
	{
	  if (MOID (t) != NO_MOID && IS (MOID (t), SERIES_MODE))
	    {
	      siga = true;
	      for (PACK_T *s = PACK (MOID (t)); s != NO_PACK; FORWARD (s))
		a68_add_mode_to_pack (&z, MOID (s), NO_TEXT, NODE (s));
	    }
	  else
	    a68_add_mode_to_pack (&z, MOID (t), NO_TEXT, NODE (t));
	}
      PACK (*p) = z;
    }
  while (siga);
}

/* Make SERIES (u, v).  */

MOID_T *
a68_make_series_from_moids (MOID_T *u, MOID_T *v)
{
  MOID_T *x = a68_new_moid ();

  ATTRIBUTE (x) = SERIES_MODE;
  a68_add_mode_to_pack (&(PACK (x)), u, NO_TEXT, NODE (u));
  a68_add_mode_to_pack (&(PACK (x)), v, NO_TEXT, NODE (v));
  a68_absorb_series_pack (&x);
  DIM (x) = a68_count_pack_members (PACK (x));
  (void) a68_register_extra_mode (&TOP_MOID (&A68_JOB), x);
  if (DIM (x) == 1)
    return MOID (PACK (x));
  else
    return x;
}

/* Absorb firmly related unions in mode.

   For instance invalid UNION (PROC REF UNION (A, B), A, B) -> valid
   UNION (A, B), which is used in balancing conformity clauses.  */

MOID_T *
a68_absorb_related_subsets (MOID_T * m)
{
  /* For instance invalid UNION (PROC REF UNION (A, B), A, B) -> valid UNION
     (A, B), which is used in balancing conformity clauses.  */
  bool siga;

  do
    {
      PACK_T *u = NO_PACK;

      siga = false;
      for (PACK_T *v = PACK (m); v != NO_PACK; FORWARD (v))
	{
	  MOID_T *n = a68_depref_completely (MOID (v));

	  if (IS (n, UNION_SYMBOL) && a68_is_subset (n, m, SAFE_DEFLEXING))
	    {
	      /*  Unpack it.  */
	      for (PACK_T *w = PACK (n); w != NO_PACK; FORWARD (w))
		a68_add_mode_to_pack (&u, MOID (w), NO_TEXT, NODE (w));
	      siga = true;
	    }
	  else
	    a68_add_mode_to_pack (&u, MOID (v), NO_TEXT, NODE (v));
	}
      PACK (m) = a68_absorb_union_pack (u);
    }
  while (siga);
  return m;
}

/* Absorb nested series and united modes recursively.  */

void
a68_absorb_series_union_pack (MOID_T **p)
{
  bool siga;

  do
    {
      PACK_T *z = NO_PACK;

      siga = false;
      for (PACK_T *t = PACK (*p); t != NO_PACK; FORWARD (t))
	{
	  if (MOID (t) != NO_MOID && (IS (MOID (t), SERIES_MODE) || IS (MOID (t), UNION_SYMBOL)))
	    {
	      siga = true;
	      for (PACK_T *s = PACK (MOID (t)); s != NO_PACK; FORWARD (s))
		a68_add_mode_to_pack (&z, MOID (s), NO_TEXT, NODE (s));
	    }
	  else
	    a68_add_mode_to_pack (&z, MOID (t), NO_TEXT, NODE (t));
	}
      PACK (*p) = z;
    }
  while (siga);
}

/* Make united mode, from mode that is a SERIES (..).  */

MOID_T *
a68_make_united_mode (MOID_T *m)
{
  if (m == NO_MOID)
    return M_ERROR;
  else if (ATTRIBUTE (m) != SERIES_MODE)
    return m;

  /* Do not unite a single UNION.  */
  if (DIM (m) == 1 && IS (MOID (PACK (m)), UNION_SYMBOL))
    return MOID (PACK (m));

  /* Straighten the series.  */
  a68_absorb_series_union_pack (&m);
  /* Copy the series into a UNION.  */
  MOID_T *u = a68_new_moid ();
  ATTRIBUTE (u) = UNION_SYMBOL;
  PACK (u) = NO_PACK;
  for (PACK_T *w = PACK (m); w != NO_PACK; FORWARD (w))
    a68_add_mode_to_pack (&(PACK (u)), MOID (w), NO_TEXT, NODE (m));

  /* Absorb and contract the new UNION.  */
  a68_absorb_series_union_pack (&u);
  DIM (u) = a68_count_pack_members (PACK (u));
  PACK (u) = a68_absorb_union_pack (PACK (u));
  a68_contract_union (u);
  DIM (u) = a68_count_pack_members (PACK (u));
  /* A UNION of one mode is that mode itself.  */
  if (DIM (u) == 1)
    return MOID (PACK (u));
  else
    return a68_register_extra_mode (&TOP_MOID (&A68_JOB), u);
}

/* Make SOID data structure.  */

void
a68_make_soid (SOID_T *s, int sort, MOID_T *type, int attribute)
{
  ATTRIBUTE (s) = attribute;
  SORT (s) = sort;
  MOID (s) = type;
  CAST (s) = false;
}

/* Whether mode is not well defined.  */

bool
a68_is_mode_isnt_well (MOID_T *p)
{
  if (p == NO_MOID)
    return true;
  else if (!A68_IF_MODE_IS_WELL (p))
    return true;
  else if (PACK (p) != NO_PACK)
    {
      for (PACK_T *q = PACK (p); q != NO_PACK; FORWARD (q))
	{
	  if (!A68_IF_MODE_IS_WELL (MOID (q)))
	    return true;
	}
    }
  return false;
}

/* Add SOID data to free chain.  */

void
a68_free_soid_list (SOID_T *root)
{
  if (root != NO_SOID)
    {
      SOID_T *q = root;

      for (; NEXT (q) != NO_SOID; FORWARD (q))
	;
      NEXT (q) = A68 (top_soid_list);
      A68 (top_soid_list) = root;
    }
}

/* Add SOID data structure to soid list.  */

void
a68_add_to_soid_list (SOID_T **root, NODE_T *where, SOID_T *soid)
{
  if (*root != NO_SOID)
    a68_add_to_soid_list (&(NEXT (*root)), where, soid);
  else
    {
      SOID_T *new_one;

      if (A68 (top_soid_list) == NO_SOID)
	new_one = (SOID_T *) ggc_cleared_alloc<SOID_T> ();
      else
	{
	  new_one = A68 (top_soid_list);
	  FORWARD (A68 (top_soid_list));
	}

      a68_make_soid (new_one, SORT (soid), MOID (soid), 0);
      NODE (new_one) = where;
      NEXT (new_one) = NO_SOID;
      *root = new_one;
    }
}

/* Pack soids in moid, gather resulting moids from terminators in a clause.  */

MOID_T *
a68_pack_soids_in_moid (SOID_T *top_sl, int attribute)
{
  MOID_T *x = a68_new_moid ();
  PACK_T *t, **p;

  ATTRIBUTE (x) = attribute;
  DIM (x) = 0;
  SUB (x) = NO_MOID;
  EQUIVALENT (x) = NO_MOID;
  SLICE (x) = NO_MOID;
  DEFLEXED (x) = NO_MOID;
  NAME (x) = NO_MOID;
  NEXT (x) = NO_MOID;
  PACK (x) = NO_PACK;
  p = &(PACK (x));
  for (; top_sl != NO_SOID; FORWARD (top_sl))
    {
      t = a68_new_pack ();
      MOID (t) = MOID (top_sl);
      TEXT (t) = NO_TEXT;
      NODE (t) = NODE (top_sl);
      NEXT (t) = NO_PACK;
      DIM (x)++;
      *p = t;
      p = &NEXT (t);
    }

  return a68_register_extra_mode (&TOP_MOID (&A68_JOB), x);
}

/* Whether P is compatible with Q.  */

bool
a68_is_equal_modes (MOID_T *p, MOID_T *q, int deflex)
{
  if (deflex == FORCE_DEFLEXING)
    return DEFLEX (p) == DEFLEX (q);
  else if (deflex == ALIAS_DEFLEXING)
    {
      if (IS (p, REF_SYMBOL) && IS (q, REF_SYMBOL))
	return (p == q
		|| a68_prove_moid_equivalence (p, q)
		|| a68_prove_moid_equivalence (DEFLEX (p), q)
		|| DEFLEX (p) == q);
      else if (!IS (p, REF_SYMBOL) && !IS (q, REF_SYMBOL))
	return (DEFLEX (p) == DEFLEX (q)
		|| a68_prove_moid_equivalence (DEFLEX (p), DEFLEX (q)));
  }
  else if (deflex == SAFE_DEFLEXING)
    {
      if (!IS (p, REF_SYMBOL) && !IS (q, REF_SYMBOL))
	return (DEFLEX (p) == DEFLEX (q)
		|| a68_prove_moid_equivalence (DEFLEX (p), DEFLEX (q)));
    }

  return (p == q || a68_prove_moid_equivalence (p, q));
}

/* Whether mode is deprefable, i.e. whether it can be either deferred or
   deprocedured.  */

bool
a68_is_deprefable (MOID_T *p)
{
  if (IS_REF (p))
    return true;
  else
    return (IS (p, PROC_SYMBOL) && PACK (p) == NO_PACK);
}

/* Deref or deproc the mode P once.  */

MOID_T *
a68_depref_once (MOID_T *p)
{
  if (IS_REF_FLEX (p))
    return SUB_SUB (p);
  else if (IS_REF (p))
    return SUB (p);
  else if (IS (p, PROC_SYMBOL) && PACK (p) == NO_PACK)
    return SUB (p);
  else
    return NO_MOID;
}

/* Depref mode completely.  */

MOID_T *
a68_depref_completely (MOID_T *p)
{
  while (a68_is_deprefable (p))
    p = a68_depref_once (p);
  return p;
}

/* Deproc_completely.  */

MOID_T *
a68_deproc_completely (MOID_T *p)
{
  while (IS (p, PROC_SYMBOL) && PACK (p) == NO_PACK)
    p = a68_depref_once (p);
  return p;
}

/* Depref rows.  */

MOID_T *
a68_depref_rows (MOID_T *p, MOID_T *q)
{
  if (q == M_ROWS)
    {
      while (a68_is_deprefable (p))
	p = a68_depref_once (p);
      return p;
    }
  else
    return q;
}

/* Derow mode, strip FLEX and BOUNDS.  */

MOID_T *
a68_derow (MOID_T *p)
{
  if (IS_ROW (p) || IS_FLEX (p))
    return a68_derow (SUB (p));
  else
    return p;
}

/* Whether rows type.  */

bool
a68_is_rows_type (MOID_T *p)
{
  switch (ATTRIBUTE (p))
    {
    case ROW_SYMBOL:
    case FLEX_SYMBOL:
      return true;
    case UNION_SYMBOL:
      {
	PACK_T *t = PACK (p);
	bool siga = true;
	while (t != NO_PACK && siga)
	  {
	    siga &= a68_is_rows_type (MOID (t));
	    FORWARD (t);
	  }
	return siga;
      }
    default:
      return false;
    }
}

/* Whether mode is PROC (REF FILE) VOID or FORMAT.  */

bool
a68_is_proc_ref_file_void_or_format (MOID_T *p)
{
  if (p == M_PROC_REF_FILE_VOID)
    return true;
  else if (p == M_FORMAT)
    return true;
  else
    return false;
}

/* Whether mode can be transput.  */

bool
a68_is_transput_mode (MOID_T *p, char rw)
{
  if (p == M_INT)
    return true;
  else if (p == M_SHORT_INT)
    return true;
  else if (p == M_SHORT_SHORT_INT)
    return true;
  else if (p == M_LONG_INT)
    return true;
  else if (p == M_LONG_LONG_INT)
    return true;
  else if (p == M_REAL)
    return true;
  else if (p == M_LONG_REAL)
    return true;
  else if (p == M_LONG_LONG_REAL)
    return true;
  else if (p == M_BOOL)
    return true;
  else if (p == M_CHAR)
    return true;
  else if (p == M_BITS)
    return true;
  else if (p == M_SHORT_BITS)
    return true;
  else if (p == M_SHORT_SHORT_BITS)
    return true;
  else if (p == M_LONG_BITS)
    return true;
  else if (p == M_LONG_LONG_BITS)
    return true;
  else if (p == M_COMPLEX)
    return true;
  else if (p == M_LONG_COMPLEX)
    return true;
  else if (p == M_LONG_LONG_COMPLEX)
    return true;
  else if (p == M_ROW_CHAR)
    return true;
  else if (p == M_STRING)
    return true;
  else if (IS (p, UNION_SYMBOL) || IS (p, STRUCT_SYMBOL))
    {
      for (PACK_T *q = PACK (p); q != NO_PACK; FORWARD (q))
	{
	  if (!(a68_is_transput_mode (MOID (q), rw)
		|| a68_is_proc_ref_file_void_or_format (MOID (q))))
	    return false;
	}
      return true;
    }
  else if (IS_FLEX (p))
    {
      if (SUB (p) == M_ROW_CHAR)
	return true;
      else
	return (rw == 'w' ? a68_is_transput_mode (SUB (p), rw) : false);
    }
  else if (IS_ROW (p))
    return (a68_is_transput_mode (SUB (p), rw)
	    || a68_is_proc_ref_file_void_or_format (SUB (p)));
  else
    return false;
}

/* Whether mode is printable.  */

bool
a68_is_printable_mode (MOID_T *p)
{
  if (a68_is_proc_ref_file_void_or_format (p))
    return true;
  else
    return a68_is_transput_mode (p, 'w');
}

/* Whether mode is readable.  */

bool
a68_is_readable_mode (MOID_T *p)
{
  if (a68_is_proc_ref_file_void_or_format (p))
    return true;
  else if (IS_REF (p))
    return a68_is_transput_mode (SUB (p), 'r');
  else if (IS_UNION (p))
    {
      for (PACK_T *q = PACK (p); q != NO_PACK; FORWARD (q))
	{
	  if (!IS_REF (MOID (q)))
	    return false;
	  else if (!a68_is_transput_mode (SUB (MOID (q)), 'r'))
	    return false;
	}
      return true;
    }
  else
    return false;
}

/* Whether name struct.  */

bool
a68_is_name_struct (MOID_T *p)
{
  return (NAME (p) != NO_MOID ? IS (DEFLEX (SUB (p)), STRUCT_SYMBOL) : false);
}

/* Yield mode to unite to.  */

MOID_T *
a68_unites_to (MOID_T *m, MOID_T *u)
{
  /* Uniting U (m).  */
  MOID_T *v = NO_MOID;

  if (u == M_SIMPLIN || u == M_SIMPLOUT)
    return m;

  for (PACK_T *p = PACK (u); p != NO_PACK; FORWARD (p))
    {
      /* Prefer []->[] over []->FLEX [].  */
      if (m == MOID (p))
	v = MOID (p);
      else if (v == NO_MOID && DEFLEX (m) == DEFLEX (MOID (p)))
	v = MOID (p);
    }
  return v;
}

/* Whether moid in pack.  */

bool
a68_is_moid_in_pack (MOID_T *u, PACK_T *v, int deflex)
{
  for (; v != NO_PACK; FORWARD (v))
    {
      if (a68_is_equal_modes (u, MOID (v), deflex))
	return true;
    }

  return false;
}

/* Whether a rows type in pack.  */

bool
a68_is_rows_in_pack (PACK_T *v)
{
  for (; v != NO_PACK; FORWARD (v))
    {
      if (a68_is_rows_type (MOID (v)))
	return true;
    }

  return false;
}

/* Whether P is a subset of Q.  */

bool
a68_is_subset (MOID_T *p, MOID_T *q, int deflex)
{
  bool j =true;

  for (PACK_T *u = PACK (p); u != NO_PACK && j; FORWARD (u))
    j = (j && a68_is_moid_in_pack (MOID (u), PACK (q), deflex));

  return j;
}

/* Whether P can be united to UNION Q.  */

bool
a68_is_unitable (MOID_T *p, MOID_T *q, int deflex)
{
  if (IS (q, UNION_SYMBOL))
    {
      if (IS (p, UNION_SYMBOL))
	return a68_is_subset (p, q, deflex);
      else if (p == M_ROWS)
	return a68_is_rows_in_pack (PACK (q));
      else
	return a68_is_moid_in_pack (p, PACK (q), deflex);
  }

  return false;
}

/* Whether all or some components of U can be firmly coerced to a component
   mode of V..  */

void
a68_investigate_firm_relations (PACK_T *u, PACK_T *v, bool *all, bool *some)
{
  *all = true;
  *some = true;
  for (; v != NO_PACK; FORWARD (v))
    {
      bool k = false;

      for (PACK_T *w = u; w != NO_PACK; FORWARD (w))
	k |= a68_is_coercible (MOID (w), MOID (v), FIRM, FORCE_DEFLEXING);
      *some |= k;
      *all &= k;
    }
}

/* Whether there is a soft path from P to Q.  */

bool
a68_is_softly_coercible (MOID_T *p, MOID_T *q, int deflex)
{
  if (a68_is_equal_modes (p, q, deflex))
    return true;
  else if (IS (p, PROC_SYMBOL) && PACK (p) == NO_PACK)
    return a68_is_softly_coercible (SUB (p), q, deflex);
  else
    return false;
}

/* Whether there is a weak path from P to Q.  */

bool
a68_is_weakly_coercible (MOID_T * p, MOID_T * q, int deflex)
{
  if (a68_is_equal_modes (p, q, deflex))
    return true;
  else if (a68_is_deprefable (p))
    return a68_is_weakly_coercible (a68_depref_once (p), q, deflex);
  else
    return false;
}

/* Whether there is a meek path from P to Q.  */

bool
a68_is_meekly_coercible (MOID_T *p, MOID_T *q, int deflex)
{
  if (a68_is_equal_modes (p, q, deflex))
    return true;
  else if (a68_is_deprefable (p))
    return a68_is_meekly_coercible (a68_depref_once (p), q, deflex);
  else
    return false;
}

/* Whether there is a firm path from P to Q.  */

bool
a68_is_firmly_coercible (MOID_T *p, MOID_T *q, int deflex)
{
  if (a68_is_equal_modes (p, q, deflex))
    return true;
  else if (q == M_ROWS && a68_is_rows_type (p))
    return true;
  else if (a68_is_unitable (p, q, deflex))
    return true;
  else if (a68_is_deprefable (p))
    return a68_is_firmly_coercible (a68_depref_once (p), q, deflex);
  else
    return false;
}

/* Whether firm.  */

bool
a68_is_firm (MOID_T *p, MOID_T *q)
{
  return (a68_is_firmly_coercible (p, q, SAFE_DEFLEXING)
	  || a68_is_firmly_coercible (q, p, SAFE_DEFLEXING));
}

/* Whether P widens to Q.

   This function returns:

   The destination mode Q if P, or
   Some other mode which is an intermediate step from P to Q, or
   NO_MOID if P cannot be widened to Q.

   This means that if P is known to widen to Q (a68_is_widenable (P,Q) return
   true) this function can be invoked repeatedly and it will eventually return
   Q.  */

MOID_T *
a68_widens_to (MOID_T *p, MOID_T *q)
{
  if (p == M_INT)
    {
      if (q == M_REAL || q == M_COMPLEX)
	{
	  return M_REAL;
	}
      else
	{
	  return NO_MOID;
	}
    }
  else if (p == M_LONG_INT)
    {
      if (q == M_LONG_REAL)
	{
	  return M_LONG_REAL;
	}
      else
	{
	  return NO_MOID;
	}
    }
  else if (p == M_LONG_LONG_INT)
    {
      if (q == M_LONG_LONG_REAL || q == M_LONG_LONG_COMPLEX)
	  return M_LONG_LONG_REAL;
      else
	return NO_MOID;
    }
  else if (p == M_REAL)
    {
      if (q == M_COMPLEX)
	{
	  return M_COMPLEX;
	}
      else
	{
	  return NO_MOID;
	}
    }
  else if (p == M_LONG_REAL)
    {
      if (q == M_LONG_COMPLEX)
	return M_LONG_COMPLEX;
      else
	return NO_MOID;
    }
  else if (p == M_LONG_LONG_REAL)
    {
      if (q == M_LONG_LONG_COMPLEX)
	return M_LONG_LONG_COMPLEX;
      else
	return NO_MOID;
    }
  else if (p == M_BITS)
    {
      if (q == M_ROW_BOOL)
	return M_ROW_BOOL;
      else if (q == M_FLEX_ROW_BOOL)
	return M_FLEX_ROW_BOOL;
      else
	return NO_MOID;
    }
  else if (p == M_SHORT_BITS)
    {
      if (q == M_ROW_BOOL)
	return M_ROW_BOOL;
      else if (q == M_FLEX_ROW_BOOL)
	return M_FLEX_ROW_BOOL;
      else
	return NO_MOID;
    }
  else if (p == M_SHORT_SHORT_BITS)
    {
      if (q == M_ROW_BOOL)
	return M_ROW_BOOL;
      else if (q == M_FLEX_ROW_BOOL)
	return M_FLEX_ROW_BOOL;
      else
	return NO_MOID;
    }
  else if (p == M_LONG_BITS)
    {
      if (q == M_ROW_BOOL)
	return M_ROW_BOOL;
      else if (q == M_FLEX_ROW_BOOL)
	return M_FLEX_ROW_BOOL;
      else
	return NO_MOID;
    }
  else if (p == M_LONG_LONG_BITS)
    {
      if (q == M_ROW_BOOL)
	return M_ROW_BOOL;
      else if (q == M_FLEX_ROW_BOOL)
	return M_FLEX_ROW_BOOL;
      else
	return NO_MOID;
    }
  else if (p == M_BYTES && q == M_ROW_CHAR)
    return M_ROW_CHAR;
  else if (p == M_LONG_BYTES && q == M_ROW_CHAR)
    return M_ROW_CHAR;
  else if (p == M_BYTES && q == M_FLEX_ROW_CHAR)
    return M_FLEX_ROW_CHAR;
  else if (p == M_LONG_BYTES && q == M_FLEX_ROW_CHAR)
    return M_FLEX_ROW_CHAR;
  else
    return NO_MOID;
}

/* Whether P widens to Q.  */

bool
a68_is_widenable (MOID_T *p, MOID_T *q)
{
  MOID_T *z = a68_widens_to (p, q);

  if (z != NO_MOID)
    return (z == q ? true : a68_is_widenable (z, q));
  else
    return false;
}

/* Whether P is a REF ROW.  */

bool
a68_is_ref_row (MOID_T *p)
{
  return (NAME (p) != NO_MOID ? IS_ROW (DEFLEX (SUB (p))) : false);
}

/* Whether strong name.  */

bool
a68_is_strong_name (MOID_T *p, MOID_T *q)
{
  if (p == q)
    return true;
  else if (a68_is_ref_row (q))
    return a68_is_strong_name (p, NAME (q));
  else
    return false;
}

/* Whether strong slice. */

bool
a68_is_strong_slice (MOID_T *p, MOID_T *q)
{
  if (p == q || a68_is_widenable (p, q))
    return true;
  else if (SLICE (q) != NO_MOID)
    return a68_is_strong_slice (p, SLICE (q));
  else if (IS_FLEX (q))
    return a68_is_strong_slice (p, SUB (q));
  else if (a68_is_ref_row (q))
    return a68_is_strong_name (p, q);
  else
    return false;
}

/* Whether strongly coercible.  */

bool
a68_is_strongly_coercible (MOID_T *p, MOID_T *q, int deflex)
{
  /* Keep this sequence of statements.  */
  if (a68_is_equal_modes (p, q, deflex))
    return true;
  else if (q == M_VOID)
    return true;
  else if ((q == M_SIMPLIN || q == M_ROW_SIMPLIN) && a68_is_readable_mode (p))
    return true;
  else if (q == M_ROWS && a68_is_rows_type (p))
    return true;
  else if (a68_is_unitable (p, a68_derow (q), deflex))
    return true;

  if (a68_is_ref_row (q) && a68_is_strong_name (p, q))
    return true;
  else if (SLICE (q) != NO_MOID && a68_is_strong_slice (p, q))
    return true;
  else if (IS_FLEX (q) && a68_is_strong_slice (p, q))
    return true;
  else if (a68_is_widenable (p, q))
    return true;
  else if (a68_is_deprefable (p))
    return a68_is_strongly_coercible (a68_depref_once (p), q, deflex);
  else if (q == M_SIMPLOUT || q == M_ROW_SIMPLOUT)
    return a68_is_printable_mode (p);
  else
    return false;
}

/* Basic coercions.  */

bool
a68_basic_coercions (MOID_T *p, MOID_T *q, int c, int deflex)
{
  if (a68_is_equal_modes (p, q, deflex))
    return true;
  else if (c == NO_SORT)
    return (p == q);
  else if (c == SOFT)
    return a68_is_softly_coercible (p, q, deflex);
  else if (c == WEAK)
    return a68_is_weakly_coercible (p, q, deflex);
  else if (c == MEEK)
    return a68_is_meekly_coercible (p, q, deflex);
  else if (c == FIRM)
    return a68_is_firmly_coercible (p, q, deflex);
  else if (c == STRONG)
    return a68_is_strongly_coercible (p, q, deflex);
  else
    return false;
}

/* Whether coercible stowed.  */

bool
a68_is_coercible_stowed (MOID_T *p, MOID_T *q, int c, int deflex)
{
  if (c != STRONG)
    /* Such construct is always in a strong position, is it not?  */
    return false;
  else if (q == M_VOID)
    return true;
  else if (IS_FLEX (q))
    {
      bool j = true;

      for (PACK_T *u = PACK (p); u != NO_PACK && j; FORWARD (u))
	j &= a68_is_coercible (MOID (u), SLICE (SUB (q)), c, deflex);
      return j;
    }
  else if (IS_ROW (q))
    {
      bool j = true;

      for (PACK_T *u = PACK (p); u != NO_PACK && j; FORWARD (u))
	j &= a68_is_coercible (MOID (u), SLICE (q), c, deflex);
      return j;
    }
  else if (IS (q, PROC_SYMBOL) || IS (q, STRUCT_SYMBOL))
    {
      if (DIM (p) != DIM (q))
	return false;
      else
	{
	  PACK_T *u = PACK (p), *v = PACK (q);
	  bool j = true;

	  while (u != NO_PACK && v != NO_PACK && j)
	    {
	      j &= a68_is_coercible (MOID (u), MOID (v), c, deflex);
	      FORWARD (u);
	      FORWARD (v);
	    }
	  return j;
	}
    }
  else
    return false;
}

/* Whether coercible series.  */

bool
a68_is_coercible_series (MOID_T *p, MOID_T *q, int c, int deflex)
{
  if (c == NO_SORT)
    return false;
  else if (p == NO_MOID || q == NO_MOID)
    return false;
  else if (IS (p, SERIES_MODE) && PACK (p) == NO_PACK)
    return false;
  else if (IS (q, SERIES_MODE) && PACK (q) == NO_PACK)
    return false;
  else if (PACK (p) == NO_PACK)
    return a68_is_coercible (p, q, c, deflex);
  else
    {
      bool j = true;

      for (PACK_T *u = PACK (p); u != NO_PACK && j; FORWARD (u))
	{
	  if (MOID (u) != NO_MOID)
	    j &= a68_is_coercible (MOID (u), q, c, deflex);
	}
    return j;
    }
}

/* Whether P can be coerced to Q in a C context.

   If P is a STOWED modes series (A, B, ...) and Q is a routine mode like `proc
   (X, Y, ...)' then this routine determines whether A can be coerced to X, B
   to Y, etc.  */

bool
a68_is_coercible (MOID_T *p, MOID_T *q, int c, int deflex)
{
  if (a68_is_mode_isnt_well (p) || a68_is_mode_isnt_well (q))
    return true;
  else if (a68_is_equal_modes (p, q, deflex))
    return true;
  else if (p == M_HIP)
    return true;
  else if (IS (p, STOWED_MODE))
    return a68_is_coercible_stowed (p, q, c, deflex);
  else if (IS (p, SERIES_MODE))
    return a68_is_coercible_series (p, q, c, deflex);
  else if (p == M_VACUUM && IS_ROW (DEFLEX (q)))
    return true;
  else
    return a68_basic_coercions (p, q, c, deflex);
}

/* Whether coercible in context.  */

bool
a68_is_coercible_in_context (SOID_T *p, SOID_T *q, int deflex)
{
  if (SORT (p) != SORT (q))
    return false;
  else if (MOID (p) == MOID (q))
    return true;
  else
    return a68_is_coercible (MOID (p), MOID (q), SORT (q), deflex);
}

/* Whether list Y is balanced.  */

bool
a68_is_balanced (NODE_T *n, SOID_T *y, int sort)
{
  if (sort == STRONG)
    return true;
  else
    {
      bool k = false;

      for (; y != NO_SOID && !k; FORWARD (y))
	k = (!IS (MOID (y), STOWED_MODE));

      if (k == false)
	a68_error (n, "construct has no unique mode");
      return k;
    }
}

/* A moid from M to which all other members can be coerced.
   If no fulcrum of the balance is found, return NO_MOID.  */

MOID_T *
a68_get_balanced_mode_or_no_mode (MOID_T *m, int sort, bool return_depreffed, int deflex)
{
  MOID_T *common_moid = NO_MOID;

  if (m != NO_MOID && !a68_is_mode_isnt_well (m) && IS (m, UNION_SYMBOL))
    {
      int depref_level;
      bool siga = true;
      /* Test for increasing depreffing.  */
      for (depref_level = 0; siga; depref_level++)
	{
	  siga = false;
	  /* Test the whole pack.  */
	  for (PACK_T *p = PACK (m); p != NO_PACK; FORWARD (p))
	    {
	      /* HIPs are not eligible of course.  */
	      if (MOID (p) != M_HIP)
		{
		  MOID_T *candidate = MOID (p);
		  int k;
		  /* Depref as far as allowed.  */
		  for (k = depref_level; k > 0 && a68_is_deprefable (candidate); k--)
		    candidate = a68_depref_once (candidate);
		  /* Only need testing if all allowed deprefs succeeded.  */
		  if (k == 0)
		    {
		      MOID_T *to = (return_depreffed ? a68_depref_completely (candidate) : candidate);
		      bool all_coercible = true;

		      siga = true;
		      for (PACK_T *q = PACK (m); q != NO_PACK && all_coercible; FORWARD (q))
			{
			  MOID_T *from = MOID (q);
			  if (p != q && from != to)
			    all_coercible &= a68_is_coercible (from, to, sort, deflex);
			}
		      /* If the pack is coercible to the candidate, we mark the
			 candidate.  We continue searching for longest series
			 of REF REF PROC REF.  */
		      if (all_coercible)
			{
			  MOID_T *mark = (return_depreffed ? MOID (p) : candidate);

			  if (common_moid == NO_MOID)
			    common_moid = mark;
			  else if (IS_FLEX (candidate) && DEFLEX (candidate) == common_moid)
			    /* We prefer FLEX.  */
			    common_moid = mark;
			}
		    }
		}
	    }
	}
    }

  return common_moid;
}

/* A moid from M to which all other members can be coerced.
   If no fulcrum of the balance is found, return M.  */

MOID_T *
a68_get_balanced_mode (MOID_T *m, int sort, bool return_depreffed, int deflex)
{
  MOID_T *common_moid
    = a68_get_balanced_mode_or_no_mode (m, sort, return_depreffed, deflex);
  return common_moid == NO_MOID ? m : common_moid;
}

/* Whether we can search a common mode from a clause or not.  */

bool
a68_clause_allows_balancing (int att)
{
  switch (att)
    {
    case CLOSED_CLAUSE:
    case CONDITIONAL_CLAUSE:
    case CASE_CLAUSE:
    case SERIAL_CLAUSE:
    case CONFORMITY_CLAUSE:
      return true;
    }
  return false;
}

/* A unique mode from Z.  */

MOID_T *
a68_determine_unique_mode (SOID_T *z, int deflex)
{
  if (z == NO_SOID)
    return NO_MOID;
  else
    {
      MOID_T *x = MOID (z);

      if (a68_is_mode_isnt_well (x))
	return M_ERROR;

      /* If X is a series containing one union, a68_make_united_mode will
	 return that union (because 'union (union (...))' is the same than
	 'union (...)') and then a68_get_balanced_mode below will try to
	 balance the modes in that union.  Not what we want.  */
      if (ATTRIBUTE (x) == SERIES_MODE
	  && DIM (x) == 1
	  && IS (MOID (PACK (x)), UNION_SYMBOL))
	return MOID (PACK (x));

      x = a68_make_united_mode (x);
      if (a68_clause_allows_balancing (ATTRIBUTE (z)))
	return a68_get_balanced_mode (x, STRONG, A68_NO_DEPREF, deflex);
      else
	return x;
    }
}

/* Whether the given mode M is a valid mode for a C formal hole.  See
   metaproduction rule 561B in ga68.vw.  */

bool
a68_is_c_mode (MOID_T *m, int level)
{
  if (m == M_VOID || m == M_BOOL || m == M_CHAR)
    return true;
  else if (IS_INTEGRAL (m))
    return true;
  else if (IS_BITS (m))
    return true;
  else if (IS_REAL (m))
    return true;
  else if (IS_REF (m))
    return a68_is_c_mode (SUB (m), level + 1);
  else if (IS (m, PROC_SYMBOL))
    {
      bool yielded_mode_valid =
	((level == 0
	  && (SUB (m) == M_STRING
	      || (IS_REF (SUB (m)) && SUB (SUB (m)) == M_STRING)))
	 || a68_is_c_mode (SUB (m), level + 1));
      bool params_valid = true;

      for (PACK_T *z = PACK (m); z != NO_PACK; FORWARD (z))
	{
	  if (level == 0 && MOID (z) == M_STRING)
	    ;
	  else
	    params_valid &= a68_is_c_mode (MOID (z), level + 1);
	}

      return yielded_mode_valid && params_valid;
    }
  else if (IS_STRUCT (m))
    {
      bool fields_valid = true;

      for (PACK_T *z = PACK (m); z != NO_PACK; FORWARD (z))
	fields_valid &= a68_is_c_mode (MOID (z), level + 1);
      return fields_valid;
    }

  return false;
}

/* Insert coercion A in the tree.  */

void
a68_make_coercion (NODE_T *l, enum a68_attribute a, MOID_T *m)
{
  a68_make_sub (l, l, a);
  MOID (l) = a68_depref_rows (MOID (l), m);
}

/* Make widening coercion.  */

static void
make_widening_coercion (NODE_T *n, MOID_T *p, MOID_T *q)
{
  MOID_T *z = a68_widens_to (p, q);

  a68_make_coercion (n, WIDENING, z);
  if (z != q)
    make_widening_coercion (n, z, q);
}

/* Make ref rowing coercion.  */

void
a68_make_ref_rowing_coercion (NODE_T *n, MOID_T *p, MOID_T *q)
{
  if (DEFLEX (p) != DEFLEX (q))
    {
      if (a68_is_widenable (p, q))
	make_widening_coercion (n, p, q);
      else if (a68_is_ref_row (q))
	{
	  a68_make_ref_rowing_coercion (n, p, NAME (q));
	  a68_make_coercion (n, ROWING, q);
	}
    }
}

/* Make rowing coercion.  */

void
a68_make_rowing_coercion (NODE_T *n, MOID_T *p, MOID_T *q)
{
  if (DEFLEX (p) != DEFLEX (q))
    {
      if (a68_is_widenable (p, q))
	make_widening_coercion (n, p, q);
      else if (SLICE (q) != NO_MOID)
	{
	  a68_make_rowing_coercion (n, p, SLICE (q));
	  a68_make_coercion (n, ROWING, q);
	}
      else if (IS_FLEX (q))
	a68_make_rowing_coercion (n, p, SUB (q));
      else if (a68_is_ref_row (q))
	a68_make_ref_rowing_coercion (n, p, q);
    }
}

/* Make uniting coercion.  */

void
a68_make_uniting_coercion (NODE_T *n, MOID_T *q)
{
  a68_make_coercion (n, UNITING, a68_derow (q));
  if (IS_ROW (q) || IS_FLEX (q))
    a68_make_rowing_coercion (n, a68_derow (q), q);
}

/* Make depreffing coercion to coerce node N from mode P to mode Q in a strong
   context.  */

void
a68_make_depreffing_coercion (NODE_T *n, MOID_T *p, MOID_T *q)
{
  if (DEFLEX (p) == DEFLEX (q))
    return;
  else if (q == M_SIMPLOUT && a68_is_printable_mode (p))
    a68_make_coercion (n, UNITING, q);
  else if (q == M_ROW_SIMPLOUT && a68_is_printable_mode (p))
    {
      a68_make_coercion (n, UNITING, M_SIMPLOUT);
      a68_make_coercion (n, ROWING, M_ROW_SIMPLOUT);
    }
  else if (q == M_SIMPLIN && a68_is_readable_mode (p))
    a68_make_coercion (n, UNITING, q);
  else if (q == M_ROW_SIMPLIN && a68_is_readable_mode (p))
    {
      a68_make_coercion (n, UNITING, M_SIMPLIN);
      a68_make_coercion (n, ROWING, M_ROW_SIMPLIN);
    }
  else if (q == M_ROWS && a68_is_rows_type (p))
    {
      a68_make_coercion (n, UNITING, M_ROWS);
      MOID (n) = M_ROWS;
    }
  else if (a68_is_widenable (p, q))
    make_widening_coercion (n, p, q);
  else if (a68_is_unitable (p, a68_derow (q), SAFE_DEFLEXING))
    a68_make_uniting_coercion (n, q);
  else if (a68_is_ref_row (q) && a68_is_strong_name (p, q))
    a68_make_ref_rowing_coercion (n, p, q);
  else if (SLICE (q) != NO_MOID && a68_is_strong_slice (p, q))
    a68_make_rowing_coercion (n, p, q);
  else if (IS_FLEX (q) && a68_is_strong_slice (p, q))
    a68_make_rowing_coercion (n, p, q);
  else if (IS_REF (p))
    {
      MOID_T *r = a68_depref_once (p);
      a68_make_coercion (n, DEREFERENCING, r);
      a68_make_depreffing_coercion (n, r, q);
    }
  else if (IS (p, PROC_SYMBOL) && PACK (p) == NO_PACK)
    {
      MOID_T *r = SUB (p);

      a68_make_coercion (n, DEPROCEDURING, r);
      a68_make_depreffing_coercion (n, r, q);
    }
  else if (p != q)
    a68_cannot_coerce (n, p, q, NO_SORT, SKIP_DEFLEXING, 0);
}

/* Whether p is a nonproc mode (that is voided directly).  */

bool
a68_is_nonproc (MOID_T *p)
{
  if (IS (p, PROC_SYMBOL) && PACK (p) == NO_PACK)
    return false;
  else if (IS_REF (p))
    return a68_is_nonproc (SUB (p));
  else
    return true;
}

/* Voiden in an appropriate way.  */

void
a68_make_void (NODE_T *p, MOID_T *q)
{
  switch (ATTRIBUTE (p))
    {
    case ASSIGNATION:
    case IDENTITY_RELATION:
    case GENERATOR:
    case CAST:
    case DENOTATION:
      a68_make_coercion (p, VOIDING, M_VOID);
      return;
    default:
      break;
    }

  /* MORFs are an involved case.  */
  switch (ATTRIBUTE (p))
    {
    case SELECTION:
    case SLICE:
    case ROUTINE_TEXT:
    case FORMULA:
    case CALL:
    case IDENTIFIER:
      /* A nonproc moid value is eliminated directly.  */
      if (a68_is_nonproc (q))
	{
	  a68_make_coercion (p, VOIDING, M_VOID);
	  return;
	}
      else
	{
	  /* Descend the chain of e.g. REF PROC .. until a nonproc moid
	     remains.  */
	  MOID_T *z = q;

	  while (!a68_is_nonproc (z))
	    {
	      if (IS_REF (z))
		a68_make_coercion (p, DEREFERENCING, SUB (z));
	      if (IS (z, PROC_SYMBOL) && NODE_PACK (p) == NO_PACK)
		a68_make_coercion (p, DEPROCEDURING, SUB (z));
	      z = SUB (z);
	    }
	  if (z != M_VOID)
	    a68_make_coercion (p, VOIDING, M_VOID);
	  return;
	}
    default:
      break;
    }

  /* All other is voided straight away.  */
  a68_make_coercion (p, VOIDING, M_VOID);
}

/* Make strong coercion of node N from mode P to mode Q.  */

void
a68_make_strong (NODE_T *n, MOID_T *p, MOID_T *q)
{
  if (q == M_VOID && p != M_VOID)
    a68_make_void (n, p);
  else
    a68_make_depreffing_coercion (n, p, q);
}
