(**
The determinant space in which we solve the Schrodinger equation.
*)

type t

type arbitrary_space =
  {
    det         : int array array ;
    det_alfa    : Spindeterminant.t array ;
    det_beta    : Spindeterminant.t array ;
    index_start : int array;
  }


type determinant_storage =
  | Arbitrary of arbitrary_space
  | Spin      of (Spindeterminant.t array * Spindeterminant.t array)


(** {1 Accessors} *)

val n_alfa : t -> int
(** Number of {% $\alpha$ %} electrons in the {% $\alpha$ %} MOs. *)

val n_beta : t -> int
(** Number of {% $\beta$ %} electrons in the {% $\beta$ %} MOs. *)

val mo_class : t -> MOClass.t
(** The MO classes used to generate the space. *)

val mo_basis : t -> MOBasis.t
(** The MO basis on which the determinants are expanded. *)

val determinants : t -> determinant_storage
(** All the determinants belonging to the space. *)

val determinants_array : t -> Determinant.t array
(** All the determinants belonging to the space. *)

val determinant_stream : t -> Determinant.t Stream.t
(** All the determinants belonging to the space, as a stream. *)

val size : t -> int
(** Size of the determinant space *)

val fock_diag : t -> Determinant.t -> float array * float array
(** Returns the diagonal of the {% $\alpha$ %} and {% $\beta$ %} Fock matrices.
    The zero elements contain the energy of the determinant.
*)


val fci_of_mo_basis : MOBasis.t -> frozen_core:bool -> t
(** Creates a space of all possible ways to put [n_alfa] electrons in the {% $\alpha$ %}
    [Active] MOs and [n_beta] electrons in the {% $\beta$ %} [Active] MOs.
    All other MOs are untouched.
*)

val cas_of_mo_basis : MOBasis.t -> frozen_core:bool -> int -> int -> t
(** Creates a CAS(n,m) space of determinants.  *)

val fci_f12_of_mo_basis : MOBasis.t -> frozen_core:bool -> int -> t
(** Creates the active space to perform a FCI-F12 with an
    auxiliary basis set. *)

val cas_f12_of_mo_basis : MOBasis.t -> frozen_core:bool -> int -> int -> int -> t
(** [cas_of_mo_basis mo_basis m n mo_num] Creates a CAS(n,m) space
  of determinants with an auxiliary basis set defined as the MOs from
  [mo_num+1] to [MOBasis.size mo_basis].
*)

(** {2 Printing} *)

val pp : Format.formatter -> t -> unit
