sig
  module type Mark =
    sig
      type t
      type call_info
      val is_bottom : PdgMarks.Mark.t -> bool
      val merge : PdgMarks.Mark.t -> PdgMarks.Mark.t -> PdgMarks.Mark.t
      val combine :
        PdgMarks.Mark.t ->
        PdgMarks.Mark.t -> PdgMarks.Mark.t * PdgMarks.Mark.t
      val pretty : Stdlib.Format.formatter -> PdgMarks.Mark.t -> unit
    end
  type select_elem = private
      SelNode of PdgTypes.Node.t * Locations.Zone.t option
    | SelIn of Locations.Zone.t
  val mk_select_node :
    ?z_opt:Locations.Zone.t option -> PdgTypes.Node.t -> PdgMarks.select_elem
  val mk_select_undef_zone : Locations.Zone.t -> PdgMarks.select_elem
  type 'tm select = (PdgMarks.select_elem * 'tm) list
  val add_to_select :
    'tm PdgMarks.select -> PdgMarks.select_elem -> 'tm -> 'tm PdgMarks.select
  val add_node_to_select :
    'tm PdgMarks.select ->
    PdgTypes.Node.t * Locations.Zone.t option -> 'tm -> 'tm PdgMarks.select
  val add_undef_in_to_select :
    'tm PdgMarks.select ->
    Locations.Zone.t option -> 'tm -> 'tm PdgMarks.select
  type 'tm pdg_select_info =
      SelList of 'tm PdgMarks.select
    | SelTopMarks of 'tm list
  type 'tm pdg_select = (PdgTypes.Pdg.t * 'tm PdgMarks.pdg_select_info) list
  type 'tm info_caller_inputs = (PdgIndex.Signature.in_key * 'tm) list
  type 'tm info_called_outputs =
      (Cil_types.stmt * (PdgIndex.Signature.out_key * 'tm) list) list
  type 'tm info_inter =
      'tm PdgMarks.info_caller_inputs * 'tm PdgMarks.info_called_outputs
  module type Fct =
    sig
      type mark
      type call_info
      type fi =
          (PdgMarks.Fct.mark, PdgMarks.Fct.call_info) PdgIndex.FctIndex.t
      type t = PdgTypes.Pdg.t * PdgMarks.Fct.fi
      val create : PdgTypes.Pdg.t -> PdgMarks.Fct.t
      val get_idx : PdgMarks.Fct.t -> PdgMarks.Fct.fi
      type mark_info_inter = PdgMarks.Fct.mark PdgMarks.info_inter
      val empty_to_prop : PdgMarks.Fct.mark_info_inter
      val mark_and_propagate :
        PdgMarks.Fct.t ->
        ?to_prop:PdgMarks.Fct.mark_info_inter ->
        PdgMarks.Fct.mark PdgMarks.select -> PdgMarks.Fct.mark_info_inter
    end
  module F_Fct :
    functor (M : Mark->
      sig
        type mark = M.t
        type call_info = M.call_info
        type fi = (mark, call_info) PdgIndex.FctIndex.t
        type t = PdgTypes.Pdg.t * fi
        val create : PdgTypes.Pdg.t -> t
        val get_idx : t -> fi
        type mark_info_inter = mark info_inter
        val empty_to_prop : mark_info_inter
        val mark_and_propagate :
          t -> ?to_prop:mark_info_inter -> mark select -> mark_info_inter
      end
  type 't_mark m2m = PdgMarks.select_elem -> 't_mark -> 't_mark option
  type 't_mark call_m2m =
      Cil_types.stmt option -> PdgTypes.Pdg.t -> 't_mark PdgMarks.m2m
  module type Proj =
    sig
      type t
      type mark
      type call_info
      type fct =
          (PdgMarks.Proj.mark, PdgMarks.Proj.call_info) PdgIndex.FctIndex.t
      val empty : unit -> PdgMarks.Proj.t
      val find_marks :
        PdgMarks.Proj.t -> Cil_types.varinfo -> PdgMarks.Proj.fct option
      val mark_and_propagate :
        PdgMarks.Proj.t ->
        PdgTypes.Pdg.t -> PdgMarks.Proj.mark PdgMarks.select -> unit
    end
  module type Config =
    sig
      module M : Mark
      val mark_to_prop_to_caller_input : M.t PdgMarks.call_m2m
      val mark_to_prop_to_called_output : M.t PdgMarks.call_m2m
    end
end