sig
  type data_t = int array array
  type local_schema_t = (int * int) array
  type schema_t = int array
  type spn_node_type = TimesNode | PlusNode | NullNode | LeafNode
  type spnode = {
    id : int;
    mutable parents : Spn.spnode array;
    mutable children : Spn.spnode array;
    mutable params : float array;
    mutable nodetype : Spn.spn_node_type;
    mutable schema : Spn.local_schema_t;
    mutable data : Spn.data_t;
    mutable acname : string;
    mutable ac_index : int;
    mutable final : bool;
    mutable infcached : bool;
    mutable logpTemp : float array;
  }
  exception HSplitNotPossible
  exception VSplitNotPossible
  exception NodeTypeError
  val node_array : Spn.spnode array Pervasives.ref
  val create_node :
    Spn.spn_node_type ->
    Spn.spnode array ->
    Spn.spnode array ->
    float array -> Spn.data_t -> Spn.local_schema_t -> Spn.spnode
  val create_plus : Spn.data_t -> Spn.local_schema_t -> Spn.spnode
  val create_times : Spn.data_t -> Spn.local_schema_t -> Spn.spnode
  val create_leaf : Spn.data_t -> Spn.local_schema_t -> Spn.spnode
  val create_null : unit -> Spn.spnode
  val get_type_name : Spn.spn_node_type -> string
  val get_node_by_id : int -> Spn.spnode
  val get_spn_size : unit -> int
  val add_child : Spn.spnode -> Spn.spnode -> unit
  val set_parent : Spn.spnode -> Spn.spnode -> unit
  val print_node : Pervasives.out_channel -> Spn.spnode -> unit
  val print_model : Pervasives.out_channel -> Spn.spnode -> unit
  val print_spn : Spn.spnode -> unit
  val load_model : string -> unit
  val h_split : Spn.spnode -> int -> float -> int -> float -> Spn.spnode list
  val h_split_force :
    Spn.spnode -> int -> float -> int -> float -> Spn.spnode list
  val v_split : Spn.spnode -> float -> Spn.spnode list
  val v_split_gtest : Spn.spnode -> float -> Spn.spnode list
end