123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182(******************************************************************************)(* This file is part of Waterproof-lib. *)(* *)(* Waterproof-lib is free software: you can redistribute it and/or modify *)(* it under the terms of the GNU General Public License as published by *)(* the Free Software Foundation, either version 3 of the License, or *)(* (at your option) any later version. *)(* *)(* Waterproof-lib is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU General Public License for more details. *)(* *)(* You should have received a copy of the GNU General Public License *)(* along with Waterproof-lib. If not, see <https://www.gnu.org/licenses/>. *)(* *)(******************************************************************************)openPpopenFeedbackletfilter_errors=Summary.ref~name:"filter_errors"trueletwp_debug_log=Summary.ref~name:"wp_debug_log"[]letwp_info_log=Summary.ref~name:"wp_info_log"[]letwp_notice_log=Summary.ref~name:"wp_notice_log"[]letwp_warning_log=Summary.ref~name:"wp_warning_log"[]letwp_error_log=Summary.ref~name:"wp_error_log"[](**
A rudimentary feedback log
*)letfeedback_log(lvl:level):Pp.tlistref=matchlvlwith|Debug->wp_debug_log|Info->wp_info_log|Notice->wp_notice_log|Warning->wp_warning_log|Error->wp_error_log(**
The id that we obtained when registering wp_feedback_logger as a feeder in Feedback.mli
*)letwp_feedback_logger_id=Summary.ref~name:"wp_feedback_logger_id"Noneletinfo_counter=Summary.ref~name:"info_counter"0(**
A custom feedback logger for waterproof
*)letwp_feedback_logger(fb:feedback):unit=matchfb.contentswith|Message(lvl,_,msg)->(feedback_loglvl:=(msg)::!(feedback_loglvl);info_counter:=!info_counter+1)|_->()(**
Adds wp_feedback_logger to Coq's feedback mechanism
*)letadd_wp_feedback_logger():unit=match!wp_feedback_logger_idwith|Some_->msg_warning(str"The waterproof feedback logger was already added")|None->letid=Feedback.add_feederwp_feedback_loggerinwp_feedback_logger_id:=Someid(**
Basic exception info
*)letfatal_flag:'aExninfo.t=Exninfo.make()(**
The last thrown warning
*)letlast_thrown_warning:Pp.toptionref=Summary.ref~name:"last_thrown_warning"None(**
Redirect warnings: this is useful when testing the plugin
*)letredirect_feedback:boolref=Summary.ref~name:"redirect_feedback"false(**
Redirect errors: this is useful when testing the plugin
*)letredirect_errors:boolref=Summary.ref~name:"redirect_errors"false(**
Print hypotheses help
*)letprint_hypothesis_help:boolref=Summary.ref~name:"print_hypothesis_help"false(**
Type of exceptions used in Wateproof
*)typewexn=|CastErrorofstring(** Indicates that a cast made by the FFI has failed *)|FailedAutomationofstring(** Indicates that the automatic solver called has failed *)|FailedTestofstring(** Indicates that the running test has failed *)|NonExistingDatasetofHints.hint_db_name(** Indicates that the user tried to import a non-existing hint dataset *)|UnusedLemmas(** Indicates that no proof using all the given lemmas has been found *)|ToUserErrorofPp.t(** An error that should go directly to the user *)(**
Converts errors to displayable messages
*)letpr_wexn(exn:wexn):t=matchexnwith|CastErrormessage->str"Cast error: "++strmessage|FailedAutomationmessage->str"Automatic solving failed: "++strmessage|FailedTesttest->str"Failed test: "++strtest|NonExistingDatasetdataset->str"Non existing dataset: the dataset "++strdataset++str" is not defined"|UnusedLemmas->str"No proof using all given lemmas has been found"|ToUserErrormessage->message(**
Throws an error with given info and message
*)letthrow?(info:Exninfo.info=Exninfo.null)(exn:wexn):'a=letfatal=Exninfo.addinfofatal_flag()inCErrors.user_err?info:(Somefatal)(pr_wexnexn)(**
Send a message
*)letmessage(lvl:Feedback.level)(input:Pp.t):unitProofview.tactic=if!redirect_feedbackthenProofview.tclUNIT@@(feedback_loglvl:=input::!(feedback_loglvl))elseProofview.tclUNIT@@feedback(Message(lvl,None,input))(**
Send a warning
*)letwarn(input:Pp.t):unitProofview.tactic=messageWarninginput(**
Send a notice
*)letnotice(input:Pp.t):unitProofview.tactic=messageNoticeinput(**
Send an info message
*)letinform(input:Pp.t):unitProofview.tactic=messageInfoinput(**
Throw an error
*)leterr(input:Pp.t):unitProofview.tactic=throw(ToUserErrorinput)(**
Return the last warning
*)letget_last_warning():Pp.toptionProofview.tactic=Proofview.tclUNIT@@match!(feedback_logWarning)with|[]->None|hd::tl->Somehdletwp_error_handler(e:exn):Pp.toption=if!filter_errorsthen(matchewith|CErrors.UserErrorpps->letstr_rep=Pp.string_of_ppcmdsppsinif(Str.string_match(Str.regexp"Expected a single focused goal *")str_rep0)thenSome(Pp.str"Write a bullet point (e.g. \"-\") or curly brace \"{\" in front of this sentence. This will start a subproof. In case you decide to insert a curly brace, after completing the subproof, write a space and curly brace after the last sentence of the subproof. \" }\"")elseif(Str.string_match(Str.regexp"Syntax error*")str_rep0)thenSome(Pp.str"Syntax error: Unfortunately, this sentence cannot be understood and whether all words are spelled correctly. Check for instance correct use of parentheses. To reduce syntax errors, it can be helpful to input sentences using the autocomplete functionality.")elseNone|Gramlib.Grammar.Errors->Some(Pp.str"Syntax error: Unfortunately, this sentence cannot be understood. Check for instance whether all parentheses match and whether all words are spelled correctly. To reduce syntax errors, it can be helpful to input sentences using the autocomplete functionality.")|CErrors.Timeout->Some(Pp.str"Timeout: Waterproof could not find a proof in the allocated time. Consider making a smaller step.")|_->None)elseNonelet()=CErrors.register_handlerwp_error_handler