summaryrefslogtreecommitdiff
path: root/proofs/tactic_debug.ml
diff options
context:
space:
mode:
Diffstat (limited to 'proofs/tactic_debug.ml')
-rw-r--r--proofs/tactic_debug.ml179
1 files changed, 179 insertions, 0 deletions
diff --git a/proofs/tactic_debug.ml b/proofs/tactic_debug.ml
new file mode 100644
index 00000000..1fa1101d
--- /dev/null
+++ b/proofs/tactic_debug.ml
@@ -0,0 +1,179 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Ast
+open Names
+open Constrextern
+open Pp
+open Pptactic
+open Printer
+open Tacexpr
+open Termops
+
+let pr_glob_tactic x =
+ (if !Options.v7 then pr_glob_tactic else Pptacticnew.pr_glob_tactic (Global.env())) x
+
+(* This module intends to be a beginning of debugger for tactic expressions.
+ Currently, it is quite simple and we can hope to have, in the future, a more
+ complete panel of commands dedicated to a proof assistant framework *)
+
+(* Debug information *)
+type debug_info =
+ | DebugOn of int
+ | DebugOff
+
+(* An exception handler *)
+let explain_logic_error = ref (fun e -> mt())
+
+(* Prints the goal *)
+let db_pr_goal g =
+ msgnl (str "Goal:" ++ fnl () ++ Proof_trees.pr_goal (Tacmach.sig_it g))
+
+(* Prints the commands *)
+let help () =
+ msgnl (str "Commands: <Enter>=Continue" ++ fnl() ++
+ str " h/?=Help" ++ fnl() ++
+ str " r<num>=Run <num> times" ++ fnl() ++
+ str " s=Skip" ++ fnl() ++
+ str " x=Exit")
+
+(* Prints the goal and the command to be executed *)
+let goal_com g tac =
+ begin
+ db_pr_goal g;
+ msg (str "Going to execute:" ++ fnl () ++ pr_glob_tactic tac ++ fnl ())
+ end
+
+(* Gives the number of a run command *)
+let run_com inst =
+ if (String.get inst 0)='r' then
+ let num = int_of_string (String.sub inst 1 ((String.length inst)-1)) in
+ if num>0 then num
+ else raise (Invalid_argument "run_com")
+ else
+ raise (Invalid_argument "run_com")
+
+let allskip = ref 0
+let skip = ref 0
+
+(* Prints the run counter *)
+let run ini =
+ if not ini then
+ for i=1 to 2 do
+ print_char (Char.chr 8);print_char (Char.chr 13)
+ done;
+ msg (str "Executed expressions: " ++ int (!allskip - !skip) ++
+ fnl() ++ fnl())
+
+(* Prints the prompt *)
+let rec prompt level =
+ begin
+ msg (fnl () ++ str "TcDebug (" ++ int level ++ str ") > ");
+ flush stdout;
+ let inst = read_line () in
+ match inst with
+ | "" -> true
+ | "s" -> false
+ | "x" -> print_char (Char.chr 8);skip:=0;allskip:=0;raise Sys.Break
+ | "h"| "?" ->
+ begin
+ help ();
+ prompt level
+ end
+ | _ ->
+ (try let ctr=run_com inst in skip:=ctr;allskip:=ctr;run true;true
+ with Failure _ | Invalid_argument _ -> prompt level)
+ end
+
+(* Prints the state and waits for an instruction *)
+let debug_prompt lev g tac f =
+ (* What to print and to do next *)
+ let continue =
+ if !skip = 0 then (goal_com g tac; prompt lev)
+ else (decr skip; run false; if !skip=0 then allskip:=0; true) in
+ (* What to execute *)
+ try f (if continue then DebugOn (lev+1) else DebugOff)
+ with e ->
+ skip:=0; allskip:=0;
+ if Logic.catchable_exception e then
+ ppnl (str "Level " ++ int lev ++ str ": " ++ !explain_logic_error e);
+ raise e
+
+(* Prints a constr *)
+let db_constr debug env c =
+ if debug <> DebugOff & !skip = 0 then
+ msgnl (str "Evaluated term: " ++ prterm_env env c)
+
+(* Prints the pattern rule *)
+let db_pattern_rule debug num r =
+ if debug <> DebugOff & !skip = 0 then
+ begin
+ msgnl (str "Pattern rule " ++ int num ++ str ":");
+ msgnl (str "|" ++ spc () ++
+ pr_match_rule false Printer.pr_pattern pr_glob_tactic r)
+ end
+
+(* Prints the hypothesis pattern identifier if it exists *)
+let hyp_bound = function
+ | Anonymous -> " (unbound)"
+ | Name id -> " (bound to "^(Names.string_of_id id)^")"
+
+(* Prints a matched hypothesis *)
+let db_matched_hyp debug env (id,c) ido =
+ if debug <> DebugOff & !skip = 0 then
+ msgnl (str "Hypothesis " ++
+ str ((Names.string_of_id id)^(hyp_bound ido)^
+ " has been matched: ") ++ prterm_env env c)
+
+(* Prints the matched conclusion *)
+let db_matched_concl debug env c =
+ if debug <> DebugOff & !skip = 0 then
+ msgnl (str "Conclusion has been matched: " ++ prterm_env env c)
+
+(* Prints a success message when the goal has been matched *)
+let db_mc_pattern_success debug =
+ if debug <> DebugOff & !skip = 0 then
+ msgnl (str "The goal has been successfully matched!" ++ fnl() ++
+ str "Let us execute the right-hand side part..." ++ fnl())
+
+let pp_match_pattern env = function
+ | Term c -> Term (extern_pattern env (names_of_rel_context env) c)
+ | Subterm (o,c) ->
+ Subterm (o,(extern_pattern env (names_of_rel_context env) c))
+
+(* Prints a failure message for an hypothesis pattern *)
+let db_hyp_pattern_failure debug env (na,hyp) =
+ if debug <> DebugOff & !skip = 0 then
+ msgnl (str ("The pattern hypothesis"^(hyp_bound na)^
+ " cannot match: ") ++
+ pr_match_pattern
+ (Printer.pr_pattern_env env (names_of_rel_context env))
+ hyp)
+
+(* Prints a matching failure message for a rule *)
+let db_matching_failure debug =
+ if debug <> DebugOff & !skip = 0 then
+ msgnl (str "This rule has failed due to matching errors!" ++ fnl() ++
+ str "Let us try the next one...")
+
+(* Prints an evaluation failure message for a rule *)
+let db_eval_failure debug s =
+ if debug <> DebugOff & !skip = 0 then
+ let s = if s="" then "no message" else "message \""^s^"\"" in
+ msgnl
+ (str "This rule has failed due to \"Fail\" tactic (" ++
+ str s ++ str ", level 0)!" ++ fnl() ++ str "Let us try the next one...")
+
+(* Prints a logic failure message for a rule *)
+let db_logic_failure debug err =
+ if debug <> DebugOff & !skip = 0 then
+ begin
+ msgnl (!explain_logic_error err);
+ msgnl (str "This rule has failed due to a logic error!" ++ fnl() ++
+ str "Let us try the next one...")
+ end