diff --git a/_oasis b/_oasis
index b114ffaa724aa3800bb9f44d0868192324f447ff..044ad498ed1c6fea4a182af54b90b6c0c864d69c 100644
--- a/_oasis
+++ b/_oasis
@@ -150,6 +150,19 @@ Executable replexample
   if flag(static)
     CCLib:            -static
 
+Executable debugger
+  CompiledObject:   native
+  Path:             src/debugger/
+  BuildTools:       ocamlbuild
+  MainIs:           debugger.ml
+  BuildDepends:     interfacencurses, libcool
+  NativeOpt:        -cc g++
+  ByteOpt:        -cc g++
+  CCOpt: -std=c++98 -x c++
+  if flag(static)
+    CCLib:            -static
+
+
 
 # some cabal similar syntax, so steal its syntax highlighting
 # vim: ft=cabal
diff --git a/src/debugger/debugger.ml b/src/debugger/debugger.ml
new file mode 100644
index 0000000000000000000000000000000000000000..bc4fd5b54539a3e23dcb05edfab4db6bd741c1e7
--- /dev/null
+++ b/src/debugger/debugger.ml
@@ -0,0 +1,72 @@
+(** Accepts formulae from the standard input and tests them for satisfiability.
+    Each formula has to be on a separate line and empty lines are ignored.
+    The input is terminated by EOF.
+    @author Florian Widmann
+ *)
+
+module CM = CoAlgMisc
+module CF = CoAlgFormula
+
+module FE = FunctorParsing
+module Reasoner = CoAlgReasoner
+
+open CoolUtils
+
+(* A partial function mapping nominals to their sorts. *)
+let nomTable name =
+  assert (CoAlgFormula.isNominal name);
+  Some 0
+
+
+let _ = Gc.set { (Gc.get()) with Gc.minor_heap_size = 4194304; major_heap_increment = 67108864; space_overhead = 120 }
+
+let printUsage () =
+  print_endline "Usage: \"debugger <functor> <formula>\" where";
+  exit 1
+
+let printResult () =
+    let str = match Reasoner.isRootSat () with
+    | None -> "Reasoning not finished yet"
+    | Some sat -> "Reasoning finished: "^(if sat then "Sat" else "Unsat")
+    in
+    print_endline str
+
+let printStatus () =
+    print_endline ("Generated states: " ^ (string_of_int (CM.graphSizeState ())));
+    print_endline ("Generated cores: " ^ (string_of_int (CM.graphSizeCore ())));
+    print_endline ("Generated constraints: " ^ (string_of_int (CM.graphSizeCnstr ())));
+    print_endline "";
+    print_endline "Queue content:";
+    print_endline (CM.queuePrettyStatus ());
+    print_endline "";
+    printResult ()
+
+let doStep args =
+    if Reasoner.reasonerFinished ()
+    then print_endline "Reasoner already finished!"
+    else try
+            Reasoner.runReasonerStep ()
+         with CoAlgMisc.CoAlg_finished _ -> printResult()
+
+
+let _ =
+  if Array.length Sys.argv < 2 then printUsage()
+  else
+    let formula = Sys.argv.(2) in
+    let sorts = (FE.sortTableFromString Sys.argv.(1)) in
+    let (tbox, f) = CoAlgFormula.importQuery formula in
+    Reasoner.initReasoner sorts nomTable tbox f;
+    let session = {
+      Repl.prompt = "> ";
+      Repl.bindings = Repl.addHelpBinding [
+        Repl.bind "s" doStep "Runs another reasoner step" "" ;
+        Repl.bind "step" doStep "Runs another reasoner step" "" ;
+        Repl.bind "st" (fun _ -> printStatus ()) "Prints reasoning status" "";
+        Repl.bind "status" (fun _ -> printStatus ()) "Prints reasoning status" "";
+        Repl.exitBinding
+      ];
+    }
+    in
+    Repl.start session
+
+
diff --git a/src/lib/CoAlgMisc.ml b/src/lib/CoAlgMisc.ml
index de751dd00ef9c9b07878a2a840626f6a5d2f2b9a..7b388db94a07504bd6639e7ce1106c180a329ee3 100644
--- a/src/lib/CoAlgMisc.ml
+++ b/src/lib/CoAlgMisc.ml
@@ -354,6 +354,11 @@ let doSatPropagation () =
   doPropagation := false;
   res
 
+let queuePrettyStatus () =
+  (Printf.sprintf "Constraints: %d\n" (List.length !queueCnstrs))
+  ^(Printf.sprintf "States: %d\n" (List.length !queueStates))
+  ^(Printf.sprintf "Cores1: %d\n" (List.length !queueCores1))
+  ^(Printf.sprintf "Cores2: %d\n" (List.length !queueCores2))
 
 (*****************************************************************************)
 (*        "Module type" and a specific implementation of the graph           *)
diff --git a/src/lib/CoAlgMisc.mli b/src/lib/CoAlgMisc.mli
index 3dec477383172fe2fca4a116b59dce2e6326b7d3..a2531f203a9b104dcc26b6607482df2061dc1199 100644
--- a/src/lib/CoAlgMisc.mli
+++ b/src/lib/CoAlgMisc.mli
@@ -163,6 +163,7 @@ val queueInsertState : state -> unit
 val queueInsertCore : core -> unit
 val queueInsertCnstr : cset -> unit
 val queueGetElement : unit -> queueElement
+val queuePrettyStatus : unit -> string
 
 val doNominalPropagation : unit -> bool
 val doSatPropagation : unit -> bool
diff --git a/src/lib/CoAlgReasoner.ml b/src/lib/CoAlgReasoner.ml
index f0c9d1c3893d9922cb9da4ebaa1968e833c3b2c6..d13903137c0ec83377f5eacd82a3211af162b298 100644
--- a/src/lib/CoAlgReasoner.ml
+++ b/src/lib/CoAlgReasoner.ml
@@ -7,6 +7,8 @@ open CoAlgMisc
 
 module M = Minisat
 
+module CU = CoolUtils
+
 type sortTable = CoAlgMisc.sortTable
 
 type nomTable = string -> CoAlgFormula.sort option
@@ -608,11 +610,39 @@ let rec expandNodesLoop () =
       expandNodesLoop ()
   | QEmpty -> ()
 
-let rec buildGraphLoop () =
+let runReasonerStep () =
   expandNodesLoop ();
-  propagateNominals ();
+  propagateNominals ()
+
+let rec buildGraphLoop () =
+  runReasonerStep ();
   if queueIsEmpty () then () else buildGraphLoop ()
+
+let initReasoner sorts nomTable tbox sf =
+  sortTable := Array.copy sorts;
+  let (tbox1, sf1, bs) = ppFormulae nomTable tbox sf in
+  let sort = fst sf in
+  let bs1 = bsetAddTBox sort bs in
+  graphInit ();
+  queueInit ();
+  let root = insertCore sort bs1 in
+  graphAddRoot root
+
+let isRootSat () =
+  match coreGetStatus (graphGetRoot ()) with
+  | Expandable -> None
+  | Unsat -> Some false
+  | Sat
+  | Open -> if (queueIsEmpty()) then Some true else None
+
+let reasonerFinished () =
+  match coreGetStatus (graphGetRoot ()) with
+  | Expandable -> false
+  | Unsat
+  | Sat  -> true
+  | Open -> queueIsEmpty ()
     
+
 (** A graph-tableau-based decision procedure framework for coalgebraic logics.
     @param verbose An optional switch which determines
     whether the procedure shall print some information on the standard output.
@@ -625,26 +655,20 @@ let rec buildGraphLoop () =
     @param sf A sorted formula.
     @return True if sf is satisfiable wrt tbox, false otherwise.
  *)
+
 let isSat ?(verbose = false) sorts nomTable tbox sf =
   let start = if verbose then Unix.gettimeofday () else 0. in
-  sortTable := Array.copy sorts;
-  let (tbox1, sf1, bs) = ppFormulae nomTable tbox sf in
-  let sort = fst sf in
-  let bs1 = bsetAddTBox sort bs in
-  graphInit ();
-  queueInit ();
-  let root = insertCore sort bs1 in
-  graphAddRoot root;
+  initReasoner sorts nomTable tbox sf;
   let sat =
     try
       buildGraphLoop ();
-      match coreGetStatus (graphGetRoot ()) with
-      | Expandable -> assert false
-      | Unsat -> false
-      | Sat
-      | Open -> true
+      (* get whether the root is satisfiable *)
+      (* we know that the reasoner finished, so the value is there, *)
+      (* i.e. isRootSat() will give a "Some x" and not "None" *)
+      CU.fromSome (isRootSat())
     with CoAlg_finished res -> res
   in
+  (* print some statistics *)
   if verbose then
     let stop = Unix.gettimeofday () in
     let addup lst = List.fold_left (fun acc sf -> acc + (CoAlgFormula.sizeSortedFormula sf)) 0 lst in
@@ -652,9 +676,11 @@ let isSat ?(verbose = false) sorts nomTable tbox sf =
     print_endline ("Query: " ^ (CoAlgFormula.exportQuery tbox sf));
     let size = (CoAlgFormula.sizeSortedFormula sf) + (addup tbox) in
     print_endline ("Added Size: " ^ (string_of_int size));
+    (*
     print_endline ("Negation Normal Form: " ^ (CoAlgFormula.exportQuery tbox1 sf1));
     let nsize = (CoAlgFormula.sizeSortedFormula sf1) + (addup tbox1) in
     print_endline ("Added Size: " ^ (string_of_int nsize));
+    *)
     print_endline ("Result: Query is " ^ (if not sat then "not " else "") ^ "satisfiable.");
     print_endline ("Time: " ^ (string_of_float (stop -. start)));
     print_endline ("Generated states: " ^ (string_of_int (graphSizeState ())));
@@ -663,3 +689,4 @@ let isSat ?(verbose = false) sorts nomTable tbox sf =
     print_newline ()
   else ();
   sat
+
diff --git a/src/lib/CoAlgReasoner.mli b/src/lib/CoAlgReasoner.mli
index 941f510b1717ab39ee2cf9056ac4dfcb2c6ad544..c96f0f943fea65da024216eae0f7b5439305e713 100644
--- a/src/lib/CoAlgReasoner.mli
+++ b/src/lib/CoAlgReasoner.mli
@@ -13,3 +13,11 @@ type input = sortTable * nomTable * assumptions * CoAlgFormula.sortedFormula
 
 val isSat : ?verbose:bool -> sortTable -> (string -> CoAlgFormula.sort option) ->
   CoAlgFormula.sortedFormula list -> CoAlgFormula.sortedFormula -> bool
+
+
+val initReasoner : sortTable -> (string -> CoAlgFormula.sort option) ->
+  CoAlgFormula.sortedFormula list -> CoAlgFormula.sortedFormula -> unit
+
+val runReasonerStep : unit -> unit
+val reasonerFinished : unit -> bool
+val isRootSat : unit -> bool option
diff --git a/src/lib/CoolUtils.ml b/src/lib/CoolUtils.ml
index 7b3880be8738e32e07c711e312afe03aec1d0bf4..5f06001044edd9162ba34768517b03936469c220 100644
--- a/src/lib/CoolUtils.ml
+++ b/src/lib/CoolUtils.ml
@@ -56,3 +56,8 @@ let foreach_l a f = List.iter f a
 let (<<) f g x = f(g(x))
 let repeat n fct = for i = 1 to n do fct () done
 
+exception No_value
+let fromSome optionalvalue =
+    match optionalvalue with
+    | Some x -> x
+    | None -> raise No_value
diff --git a/src/lib/CoolUtils.mli b/src/lib/CoolUtils.mli
index af5653b1bd7ee489ae0fb1fc7298c04f7aec008a..a79acee065fd1aaff76edb29575e84f942bcb84d 100644
--- a/src/lib/CoolUtils.mli
+++ b/src/lib/CoolUtils.mli
@@ -30,3 +30,6 @@ val foreach_l : ('a list) -> ('a -> unit) -> unit
 val repeat : int -> (unit -> unit) -> unit
 val (<<) : ('b -> 'c) -> ('a -> 'b) -> ('a -> 'c)
 
+exception No_value
+val fromSome : 'a option -> 'a
+