sig
  module Poly :
    sig
      module Coeff :
        sig
          type t = float
          val compare : t -> t -> int
          val zero : t
          val one : t
          val of_float : float -> t
          val to_float : t -> float
          val of_q : Q.t -> t
          val to_q : t -> Q.t
          val add : t -> t -> t
          val sub : t -> t -> t
          val mult : t -> t -> t
          val div : t -> t -> t
          val pp : Format.formatter -> t -> unit
          val minus_one : t
          val of_int : int -> t
          val neg : t -> t
          val inv : t -> t
          val equal : t -> t -> bool
          val leq : t -> t -> bool
          val geq : t -> t -> bool
          val lt : t -> t -> bool
          val gt : t -> t -> bool
          val sign : t -> int
          val ( ~- ) : t -> t
          val ( + ) : t -> t -> t
          val ( - ) : t -> t -> t
          val ( * ) : t -> t -> t
          val ( / ) : t -> t -> t
          val ( = ) : t -> t -> bool
          val ( <> ) : t -> t -> bool
          val ( <= ) : t -> t -> bool
          val ( >= ) : t -> t -> bool
          val ( < ) : t -> t -> bool
          val ( > ) : t -> t -> bool
        end
      type t = Polynomial.Float.t
      val of_list : (Monomial.t * Coeff.t) list -> t
      val to_list : t -> (Monomial.t * Coeff.t) list
      val zero : t
      val one : t
      val var : ?c:Coeff.t -> ?d:int -> int -> t
      val const : Coeff.t -> t
      val monomial : Monomial.t -> t
      val mult_scalar : Coeff.t -> t -> t
      val add : t -> t -> t
      val sub : t -> t -> t
      val mult : t -> t -> t
      val power : t -> int -> t
      exception Dimension_error
      val compose : t -> t list -> t
      val derive : t -> int -> t
      val eval : t -> Coeff.t list -> Coeff.t
      val compare : t -> t -> int
      val nb_vars : t -> int
      val degree : t -> int
      val degree_list : t -> int list
      val is_homogeneous : t -> bool
      val is_var : t -> (Coeff.t * int * int) option
      val is_const : t -> Coeff.t option
      val is_monomial : t -> Monomial.t option
      val ( ?? ) : int -> t
      val ( ! ) : Coeff.t -> t
      val ( *. ) : Coeff.t -> t -> t
      val ( ~- ) : t -> t
      val ( + ) : t -> t -> t
      val ( - ) : t -> t -> t
      val ( * ) : t -> t -> t
      val ( / ) : t -> Coeff.t -> t
      val ( /. ) : Coeff.t -> Coeff.t -> t
      val ( ** ) : t -> int -> t
      val pp : Format.formatter -> t -> unit
      val pp_names : string list -> Format.formatter -> t -> unit
      val merge :
        (Monomial.t -> Coeff.t option -> Coeff.t option -> Coeff.t option) ->
        t -> t -> t
      val fold : (Monomial.t -> Coeff.t -> '-> 'a) -> t -> '-> 'a
    end
  type var
  type polynomial_expr =
      Const of Poly.t
    | Var of var
    | Mult_scalar of Poly.Coeff.t * polynomial_expr
    | Add of polynomial_expr * polynomial_expr
    | Sub of polynomial_expr * polynomial_expr
    | Mult of polynomial_expr * polynomial_expr
    | Power of polynomial_expr * int
    | Compose of polynomial_expr * polynomial_expr list
    | Derive of polynomial_expr * int
  val make : ?n:int -> ?d:int -> ?homogen:bool -> string -> polynomial_expr
  val const : Poly.t -> polynomial_expr
  val scalar : Poly.Coeff.t -> polynomial_expr
  val monomial : Monomial.t -> polynomial_expr
  val mult_scalar : Poly.Coeff.t -> polynomial_expr -> polynomial_expr
  val add : polynomial_expr -> polynomial_expr -> polynomial_expr
  val sub : polynomial_expr -> polynomial_expr -> polynomial_expr
  val mult : polynomial_expr -> polynomial_expr -> polynomial_expr
  val power : polynomial_expr -> int -> polynomial_expr
  val compose : polynomial_expr -> polynomial_expr list -> polynomial_expr
  val derive : polynomial_expr -> int -> polynomial_expr
  val of_list : (Monomial.t * polynomial_expr) list -> polynomial_expr
  exception Dimension_error
  val to_list : polynomial_expr -> (Monomial.t * polynomial_expr) list
  val nb_vars : polynomial_expr -> int
  val degree : polynomial_expr -> int
  val is_homogeneous : polynomial_expr -> bool
  val param_vars : polynomial_expr -> var list
  val ( !! ) : Poly.t -> polynomial_expr
  val ( ?? ) : int -> polynomial_expr
  val ( ! ) : Poly.Coeff.t -> polynomial_expr
  val ( *. ) : Poly.Coeff.t -> polynomial_expr -> polynomial_expr
  val ( ~- ) : polynomial_expr -> polynomial_expr
  val ( + ) : polynomial_expr -> polynomial_expr -> polynomial_expr
  val ( - ) : polynomial_expr -> polynomial_expr -> polynomial_expr
  val ( * ) : polynomial_expr -> polynomial_expr -> polynomial_expr
  val ( / ) : polynomial_expr -> Poly.Coeff.t -> polynomial_expr
  val ( /. ) : Poly.Coeff.t -> Poly.Coeff.t -> polynomial_expr
  val ( ** ) : polynomial_expr -> int -> polynomial_expr
  val ( >= ) : polynomial_expr -> polynomial_expr -> polynomial_expr
  val ( <= ) : polynomial_expr -> polynomial_expr -> polynomial_expr
  val pp : Format.formatter -> polynomial_expr -> unit
  val pp_names : string list -> Format.formatter -> polynomial_expr -> unit
  type options = {
    sdp : Sdp.options;
    verbose : int;
    scale : bool;
    trace_obj : bool;
    dualize : bool;
    monoms : Monomial.t list list;
    pad : float;
    pad_list : float list;
  }
  val default : options
  type obj =
      Minimize of polynomial_expr
    | Maximize of polynomial_expr
    | Purefeas
  type values
  type 'a witness = Monomial.t array * 'a array array
  exception Not_linear
  val solve :
    ?options:options ->
    ?solver:Sdp.solver ->
    obj ->
    polynomial_expr list ->
    SdpRet.t * (float * float) * values * float witness list
  val value : polynomial_expr -> values -> Poly.Coeff.t
  val value_poly : polynomial_expr -> values -> Poly.t
  val check :
    ?options:options ->
    ?values:values -> polynomial_expr -> float witness -> bool
  val check_round :
    ?options:options ->
    ?values:values ->
    polynomial_expr list ->
    float witness list -> (values * Scalar.Q.t witness list) option
end