How to output Graph.SS.t type varible

I am using OCaml to solve a max-cut problem, and I am learning other’s code. I want to know how to output a Graph.SS.t type variable. A part of the main code is as follows:

let ()=
  if (Array.length Sys.argv) = 2 then
	  let demo = Graph.create_graph_DIMACS Sys.argv.(1) in
	  let time_start = Unix.time () in
	  let (fbest, c) = bls demo 1000. in
	  let time_end = Unix.time () in
	  Printf.printf "durrée : %f\n" (time_end -. time_start);
	  Printf.printf "fbest: %d\n" fbest;
  	  if isClique demo c then Printf.printf "OK\n"
  else Printf.printf "Entrez le path du fichier DIMACS\n" ;;

Where does Graph.create_graph_SS come from?

Graph.create_graph_SS is a function to create a graph.

let create_graph_DIMACS = fun filename ->
	let ic = open_in filename in
	let comment_flag = ref true in
	let num_edges = ref 0 in
	let num_nodes = ref 0 in
		while !comment_flag do
			let line = input_line ic in
			let line_type = String.get line 0 in
			if line_type = 'p' then 
				(let l = Str.split (Str.regexp " ") line in
				num_edges := int_of_string (List.nth l 3);
				num_nodes := int_of_string (List.nth l 2);
				comment_flag := false )
		let graph = create_graph !num_nodes in
		for i = 1 to !num_edges do
			let line = input_line ic in
			let l = Str.split (Str.regexp " ") line in
			add_edge_id graph (int_of_string (List.nth l 1) ) (int_of_string (List.nth l 2))

Maybe bls more important, which is the function to solve max-cut problem.

(*fonction principale de la recherche*)
let bls = fun graph t ->
  (*Graphics.open_graph (Printf.sprintf " %dx%d+50-0" 800 800);*)
  Random.self_init () ;
  (* on commence par initialiser les ensembles, les variables et parametres utilises *)
  let c = ref (Move.first_solution graph) in (* la clique courante *)
  let pa = ref Pqueue.empty in
  let om = ref (Move.create_om graph !c) in
  let fc = ref (func_eval !c) in 	(* la valeur de la fonction objective*)
  (*let fc_array = ref [|(0, !fc * 5)|] in*)
  let cbest = ref !c in  	(* la meilleure clique *)
  let fbest = ref !fc in  	(* la meilleur valeure de la fonction objective *)
  let cp = ref !c in  		(* le dernier optimum local *)
  let w = ref 0 in  		(* compteur pour les optima locals consecutifs sans amelioration *)
  let l0 = (Array.length graph.Graph.nodes) / 100 in
  let lmax = (Array.length graph.Graph.nodes) / 10 in
  let l = ref l0 in
  let tl = (fun a -> (0-max_int, 0)) graph.Graph.nodes in (* inialisation de la tabou list *)
  let nbIter = ref 0 in
  let alpha_r = 0.8 and alpha_s=0.8 and p0 = 0.75 in (*alpha_r = 0.83 and alpha_s=0.58 and p0 = 0.63 in*)
  (* boucle principale de la recherche *)
  while !nbIter < 10000 do
    while in_local_search graph !nbIter tl !pa !om !c do (* tant que PA est non vide ou OM est non vide et ameliore la recherche*)
      if Pqueue.is_empty !pa then (* on applique M2 si M1 n'est pas applicable *)
	(let m = Move.M2 in
	Move.apply_move m graph c pa om fc !nbIter tl)
      else if Pqueue.is_empty !om then (* on applique M1 si M2 n'est pas applicable *)
	(let m = Move.M1 in
	Move.apply_move m graph c pa om fc !nbIter tl)
	(let m = Move.best_move !pa !om !fc in    
	Move.apply_move m graph c pa om fc !nbIter tl);   (* on applique le meilleur mouvement entre M1 et
	la mise a jour des ensembles PA et OM et la tabou liste se fait dans la fonction apply_move*)
      nbIter := !nbIter + 1
    (*fc_array:= Array.append !fc_array [|(!nbIter, !fc*5)|];
    Draw.draw graph !c;
    Graphics.draw_poly_line !fc_array;*)
      if fc > fbest then	(* si vrai, on met a jour la meilleure solution, et on remet le compteur a 0 *)
        (cbest := !c;
         fbest := !fc;
         w := 0) 
        w := !w + 1
      if float_of_int !w > t then (* si le compteur est superieur au parametre t 
      c.a.d on a pas une meilleure solution pour t iteration, on met l la puissance de la perturbation a lmax *) 
        (l := lmax;
         w := 0)
      else if !c = !cp then
        l := !l + 1
      else (* on a trouve une meilleure solution on met la puissance de la perturbation au niveau l0 *)
        l := l0
    cp := !c;
    (* on applique la fonction perturbation *)
    Perturbation.perturbation graph pa om fc c !l tl nbIter !w alpha_r alpha_s t p0 fbest;
  (!fbest, !cbest);;

Do you have an interface for the Graph module? SS sounds like subset [of nodes], so it might be the result of Set.Make (Node) for some Node module, but without the code I can’t give you a definitive answer.

By the way, you don’t need Str.split to split on a single char, there’s String.split_on_char since OCaml 4.04.

The first solution is generated by:

(* first_solution graph renvoie une clique maxiximale (dans le sens on ne peut plus ajouter de noeud à la clique) dont le noeud initial est choisi au hasard *)
let first_solution = fun graph ->
  let u = Graph.get_node_id graph ( (1 + Array.length graph.Graph.nodes)) in
  let rec update = fun c auth_list ->	(* mettre à jour la liste des noeuds autorisés à être ajouter à la clique *)
    match auth_list with
      [] ->  c							(* on arrête quand on ne peut plus ajouter de noeud à la clique *)
    |tete::queue -> update (Graph.SS.add tete c) (authorized graph tete queue) in
  update (Graph.SS.singleton u) (Graph.get_voisins graph u)

It might be an instance of Set.S. Your editor could tell you, if you used merlin. Anyway… try Graph.SS.iter (Printf.printf "%d\n") c, then use the error you’ll get from the typechecker to figure out the type of nodes.

This is how I get the type of c.

Printf.printf "%d\n" c;
Error: This expression has type Graph.SS.t
       but an expression was expected of type int

That’s nothing new for me, as you gave me its type in your first message. Have you tried this?

Sorry, I miss your message. I try it and meet an error.

Error: This expression has type int -> unit
       but an expression was expected of type Graph.SS.elt -> unit
       Type int is not compatible with type Graph.SS.elt = Graph.node