(** Encodes the powers of x, y, z in a compact form, suitable for being
  used as keys in a hash table.

  Internally, the {Zkey.t} is made of two integers, [left] and [right].
  The small integers x, y and z are stored compactly in this 126-bits
  space:

  {[
                                Left                                                                Right
 3 [--------------------------------------------------------------]       [------------------|---------------|---------------|---------------]
                                                                                                     x               y               z        

 6 [--------------------------------------------------------------]       [---|----------|----------|----------|----------|----------|---------]
                                                                                   x1         y1         z1         x2         y2         z2        

 9 [---------------------------------|----------|----------|---------]    [---|----------|----------|----------|----------|----------|---------]
                                          x1         y1         z1                 x2         y2         z2         x3         y3         z3        

12 [---|----------|----------|----------|----------|----------|---------] [---|----------|----------|----------|----------|----------|---------]
            x1         y1         z1         x2         y2         z2              x3         y3         z3         x4         y4         z4
  ]}

  The values of x,y,z should be positive and should not exceed 32767 for
  [kind=3]. For all other kinds kinds the values should not exceed 1023.

*)

type t 

val to_string : t -> string
(** Pretty printing *)

val of_powers_three  : Powers.t -> t
(** Create from a {!Powers.t}. *)

val of_int_four  : int -> int -> int -> int -> t
(** Create from four integers. *)

val of_powers_six    : Powers.t -> Powers.t -> t
(** Create from two {!Powers.t}. *)

val of_powers_nine   : Powers.t -> Powers.t -> Powers.t -> t
(** Create from three {!Powers.t}. *)

val of_powers_twelve : Powers.t -> Powers.t -> Powers.t -> Powers.t -> t
(** Create from four {!Powers.t}. *)

type kind =
  | Three  of  Powers.t
  | Four   of (int * int * int * int)
  | Six    of (Powers.t * Powers.t)
  | Nine   of (Powers.t * Powers.t * Powers.t)
  | Twelve of (Powers.t * Powers.t * Powers.t * Powers.t)

val of_powers : kind -> t
(** Create using the [kind] type *)

val to_int_array : t -> int array
(** Convert to an int array. *)

val of_int_array : int array -> t
(** Convert from an int array. *)

val to_powers : t -> kind

(** {1 Functions for hash tables} *)

val hash : t -> int
(** Associates a nonnegative integer to any Zkey. *)

val equal : t -> t -> bool
(** The equal function. True if two Zkeys are equal. *)

val compare : t -> t -> int
(** Comparison function, used for sorting. *)


