#if !defined (BAS_COMMON_H)
#   define BAS_COMMON_H 1

#   include <bad.h>

/* 
 * The _MSC_VER flag is set if the code is compiled under WINDOWS
 * by using Microsoft Visual C (through Visual Studio 2008).
 *
 * In that case, some specific annotations must be added for DLL exports
 * Beware to the fact that this header file is going to be used either
 * for/while building BLAD or for using BLAD from an outer software.
 *
 * In the first case, functions are exported.
 * In the second one, they are imported.
 *
 * The flag BAS_BLAD_BUILDING must thus be set in the Makefile and passed
 * to the C preprocessor at BAS building time. Do not set it when using BAS.
 *
 * When compiling static libraries under Windows, set BA0_STATIC.
 */

#   if defined (_MSC_VER) && ! defined (BA0_STATIC)
#      if defined (BLAD_BUILDING) || defined (BAS_BLAD_BUILDING)
#         define BAS_DLL  __declspec(dllexport)
#      else
#         define BAS_DLL  __declspec(dllimport)
#      endif
#   else
#      define BAS_DLL
#   endif

/* #   include "bas_mesgerr.h" */

/* 
 * For Solaris 8
 */

#   if HAVE_IEEEFP_H
#      include <ieeefp.h>
#   endif

BEGIN_C_DECLS

#   define BAS_NOT_A_NUMBER -1

extern BAS_DLL void bas_reset_all_settings (
    void);

extern BAS_DLL void bas_restart (
    ba0_int_p,
    ba0_int_p);

extern BAS_DLL void bas_terminate (
    enum ba0_restart_level);

END_C_DECLS
#endif /* !BAS_COMMON_H */
#if !defined (BAS_MESGERR_H)
#   define BAS_MESGERR_H 1

/* #   include "bas_common.h" */

BEGIN_C_DECLS

extern BAS_DLL char BAS_ERRPAT[];

extern BAS_DLL char BAS_ERRSTR[];

END_C_DECLS
#endif /* !BAS_MESGERR_H */
#if ! defined (BAS_DL_EDGE_H)
#   define BAS_DL_EDGE_H 1

/* #   include "bas_common.h" */

BEGIN_C_DECLS

/*
 * texinfo: bas_typeof_DL_edge
 * This data type is a subtype of @code{bas_DL_edge}.
 * It permits to associate a type to an edge in the DL tree
 * generated by the @code{DenefLipshitz_leaf} algorithm.
 */

enum bas_typeof_DL_edge
{
// not an edge
  bas_none_edge,
// investigation of some coefficient being zero
  bas_vanishing_edge,
// investigation of some coefficient being nonzero
  bas_non_vanishing_edge,
// splitting due to regular chain decomposition
  bas_RG_edge
};

/*
 * texinfo: bas_DL_edge
 * This data type is a subtype of @code{struct bas_DL_vertex} and
 * @code{struct bas_DL_tree}. The @code{bas_DenefLipshitz_leaf}
 * function is led to consider some polynomials which may possibly
 * vanish. In such cases, two cases are generated: the one in which
 * the polynomial under consideration vanish and the one in which
 * it does not. 
 * The two corresponding types are @code{bas_vanishing_edge} and
 * @code{bas_non_vanishing_edge}.
 * The @code{bas_DenefLipshitz_leaf} function is also
 * led to generate prolongation equations, which are simplified by
 * a regular chain decomposition algorithm, possibly yielding some
 * case discussion. The corresponding branches have type
 * @code{bas_RG_edge}.
 */

struct bas_DL_edge
{
// the type of the edge
  enum bas_typeof_DL_edge type;
// the number of the source vertex
  ba0_int_p src;
// the number of the target vertex
  ba0_int_p dst;
};

struct bas_tableof_DL_edge
{
  ba0_int_p alloc;
  ba0_int_p size;
  struct bas_DL_edge **tab;
};


extern BAS_DLL void bas_init_DL_edge (
    struct bas_DL_edge *);

extern BAS_DLL struct bas_DL_edge *bas_new_DL_edge (
    void);

extern BAS_DLL char *bas_typeof_DL_edge_to_string (
    enum bas_typeof_DL_edge);

extern BAS_DLL void bas_set_DL_edge (
    struct bas_DL_edge *,
    struct bas_DL_edge *);

extern BAS_DLL void bas_set_tsd_DL_edge (
    struct bas_DL_edge *,
    enum bas_typeof_DL_edge,
    ba0_int_p,
    ba0_int_p);

extern BAS_DLL ba0_scanf_function bas_scanf_DL_edge;

extern BAS_DLL ba0_printf_function bas_printf_DL_edge;

extern BAS_DLL ba0_garbage1_function bas_garbage1_DL_edge;

extern BAS_DLL ba0_garbage2_function bas_garbage2_DL_edge;

extern BAS_DLL ba0_copy_function bas_copy_DL_edge;

END_C_DECLS
#endif /* !BAS_DL_EDGE_H */
#if ! defined (BAS_POSITIVE_INTEGER_ROOTS_H)
#   define BAS_POSITIVE_INTEGER_ROOTS_H 1

/* #   include "bas_common.h" */

BEGIN_C_DECLS

extern BAS_DLL void bas_nonnegative_integer_roots (
    struct ba0_tableof_mpz *,
    struct bap_polynom_mpz *,
    struct bav_variable *,
    struct bad_regchain *);

END_C_DECLS
#endif /* !BAS_POSITIVE_INTEGER_ROOTS_H */
#if ! defined (BAS_HURWITZ_H)
#   define BAS_HURWITZ_H 1

/* #   include "bas_common.h" */

BEGIN_C_DECLS

extern BAS_DLL void bas_Hurwitz_coeffs (
    struct bap_tableof_polynom_mpz *,
    struct bap_polynom_mpz *,
    struct bap_polynom_mpz *,
    ba0_int_p,
    struct bav_symbol *);

END_C_DECLS
#endif /* !BAS_HURWITZ_H */
#if ! defined (BAS_YUPLE_H)
#   define BAS_YUPLE_H 1

/* #   include "bas_common.h" */

BEGIN_C_DECLS

/*
 * texinfo: bas_Yuple
 * The data type is used by the @code{bas_Denef_Lipshitz} algorithm.
 * It contains the part of the data related to the differential
 * indeterminates @var{y} for which formal power series are sought
 * and to their defining differential equations.
 * 
 * The field @code{Y} contains the table of the differential indeterminates.
 *
 * The other fields which are tables all have the same size as @code{Y}.
 * The @math{i}th entry of any table applies to the @math{i}th
 * differential indeterminate. Some of these entries may remain unused:
 * the ones for which the differential indeterminate have no defining equation.
 *
 * Let @math{y} denote one of the differential indeterminates
 * for which formal power series solutions are sought
 * and @math{y_i} the coefficients of the sought formal power
 * series solution @math{\bar{\bar{y}}}.
 * These coefficients are implemented as
 * @emph{subscripted variables} @code{y[i]}.
 * The @math{y} defining ODE i.e. the one which has a derivative
 * of @math{y} for leader is denoted @math{F}.
 * Its separant is denoted @math{S}.
 * The coefficients of the series obtained by evaluating @math{F}
 * at @math{\bar{\bar{y}}} are the non-differential polynomials
 * @math{F^{(j)}(y_i)}. They are called the @dfn{prolongation equations}.
 *
 * To simplify statements, the table fields of the data structure
 * are described as if they applied to the single differential
 * indeterminate @math{y}.
 *
 * The field @code{dict_Y} permits to map @var{y} to its index in @code{Y}.
 * 
 * The field @code{Ybar} contains the prolongation pattern which
 * permits to evaluate derivatives of @var{y}
 * to subscripted variables, possibly multiplied by some coefficient.
 * Assume for instance that @code{Ybar} the second derivative derivative 
 * @math{\ddot y} gets evaluated to @math{y_2}. Then @code{Ybar}
 * defines a map which associates the subscripted variable @code{y[2]}
 * to the variable @code{y[x,x]}.
 * 
 * The field @code{point} is an evaluation point defined by @code{Ybar},
 * which is involved in the evaluation process mentioned above.
 * 
 * All the subscripted variables generated from @var{y}
 * have different symbols but all these 
 * symbols share the same @code{index_in_rigs} field.
 * 
 * The field @code{R} contains the value of the @code{index_in_rigs} field
 * of the subscripted variables associated to @var{y}.
 * 
 * The field @code{dict_R} permits to map any @code{index_in_rigs} to its
 * index in @code{R} hence to the index of the corresponding
 * differential indeterminate in @code{Y}.
 * 
 * The field @code{ozs} contains the subscript associated to 
 * the order zero derivative of @var{y}.
 *
 * The field @code{kappa} contains an upper bound on the valuation
 * of the separant of the @var{y}-defining ODE. 
 * More precisely, it is the smallest integer such that
 * @math{S^{(k)}(y_i)} is nonzero.
 * If undefined, it is equal to @math{-1}.
 * 
 * The field @code{ode} is a table containing derivatives of @math{F}.
 * If undefined it contains the empty table.
 * Otherwise, it contains at least @math{F}.
 * 
 * The field @code{order} contains the order of the leader of @math{F}.
 * 
 * The field @code{sep} is a table containing derivatives of @math{S}.
 * If undefined it contains the empty table.
 * Otherwise, it contains at least @math{S}.
 * 
 * The field @code{S} is the list of the inequations provided
 * by the user and which apply to constant polynomials with respect
 * to the derivation.
 * These inequations, which include in particular
 * constraints on the subscripted variables associated to differential
 * indeterminates, are provided to the regular chain decomposition method.
 *
 * The field @code{binomials} contains binomial polynomials involved
 * in the computation process of the polynomials @math{A(q)}.
 * See the @code{struct bas_Zuple} data structure.
 * 
 * The field @code{q} contains the variable to be used in the context
 * of Hurwitz formula. It stands for a number of differentiations.
 * 
 * The field @code{x} contains the independent variable.
 */

struct bas_Yuple
{
  struct bav_tableof_symbol Y;
  struct bav_dictionary_symbol dict_Y;

  struct baz_prolongation_pattern Ybar;
  struct baz_point_ratfrac point;

  struct ba0_tableof_int_p R;
  struct ba0_dictionary dict_R;

  struct ba0_tableof_int_p ozs;

  struct ba0_tableof_int_p kappa;

  struct bap_tableof_tableof_polynom_mpz ode;
  struct ba0_tableof_int_p order;

  struct bap_tableof_tableof_polynom_mpz sep;

  struct bap_listof_polynom_mpz *S;

  struct bap_tableof_polynom_mpq binomials;

  struct bav_variable *q;
  struct bav_symbol *x;
};

extern BAS_DLL void bas_init_Yuple (
    struct bas_Yuple *);

extern BAS_DLL struct bas_Yuple *bas_new_Yuple (
    void);

extern BAS_DLL void bas_set_Yuple (
    struct bas_Yuple *,
    struct bas_Yuple *);

extern BAS_DLL void bas_set_Y_Ybar_Yuple (
    struct bas_Yuple *,
    struct bav_tableof_symbol *,
    struct baz_prolongation_pattern *,
    struct bap_tableof_polynom_mpz *,
    struct bav_variable *,
    struct bav_symbol *);

extern BAS_DLL void bas_set_ode_Yuple (
    struct bas_Yuple *,
    struct bad_regchain *,
    struct bad_base_field *);

extern BAS_DLL void bas_prolongate_binomials_Yuple (
    struct bas_Yuple *,
    ba0_int_p);

extern BAS_DLL ba0_scanf_function bas_scanf_Yuple;

extern BAS_DLL ba0_printf_function bas_printf_Yuple;

extern BAS_DLL ba0_garbage1_function bas_garbage1_Yuple;

extern BAS_DLL ba0_garbage2_function bas_garbage2_Yuple;

extern BAS_DLL ba0_copy_function bas_copy_Yuple;

END_C_DECLS
#endif /* !BAS_YUPLE_H */
#if ! defined (BAS_ZUPLE_H)
#   define BAS_ZUPLE_H 1

/* #   include "bas_common.h" */
/* #   include "bas_Yuple.h" */

BEGIN_C_DECLS

/*
 * texinfo: bas_Zuple
 * This data structure is a working data structure used by
 * the @code{bas_Denef_Lipshitz_leaf} function.
 * 
 * This data structure is meaningful with respect to some
 * @code{struct bas_Yuple} data structure, denoted @var{U}
 * in the following text. 
 * 
 * The fields which are tables all have the same size:
 * the number of differential indeterminates for which formal
 * power series solutions are sought (see the field @code{Y} of @var{U}).
 * The @math{i}th entry of any table applies to the @math{i}th
 * differential indeterminate. Some of these entries may remain unused:
 * the ones for which the differential indeterminate is not constrained
 * by any differential polynomial, corresponding to an empty entry
 * in the field @code{ode} of @var{U}.
 * 
 * Let @math{y} denote one of the differential indeterminates
 * for which formal power series solutions are sought
 * and @math{y_i} the coefficients of the sought formal power
 * series solution @math{\bar{\bar{y}}}. 
 * These coefficients are implemented as
 * @emph{subscripted variables} @code{y[i]}.
 * The @math{y} defining ODE i.e. the one which has a derivative
 * of @math{y} for leader is denoted @math{F}.
 * Its separant is denoted @math{S}.
 * The coefficients of the series obtained by evaluating @math{F}
 * at @math{\bar{\bar{y}}} are the non-differential polynomials 
 * @math{F^{(j)}(y_i)}. They are called the @emph{prolongation equations}.
 * 
 * To simplify statements, the table fields of the data structure
 * are described as if they applied to the single differential
 * indeterminate @math{y}.
 * 
 * The field @code{sigma} contains the maximum of the subscripts
 * of the variables @code{y[i]} occurring in the fields @code{C},
 * @code{P} and @code{S}.
 * If undefined, @code{sigma} is equal to @math{-1}.
 * 
 * The field @code{mu} contains the prolongation order for @math{F}.
 * Roughly speaking, the field @code{C} contains the polynomials
 * @math{F^{(j)}(y_i)} for @math{0 \leq j \leq \mu}.
 * Strictly speaking, the above statement is incorrect because @code{C} is a
 * regular differential chain obtained by processing these polynomials
 * by a non-differential regular chain decomposition algorithm.
 * Moreover, before being processed, these polynomials lie in @code{P} and
 * not in @code{C}.
 * 
 * The field @code{zeta} contains the last tried value for the
 * valuation @code{k} of the separant of @math{F}.
 * Its value is bounded by the field @code{kappa} of @var{U}.
 * If undefined, @code{zeta} is equal to @math{-1}.
 * 
 * The field @code{C} contains a regular differential chain obtained
 * by extension of an initial regular differential chain with
 * prolongation equations and other polynomials considered while
 * building the polynomial @math{A(q)}.
 * 
 * The field @code{P} contains the equations waiting for being processed.
 * The polynomials in @code{P} are meant to be processed by a 
 * non-differential regular chain decomposition algorithm in order
 * to extend @code{C}. This process may actually split the 
 * current regular differential chain.
 * After the process, the field @code{P} becomes empty.
 * 
 * The field @code{S} contains the non-differential inequations to be taken into
 * account by the non-differential regular chain decomposition algorithm.
 * It contains polynomials which must be guaranteed to be nonzero in
 * order to guarantee the valuations of the separants of the ODE
 * system (the field @code{k}) and the degrees of the polynomials @math{A(q)}
 * (the fields @code{r} and @code{A}).
 * It is never emptied but its elements may get simplified when
 * @code{C} is updated.
 * 
 * The field @code{k} contains the valuation of the separant of @math{F}
 * i.e. of the series @math{S(\bar{\bar{y}})}.
 * If undefined, it is equal to @math{-1} otherwise, the polynomial
 * @math{S^{(k)}(y_i)} is guaranteed to be nonzero: it is either an element
 * of the base field or stored in the field @code{S}.
 * 
 * The field @code{fn} contains the Hurwitz coefficients of @math{F}
 * with respect to the valuation stored in @code{k}.
 * See the @code{bas_Hurwitz_coeffs} function.
 * This field is undefined if @code{k} is undefined else it 
 * contains @math{k+1} differential polynomials denoted
 * (see [DL84, Lemma 2.2])
 * @display
 * @math{[f_n, f_{n+1}, f_{n+2}, ..., f_{n+k}].}
 * @end display
 * 
 * The field @code{der_fn} contains differential polynomials 
 * involved in the definition of the polynomial @math{A(q)}.
 * It is built incrementally.
 * Successive values of this field are
 * @display
 * @math{[f_n], \quad [f_{n+1}, f_n'], \quad [f_{n+2}, f_{n+1}', f_n''], \quad @dots{}}
 * @end display
 * 
 * The field @code{phi} contains the last tried value for @code{r}.
 * Its value is bounded by the valuation @code{k}.
 * It is equal to the index of the last defined entry of @code{der_fn}.
 * If undefined, @code{phi} is equal to @math{-1}.
 * 
 * The field @code{deg} contains the last tried value for the
 * degree of the polynomial @math{A(q)}.
 * Its value is bounded by @code{phi}.
 * If undefined, @code{deg} is equal to @math{-1}.
 * 
 * The field @code{r} contains the first value of @code{phi} for
 * which a nonzero polynomial @math{A(q)} has been determined.
 * Its value is bounded by the valuation @code{k}.
 * The field @code{deg} then contains the degree of @math{A(q)}.
 * The leading coefficient of @math{A(q)} is either a base field
 * element or stored in the list @code{S} of polynomials which must
 * not vanish.
 * If undefined, @code{r} is equal to @math{-1}.
 *
 * The field @code{coeffs} contains the coefficients of the
 * polynomial @math{A(q)}. It is built using @code{der_fn}.
 * If undefined, it is empty else it involves @math{@code{deg} + 1} elements.
 * Indeed we have
 * @display
 * @math{A(q) = \sum_{i=0}^{@code{deg}}} @code{coeffs}_@math{i} @math{{q \choose i}}
 * @end display
 * 
 * The field @code{A} contains the polynomial @math{A(q)}.
 * Its degree in @math{q} is stored in the field @code{deg}.
 * If undefined it contains @math{0}.
 * 
 * The field @code{roots} contains the positive integer roots
 * of @math{A(q)}, stored by increasing values.
 * 
 * The field @code{gamma} contains either @math{0} is @code{roots}
 * is empty or @math{1} plus the maximal positive integer root
 * of @math{A(q)}.
 * If undefined, it contains @math{-1}.
 * 
 * The field @code{beta} contains the bound @math{2\,k+2+\gamma+r}
 * or @math{-1} if undefined.
 * 
 * The field @code{delta} contains the bound @math{n+2\,k+2+\gamma}
 * where @math{n} denotes the order of @math{F}
 * or @math{-1} if undefined.
 * 
 * The field @code{done} contains @code{true} if the bounds are
 * considered as correct, @code{false} otherwise.
 * Indeed, when the bound @code{beta} is determined, new prolongation
 * equations are generated which may simplify coefficients of the 
 * polynomial @math{A(q)} thereby increase @code{gamma} hence
 * @code{beta}. In such cases, some computations have to be 
 * done again.
 * If @code{done} is equal to @code{false} then the coefficients
 * of the polynomial @math{A(q)} are checked and the computation
 * of @code{beta} is possibly restarted.
 * If @code{done} is equal to @code{true}, the current @code{struct bas_Zuple}
 * is complete and can be transformed into a @code{bas_DLuple}.
 * Eventually, @code{beta} is equal to @code{mu} minus @math{1}.
 *
 * The field @code{number} identifies the current 
 * @code{struct bas_Zuple} in a @code{struct bas_DL_tree}.
 */

struct bas_Zuple
{
  struct ba0_tableof_int_p sigma;

  struct ba0_tableof_int_p mu;

  struct ba0_tableof_int_p zeta;

  struct bad_regchain C;
  struct bap_listof_polynom_mpz *P;
  struct bap_listof_polynom_mpz *S;

  struct ba0_tableof_int_p k;
  struct bap_tableof_tableof_polynom_mpz fn;
  struct bap_tableof_tableof_polynom_mpz der_fn;

  struct ba0_tableof_int_p phi;
  struct ba0_tableof_int_p deg;
  struct ba0_tableof_int_p r;

  struct baz_tableof_tableof_ratfrac coeffs;
  struct baz_tableof_ratfrac A;
  struct ba0_tableof_tableof_mpz roots;
  struct ba0_tableof_int_p gamma;
  struct ba0_tableof_int_p beta;
  struct ba0_tableof_int_p delta;

  struct ba0_tableof_int_p done;

  ba0_int_p number;
};

struct bas_tableof_Zuple
{
  ba0_int_p alloc;
  ba0_int_p size;
  struct bas_Zuple **tab;
};

/*
 * texinfo: bas_typeof_action_on_Zuple
 * This data type is used to determine which action needs be
 * undertaken over a given Zuple.
 */

enum bas_typeof_action_on_Zuple
{
  bas_nothing_to_do_Zuple,
  bas_discard_Zuple,
  bas_k_to_secure_Zuple,
  bas_r_to_secure_Zuple,
  bas_beta_to_compute_Zuple,
  bas_A_to_specialize_and_beta_to_recompute_Zuple
};

struct bas_DL_tree;

extern BAS_DLL void bas_init_Zuple (
    struct bas_Zuple *);

extern BAS_DLL struct bas_Zuple *bas_new_Zuple (
    void);

extern BAS_DLL void bas_set_Yuple_Zuple (
    struct bas_tableof_Zuple *,
    struct ba0_tableof_int_p *,
    struct bas_Yuple *,
    struct bas_DL_tree *,
    struct bap_tableof_polynom_mpz *,
    struct bad_regchain *,
    struct bad_base_field *,
    struct bav_tableof_variable *);

extern BAS_DLL void bas_set_but_change_regchain_Zuple (
    struct bas_Zuple *,
    struct bas_Zuple *,
    struct bad_regchain *);

extern BAS_DLL void bas_set_Zuple (
    struct bas_Zuple *,
    struct bas_Zuple *);

extern BAS_DLL void bas_set_number_Zuple (
    struct bas_Zuple *,
    ba0_int_p);

extern BAS_DLL char *bas_typeof_action_on_Zuple_to_string (
    enum bas_typeof_action_on_Zuple);

extern BAS_DLL enum bas_typeof_action_on_Zuple bas_get_action_on_Zuple (
    struct bas_Zuple *,
    struct bas_Yuple *);

extern BAS_DLL void bas_secure_k_Zuple (
    struct bas_tableof_Zuple *,
    struct ba0_tableof_int_p *,
    struct bas_Yuple *,
    struct bas_DL_tree *,
    struct bad_base_field *);

extern BAS_DLL void bas_secure_r_Zuple (
    struct bas_tableof_Zuple *,
    struct ba0_tableof_int_p *,
    struct bas_Yuple *,
    struct bas_DL_tree *,
    struct bad_base_field *);

extern BAS_DLL void bas_compute_beta_Zuple (
    struct bas_tableof_Zuple *,
    struct ba0_tableof_int_p *,
    struct bas_Yuple *,
    struct bas_DL_tree *,
    struct bad_base_field *);

extern BAS_DLL void bas_specialize_A_and_recompute_beta_Zuple (
    struct bas_tableof_Zuple *,
    struct ba0_tableof_int_p *,
    struct bas_Yuple *,
    struct bas_DL_tree *,
    struct bad_base_field *);

extern BAS_DLL ba0_scanf_function bas_scanf_Zuple;

extern BAS_DLL ba0_printf_function bas_printf_Zuple;

extern BAS_DLL ba0_garbage1_function bas_garbage1_Zuple;

extern BAS_DLL ba0_garbage2_function bas_garbage2_Zuple;

extern BAS_DLL ba0_copy_function bas_copy_Zuple;


END_C_DECLS
#endif /* !BAS_ZUPLE_H */
#if !defined (BAS_DL_VERTEX_H)
#   define BAS_DL_VERTEX_H 1

/* #   include "bas_DL_edge.h" */
/* #   include "bas_Zuple.h" */

BEGIN_C_DECLS

/*
 * texinfo: bas_typeof_consistency_vertex
 * This data type is a subtype of @code{bas_DL_vertex}.
 * It determines the consistency information of one vertex
 * of a DL tree.
 */

enum bas_typeof_consistency_vertex
{
// the vertex is inconsistent
  bas_inconsistent_vertex,
// the vertex is rejected because kappa is exceeded
  bas_rejected_vertex,
// the consistency of the vertex is uncertain (at least when created)
  bas_uncertain_vertex,
// the vertex is consistent
  bas_consistent_vertex
};

/*
 * texinfo: bas_DL_vertex
 * This data type is a subtype of @code{bas_DL_tree}.
 * It permits to describe one vertex of the tree.
 * Each vertex corresponds to a Zuple @var{Z}, which
 * is identified by its @emph{number}.
 *
 * The field @code{number} contains the number of the vertex.
 *
 * The field @code{consistency} provides the consistency information
 * for the vertex. The default value is @code{bas_uncertain_vertex}.
 *
 * The field @code{edges} contains the table of the edges starting
 * from the vertex towards other vertices of the DL tree.
 *
 * The field @code{action} contains the action to be undertaken on the vertex.
 * The field @code{y} contains the differential indeterminate
 * with respect to which the action is undertaken. 
 * The fields @code{k}, @code{r} and @code{deg} contain the entries of the 
 * corresponding fields of @var{Z} which apply to @code{y}.
 */

struct bas_DL_vertex
{
// the number of the vertex which is also the number of the quadruple
  ba0_int_p number;
// the consistency information for the vertex
  enum bas_typeof_consistency_vertex consistency;
// the edges towards the children of the vertex
  struct bas_tableof_DL_edge edges;
// information of the process undertaken by the vertex
  enum bas_typeof_action_on_Zuple action;
  struct bav_symbol *y;
  ba0_int_p k;
  ba0_int_p r;
  ba0_int_p deg;
};

struct bas_tableof_DL_vertex
{
  ba0_int_p alloc;
  ba0_int_p size;
  struct bas_DL_vertex **tab;
};

extern BAS_DLL void bas_init_DL_vertex (
    struct bas_DL_vertex *);

extern BAS_DLL struct bas_DL_vertex *bas_new_DL_vertex (
    void);

extern BAS_DLL void bas_reset_DL_vertex (
    struct bas_DL_vertex *,
    ba0_int_p);

extern BAS_DLL void bas_set_DL_vertex (
    struct bas_DL_vertex *,
    struct bas_DL_vertex *);

extern BAS_DLL void bas_set_aykrd_DL_vertex (
    struct bas_DL_vertex *,
    enum bas_typeof_action_on_Zuple,
    struct bav_symbol *,
    ba0_int_p,
    ba0_int_p,
    ba0_int_p);

extern BAS_DLL ba0_scanf_function bas_scanf_DL_vertex;

extern BAS_DLL ba0_printf_function bas_printf_DL_vertex;

extern BAS_DLL ba0_garbage1_function bas_garbage1_DL_vertex;

extern BAS_DLL ba0_garbage2_function bas_garbage2_DL_vertex;

extern BAS_DLL ba0_copy_function bas_copy_DL_vertex;

END_C_DECLS
#endif /* !BAS_DL_VERTEX_H */
#if !defined (BAS_DL_TREE_H)
#   define BAS_DL_TREE_H 1

/* #   include "bas_DL_vertex.h" */

BEGIN_C_DECLS

/*
 * texinfo: bas_activity_level_DL_tree
 * This data type is a subtype of @code{bas_DL_tree}.
 */

enum bas_activity_level_DL_tree
{
// the DL tree is not generated
  bas_inactive_DL_tree,
// the DL tree is generated
  bas_quiet_DL_tree,
// the DL tree is generated and messages are printed
  bas_verbose_DL_tree
};

/*
 * texinfo: bas_DL_tree
 * This data type permits to describe the DL tree generated by the
 * @code{bas_Denef_Lipshitz_leaf} function.
 *
 * The field @code{roots} contains the numbers of the different
 * roots of the different trees (the data structure actually contains
 * a forrest rather than a single tree).
 *
 * The field @code{vertices} contains the table of the tree vertices.
 * Each vertex is associated to one Zuple, identified
 * by its @emph{number}. This @emph{number} is moreover equal to
 * the index of the vertex in the table. 
 *
 * The field @code{number} contains the next free vertex number.
 * It may be greater than the @code{alloc} field of the @code{vertices}
 * table.
 *
 * The field @code{activity} provides the level of activity of the
 * tree. It may have three values:
 * @itemize
 * @item @code{bas_inactive_DL_tree} then the only active field
 * if @code{number} and the two tables remain empty~;
 * @item @code{bas_quiet_DL_tree} then the DL tree is generated
 * @item @code{bas_verbose_DL_tree} same as above but the
 * the @code{bas_Denef_Lipshitz_leaf} function may print some 
 * further data on the standard output.
 * @end itemize
 */

struct bas_DL_tree
{
  enum bas_activity_level_DL_tree activity;
// the table of the roots
  struct ba0_tableof_int_p roots;
// the table of vertices
  struct bas_tableof_DL_vertex vertices;
// the next free vertex number
  ba0_int_p number;
};

extern BAS_DLL void bas_init_DL_tree (
    struct bas_DL_tree *);

extern BAS_DLL struct bas_DL_tree *bas_new_DL_tree (
    void);

extern BAS_DLL void bas_reset_DL_tree (
    struct bas_DL_tree *,
    enum bas_activity_level_DL_tree);

extern BAS_DLL void bas_set_DL_tree (
    struct bas_DL_tree *,
    struct bas_DL_tree *);

extern BAS_DLL void bas_add_root_DL_tree (
    struct bas_DL_tree *,
    ba0_int_p);

extern BAS_DLL ba0_int_p bas_next_number_DL_tree (
    struct bas_DL_tree *);

extern BAS_DLL struct bas_DL_vertex *bas_ith_vertex_DL_tree (
    struct bas_DL_tree *,
    ba0_int_p);

extern BAS_DLL void bas_set_vertex_consistency_DL_tree (
    struct bas_DL_tree *,
    ba0_int_p,
    enum bas_typeof_consistency_vertex);

extern BAS_DLL void bas_set_aykrd_vertex_DL_tree (
    struct bas_DL_tree *,
    ba0_int_p,
    enum bas_typeof_action_on_Zuple,
    struct bav_symbol *,
    ba0_int_p,
    ba0_int_p,
    ba0_int_p);

extern BAS_DLL void bas_add_edge_DL_tree (
    struct bas_DL_tree *,
    enum bas_typeof_DL_edge,
    ba0_int_p,
    ba0_int_p);

extern BAS_DLL void bas_dot_DL_tree (
    struct bas_DL_tree *);

extern BAS_DLL ba0_scanf_function bas_scanf_DL_tree;

extern BAS_DLL ba0_printf_function bas_printf_DL_tree;

extern BAS_DLL ba0_garbage1_function bas_garbage1_DL_tree;

extern BAS_DLL ba0_garbage2_function bas_garbage2_DL_tree;

extern BAS_DLL ba0_copy_function bas_copy_DL_tree;

END_C_DECLS
#endif
#if ! defined (BAS_DLUPLE_H)
#   define BAS_DLUPLE_H 1

/* #   include "bas_Yuple.h" */
/* #   include "bas_Zuple.h" */

BEGIN_C_DECLS

/*
 * texinfo: bas_DLuple
 * This data structure is used to store the output of the
 * Denef Lipshitz algorithm. Its fields are copies of
 * the corresponding fields of a @code{struct bas_Yuple} and
 * a @code{struct bas_Zuple} produced by the 
 * @code{bas_Denef_Lipshitz_leaf} function.
 */

struct bas_DLuple
{
  struct bav_tableof_symbol Y;
  struct baz_prolongation_pattern Ybar;
  struct bav_symbol *x;
  struct ba0_tableof_int_p order;
  struct ba0_tableof_int_p kappa;
  struct bad_regchain C;
  struct bap_listof_polynom_mpz *S;
  struct ba0_tableof_int_p k;
  struct ba0_tableof_int_p r;
  struct bav_variable *q;
  struct baz_tableof_ratfrac A;
  struct ba0_tableof_int_p gamma;
  struct ba0_tableof_int_p mu;
  struct ba0_tableof_int_p sigma;
  struct ba0_tableof_int_p beta;
  struct ba0_tableof_int_p delta;
};

struct bas_tableof_DLuple
{
  ba0_int_p alloc;
  ba0_int_p size;
  struct bas_DLuple **tab;
};

extern BAS_DLL void bas_init_DLuple (
    struct bas_DLuple *);

extern BAS_DLL struct bas_DLuple *bas_new_DLuple (
    void);

extern BAS_DLL void bas_set_DLuple (
    struct bas_DLuple *,
    struct bas_DLuple *);

extern BAS_DLL void bas_set_YZuple_DLuple (
    struct bas_DLuple *,
    struct bas_Yuple *,
    struct bas_Zuple *);

extern BAS_DLL unsigned ba0_int_p bas_sizeof_DLuple (
    struct bas_DLuple *,
    enum ba0_garbage_code);

extern BAS_DLL void bas_switch_ring_DLuple (
    struct bas_DLuple *,
    struct bav_differential_ring *);

extern BAS_DLL void bas_constant_variables_DLuple (
    struct ba0_tableof_int_p *,
    struct bav_tableof_variable *,
    struct bas_DLuple *);

extern BAS_DLL void bas_series_coefficients_DLuple (
    struct baz_tableof_tableof_ratfrac *,
    struct bas_DLuple *);

extern BAS_DLL ba0_scanf_function bas_scanf_DLuple;

extern BAS_DLL ba0_printf_function bas_printf_DLuple;

extern BAS_DLL ba0_printf_function bas_printf_stripped_DLuple;

extern BAS_DLL ba0_garbage1_function bas_garbage1_DLuple;

extern BAS_DLL ba0_garbage2_function bas_garbage2_DLuple;

extern BAS_DLL ba0_copy_function bas_copy_DLuple;

END_C_DECLS
#endif /* !BAS_DL_UPLE_H */
#if ! defined (BAS_BETA_H)
#   define BAS_BETA_H 1

/* #   include "bas_common.h" */

BEGIN_C_DECLS

/*
 * texinfo: bas_beta_control
 * This data type permits to control the management of the @math{\beta}
 * bounds in the @code{bas_Denef_Lipshitz} function and, more precisely
 * in the @code{bas_Denef_Lipshitz_aux} subfunction.
 *
 * The value @code{bas_single_beta_control} corresponds to the strategy 
 * given in [Theorem 3.1, DL84]: the bound @math{\beta} is a single
 * nonnegative integer.
 *
 * The value @code{bas_vector_beta_control} is an optimization, leading
 * to lower bounds: the bound @math{\beta} is a vectior with one entry
 * per differential indeterminate for which formal power series are sought.
 */

enum bas_beta_control
{
  bas_single_beta_control,
  bas_vector_beta_control
};

/*
 * texinfo: bas_beta
 * This data type implements the beta bound in the @code{bas_Denef_Lipshitz_aux}
 * algorithm.
 *
 * The field @code{control} contains the type of control to be applied.
 *
 * The field @code{single} contains the value of @math{\beta} in the
 * @code{bas_single_beta_control} case.
 *
 * The field @code{vector} contains the value of @math{\beta} in the
 * @code{bas_vector_beta_control} case.
 *
 * In the documentation of functions, by @emph{entries of @math{\beta}}
 * we mean either the @code{single} field when @code{control}
 * contains @code{bas_single_beta_control}~; or the coordinates
 * of the @code{vector} table in the other case.
 */

struct bas_beta
{
  enum bas_beta_control control;
  ba0_int_p single;
  struct ba0_tableof_int_p vector;
};

struct bas_Yuple;

extern BAS_DLL void bas_init_beta (
    struct bas_beta *);

extern BAS_DLL struct bas_beta *bas_new_beta (
    void);

extern BAS_DLL void bas_set_Y_control_beta (
    struct bas_beta *,
    struct bav_tableof_symbol *,
    enum bas_beta_control);

extern BAS_DLL void bas_set_beta (
    struct bas_beta *,
    struct bas_beta *);

extern BAS_DLL void bas_set_int_beta (
    struct bas_beta *,
    ba0_int_p);

extern BAS_DLL void bas_max_componentwise_beta (
    struct bas_beta *,
    struct bas_beta *);

extern BAS_DLL void bas_max_componentwise2_beta (
    struct bas_beta *,
    struct ba0_tableof_int_p *);

extern BAS_DLL ba0_int_p bas_max_value_beta (
    struct bas_beta *);

extern BAS_DLL void bas_add_thetas_to_beta (
    struct bas_beta *,
    struct bas_Yuple *,
    struct bav_tableof_variable *,
    struct bav_tableof_term *);

extern BAS_DLL void bas_max_splitting_edge_beta (
    struct bas_beta *,
    struct bas_beta *,
    struct bad_splitting_edge *,
    struct bas_Yuple *);

extern BAS_DLL ba0_printf_function bas_printf_beta;

END_C_DECLS
#endif /* !BAS_BETA_H */
#if ! defined (BAS_DENEF_LIPSHITZ_H)
#   define BAS_DENEF_LIPSHITZ_H 1

/* #   include "bas_DLuple.h" */
/* #   include "bas_DL_tree.h" */
/* #   include "bas_beta.h" */

BEGIN_C_DECLS

extern BAS_DLL void bas_prolongate_DLuple (
    struct bas_DLuple *,
    struct bas_DLuple *,
    struct bav_tableof_variable *);

extern BAS_DLL void bas_Denef_Lipshitz_resume (
    struct bas_tableof_DLuple *,
    struct bas_DLuple *,
    struct bap_tableof_polynom_mpz *,
    struct bap_tableof_polynom_mpz *);

extern BAS_DLL ba0_int_p bas_Denef_Lipshitz_leaf (
    struct bas_tableof_DLuple *,
    struct bas_DL_tree *,
    ba0_int_p,
    struct bas_Yuple *,
    struct bad_regchain *,
    struct bad_base_field *);

extern BAS_DLL ba0_int_p bas_Denef_Lipshitz_aux (
    struct bas_tableof_DLuple *,
    struct bas_DL_tree *,
    ba0_int_p,
    struct bas_Yuple *,
    struct bad_intersectof_regchain *,
    struct bad_splitting_tree *,
    ba0_int_p,
    struct bad_base_field *);

extern BAS_DLL void bas_Denef_Lipshitz (
    struct bas_tableof_DLuple *,
    struct bas_DL_tree *,
    struct bap_tableof_polynom_mpz *,
    struct bap_tableof_polynom_mpz *,
    struct ba0_tableof_string *,
    struct bav_tableof_symbol *,
    struct baz_prolongation_pattern *,
    struct bav_variable *,
    struct bav_symbol *,
    enum bas_beta_control);

END_C_DECLS
#endif /* !BAS_DENEF_LIPSHITZ_H */
