A module internal to Incremental. Users should see Incremental_intf.

A `Node.t` is one node in the incremental DAG. The key invariants of a node `t` are:

- if `is_necessary t`, then `t.height > c.height`, for all children `c` of `t`.
- if `is_necessary t`, then `t.height > Scope.height t.created_in`.
- `is_necessary p` for all parents `p` of `t`.
- `t.height < p.height` for all parents `p` of `t`.
- `needs_to_be_computed t = is_in_recompute_heap t`.

Outside of stabilization, when the recompute heap is empty, the invariant implies that if `is_necessary t`, then `t.recomputed_at >= c.changed_at` for all children `c` of `t`. I.e. it implies that all necessary nodes aren't stale.

`module Packed : sig ... end`

For performance reasons, we do not use an OCaml existential type for `Node.Packed.t`:

`include module type of sig ... end`
`type 'a t``= 'a Incremental_kernel__Types.Node.t``=` `{`

`id : Incremental_kernel__.Node_id.t;`
`mutable recomputed_at : Incremental_kernel__.Stabilization_num.t;`
`mutable value_opt : 'a Incremental_kernel__.Uopt.t;`
`mutable kind : 'a Incremental_kernel__Types.Kind.t;`
`mutable cutoff : 'a Incremental_kernel__.Cutoff.t;`
`mutable changed_at : Incremental_kernel__.Stabilization_num.t;`
`mutable num_on_update_handlers : int;`
`mutable num_parents : int;`
`mutable parent1_and_beyond : Incremental_kernel__Types.Packed_node.t Incremental_kernel__.Uopt.t array;`
`mutable parent0 : Incremental_kernel__Types.Packed_node.t Incremental_kernel__.Uopt.t;`
`mutable created_in : Incremental_kernel__Types.Scope.t;`
`mutable next_node_in_same_scope : Incremental_kernel__Types.Packed_node.t Incremental_kernel__.Uopt.t;`
`mutable height : int;`
`mutable height_in_recompute_heap : int;`
`mutable prev_in_recompute_heap : Incremental_kernel__Types.Packed_node.t Incremental_kernel__.Uopt.t;`
`mutable next_in_recompute_heap : Incremental_kernel__Types.Packed_node.t Incremental_kernel__.Uopt.t;`
`mutable height_in_adjust_heights_heap : int;`
`mutable next_in_adjust_heights_heap : Incremental_kernel__Types.Packed_node.t Incremental_kernel__.Uopt.t;`
`mutable old_value_opt : 'a Incremental_kernel__.Uopt.t;`
`mutable observers : 'a Incremental_kernel__Types.Internal_observer.t Incremental_kernel__.Uopt.t;`
`mutable is_in_handle_after_stabilization : bool;`
`mutable on_update_handlers : 'a Incremental_kernel__.On_update_handler.t list;`
`mutable my_parent_index_in_child_at_index : int array;`
`mutable my_child_index_in_parent_at_index : int array;`
`mutable force_necessary : bool;`
`mutable user_info : Core_kernel.Info.t option;`
`creation_backtrace : Core_kernel.Backtrace.t option;`

`}```
`val sexp_of_t : ('a ‑> Base.Sexp.t) ‑> 'a t ‑> Base.Sexp.t`
`val pack : 'a t ‑> Incremental_kernel__Types.Packed_node.t`
`val is_valid : 'a t ‑> bool`
`val is_necessary : 'a t ‑> bool`
`include Core_kernel.Invariant.S1 with type a t := a t`
`type 'a t`````
`val invariant : 'a Base__.Invariant_intf.inv ‑> 'a t Base__.Invariant_intf.inv`
`val create : Incremental_kernel__.Scope.t ‑> 'a Incremental_kernel__.Kind.t ‑> 'a t`
`val set_kind : 'a t ‑> 'a Incremental_kernel__.Kind.t ‑> unit`

One should only set the kind of a node using `set_kind` -- using `t.kind <-` will violate invariants.

`val pack : _ t ‑> Packed.t`
`val same : _ t ‑> _ t ‑> bool`
`val iteri_children : _ t ‑> f:(int ‑> Packed.t ‑> unit) ‑> unit`

`iteri_children t ~f` applies `f` to all children of `t`.

`val get_parent : _ t ‑> index:int ‑> Packed.t`

`get_parent t ~index` raises unless `0 <= index < t.num_parents`.

`val add_parent : child:'a t ‑> parent:'b t ‑> child_index:int ‑> unit`
`val remove_parent : child:'a t ‑> parent:'b t ‑> child_index:int ‑> unit`
`val swap_children_except_in_kind : _ t ‑> child1:_ t ‑> child_index1:int ‑> child2:_ t ‑> child_index2:int ‑> unit`
`val is_const : _ t ‑> bool`
`val is_in_recompute_heap : _ t ‑> bool`
`val is_necessary : _ t ‑> bool`

`is_necessary t` iff `t` is a descendant of an observer or `t` is a `Freeze` node.

`val is_valid : _ t ‑> bool`

`is_valid t` returns `true` iff the left-hand-side of `t`'s defining bind hasn't changed since `t` was created.

`val should_be_invalidated : _ t ‑> bool`

`should_be_invalidated t` returns `true` iff `t` has an invalid child that implies that `t` should be invalid. It doesn't take into account `t.created_in`.

`val edge_is_stale : child:_ t ‑> parent:_ t ‑> bool`

`edge_is_stale` returns `true` iff `child` has changed since `parent` was computed, and implies `is_stale parent`. `edge_is_stale` is constant-time.

`val is_stale : _ t ‑> bool`

`is_stale t` is true if `t` has never been computed or if some child changed since `t` was last computed. `is_stale` doesn't take into account `t.created_in`.

`val needs_to_be_computed : _ t ‑> bool`

`needs_to_be_computed` is `is_necessary t && is_stale t`

`val value_exn : 'a t ‑> 'a`

Getting the value of a node.

`value_exn t` raises iff `Uopt.is_none t.value_opt`. `unsafe_value t` is safe iff `Uopt.is_some t.value_opt`.

`val unsafe_value : 'a t ‑> 'a`
`val get_cutoff : 'a t ‑> 'a Incremental_kernel__.Cutoff.t`
`val set_cutoff : 'a t ‑> 'a Incremental_kernel__.Cutoff.t ‑> unit`
`val on_update : 'a t ‑> 'a Incremental_kernel__.On_update_handler.t ‑> unit`

`on_update t on_update_handler` adds an on-update handler to `t`.

`val run_on_update_handlers : 'a t ‑> 'a Incremental_kernel__.On_update_handler.Node_update.t ‑> now:Incremental_kernel__.Stabilization_num.t ‑> unit`

`run_on_update_handlers t node_update ~now` runs `t`'s on-update handlers, except those created at the stabilization `now`.

`val keep_node_creation_backtrace : bool Core_kernel.ref`
`val user_info : _ t ‑> Core_kernel.Info.t option`
`val set_user_info : _ t ‑> Core_kernel.Info.t option ‑> unit`
`val has_child : _ t ‑> child:_ t ‑> bool`

These functions are meant for debug, as they are not very efficient.

`val has_parent : _ t ‑> parent:_ t ‑> bool`