/**
  * g must form a circuit
  *
  * @param g a directed graph variable
  * @return a circuit constraint
  */
 public static Constraint circuit(IDirectedGraphVar g) {
   if (g.getMandatoryNodes().getSize() == g.getNbMaxNodes()) {
     return hamiltonian_circuit(g);
   }
   return new Constraint(
       "circuit",
       new PropNodeDegree_AtLeast_Incr(g, Orientation.SUCCESSORS, 1),
       new PropNodeDegree_AtLeast_Incr(g, Orientation.PREDECESSORS, 1),
       new PropNodeDegree_AtMost_Incr(g, Orientation.SUCCESSORS, 1),
       new PropNodeDegree_AtMost_Incr(g, Orientation.PREDECESSORS, 1),
       new PropNbSCC(g, g.getSolver().ONE),
       new PropCircuit(g));
 }
 /**
  * Creates a constraint which states that d is the diameter of g i.e. d is the length (number of
  * arcs) of the largest shortest path among any pair of nodes This constraint implies that g is
  * strongly connected
  *
  * @param g a directed graph variable
  * @param d an integer variable
  * @return a constraint which states that d is the diameter of g
  */
 public static Constraint diameter(IDirectedGraphVar g, IntVar d) {
   return new Constraint("NbCliques", new PropNbSCC(g, g.getSolver().ONE), new PropDiameter(g, d));
 }
 /**
  * Creates a strong connectedness constraint which ensures that g is strongly connected
  *
  * @param g a directed graph variable
  * @return A strong connectedness constraint which ensures that g is strongly connected
  */
 public static Constraint strongly_connected(IDirectedGraphVar g) {
   return nb_strongly_connected_components(
       g, VF.bounded("nbSCC", 0, g.getNbMaxNodes(), g.getSolver()));
 }