#if !defined (BAD_SPLITTING_TREE_H)
#   define BAD_SPLITTING_TREE_H 1

#   include "bad_splitting_vertex.h"

BEGIN_C_DECLS

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

enum bad_activity_level_splitting_tree
{
// the splitting tree is not generated
  bad_inactive_splitting_tree,
// the splitting tree is generated
  bad_quiet_splitting_tree,
// the splitting tree is generated and messages are printed
  bad_verbose_splitting_tree
};

/*
 * texinfo: bad_splitting_tree
 * This data type permits to describe the splitting tree generated by a
 * differential elimination algorithm.
 *
 * The field @code{vertices} contains the table of the tree vertices.
 * Each vertex is associated to one quadruple / regular chain, identified
 * by its @emph{number}. This @emph{number} is moreover equal to
 * the index of the vertex in the table. 
 *
 * The first entry of @code{vertices}, with @emph{number} zero,
 * is the @dfn{root vertex}. It does not correspond to any
 * actual quadruple / regular chain. It permits to handle
 * systems which have many different @emph{first} vertices.
 * First vertices play a special role in differential elimination methods
 * because they provide bounds which permit to discard quadruples
 * by means of a dimension argument.
 *
 * 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{bad_inactive_splitting_tree} then at most one vertex
 * is allocated to @code{vertices}: the @emph{root} vertex
 * @item @code{bad_quiet_splitting_tree} then the splitting tree
 * is generated
 * @item @code{bad_verbose_splitting_tree} same as above but the
 * differential elimination algorithm which builds the tree
 * may print some data on the standard output.
 * @end itemize
 */

struct bad_splitting_tree
{
  enum bad_activity_level_splitting_tree activity;
// the table of vertices
  struct bad_tableof_splitting_vertex vertices;
// the next free vertex number
  ba0_int_p number;
};

extern BAD_DLL void bad_init_splitting_tree (
    struct bad_splitting_tree *);

extern BAD_DLL struct bad_splitting_tree *bad_new_splitting_tree (
    void);

extern BAD_DLL void bad_reset_splitting_tree (
    struct bad_splitting_tree *,
    enum bad_activity_level_splitting_tree);

extern BAD_DLL void bad_set_splitting_tree (
    struct bad_splitting_tree *,
    struct bad_splitting_tree *);

extern BAD_DLL ba0_int_p bad_next_number_splitting_tree (
    struct bad_splitting_tree *);

extern BAD_DLL struct bad_splitting_vertex *bad_ith_vertex_splitting_tree (
    struct bad_splitting_tree *,
    ba0_int_p);

extern BAD_DLL bool bad_is_first_vertex_splitting_tree (
    struct bad_splitting_tree *,
    ba0_int_p);

extern BAD_DLL void bad_set_first_vertex_splitting_tree (
    struct bad_splitting_tree *,
    ba0_int_p,
    bool);

extern BAD_DLL void bad_set_vertex_consistency_splitting_tree (
    struct bad_splitting_tree *,
    ba0_int_p,
    enum bad_typeof_consistency_vertex,
    enum bad_inconsistency_argument_vertex);

extern BAD_DLL void bad_merge_thetas_leaders_vertex_splitting_tree (
    struct bad_splitting_tree *,
    ba0_int_p,
    struct bav_tableof_term *,
    struct bav_tableof_variable *);

extern BAD_DLL void bad_set_discarded_branch_splitting_tree (
    struct bad_splitting_tree *,
    ba0_int_p,
    bool);

extern BAD_DLL void bad_add_edge_splitting_tree (
    struct bad_splitting_tree *,
    enum bad_typeof_splitting_edge,
    ba0_int_p,
    struct bav_variable *,
    ba0_int_p,
    struct bav_variable *);

extern BAD_DLL void bad_add_edge_novar_splitting_tree (
    struct bad_splitting_tree *,
    enum bad_typeof_splitting_edge,
    ba0_int_p,
    ba0_int_p);

extern BAD_DLL void bad_dot_splitting_tree (
    struct bad_splitting_tree *);

extern BAD_DLL ba0_scanf_function bad_scanf_splitting_tree;

extern BAD_DLL ba0_printf_function bad_printf_splitting_tree;

extern BAD_DLL ba0_garbage1_function bad_garbage1_splitting_tree;

extern BAD_DLL ba0_garbage2_function bad_garbage2_splitting_tree;

extern BAD_DLL ba0_copy_function bad_copy_splitting_tree;

END_C_DECLS
#endif /* !BAD_SPLITTING_TREE_H */
