diff --git a/src/coalg/coalg.ml b/src/coalg/coalg.ml
index c2180eedc9b2e5ba7dedb5882bf5876888c1ba8f..76e4123ff4d67676db68368d8b34fa7ccebcafdb 100644
--- a/src/coalg/coalg.ml
+++ b/src/coalg/coalg.ml
@@ -187,10 +187,7 @@ let choiceNNF () =
 
 let choiceGraph () =
   choiceSat ();
-  print_endline "digraph reasonerstate {";
-  CM.graphIterCores (fun core -> print_endline (CM.coreToDot core));
-  CM.graphIterStates (fun state -> print_endline (CM.stateToDot state));
-  print_endline "}"
+  print_endline (CM.graphToDot ())
 
 let choiceVerify () =
     try
diff --git a/src/debugger/debugger.ml b/src/debugger/debugger.ml
index b2366bdeb2f791fe76cabc46531e98b509a88af8..a1a1aaab311b4e3e8b45204f2fb933d6f34c291f 100644
--- a/src/debugger/debugger.ml
+++ b/src/debugger/debugger.ml
@@ -72,10 +72,11 @@ let listStates args =
     CM.graphIterStates (fun state -> print_endline (CM.stateToString state))
 
 let exportGraph args =
-  print_endline "digraph reasonerstate {";
-  CM.graphIterCores (fun core -> print_endline (CM.coreToDot core));
-  CM.graphIterStates (fun state -> print_endline (CM.stateToDot state));
-  print_endline "}"
+  let out = match args with
+    | (filename::_) -> open_out filename
+    | _ -> stdout
+  in
+  Printf.fprintf out "%s" (CM.graphToDot ())
 
 let showNode = function
     | (n::_) ->
diff --git a/src/lib/CoAlgMisc.ml b/src/lib/CoAlgMisc.ml
index 667d3a6be3d99c1a63af65449f1ead212f2423c2..6d20a7ac4da9096ac1e9d3c49ccc5930e2c457eb 100644
--- a/src/lib/CoAlgMisc.ml
+++ b/src/lib/CoAlgMisc.ml
@@ -811,59 +811,58 @@ let stateToString (state:state): string =
     "  Parents: { "^(String.concat ", " parents)^" }\n"^
     "}"
 
-let stateToDot (state:state): string =
-  let color = match state.statusS with
-    | Sat -> "green"
-    | Unsat -> "red"
-    | Open -> "yellow"
+let nodeToDot idx typ sort formulas deferrals status parentIdxs : string =
+  let color = match status with
+    | Sat -> "#8ae234"
+    | Unsat -> "#ef2929"
+    | Open -> "#729fcf"
     | Expandable -> "white"
   in
   let toFormula (lf:localFormula) (lst: string list) : string list =
-    let formula: C.formula = lfGetFormula state.sortS lf in
-    if (bsetMem state.deferralS lf)
-    then ("<B>"^(escapeHtml (C.string_of_formula formula))^"</B>") :: lst
+    let formula: C.formula = lfGetFormula sort lf in
+    if (bsetMem deferrals lf)
+    then ("<U>"^(escapeHtml (C.string_of_formula formula))^"</U>") :: lst
     else (escapeHtml (C.string_of_formula formula)) :: lst
   in
-  let formulaList = bsetFold toFormula state.bsS [] in
-  let ownidx = (string_of_int state.idxS) in
+  let formulaList = bsetFold toFormula formulas [] in
+  let ownidx = (string_of_int idx) in
   let parents =
-    List.map (fun (co:core) ->
-              "Node"^string_of_int co.idxC^" -> Node"^ownidx^";")
-             state.parentsS
+    List.map (fun (parentIdx) ->
+              "Node"^string_of_int parentIdx^" -> Node"^ownidx^";")
+             parentIdxs
   in
-  "Node" ^ ownidx ^ " [shape=ellipse,style=filled,fillcolor=" ^ color
-  ^ ",label=<State "  ^ ownidx
-  ^ "<BR/>" ^ (String.concat "<BR/>" formulaList)
+  let style = if typ = "Core" then "filled,rounded" else "filled" in
+  "Node" ^ ownidx ^ " [shape=box,style=\"" ^ style
+  ^ "\",fillcolor=\"" ^ color ^ "\""
+  ^ ",label=<<B>" ^ typ ^ " "  ^ ownidx ^ "</B>"
+  ^ "<BR/><BR/>" ^ (String.concat "<BR/>" formulaList)
   ^ ">];\n"
   ^ (String.concat "\n" parents)
 
+let stateToDot (state:state): string =
+  nodeToDot state.idxS "State" state.sortS state.bsS state.deferralS
+            state.statusS (List.map (fun c -> c.idxC) state.parentsS)
 
 let coreToDot (core:core): string =
-  let color = match core.statusC with
-    | Sat -> "green"
-    | Unsat -> "red"
-    | Open -> "yellow"
-    | Expandable -> "white"
-  in
-  let toFormula (lf:localFormula) (lst: string list) : string list =
-    let formula: C.formula = lfGetFormula core.sortC lf in
-    if (bsetMem core.deferralC lf)
-    then ("<B>"^(escapeHtml (C.string_of_formula formula))^"</B>") :: lst
-    else (escapeHtml (C.string_of_formula formula)) :: lst
-  in
-  let formulaList = bsetFold toFormula core.bsC [] in
-  let ownidx = (string_of_int core.idxC) in
-  let parents =
-    List.map (fun (st,_:state*int) ->
-              "Node"^string_of_int st.idxS^" -> Node"^ownidx^";")
-             core.parentsC
-  in
-  "Node" ^ ownidx ^ " [shape=ellipse,style=filled,fillcolor=" ^ color
-  ^ ",label=<Core "  ^ ownidx
-  ^ "<BR/>" ^ (String.concat "<BR/>" formulaList)
-  ^ ">];\n"
-  ^ (String.concat "\n" parents)
-
+  nodeToDot core.idxC "Core" core.sortC core.bsC core.deferralC
+            core.statusC (List.map (fun (s,_) -> s.idxS) core.parentsC)
+
+let graphToDot () : string =
+  let lines = ref ["digraph reasonerstate {"] in
+  graphIterCores (fun core -> lines := (coreToDot core)::!lines);
+  graphIterStates (fun state -> lines := (stateToDot state)::!lines);
+
+  let legend =
+    "subgraph legend {\n"
+    ^ "key [label=<<TABLE CELLBORDER=\"0\" BGCOLOR=\"#d3d7cf\">\n"
+    ^ "<TR><TD>Color:</TD><TD BGCOLOR=\"#8ae234\">sat</TD><TD BGCOLOR=\"#ef2929\">unsat</TD><TD BGCOLOR=\"#729fcf\">open</TD><TD BGCOLOR=\"white\">expandable</TD></TR>"
+    ^ "<TR><TD>Rounded:</TD><TD>cores</TD></TR>"
+    ^ "<TR><TD>Boxed:</TD><TD>states</TD></TR>"
+    ^ "<TR><TD>Underlined:</TD><TD>focus</TD></TR>"
+    ^ "</TABLE>>, shape=none];}" in
+
+  lines := "}"::legend::!lines;
+  String.concat "\n" (List.rev !lines)
 
 let queuePrettyStatus () =
   let printList (sl : int list) : string =
diff --git a/src/lib/CoAlgMisc.mli b/src/lib/CoAlgMisc.mli
index 3187932aabb83dfcc9cd143a713e04fb44ba496a..b38722f508fda56701adccfe04381727a07918f0 100644
--- a/src/lib/CoAlgMisc.mli
+++ b/src/lib/CoAlgMisc.mli
@@ -195,6 +195,9 @@ val graphSizeCnstr : unit -> int
 val graphAddRoot : core -> unit
 val graphGetRoot : unit -> core
 
+(** Generate a graphviz dot description of the current reasoner graph *)
+val graphToDot : unit -> string
+
 
 (*****************************************************************************)
 (*     "Module type" and a specific implementation of sets of constraints    *)
@@ -231,7 +234,6 @@ val stateGetConstraints : state -> csetSet
 val stateSetConstraints : state -> csetSet -> unit
 val stateNextRule : state -> ruleEnumeration
 val stateToString : state -> string
-val stateToDot : state -> string
 val stateGetIdx : state -> int
 
 
@@ -264,7 +266,6 @@ val coreGetIdx : core -> int
 val coreGetConstraintParents : core -> cset list
 val coreAddConstraintParent : core -> cset -> unit
 val coreToString : core -> string
-val coreToDot : core -> string
 
 
 (*****************************************************************************)