123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214(* This file is free software, part of Zipperposition. See file "license" for more details. *)(** {1 Phases of the Prover} *)openLogtkopenLibzipperpositionmoduleE=CCResulttypefilename=stringtype'aor_error=('a,string)CCResult.t(** {2 Phases} *)typeenv_with_clauses=Env_clauses:'cEnv.packed*'cClause.sets->env_with_clausestypeenv_with_result=Env_result:'cEnv.packed*Saturate.szs_status->env_with_resulttypeerrcode=inttypeprelude=UntypedAST.statementIter.ttype('ret,'before,'after)phase=|Init:(unit,_,[`Init])phase(* global setup *)|Setup_gc:(unit,[`Init],[`Init])phase|Setup_signal:(unit,[`Init],[`Init])phase|Parse_CLI:(filenamelist*Params.t,[`Init],[`Parse_cli])phase(* parse CLI options: get a list of files to process, and parameters *)|LoadExtensions:(Extensions.tlist,[`Parse_cli],[`LoadExtensions])phase|Parse_prelude:(prelude,[`LoadExtensions],[`Parse_prelude])phase|Start_file:(filename,[`Parse_prelude],[`Start_file])phase(* file to process *)|Parse_file:(Input_format.t*UntypedAST.statementIter.t,[`Start_file],[`Parse_file])phase(* parse some file *)|Typing:(TypeInference.typed_statementCCVector.ro_vector,[`Parse_file],[`Typing])phase|CNF:(Statement.clause_tCCVector.ro_vector,[`Typing],[`CNF])phase|Compute_prec:(Precedence.t,[`CNF],[`Precedence])phase|Compute_ord_select:(Ordering.t*Selection.t,[`Precedence],[`Compute_ord_select])phase(* compute orderign and selection function *)|MakeCtx:((moduleCtx.S),[`Compute_ord_select],[`MakeCtx])phase|MakeEnv:(env_with_clauses,[`MakeCtx],[`MakeEnv])phase|Pre_saturate:('cEnv.packed*Saturate.szs_status*'cClause.sets,[`MakeEnv],[`Pre_saturate])phase|Saturate:(env_with_result,[`Pre_saturate],[`Saturate])phase|Print_result:(unit,[`Saturate],[`Print_result])phase|Print_dot:(unit,[`Print_result],[`Print_dot])phase|Check_proof:(errcode,[`Print_dot],[`Check_proof])phase|Print_stats:(unit,[`Check_proof],[`Print_stats])phase|Exit:(unit,_,[`Exit])phasetypeany_phase=Any_phase:(_,_,_)phase->any_phase(** A phase hidden in an existential type *)moduleState=Flex_statemoduleKey=structletcur_phase=State.create_key()end(* empty state: at Init *)letempty_state=State.empty|>State.addKey.cur_phase(Any_phaseInit)(* A simple state monad *)type(+'a,'p1,'p2)t=State.t->(State.t*'a)or_errorletstring_of_phase:typeabc.(a,b,c)phase->string=function|Init->"init"|Setup_gc->"setup_gc"|Setup_signal->"setup_signal"|Parse_CLI->"parse_cli"|LoadExtensions->"load_extensions"|Parse_prelude->"parse_prelude"|Start_file->"start_file"|Parse_file->"parse_file"|Typing->"typing"|CNF->"cnf"|Compute_prec->"compute_prec"|Compute_ord_select->"compute_ord_select"|MakeCtx->"make_ctx"|MakeEnv->"make_env"|Pre_saturate->"pre_saturate"|Saturate->"saturate"|Print_result->"print_result"|Print_stats->"print_stats"|Print_dot->"print_dot"|Check_proof->"check_proof"|Exit->"exit"letstring_of_any_phase(Any_phasep)=string_of_phasepletreturnxst=E.return(st,x)letreturn_errxst=matchxwith|E.Okx->E.Ok(st,x)|E.Errormsg->E.Errormsgletfailmsg_=E.Errormsgletbindx~fst=matchxstwith|E.Ok(st,x)->fxst|E.Errormsg->E.Errormsg(* cut evaluation *)letbind_erre~fst=matchewith|E.Okx->fxst|E.Errormsg->failmsgst(* cut evaluation *)letmapx~fst=matchxstwith|E.Errormsg->E.Errormsg|E.Ok(st,x)->E.Ok(st,fx)moduleInfix=structlet(>>=)xf=bindx~flet(>>?=)xf=bind_errx~flet(>|=)xf=mapx~fendincludeInfixletrecfold_l~f~x=function|[]->returnx|y::ys->fxy>>=funx'->fold_l~f~x:x'ysletcurrent_phasest=tryE.Ok(st,State.get_exnKey.cur_phasest)withNot_found->letmsg="could not find current phase"inE.Errormsgletstart_phasepst=Util.debugf~section:Const.section2"@{<yellow>start phase@} %s"(funk->k(string_of_phasep));letst=State.addKey.cur_phase(Any_phasep)stinE.Ok(st,())letreturn_phase_errx=current_phase>>=funp->Util.debugf~section:Const.section2"@{<yellow>terminate phase@} %s"(funk->k(string_of_any_phasep));return_errxletreturn_phasex=return_phase_err(E.Okx)letwith_phase1p~fx=start_phasep>>=fun()->lety=fxinreturn_phaseyletwith_phasep~f=with_phase1p~f()letwith_phase2p~fxy=with_phase1p~f:(fx)yletexit=start_phaseExit>>=fun()->return_phase()letgetst=E.Ok(st,st)letget_keykst=matchFlex_state.getkstwith|None->E.Error"key not found"|Somev->E.Ok(st,v)letsetnew_st_st=E.Ok(new_st,())letset_keykvst=letst=Flex_state.addkvstinE.Ok(st,())letrun_parallell=letrecaux=function|[]->return0|[a]->a|a::tail->get>>=funold_st->a>>=funn->ifn<>0thenreturnnelse((* restore old state *)setold_st>>=fun()->auxtail)inauxlletupdate~fst=letst=fstinE.Ok(st,())letrun_withstm=trymstwithe->letstack=Printexc.get_backtrace()inletmsg=Printexc.to_stringeinE.Error(msg^"\n"^stack)letrunm=run_withState.emptym