123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341(* This file is free software, part of Zipperposition. See file "license" for more details. *)(** {1 boolean subterms} *)openLogtklet_tmp_dir=ref"/tmp"let_encode_lams=ref`IgnoreexceptionPolymorphismDetectedmoduletypeS=sigmoduleEnv:Env.S(** {5 Registration} *)valset_e_bin:string->unitvaltry_e:Env.C.tIter.t->Env.C.tIter.t->Env.C.toptionvalsetup:unit->unit(** Register rules in the environment *)endlet_timeout=ref11let_e_auto=reffalselet_max_derived=ref16let_only_ho_steps=reftruelet_sort_by_weight_only=reffalselete_bin=ref(None:stringoption)letregex_refutation_begin=Str.regexp".*SZS output start CNFRefutation.*"letregex_refutation_end=Str.regexp".*SZS output end CNFRefutation.*"letreg_thf_clause=Str.regexp"thf(zip_cl_\\([0-9]+\\),.*"moduleIntSet=CCSet.Make(CCInt)moduleMake(E:Env.S):SwithmoduleEnv=E=structmoduleEnv=EmoduleC=Env.CmoduleCtx=Env.CtxmoduleT=TermmoduleCombs=Combinators.Make(E)moduleLLift=Lift_lambdas.Make(E)let(==>)=Type.(==>)letinit_clauses=refC.ClauseSet.emptyletinitialize()=init_clauses:=C.ClauseSet.of_iter(Env.get_passive())exceptionCantEncodeofstringletoutput_empty_conj~out=Format.fprintfout"thf(conj,conjecture,($false))."letrecencode_ty_args_t~encoded_symbolst=letmake_new_symmono_head=ifnot(T.is_groundmono_head)then(leterr=CCFormat.sprintf"%a has non-ground type argument"T.pptinraise@@CantEncodeerr;);let(id,ty),res=T.mk_fresh_skolem~prefix:"ty_enc"[](T.tymono_head)inEnv.Ctx.declareidty;resinletrecaux~sym_mapt=ifnot(Type.is_ground(T.tyt))then(leterr=CCFormat.sprintf"%a has non-ground type %a"T.pptType.pp(T.tyt)inraise@@CantEncodeerr;);matchT.viewtwith|T.Const_|T.Var_|T.DB_->sym_map,t|T.Fun_->leterr=CCFormat.sprintf"%a is a lambda"T.pptinraise@@CantEncodeerr|T.AppBuiltin(b,_)when(Builtin.is_logical_opb||b==Builtin.Eq||b=Builtin.Neq)&¬(Type.is_prop(T.tyt))->leterr=CCFormat.sprintf"%a is ho bool"T.pptinraise@@CantEncodeerr(* type erasure for terms E can understand *)|T.AppBuiltin((Builtin.Eq|Builtin.Neq)asb,[ty;lhs;rhs])whenT.is_groundty->letsym_map,lhs'=aux~sym_maplhsinletsym_map,rhs'=aux~sym_maprhsinsym_map,T.app_builtin~ty:Type.propb[ty;lhs';rhs']|T.AppBuiltin((Builtin.ForallConst|Builtin.ExistsConst)asb,([q;body]))whenType.is_ground(T.tybody)->letvars,body=T.open_funbodyinletsym_map,body'=aux~sym_mapbodyinsym_map,T.app_builtin~ty:Type.propb[q;T.fun_lvarsbody']|T.AppBuiltin(_,l)|T.App(_,l)->lethd_mono,args=T.as_app_monotinletsym_map,hd=ifList.lengthargs!=List.lengthlthen(matchT.Map.gethd_monosym_mapwith|Somemapped->sym_map,mapped|None->letnew_sym=make_new_symhd_monoinT.Map.addhd_mononew_symsym_map,new_sym)else(sym_map,hd_mono)inletsym_map,args'=List.fold_right(funa(sym_map,as_)->letsym_map,a'=aux~sym_mapain(sym_map,a'::as_))args(sym_map,[])insym_map,T.apphdargs'inaux~sym_map:encoded_symbolstletencode_ty_args_cl~encoded_symbolscl=letencoded_symbols,lits=CCArray.fold_right(funl(encoded_symbols,ls)->matchlwith|Literal.Equation(lhs,rhs,sign)->letencoded_symbols,lhs=encode_ty_args_t~encoded_symbolslhsinletencoded_symbols,rhs=encode_ty_args_t~encoded_symbolsrhsinencoded_symbols,(Literal.mk_litlhsrhssign)::ls|_->(encoded_symbols,l::ls))(C.litscl)(encoded_symbols,[])inletrule=Proof.Rule.mk"remove_ty_args"inletproof=Proof.Step.inference~rule[C.proof_parentcl]inletres=ifLiterals.equal(CCArray.of_listlits)(C.litscl)thenclelseC.create~penalty:(C.penaltycl)~trail:(C.trailcl)litsproofinencoded_symbols,resletoutput_cl~outclause=letlits_converted=Literals.Conv.to_tst(C.litsclause)inFormat.fprintfout"%% %d:\n"(C.proof_depthclause);letorig_cl_str=CCFormat.sprintf"%% @[%a@]@."C.pp_tstpclauseinletcommented=CCString.replace~which:`All~sub:"\n"~by:"\n% "orig_cl_strinFormat.fprintfout"%% orig:@.@[%s@]@."commented;match(C.distance_to_goalclause)with|Somedwhend=0->Format.fprintfout"@[thf(zip_cl_%d,negated_conjecture,@[%a@]).@]@\n"(C.idclause)TypedSTerm.TPTP_THF.pplits_converted|_->Format.fprintfout"@[thf(zip_cl_%d,axiom,@[%a@]).@]@\n"(C.idclause)TypedSTerm.TPTP_THF.pplits_convertedletoutput_symdecl~outsymty=Format.fprintfout"@[thf(@['%a_type',type,@[%a@]:@ @[%a@]@]).@]@\n"ID.ppsymID.pp_tstpsym(Type.TPTP.pp_ho~depth:0)tyletoutput_all?(already_defined=ID.Set.empty)~outcl_set=letcl_iter=Iter.of_listcl_setinletsyms=C.symbols~include_types:truecl_iter|>(funsyms->ID.Set.diffsymsalready_defined)|>ID.Set.to_listin(* first printing type declarations, and only then the types *)CCList.fold_right(funsymacc->letty=Ctx.find_signature_exnsyminifType.is_tTypetythen(output_symdecl~outsymty;acc)else(if(((Type.Seq.subty)|>Iter.exists(Type.is_tType)))then(raisePolymorphismDetected;);Iter.cons(sym,ty)acc))symsIter.empty|>Iter.iter(fun(sym,ty)->output_symdecl~outsymty);Iter.iter(output_cl~out)cl_iter;ifID.Set.is_emptyalready_definedthen(output_empty_conj~out);ID.Set.of_listsymsletset_e_binpath=e_bin:=Somepathletdisable_e()=e_bin:=Noneletrun_eprob_path=match!e_binwith|Somee_path->letto_=!_timeoutinletcmd=CCFormat.sprintf"timeout %d %s --pos-ext=all --neg-ext=all %s --cpu-limit=%d %s -s -p"(to_+2)e_pathprob_pathto_(if!_e_autothen"--auto"else"--auto-schedule")inletprocess_channel=Unix.open_process_incmdinletrefutation_found=reffalseinletres=(trywhilenot!refutation_founddoletline=input_lineprocess_channelinifStr.string_matchregex_refutation_beginline0thenrefutation_found:=true;done;if!refutation_foundthen(letclause_ids=ref[]in(trywhiletruedoletline=input_lineprocess_channelinflush_all();ifStr.string_matchreg_thf_clauseline0then(letid=CCInt.of_string(Str.matched_group1line)inclause_ids:=CCOpt.get_exnid::!clause_ids;)elseifStr.string_matchregex_refutation_endline0then(raiseEnd_of_file)done;Some!clause_idswithEnd_of_file->Some!clause_ids))elseNonewithEnd_of_file->None)inclose_inprocess_channel;res|None->invalid_arg"cannot run E if E binary is not set up"lettry_eactive_setpassive_set=letlambdas_too_deepc=letlambda_limit=6inC.Seq.termsc|>Iter.map(funt->CCOpt.get_or~default:0(Term.lambda_deptht))|>Iter.max|>CCOpt.get_or~default:0|>(funlam_depth->lam_depth>lambda_limit)inletconvert_clauses~converter~encoded_symbolsiter=letconverted=Iter.map(func->CCOpt.get_or~default:c(C.eta_reducec))iter|>Iter.flat_map_lconverterinletencoded,encoded_symbols=Iter.fold(fun(acc,encoded_symbols)cl->tryletencoded_symbols,cl'=encode_ty_args_cl~encoded_symbolsclin(cl'::acc,encoded_symbols)withCantEncodereason->Util.debugf5"cannot encode(%s):@.@[%a@]@."(funk->kreasonC.ppcl);(acc,encoded_symbols))([],encoded_symbols)convertedinencoded_symbols,encodedinlettake_initial~converter()=letmoduleCS=C.ClauseSetinCS.filter(func->not(lambdas_too_deepc))!init_clauses|>CS.to_iter|>convert_clauses~converter~encoded_symbols:T.Map.emptyinlettake_ho_clauses~converter~encoded_symbolsclauses=Iter.filter(funcl->letpd=C.proof_depthclinpd>0&&pd<=5)clauses|>Iter.sort~cmp:(func1c2->letpd1=C.proof_depthc1andpd2=C.proof_depthc2inifpd1=pd2||!_sort_by_weight_onlythenCCInt.compare(C.ho_weightc1)(C.ho_weightc2)elseCCInt.comparepd1pd2)|>Iter.take!_max_derived|>convert_clauses~converter~encoded_symbolsinletprob_name,prob_channel=Filename.open_temp_file~temp_dir:!_tmp_dir"e_input"""inletout=Format.formatter_of_out_channelprob_channelintryletconverter=match!_encode_lamswith|`Ignore->(func->[c])|`Combs->(func->([Combs.force_conv_lamsc]:>C.tlist))|_->(func->letlifted=LLift.lift_lambdascinifCCList.is_emptyliftedthen[c]elselifted)inletencoded_symbols,initial=take_initial~converter()inlet_,ho_clauses=take_ho_clauses~encoded_symbols~converter(Iter.appendactive_setpassive_set)inletalready_defined=output_all~outinitialinFormat.fprintfout"%% -- PASSIVE -- \n";ignore(output_all~already_defined~outho_clauses);close_outprob_channel;letcl_set=initial@ho_clausesinletres=matchrun_eprob_namewith|Someids->assert(not(CCList.is_emptyids));letclauses=List.map(funid->List.find(funcl->(C.idcl)=id)cl_set)idsinletrule=Proof.Rule.mk"eprover"inletproof=Proof.Step.inference~rule(List.mapC.proof_parentclauses)inletpenalty=CCOpt.get_exn@@Iter.max(Iter.mapC.penalty(Iter.of_listclauses))inlettrail=C.trail_lclausesinSome(C.create~penalty~trail[]proof)|_->Nonein(* Sys.remove prob_name; *)reswithPolymorphismDetected->CCFormat.printf"%% Running E stopped because polymorphism was detected @.";Noneletsetup()=()let()=Signal.onceEnv.on_startinitialize;endlet()=Options.add_opts["--e-encode-lambdas",Arg.Symbol(["ignore";"lift";"combs"],(funstr->matchstrwith|"ignore"->_encode_lams:=`Ignore|"lift"->_encode_lams:=`Lift|"combs"->_encode_lams:=`Combs|_->assertfalse))," how to treat lambdas when giving problem to E";"--tmp-dir",Arg.String(funv->_tmp_dir:=v)," scratch directory for running E";"--e-timeout",Arg.Set_int_timeout," set E prover timeout.";"--e-sort-by-weight-only",Arg.Bool((:=)_sort_by_weight_only)," order the clauses only by the weight, not by the proof depth.";"--e-only-ho-steps",Arg.Bool((:=)_only_ho_steps)," translate only HO proof steps to E";"--e-max-derived",Arg.Set_int_max_derived," set the limit of clauses that are derived by Zipperposition and given to E";"--e-auto",Arg.Bool(funv->_e_auto:=v)," If set to on eprover will not run in autoschedule, but in auto mode"]