sig
  type ndetails =
    Node.ndetails =
      TimesNode
    | PlusNode
    | VarNode of int * int
    | ConstNode of float
    | NullNode
  type node =
    Node.node = {
    hashid : int;
    mutable id : int;
    mutable parents : Circuit.node list;
    mutable children : Circuit.node list;
    mutable details : Circuit.ndetails;
  }
  val null_node : Circuit.node
  val create_node : Circuit.ndetails -> Circuit.node list -> Circuit.node
  val ncopy : Circuit.node -> Circuit.node
  val create_var : int -> int -> Circuit.node
  val create_const : float -> Circuit.node
  val create_times : Circuit.node list -> Circuit.node
  val create_plus : Circuit.node list -> Circuit.node
  val is_times : Circuit.node -> bool
  val is_plus : Circuit.node -> bool
  val is_var : Circuit.node -> bool
  val is_const : Circuit.node -> bool
  val is_null : Circuit.node -> bool
  val const_value : Circuit.node -> float
  val var_details : Circuit.node -> int * int
  val var_var : Circuit.node -> int
  val var_value : Circuit.node -> int
  val is_var_product : Circuit.node -> bool
  val is_sot_dist : Circuit.node -> bool
  val set_const : Circuit.node -> float -> unit
  val add_child : Circuit.node -> Circuit.node -> unit
  val remove_child : Circuit.node -> Circuit.node -> unit
  val remove_all_children : Circuit.node -> unit
  val remove_all_parents : Circuit.node -> unit
  val unlink : Circuit.node -> unit
  val id : Circuit.node -> int
  val parents : Circuit.node -> Circuit.node list
  val children : Circuit.node -> Circuit.node list
  val num_children : Circuit.node -> int
  val node_name : Circuit.node -> string
  val string_of_node : Circuit.node -> string
  val output_node : Pervasives.out_channel -> Circuit.node -> unit
  val output_root :
    Pervasives.out_channel -> int array -> Circuit.node -> unit
  val print_node : Circuit.node -> unit
  val print_node_endline : Circuit.node -> unit
  exception Unknown_child of string * string
  exception NonConstantFeatureWeight of int
  exception UnsupportedNodeType
  type evidence_t = float array array
  type schema_t = Data.schema_t
  type example_t = Data.example_t
  type circuit = {
    schema : Circuit.schema_t;
    vnodes : Circuit.node array array;
    vnodes_l : Circuit.node list array;
    flat_vnodes : Circuit.node array;
    mutable nodes : Circuit.node array;
    mutable root : Circuit.node;
    mutable size : int;
  }
  val load : Pervasives.in_channel -> Circuit.circuit
  val output : Pervasives.out_channel -> Circuit.circuit -> unit
  val output_js : Pervasives.out_channel -> Circuit.circuit -> unit
  val output_dot : Pervasives.out_channel -> Circuit.circuit -> unit
  val print : Circuit.circuit -> unit
  val schema : Circuit.circuit -> Circuit.schema_t
  val numvars : Circuit.circuit -> int
  val node : Circuit.circuit -> int -> Circuit.node
  val all_var_dists : Circuit.circuit -> Circuit.node list
  val dist_var : Circuit.node -> int
  val all_vars : Circuit.circuit -> Circuit.node array array
  val sibling_vars : Circuit.circuit -> Circuit.node -> Circuit.node list
  val var : Circuit.circuit -> int -> Circuit.node array
  val flat_vars : Circuit.circuit -> Circuit.node array
  val order : Circuit.circuit -> unit
  val make_vnodes : Circuit.schema_t -> Circuit.node array array
  val rebuild : Circuit.circuit -> unit
  val of_graph :
    Circuit.schema_t ->
    Circuit.node array array ->
    Circuit.node list array -> Circuit.node -> Circuit.circuit
  val depth : Circuit.circuit -> int
  val update_parents : Circuit.circuit -> unit
  val num_edges : Circuit.circuit -> int
  val num_params : Circuit.circuit -> int
  val create_evidence_s : Circuit.schema_t -> Circuit.evidence_t
  val create_evidence : Circuit.circuit -> Circuit.evidence_t
  val ev_true : Circuit.evidence_t -> int -> int -> unit
  val ev_false : Circuit.evidence_t -> int -> int -> unit
  val set_evidence : 'a array -> Circuit.circuit -> 'a array array -> unit
  val example_to_ev :
    Circuit.schema_t -> Circuit.example_t -> Circuit.evidence_t
  val ev_intersect : Circuit.evidence_t -> Circuit.evidence_t -> bool
  val ev_subset : Circuit.evidence_t -> Circuit.evidence_t -> bool
  val ev_intersect2 : Circuit.evidence_t -> Circuit.evidence_t -> bool
  val ev_union :
    Circuit.circuit ->
    Circuit.evidence_t -> Circuit.evidence_t -> Circuit.evidence_t
  val print_ev : Circuit.evidence_t -> unit
  type condition = bool * int * int
  type feature = {
    acnode : Circuit.node;
    mutable weight : float;
    cond : Circuit.condition list;
    ev : Circuit.evidence_t;
  }
  val feature_node : Circuit.feature -> Circuit.node
  val feature_value : Circuit.feature -> float
  val set_feature_value : Circuit.feature -> float -> unit
  val feature_contains_var : Circuit.feature -> Circuit.node -> bool
  val prune_for_evidence : Circuit.circuit -> Circuit.example_t -> unit
  val c_satisfied : Circuit.example_t -> Circuit.condition -> bool
  val f_satisfied : Circuit.example_t -> Circuit.feature -> bool
  val prune_features :
    Circuit.feature list -> Circuit.example_t -> Circuit.feature list
  val conditions_to_ev :
    Circuit.schema_t -> Circuit.condition array -> Circuit.evidence_t
  val cond_intersect :
    Circuit.schema_t ->
    Circuit.condition array -> Circuit.condition array -> bool
  val string_of_feature : Circuit.feature -> string
  val output_feature : Pervasives.out_channel -> Circuit.feature -> unit
  val output_with_features :
    Pervasives.out_channel -> Circuit.circuit -> Circuit.feature list -> unit
  val output_root_with_features :
    Pervasives.out_channel ->
    Circuit.schema_t -> Circuit.node -> Circuit.feature list -> unit
  val output_features :
    Pervasives.out_channel -> Circuit.node -> Circuit.feature list -> unit
  val load_with_features :
    Pervasives.in_channel -> Circuit.circuit * Circuit.feature list
  type deriv_scratch = {
    dr : float array;
    vr : float array;
    vr_nz : float array;
    bit1 : bool array;
    bit2 : bool array;
    cids : int array array;
  }
  val create_deriv_scratch : Circuit.circuit -> Circuit.deriv_scratch
  val get_derivatives_raw :
    Circuit.circuit -> Circuit.deriv_scratch -> Circuit.evidence_t -> unit
  type scratch_t = float array * int array array
  val create_scratch : Circuit.circuit -> Circuit.scratch_t
  val logvalues : Circuit.scratch_t -> Circuit.circuit -> float array
  val logprob_ev :
    Circuit.scratch_t -> Circuit.circuit -> Circuit.evidence_t -> float
  val logprob_x :
    Circuit.scratch_t -> Circuit.circuit -> Circuit.example_t -> float
  val get_logmarginals :
    Circuit.circuit ->
    Circuit.deriv_scratch -> Circuit.example_t -> float array array
  val get_marginals :
    Circuit.circuit ->
    Circuit.deriv_scratch -> Circuit.example_t -> float array array
  val compute_z : Circuit.scratch_t -> Circuit.circuit -> float
  val get_mpe :
    Circuit.circuit ->
    Circuit.deriv_scratch -> Circuit.example_t -> int array
  module NSet :
    sig
      type key = Circuit.node
      type 'a t = 'Node.NSet.t
      val create : int -> 'Circuit.NSet.t
      val clear : 'Circuit.NSet.t -> unit
      val copy : 'Circuit.NSet.t -> 'Circuit.NSet.t
      val remove : 'Circuit.NSet.t -> Circuit.NSet.key -> unit
      val find : 'Circuit.NSet.t -> Circuit.NSet.key -> 'a
      val find_all : 'Circuit.NSet.t -> Circuit.NSet.key -> 'a list
      val replace : 'Circuit.NSet.t -> Circuit.NSet.key -> '-> unit
      val mem : 'Circuit.NSet.t -> Circuit.NSet.key -> bool
      val length : 'Circuit.NSet.t -> int
      val add : unit Circuit.NSet.t -> Circuit.NSet.key -> unit
      val iter : (Circuit.NSet.key -> unit) -> unit Circuit.NSet.t -> unit
      val fold :
        (Circuit.NSet.key -> '-> 'a) -> unit Circuit.NSet.t -> '-> 'a
      val to_list : unit Circuit.NSet.t -> Circuit.NSet.key list
      val sum_map : (Circuit.NSet.key -> int) -> unit Circuit.NSet.t -> int
      val sumf_map :
        (Circuit.NSet.key -> float) -> unit Circuit.NSet.t -> float
      val filter : (Circuit.NSet.key -> bool) -> unit Circuit.NSet.t -> unit
    end
  module NMap :
    sig
      type key = Circuit.node
      type 'a t = 'Node.NMap.t
      val create : int -> 'Circuit.NMap.t
      val clear : 'Circuit.NMap.t -> unit
      val copy : 'Circuit.NMap.t -> 'Circuit.NMap.t
      val add : 'Circuit.NMap.t -> Circuit.NMap.key -> '-> unit
      val remove : 'Circuit.NMap.t -> Circuit.NMap.key -> unit
      val find : 'Circuit.NMap.t -> Circuit.NMap.key -> 'a
      val find_all : 'Circuit.NMap.t -> Circuit.NMap.key -> 'a list
      val replace : 'Circuit.NMap.t -> Circuit.NMap.key -> '-> unit
      val mem : 'Circuit.NMap.t -> Circuit.NMap.key -> bool
      val iter :
        (Circuit.NMap.key -> '-> unit) -> 'Circuit.NMap.t -> unit
      val fold :
        (Circuit.NMap.key -> '-> '-> 'b) -> 'Circuit.NMap.t -> '-> 'b
      val length : 'Circuit.NMap.t -> int
    end
  val node_iter : (Circuit.node -> 'a) -> Circuit.node -> unit
  val node_map : (Circuit.node -> 'a) -> Circuit.node -> 'a list
  val root_to_list : Circuit.node -> Circuit.node list
  val relatedl_a :
    int ->
    (Circuit.node -> Circuit.node list) -> Circuit.node list -> bool array
  val a_mem : 'a array -> Circuit.node -> 'a
end