12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739(* This file is free software, part of Zipperposition. See file "license" for more details. *)(** {1 Priority Queue of clauses} *)openLogtkmoduleO=OrderingmoduleLit=LiteralmoduleLits=LiteralsmoduletypeS=ClauseQueue_intf.Stypeprofile=ClauseQueue_intf.profileletsection=Util.Section.make~parent:Const.section"clause.queue"letcr_var_ratio=ref5letcr_var_mul=ref1.1letparameters_magnitude=ref`Largeletgoal_penalty=reffalseletprofiles_=letopenClauseQueue_intfin["default",P_default;"bfs",P_bfs;"almost-bfs",P_almost_bfs;"explore",P_explore;"ground",P_ground;"goal",P_goal;"conjecture-relative",P_conj_rel;"conjecture-relative-var",P_conj_rel_var;"ho-weight",P_ho_weight;"ho-weight-init",P_ho_weight_init;"avoid-expensive",P_avoid_expensive]letprofile_of_strings=lets=s|>String.trim|>CCString.lowercase_asciiintrymatchCCString.chop_prefix~pre:"conjecture-relative-var"swith|Somesuffix->leterr_msg="conjecture-relative-var(ratio:int,var_mul:float,par:[L,S],goal_penalty:[true,false])"inletargs=List.map(funs->String.trim(CCString.replace~sub:")"~by:""(CCString.replace~sub:"("~by:""s)))(CCString.split~by:","suffix)inifList.lengthargs!=4then(invalid_argerr_msg)else(letratio=CCInt.of_string(List.nthargs0)inletvar_mul=tryfloat_of_string(List.nthargs1)with_->invalid_argerr_msginletpar_mag=List.nthargs2inletgoal_pen=List.nthargs3inifCCOpt.is_noneratiothen(invalid_argerr_msg;)else(cr_var_ratio:=CCOpt.get_exnratio;cr_var_mul:=var_mul;parameters_magnitude:=ifCCString.equalpar_mag"l"then`LargeelseifCCString.equalpar_mag"s"then`Smallelseinvalid_argerr_msg;goal_penalty:=ifCCString.prefix~pre:"t"goal_penthentrueelseifCCString.prefix~pre:"f"goal_penthenfalseelseinvalid_argerr_msg;ClauseQueue_intf.P_conj_rel_var))|None->List.assocsprofiles_withNot_found->invalid_arg("unknown queue profile: "^s)let_profile=refClauseQueue_intf.P_defaultletget_profile()=!_profileletset_profilep=_profile:=pletparse_profiles=_profile:=(profile_of_strings)letfuns_to_parse=ref[]let_ignoring_orphans=reftruelet_rel_terms_enabled=reffalseletignoring_orphans()=!_ignoring_orphansletdisable_ignoring_orphans()=_ignoring_orphans:=falsemoduleMake(C:Clause_intf.S)=structmoduleC=C(* weight of a term [t], using the precedence's weight *)letterm_weightt=Term.sizetlet_related_terms=refTerm.Set.emptyletmax_related_=100leton_proof_state_init=Signal.create()letnorm_apphdarg=letbody=Term.apphd[arg]inletnormalize=ifTerm.is_funhdthenLambda.whnfelseifTerm.is_combhdthenCombinators_base.narrowelseCCFun.idinnormalizebodyletunroll_logical_symbolst=letrecauxt=matchTerm.viewtwith|AppBuiltin((Builtin.ForallConst|Builtin.ExistsConst),[_;x])->letvar_ty=List.hd(fst(Type.open_fun(Term.tyx)))inletfresh_var=Term.var@@HVar.fresh~ty:var_ty()inletapp_x=norm_appxfresh_varinauxapp_x|AppBuiltin(b,l)whenBuiltin.is_logical_binopb->List.fold_left(funacct->Term.Set.unionacc(auxt))Term.Set.emptyl|_->Term.Set.singletontinauxt|>Term.Set.filter(funt->not(Term.is_true_or_falset)&¬(Term.is_constt))letadd_related_term_t=ifTerm.Set.cardinal!_related_terms<max_related_then(letnew_terms=unroll_logical_symbolstinUtil.debugf~section20"addding related terms:@.@[%a@]@."(funk->k(Term.Set.ppTerm.pp)new_terms);_related_terms:=Term.Set.union!_related_termsnew_terms)letregister_conjecture_clausecl=matchC.distance_to_goalclwith|Some0when!_rel_terms_enabled&&Term.Set.cardinal!_related_terms<max_related_->C.Seq.termscl|>Iter.filter(funt->not(Term.is_true_or_falset))|>Iter.iteradd_related_term_|_->()(** {5 Weight functions} *)moduleWeightFun=structtypet=C.t->intletweight_lits_l=Array.fold_left(funacclit->acc+Lit.heuristic_weightterm_weightlit)0lletdefaultc=(* maximum depth of types. Avoids reasoning on list (list (list .... (list int))) *)let_depth_ty=Lits.Seq.terms(C.litsc)|>Iter.mapTerm.ty|>Iter.mapType.depth|>Iter.max?lt:None|>CCOpt.map_orCCFun.id~default:0inletw_lits=weight_lits_(C.litsc)inw_lits*Array.length(C.litsc)+_depth_tyletho_weight_calcc=letall_termsc=C.Seq.termsc|>Iter.flat_map(Term.Seq.subterms~include_builtin:true)inletapp_var_numc=float_of_int@@Iter.fold(funacct->acc+(ifTerm.is_app_vartthen1else0))0(all_termsc)inletformulas_numc=float_of_int@@Iter.fold(funacct->acc+(ifTerm.is_formulatthen1else0))0(C.Seq.termsc)inletp_depthc=float_of_int(C.proof_depthc)inlett_depthc=C.Seq.termsc|>Iter.mapTerm.depth|>Iter.max|>CCOpt.get_or~default:0|>float_of_intinletweightc=float_of_int(weight_lits_(C.litsc))inletres=int_of_float(weightc*.(1.25**(app_var_numc*.(1.35**p_depthc)))*.(0.85**formulas_numc)*.1.05**t_depthc)inUtil.debugf~section5"[C_W:]@ @[%a@]@ :@ %d(%g, %g, %g).\n"(funk->kC.ppcres(app_var_numc)(formulas_numc)(p_depthc));resletavoid_expensivec=letmax_lits=C.maxlits(c,0)Subst.emptyinletsignature=C.Ctx.signature()inCCArray.foldi(funaccil->letmax_terms=ifCCBV.getmax_litsithenLiteral.Comp.max_terms~ord:(C.Ctx.ord())lelse[]inletlit_weight=Literal.Seq.termsl|>Iter.map(funt->letvar,f_nc,f_c=ifList.memtmax_termsthen(2,6,3)else(1,2,1)inletsymid_=ifSignature.sym_in_conjid_signaturethenf_celsef_ncinTerm.weight~var~symt*(ifTerm.is_app_vartthen2else1))|>Iter.suminletmultiplier=(ifLiteral.is_typex_predlthen1.2else1.0)*.(ifLiteral.is_type_predlthen1.8else1.0)*.(ifLiteral.is_groundlthen0.5else1.0)inint_of_float(multiplier*.(float_of_intlit_weight))+acc)0(C.litsc)letorient_lmax_weight~v_w~f_w~pos_m~unord_m~max_l_mulc=letmax_lits=ifC.has_selected_litscthenC.selected_lits_bvcelseC.maxlits(c,0)Subst.emptyinletord=C.Ctx.ord()inletres=CCArray.foldi(funsumilit->letterm_w=(funt->ifTerm.is_true_or_falsetthen0.0elsefloat_of_int(Term.weight~var:v_w~sym:(fun_->f_w)t))inletw=matchlitwith|Lit.Equation(l,r,_)->lett_w=max(term_wl)(term_wr)inlett_w=ifLit.is_positivoidlitthenpos_m*.t_welset_winlett_w=ifCCBV.getmax_litsithenmax_l_mul*.t_welset_winletordered=Ordering.compareordlr!=Comparison.Incomparableint_w*.(ifnotorderedthenunord_melse1.0)|_->1.0insum+.w)0.0(C.litsc)inint_of_floatresletclauseweight~fw~vw~pos_lit_mulc=leteval_t=Term.weight~var:vw~sym:(fun_->fw)inCCArray.fold(funacclit->matchlitwith|Lit.Equation(lhs,rhs,_)->letlit_w=(eval_tlhs+eval_trhs)inletmul=(ifLit.is_positivoidlitthenpos_lit_mulelse1.0)inacc+(int_of_float((float_of_intlit_w)*.mul))|_->acc)0(C.litsc)letpn_refined_weight~pv_w~pf_w~nv_w~nf_w~max_t_m~max_l_m~pos_mc=letmax_lits=ifC.has_selected_litscthenC.selected_lits_bvcelseC.maxlits(c,0)Subst.emptyinletord=C.Ctx.ord()inletres=CCArray.foldi(funsumilit->letpterm_w=(funt->float_of_int(Term.weight~var:pv_w~sym:(fun_->pf_w)t))inletnterm_w=(funt->float_of_int(Term.weight~var:nv_w~sym:(fun_->nf_w)t))inletw=matchlitwith|Lit.Equation(l,r,_)->letterm_w=ifLit.is_positivoidlitthenpterm_welsenterm_winletord_side=Ordering.compareordlrinletl_mul=iford_side=Comparison.Gt||ord_side=Comparison.Incomparablethenmax_t_melse1.0inletr_mul=iford_side=Comparison.Lt||ord_side=Comparison.Incomparablethenmax_t_melse1.0inleteq_inc=ifnot(Lit.is_predicate_litlit)thenfloat_of_int(ifLit.is_positivoidlitthenpf_welsenf_w)else0.0inlett_w=l_mul*.(term_wl)+.r_mul*.(term_wr)+.eq_incinlett_w=ifLit.is_positivoidlitthenpos_m*.t_welset_winlett_w=ifCCBV.getmax_litsithenmax_l_m*.t_welset_wint_w|_->1.0insum+.w)0.0(C.litsc)inletw=int_of_floatresinUtil.debugf~section5"pnrefined(@[%a@],@[%g@])=%d@."(funk->kC.ppcpos_mw);wletho_weight_initialc=ifC.proof_depthc=0then1elseho_weight_calccletreccalc_tweighttsgvwc_mul=matchTerm.viewtwithTerm.AppBuiltin(_,l)->w+List.fold_left(funacct->acc+calc_tweighttsgvwc_mul)0l|Term.Var_->v|Term.DB_->w|Term.App(f,l)->calc_tweightfsgvwc_mul+List.fold_left(funacct->acc+calc_tweighttsgvwc_mul)0l|Term.Constid->(int_of_float((ifSignature.sym_in_conjidsgthenc_mulelse1.0)*.float_of_intw))|Term.Fun(_,t)->calc_tweighttsgvwc_mulletcalc_lweightlsgvwc_mul=assert(Literal.no_prop_invariantl);matchlwith(* Special treatment of propositions *)|Lit.Equation(lhs,_,_)whenLit.is_predicate_litl->calc_tweightlhssgvwc_mul,Lit.is_positivoidl|Lit.Equation(lhs,rhs,sign)->(calc_tweightlhssgvwc_mul+calc_tweightrhssgvwc_mul,sign)|_->(0,false)letconj_relative_cheap~v~f~pos_mul~conj_mul~dist_var_mulc=letsgn=C.Ctx.signature()inletres=Array.mapi(funixx->i,xx)(C.litsc)|>(Array.fold_left(funacc(i,l)->acc+.letl_w,l_s=(calc_lweightlsgnvfconj_mul)in(ifl_sthenpos_mulelse1.0)*.float_of_intl_w)0.0)inletdist_vars=List.length(Literals.vars(C.litsc))inint_of_float(dist_var_mul**(float_of_intdist_vars)*.res)letconj_relative?(distinct_vars_mul=(-1.0))?(parameters_magnitude=`Large)?(goal_penalty=false)c=letsgn=C.Ctx.signature()inletmax_lits=ifC.has_selected_litscthenC.selected_lits_bvcelseC.maxlits(c,0)Subst.emptyinletpos_mul,max_mul,v,f=matchparameters_magnitudewith|`Large->(1.5,1.5,100,100)|`Small->(2.0,1.5,2,3)inletconj_mul=0.5inArray.mapi(funixx->i,xx)(C.litsc)|>(Array.fold_left(funacc(i,l)->acc+.letl_w,l_s=(calc_lweightlsgnvfconj_mul)in(ifl_sthenpos_mulelse1.0)*.(ifCCBV.getmax_litsithenmax_mulelse1.0)*.float_of_intl_w)0.0)|>(funres->ifdistinct_vars_mul<0.0thenint_of_floatreselseletdist_vars=Literals.vars(C.litsc)|>List.filter(funv->not(Type.is_tType(HVar.tyv)))inletn_vars=List.lengthdist_vars+1inletdist_var_penalty=distinct_vars_mul**(float_of_intn_vars)inletgoal_dist_penalty=ifgoal_penaltythen(letdivider=matchC.distance_to_goalcwith|Somed->1.5**(1.0/.(1.0+.(float_of_int@@d)))|None->1.0in1.0/.divider)else1.0inletval_=int_of_float(goal_dist_penalty*.dist_var_penalty*.res)in(Util.debugf~section5"cl: %a, w:%d\n"(funk->kC.ppcval_);val_))(* function inspired by Struct from the paper https://arxiv.org/abs/1606.03888 *)letconj_relative_struct~inst_penalty~gen_penalty~var_w~sym_wc=letpos_mul,max_mul=2.0,1.5inletmax_lits=ifC.has_selected_litscthenC.selected_lits_bvcelseC.maxlits(c,0)Subst.emptyinletstruct_diff_weightt=letmoduleT=Terminletwt=float_of_int@@Term.weight~var:var_w~sym:(fun_->sym_w)tinletrecw_diff~given_term~conj_term=matchT.viewgiven_term,T.viewconj_termwith|T.Var_,T.Var_->1|T.Constx,T.ConstywhenID.equalxy->1|T.DBi,T.DBjwheni=j->1|T.Var_,_->int_of_float(inst_penalty*.(wconj_term))|T.App(hd,_),_whenT.is_varhd->int_of_float(wgiven_term+.inst_penalty*.(wconj_term))|_,T.Var_->int_of_float(gen_penalty*.(wgiven_term))|_,T.App(hd,_)whenT.is_varhd->int_of_float(wconj_term+.inst_penalty*.(wgiven_term))|T.App(hd1,args1),T.App(hd2,args2)whenT.equalhd1hd2&&List.lengthargs1=List.lengthargs2->w_diff_largs1args2|T.AppBuiltin(hd1,args1),T.AppBuiltin(hd2,args2)whenBuiltin.equalhd1hd2&&List.lengthargs1=List.lengthargs2->w_diff_largs1args2|T.Fun(ty1,body1),T.Fun(ty2,body2)whenType.equalty1ty2&&Type.equal(T.tybody1)(T.tybody2)->w_diffbody1body2|_,_->int_of_float(inst_penalty*.(wconj_term)+.gen_penalty*.(wgiven_term))andw_diff_lxsys=CCList.fold_left2(funaccxy->acc+w_diff~given_term:x~conj_term:y)0xsysinlett=Lambda.eta_expandtinifTerm.Set.is_empty!_related_termsthenint_of_float(wt)else(Term.Set.to_iter!_related_terms|>Iter.map(funconj_term->letconj_term=Lambda.eta_expandconj_terminw_diff~given_term:t~conj_term)|>Iter.min_exn~lt:(funxy->x<y))inC.Seq.litsc|>Iter.foldi(funaccidxlit->letis_pos=Lit.is_positivoidlitinletis_max=CCBV.getmax_litsidxinLit.Seq.termslit|>Iter.filter(funt->not(Term.is_true_or_falset))|>Iter.fold(funacct->letw=struct_diff_weighttinUtil.debugf~section5"struct(@[%a@])=%d"(funk->kTerm.pptw);acc+w)acc|>(funres->letmul=(ifis_posthenpos_mulelse1.0)*.(ifis_maxthenmax_mulelse1.0)inint_of_float(mul*.(float_of_intres))))0letconjecture_relative_e~conj_mul~fresh_mul~f~cst~p~v~max_term_mul~max_lit_mul~pos_mulc=letsgn=C.Ctx.signature()inletf_weightsymty=letmultipliers=(ifSignature.sym_in_conjsymsgnthenconj_mulelse1.0)*.(ifID.is_postcnf_skolemsymthenfresh_mulelse1.0)inint_of_float(float_of_int(ifType.returns_proptythenpelseifType.is_funtythenfelsecst)*.multipliers)inlett_weight~mult=letrecauxt=ifType.is_tType(Term.tyt)then0elsematchTerm.viewtwith|App(hd,args)->aux_l(hd::args)|AppBuiltin(b,args)->f+aux_largs|Fun(_,body)->v+auxbody|DB_|Var_->v|Constsym->f_weightsym(Term.tyt)andaux_lxs=List.fold_left(funaccarg->acc+auxarg)0xsinint_of_float(mul*.float_of_int(auxt))inletlit_weightis_maxlit=letis_pos=Lit.is_positivoidlitinletmultipliers=(ifis_maxthenmax_lit_mulelse1.0)*.(ifis_posthenpos_mulelse1.0)inletbase_weight=matchlitwith|Literal.Equation(lhs,rhs,_)->beginmatchOrdering.compare(C.Ctx.ord())lhsrhswith|Comparison.Gt->t_weight~mul:max_term_mullhs+t_weight~mul:1.0rhs|Comparison.Lt->t_weight~mul:max_term_mulrhs+t_weight~mul:1.0lhs|_->t_weight~mul:1.0lhs+t_weight~mul:1.0rhsend|_->1inint_of_float(multipliers*.(float_of_intbase_weight))inletmax_lits=ifC.has_selected_litscthenC.selected_lits_bvcelseC.maxlits(c,0)Subst.emptyinC.Seq.litsc|>Iter.foldi(funaccidxlit->letis_max=CCBV.getmax_litsidxinacc+lit_weightis_maxlit)0|>(funres->Util.debugf~section5"cr-e(@[%a@])=%d@."(funk->kC.ppcres);res)letdag_weight~fweight~vweight~pos_multiplier~dup_weight~pos_use_dag~pos_t_reset~pos_eqn_reset~neg_use_dag~neg_t_reset~neg_eqn_reset~pos_neg_resetc=let_tbl=Term.Tbl.create(128)inletcalc_wuse_dagreset_litreset_termlit=letterm_dag_wresett=ifresetthenTerm.Tbl.clear_tbl;letrecauxt=ifTerm.Tbl.mem_tbltthendup_weightelse(Term.Tbl.replace_tblt();matchTerm.viewtwith|Term.App(hd,args)->aux_l(hd::args)|Term.AppBuiltin(hd,args)->fweight+aux_largs|Term.Fun(_,body)->vweight+auxbody|Term.Var_|Term.DB_->vweight|Term.Const_->fweight)andaux_ll=List.fold_left(funacct->acc+auxt)0linauxtinletlit_t_w=Term.weight~var:vweight~sym:(fun_->fweight)inlett_wreset_t=ifuse_dagthenterm_dag_wreset_telselit_t_winifreset_litthenTerm.Tbl.clear_tbl;letp_m=ifLit.is_positivoidlitthenpos_multiplierelse1.0inmatchlitwith|Lit.Equation(lhs,rhs,_)->int_of_float(p_m*.(float_of_int(t_wfalselhs+t_wreset_termrhs)))|_->0inlet_w=ref0inCCArray.iter(funlit->ifLit.is_positivoidlitthen(_w:=!_w+calc_wpos_use_dagpos_eqn_resetpos_t_resetlit))(C.litsc);ifpos_neg_resetthen(Term.Tbl.clear_tbl);CCArray.iter(funlit->ifLit.is_negativoidlitthen(_w:=!_w+calc_wneg_use_dagneg_eqn_resetneg_t_resetlit))(C.litsc);!_wletdiversity_weight~var_w~sym_w~pos_mul~max_t_mul~max_l_mul~fdiff_a~fdiff_b~vdiff_a~vdiff_bc=letord=C.Ctx.ord()inletmul_max_t(l,w_l)(r,w_r)=matchOrdering.compareordlrwith|Comparison.Incomparable->(max_t_mul*.(float_of_intw_l))+.max_t_mul*.(float_of_intw_r)|Comparison.Gt->(max_t_mul*.(float_of_intw_l))+.(float_of_intw_r)|Comparison.Lt->(max_t_mul*.(float_of_intw_r))+.(float_of_intw_l)|_->float_of_int(w_l+w_r)inletmax_lits=ifC.has_selected_litscthenC.selected_lits_bvcelseC.maxlits(c,0)Subst.emptyinletget_symslr=ID.Set.union(Term.symbolsl)(Term.symbolsr)inletget_varslr=Term.VarSet.union(Term.varsl)(Term.varsr)inletres=C.Seq.litsc|>Iter.foldi(fun(weight,syms,vars)idxlit->letpos_c=ifLit.is_positivoidlitthenpos_mulelse1.0inletmax_c=ifCCBV.getmax_litsidxthenmax_l_mulelse1.0inmatchlitwith|Literal.Equation(l,r,_)->letw_l=Term.weight~var:var_w~sym:(fun_->sym_w)linletw_r=Term.weight~var:var_w~sym:(fun_->sym_w)rinletw=pos_c*.max_c*.mul_max_t(l,w_l)(r,w_r)inassert(int_of_floatw!=0);(w+.weight,ID.Set.unionsyms(get_symslr),Term.VarSet.unionvars(get_varslr))|_->weight+.1.0,syms,vars)(0.0,ID.Set.empty,Term.VarSet.empty)|>(fun(w,syms,vars)->letf=float_of_int@@ID.Set.cardinalsymsinletv=float_of_int@@Term.VarSet.cardinalvarsinletf_factor=fdiff_a*.f+.fdiff_binletv_factor=vdiff_a*.v+.vdiff_binUtil.debugf~section5"w:%g;f:%g;v:%g"(funk->kwf_factorv_factor);int_of_float(w+.f_factor+.v_factor))inUtil.debugf~section5"diversity_weight(@[%a@])=%d@."(funk->kC.ppcres);reslet_max_weight=ref(-1.0)letstaggered~stagger_factorc=letfloat_weightc=float_of_int@@C.weightcin_max_weight:=max(!_max_weight)(float_weightc)+.1.0;int_of_float@@float_weightc/.(!_max_weight*.stagger_factor)letpenalty=C.penaltyletpenalizewc=assert(penaltyc>=1);wc*penaltycletpenalty_coeff_=20letfavor_pos_unitc=letis_unit_posc=matchC.litscwith|[|lit|]whenLit.is_positivoidlit->true|_->falseinifis_unit_poscthen0elsepenalty_coeff_(* favorize small number of variables in a clause *)letfavor_small_num_varsc=(* number of distinct term variables *)letn_vars=Literals.vars(C.litsc)|>List.filter(funv->not(Type.is_tType(HVar.tyv)))|>List.lengthinletn=ifn_vars<4then0elseifn_vars<6then1elseifn_vars<8then3elsen_varsinn*penalty_coeff_letfavor_hornc=ifLits.is_horn(C.litsc)then0elsepenalty_coeff_letgoal_threshold_=15letfavor_goalc=ifC.is_emptycthen0elseletd=matchC.distance_to_goalcwith|Somed->mindgoal_threshold_|None->goal_threshold_in1+d(* check whether a literal is a ground neg lit *)letis_ground_neglit=Lit.is_negativoidlit&&Lit.is_groundlitletall_ground_negc=CCArray.for_allis_ground_neg(C.litsc)letfavor_all_negc=ifall_ground_negcthen0elsepenalty_coeff_letfavor_groundc=ifC.is_groundcthen0elsepenalty_coeff_letfavor_non_all_negc=ifnot(all_ground_negc)then0elsepenalty_coeff_letcombinews=assert(ws<>[]);assert(List.for_all(fun(_,c)->c>0)ws);func->List.fold_left(funsum(w,coeff)->sum+coeff*wc)0wsletexplore_fun=penalize(combine[default,4;favor_small_num_vars,1;favor_all_neg,1])letdefault_fun=penalize(combine[default,3;favor_all_neg,1;favor_small_num_vars,2;favor_goal,1;favor_pos_unit,1;])(* imitation of the E function of the same name *)letparse_diversity_weights=letcrv_regex=Str.regexp("diversity-weight("^"\\([0-9]+\\),\\([0-9]+\\),\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\),\\([0-9]+[.]?[0-9]*\\),"^"\\([+-]?[0-9]+[.]?[0-9]*\\),\\([+-]?[0-9]+[.]?[0-9]*\\),"^"\\([+-]?[0-9]+[.]?[0-9]*\\),\\([+-]?[0-9]+[.]?[0-9]*\\))")intryignore(Str.search_forwardcrv_regexs0);letsym_w=CCOpt.get_exn@@CCInt.of_string(Str.matched_group1s)inletvar_w=CCOpt.get_exn@@CCInt.of_string(Str.matched_group2s)inletmax_t_mul=CCFloat.of_string_exn(Str.matched_group3s)inletmax_l_mul=CCFloat.of_string_exn(Str.matched_group4s)inletpos_mul=CCFloat.of_string_exn(Str.matched_group5s)inletfdiff_a=CCFloat.of_string_exn(Str.matched_group6s)inletfdiff_b=CCFloat.of_string_exn(Str.matched_group7s)inletvdiff_a=CCFloat.of_string_exn(Str.matched_group8s)inletvdiff_b=CCFloat.of_string_exn(Str.matched_group9s)indiversity_weight~sym_w~var_w~max_t_mul~max_l_mul~pos_mul~fdiff_a~fdiff_b~vdiff_a~vdiff_bwithNot_found|Invalid_argument_->invalid_arg("expected diversity-weight("^"f_w:int,v_w:int,max_t_mul:float,max_l_mul:float,pos_mul:float,"^"fdiff_a:float,fdiff_b:flaot,vdiff_a:float,vdiff_b:float)")letparse_crvs=letcrv_regex=Str.regexp"conjecture-relative-var(\\([0-9]+[.]?[0-9]*\\),\\([lsLS]\\),\\([tfTF]\\))"intryignore(Str.search_forwardcrv_regexs0);letdistinct_vars_mul=CCFloat.of_string_exn(Str.matched_group1s)inletparameters_magnitude=Str.matched_group2s|>CCString.trim|>String.lowercase_ascii|>(funs->ifCCString.prefix~pre:"l"sthen`Largeelse`Small)inletgoal_penalty=Str.matched_group3s|>CCString.trim|>String.lowercase_ascii|>CCString.prefix~pre:"t"inconj_relative~distinct_vars_mul~parameters_magnitude~goal_penaltywithNot_found|Invalid_argument_->invalid_arg"expected conjecture-relative-var(dist_var_mul:float,parameters_magnitude:l/s,goal_penalty:t/f)"letparse_dag_weights=letcrv_regex=Str.regexp("dagweight(\\([0-9]+\\),\\([0-9]+\\),\\([0-9]+[.]?[0-9]*\\),\\([0-9]+\\),"^"\\([tfTF]\\),\\([tfTF]\\),\\([tfTF]\\),\\([tfTF]\\),"^"\\([tfTF]\\),\\([tfTF]\\),\\([tfTF]\\))")intryignore(Str.search_forwardcrv_regexs0);letparse_bools=CCString.prefix~pre:"t"(String.lowercase_asciis)inletfweight=CCOpt.get_exn@@CCInt.of_string(Str.matched_group1s)inletvweight=CCOpt.get_exn@@CCInt.of_string(Str.matched_group2s)inletpos_multiplier=CCFloat.of_string_exn(Str.matched_group3s)inletdup_weight=CCOpt.get_exn@@CCInt.of_string(Str.matched_group4s)inletpos_use_dag=parse_bool@@Str.matched_group5sinletpos_t_reset=parse_bool@@Str.matched_group6sinletpos_eqn_reset=parse_bool@@Str.matched_group7sinletneg_use_dag=parse_bool@@Str.matched_group8sinletneg_t_reset=parse_bool@@Str.matched_group9sinletneg_eqn_reset=parse_bool@@Str.matched_group10sinletpos_neg_reset=parse_bool@@Str.matched_group11sindag_weight~fweight~vweight~pos_multiplier~dup_weight~pos_use_dag~pos_t_reset~pos_eqn_reset~neg_use_dag~neg_t_reset~neg_eqn_reset~pos_neg_resetwithNot_found|Invalid_argument_->invalid_arg("expected dagweight(fweight,vweight,pos_mul,dup_weight,"^"pos_use_dag,pos_t_reset,pos_eqn_reset,neg_use_dag,"^"neg_t_reset,neg_eqn_reset,pos_neg_reset)")letparse_cr_es=letcrv_regex=Str.regexp("conjecture-relative-e(\\([0-9]+[.]?[0-9]*\\),\\([0-9]+[.]?[0-9]*\\),\\([0-9]+\\),\\([0-9]+\\),"^"\\([0-9]+\\),\\([0-9]+\\),\\([0-9]+[.]?[0-9]*\\),\\([0-9]+[.]?[0-9]*\\),\\([0-9]+[.]?[0-9]*\\)"^")")intryignore(Str.search_forwardcrv_regexs0);letconj_mul=CCFloat.of_string_exn(Str.matched_group1s)inletfresh_mul=CCFloat.of_string_exn(Str.matched_group2s)inletf=CCOpt.get_exn@@CCInt.of_string(Str.matched_group3s)inletcst=CCOpt.get_exn@@CCInt.of_string(Str.matched_group4s)inletp=CCOpt.get_exn@@CCInt.of_string(Str.matched_group5s)inletv=CCOpt.get_exn@@CCInt.of_string(Str.matched_group6s)inletmax_term_mul=CCFloat.of_string_exn(Str.matched_group7s)inletmax_lit_mul=CCFloat.of_string_exn(Str.matched_group8s)inletpos_mul=CCFloat.of_string_exn(Str.matched_group9s)inconjecture_relative_e~conj_mul~fresh_mul~f~cst~p~v~max_term_mul~max_lit_mul~pos_mulwithNot_found|Invalid_argument_->invalid_arg("expected conjecture-relative-e(conj_mul:float, fresh_mul:float, f:int, const:int,"^"p:int, v:int, max_term_mul:float, max_lit_mul:float, pos_mul:float)")letparse_cr_structs=_rel_terms_enabled:=true;letcrs_regex=Str.regexp"conjecture-relative-struct(\\([0-9][.]?[0-9]*+\\),\\([0-9][.]?[0-9]*+\\),\\([0-9]+\\),\\([0-9]+\\))"intryignore(Str.search_forwardcrs_regexs0);letinst_penalty=CCFloat.of_string_exn(Str.matched_group1s)inletgen_penalty=CCFloat.of_string_exn(Str.matched_group2s)inletvar_w=CCOpt.get_exn@@CCInt.of_string(Str.matched_group3s)inletsym_w=CCOpt.get_exn@@CCInt.of_string(Str.matched_group4s)inconj_relative_struct~inst_penalty~gen_penalty~var_w~sym_wwithNot_found|Invalid_argument_->invalid_arg"expected conjecture-relative-struct(inst_penalty:float,gen_penalty:float,var_weight:int,sym_weight:int)"letparse_orient_lmaxs=letor_lmax_regex=Str.regexp("orient-lmax(\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\))")intryignore(Str.search_forwardor_lmax_regexs0);letv_w=CCOpt.get_exn(CCInt.of_string(Str.matched_group1s))inletf_w=CCOpt.get_exn(CCInt.of_string(Str.matched_group2s))inletpos_m=CCFloat.of_string_exn(Str.matched_group3s)inletunord_m=CCFloat.of_string_exn(Str.matched_group4s)inletmax_l_mul=CCFloat.of_string_exn(Str.matched_group5s)inorient_lmax_weight~v_w~f_w~pos_m~unord_m~max_l_mulwithNot_found|Invalid_argument_->invalid_arg@@"expected orient-lmax(var_weight:int,fun_weight:int"^"pos_lit_mult:float, unorderable_lit_mul:float, max_lit_mul:float)"letparse_pnrefines=letor_lmax_regex=Str.regexp("pnrefined(\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\))")intryignore(Str.search_forwardor_lmax_regexs0);letpf_w=CCOpt.get_exn(CCInt.of_string(Str.matched_group1s))inletpv_w=CCOpt.get_exn(CCInt.of_string(Str.matched_group2s))inletnf_w=CCOpt.get_exn(CCInt.of_string(Str.matched_group3s))inletnv_w=CCOpt.get_exn(CCInt.of_string(Str.matched_group4s))inletmax_t_m=CCFloat.of_string_exn(Str.matched_group5s)inletmax_l_m=CCFloat.of_string_exn(Str.matched_group6s)inletpos_m=CCFloat.of_string_exn(Str.matched_group7s)inpn_refined_weight~pv_w~pf_w~nv_w~nf_w~pos_m~max_t_m~max_l_mwithNot_found|Invalid_argument_->invalid_arg@@"expected pnrefined(+fun_weight:int,+var_weight:int"^"-fun_weight:int,-var_weight:int"^"max_t_mult:float, max_lit_mul:float, pos_lit_mult:float)"let_f_weights=ID.Tbl.create100let_default=ref(-1)letcalc_polybasex~c~lin~sq=base*(int_of_float(c+.(lin*.(float_of_intx))+.(sq*.(float_of_int(x*x)))))letrel_weight~vw~max_t_mul~max_lit_mul~pos_lit_mulc=letmax_lits=ifC.has_selected_litscthenC.selected_lits_bvcelseC.maxlits(c,0)Subst.emptyinletord=C.Ctx.ord()inletres=CCArray.foldi(funsumilit->assert(!_default!=(-1));letw=matchlitwith|Lit.Equation(l,r,_)->letterm_w()t=float_of_int@@Term.weight~var:vw~sym:(funid->ID.Tbl.get_or_f_weights~default:!_defaultid)tinletord_side=Ordering.compareordlrinletl_mul=iford_side=Comparison.Gt||ord_side=Comparison.Incomparablethenmax_t_mulelse1.0inletr_mul=iford_side=Comparison.Lt||ord_side=Comparison.Incomparablethenmax_t_mulelse1.0inlett_w=l_mul*.(term_w()l)+.r_mul*.(term_w()r)inlett_w=ifLit.is_positivoidlitthenpos_lit_mul*.t_welset_winlett_w=ifCCBV.getmax_litsithenmax_lit_mul*.t_welset_wint_w|_->1.0insum+.w)0.0(C.litsc)inint_of_floatresletconj_pref_weight(modulePW:PrefWeight.S)~max_t_mul~max_lit_mul~pos_lit_mulc=letmax_lits=ifC.has_selected_litscthenC.selected_lits_bvcelseC.maxlits(c,0)Subst.emptyinletord=C.Ctx.ord()inletres=CCArray.foldi(funsumilit->letw=matchlitwith|Lit.Equation(l,r,_)->lettwt=float_of_int(PW.calc_pref_weightt)inletord_side=Ordering.compareordlrinletl_mul=iford_side=Comparison.Gt||ord_side=Comparison.Incomparablethenmax_t_mulelse1.0inletr_mul=iford_side=Comparison.Lt||ord_side=Comparison.Incomparablethenmax_t_mulelse1.0inlett_w=l_mul*.(twl)+.r_mul*.(twr)inlett_w=ifLit.is_positivoidlitthenpos_lit_mul*.t_welset_winlett_w=ifCCBV.getmax_litsithenmax_lit_mul*.t_welset_wint_w|_->1.0insum+.w)0.0(C.litsc)inint_of_floatresletparse_rel_lvl_weights=letr_str="rel_lvl_weight(\\([0-9]+[.]?[0-9]*\\),\\([0-9]+[.]?[0-9]*\\),\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+\\),\\([0-9]+\\),\\([0-9]+\\),\\([0-9]+\\),\\([0-9]+\\),"^"\\([0-9]+[.]?[0-9]*\\),\\([0-9]+[.]?[0-9]*\\),\\([0-9]+[.]?[0-9]*\\))"inletrel_w_regex=Str.regexpr_strintryignore(Str.search_forwardrel_w_regexs0);letl_poly_const=CCFloat.of_string_exn(Str.matched_group1s)inletl_poly_lin=CCFloat.of_string_exn(Str.matched_group2s)inletl_poly_sq=CCFloat.of_string_exn(Str.matched_group3s)inletdef_l=CCOpt.get_exn(CCInt.of_string(Str.matched_group4s))inletfw=CCOpt.get_exn(CCInt.of_string(Str.matched_group5s))inletcw=CCOpt.get_exn(CCInt.of_string(Str.matched_group6s))inletpw=CCOpt.get_exn(CCInt.of_string(Str.matched_group7s))inletvw=CCOpt.get_exn(CCInt.of_string(Str.matched_group8s))inletmax_t_mul=CCFloat.of_string_exn(Str.matched_group9s)inletmax_lit_mul=CCFloat.of_string_exn(Str.matched_group10s)inletpos_lit_mul=CCFloat.of_string_exn(Str.matched_group11s)inSignal.onceon_proof_state_init(funcls->letgoals,axs=Iter.fold(fun(goals,axs)cl->matchC.distance_to_goalclwith|Some_->((cl::goals),axs)|None->(goals,(cl::axs)))([],[])clsinletgoal_syms=C.symbols(Iter.of_listgoals)inletcl_map=ID.Tbl.create100inList.iter(funcl->C.symbols(Iter.singletoncl)|>ID.Set.iter(funk->ID.Tbl.updatecl_map~f:(fun_->function|Someold->Some(cl::old)|None->Some[cl])~k))axs;letrecfill_levelssyms_at_levellevel=ID.Set.iter(funid->assert(not(ID.Tbl.mem_f_weightsid));ID.Tbl.replace_f_weightsidlevel)syms_at_level;letnew_syms=ID.Set.fold(funidnew_syms->letcls=ID.Tbl.get_or~default:[]cl_mapidinID.Set.fold(funidacc->ifnot(ID.Tbl.mem_f_weightsid)then(ID.Set.addidacc)elseacc)(C.symbols(Iter.of_listcls))new_syms)syms_at_levelID.Set.emptyinifnot(ID.Set.is_emptynew_syms)thenfill_levelsnew_syms(level+1)elselevelinletmax_lvl=fill_levelsgoal_syms1in_default:=calc_poly~c:l_poly_const~lin:l_poly_lin~sq:l_poly_sq(maxcw(maxpwfw))(def_l+max_lvl);ID.Tbl.filter_map_inplace(funidlvl->letty=Signature.find_exn(C.Ctx.signature())idinletbase=ifType.returns_proptythenpwelseifType.is_funtythenfwelsecwinletv=calc_poly~c:l_poly_const~lin:l_poly_lin~sq:l_poly_sqbaselvlinSomev)_f_weights;);rel_weight~vw~max_t_mul~max_lit_mul~pos_lit_mulwithNot_found|Invalid_argument_->invalid_arg@@"expected rel_lev_weight(poly_const:float,,poly_lin:float,poly_sq:float,"^"def_l:int, fun_w:int, const_w:int, pred_w:int, var_w:int,"^"max_t_mul:float,max_lit_mul:float,pos_lit_mul:float)"letparse_conj_pref_weights=letr_str="conj_pref_weight(\\([0-9]+[.]?[0-9]*\\),\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\),\\([0-9]+[.]?[0-9]*\\),\\([0-9]+[.]?[0-9]*\\))"inletrel_w_regex=Str.regexpr_strintryignore(Str.search_forwardrel_w_regexs0);letmatch_w=CCFloat.of_string_exn(Str.matched_group1s)inletmiss_w=CCFloat.of_string_exn(Str.matched_group2s)inletmax_t_mul=CCFloat.of_string_exn(Str.matched_group3s)inletmax_lit_mul=CCFloat.of_string_exn(Str.matched_group4s)inletpos_lit_mul=CCFloat.of_string_exn(Str.matched_group5s)inletmodulePW=PrefWeight.Make(structletmatch_weight=match_wletmiss_weight=miss_wend)inSignal.onceon_proof_state_init(funcls->Iter.iter(funcl->matchC.distance_to_goalclwith|Some0->C.Seq.litscl|>Iter.iter(function|Literal.Equation(lhs,rhs,_)asl->(ifLit.is_predicate_litlthen(Term.Seq.subterms~include_builtin:truelhs)else(Iter.append(Term.Seq.subterms~include_builtin:truelhs)(Term.Seq.subterms~include_builtin:truerhs)))|>Iter.iter(funt->if(not(Term.is_typet))thenPW.insert_termt)|_->())|_->())cls;);conj_pref_weight(modulePW:PrefWeight.S)~max_t_mul~max_lit_mul~pos_lit_mulwithNot_found|Invalid_argument_->invalid_arg@@"expected conj_pref_weight(match_weight:float,miss_weight:float,"^"max_t_mul:float,max_lit_mul:float,pos_lit_mul:float)"letparse_clauseweights=letor_lmax_regex=Str.regexp("clauseweight(\\([0-9]+\\),\\([0-9]+\\),\\([0-9]+[.]?[0-9]*\\)")intryignore(Str.search_forwardor_lmax_regexs0);letfw=CCOpt.get_exn(CCInt.of_string(Str.matched_group1s))inletvw=CCOpt.get_exn(CCInt.of_string(Str.matched_group2s))inletpos_lit_mul=CCFloat.of_string_exn(Str.matched_group3s)inclauseweight~fw~vw~pos_lit_mulwithNot_found|Invalid_argument_->invalid_arg@@"expected clauseweight(+fun_weight:int,+var_weight:int,"^"pos_lit_mult:float)"letparse_staggereds=letor_lmax_regex=Str.regexp("staggered(\\([0-9]+[.]?[0-9]*\\))")intryignore(Str.search_forwardor_lmax_regexs0);letstagger_factor=CCFloat.of_string_exn(Str.matched_group1s)instaggered~stagger_factorwithNot_found|Invalid_argument_->invalid_arg@@"expected staggered(+stagger_factor:int)"letparse_conj_relative_cheaps=letor_lmax_regex=Str.regexp("conjecture-relative-cheap(\\([0-9]+\\),"^"\\([0-9]+\\),"^"\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\),"^"\\([0-9]+[.]?[0-9]*\\))")intryignore(Str.search_forwardor_lmax_regexs0);letv=CCOpt.get_exn(CCInt.of_string(Str.matched_group1s))inletf=CCOpt.get_exn(CCInt.of_string(Str.matched_group2s))inletpos_mul=CCFloat.of_string_exn(Str.matched_group3s)inletconj_mul=CCFloat.of_string_exn(Str.matched_group4s)inletdist_var_mul=CCFloat.of_string_exn(Str.matched_group5s)inconj_relative_cheap~v~f~pos_mul~conj_mul~dist_var_mulwithNot_found|Invalid_argument_->Util.invalid_argf"expected conjecture-relative-cheap(v:int,f:int,pos_mul:float,conj_mul:float,dist_var_mul:float\n\
got: %s"sletparsers=["fifo",(fun_c->C.idc);"default",(fun_->default_fun);"explore",(fun_->explore_fun);"conjecture-relative",(fun_->conj_relative~distinct_vars_mul:1.0~parameters_magnitude:`Large~goal_penalty:false);"conjecture-relative-var",parse_crv;"conjecture-relative-struct",parse_cr_struct;"conjecture-relative-cheap",parse_conj_relative_cheap;"conjecture-relative-e",parse_cr_e;"conj_pref_weight",parse_conj_pref_weight;"diversity-weight",parse_diversity_weight;"pnrefined",parse_pnrefine;"rel_lvl_weight",parse_rel_lvl_weight;"staggered",parse_staggered;"clauseweight",parse_clauseweight;"dagweight",parse_dag_weight;"orient-lmax",parse_orient_lmax]letof_strings=tryletsplitted=CCString.split~by:"("sinletname=List.hdsplittedinletw=List.assocnameparserssinfunc->letres=penalizewcinUtil.debugf~section2"@[%s(%a)@]=@[%d@]"(funk->knameC.ppcres);reswithNot_found|Failure_->invalid_arg(CCFormat.sprintf"unknown weight function %s"s)endmodulePriorityFun=structtypet=C.t->intletconst_prioc=1letprefer_ho_stepsc=ifProof.Step.has_ho_step(C.proof_stepc)then0else1letprefer_sosc=ifC.proof_depthc=0||CCOpt.is_some(C.distance_to_goalc)then0else1letprefer_non_goalsc=ifIter.existsLiteral.is_positivoid(C.Seq.litsc)then0else1letprefer_unit_ground_non_goalsc=ifIter.existsLiteral.is_positivoid(C.Seq.litsc)&&C.is_unit_clausec&&C.is_groundcthen0else1letprefer_unit_ground_goalsc=ifnot(Iter.existsLiteral.is_positivoid(C.Seq.litsc))&&C.is_unit_clausec&&C.is_groundcthen0else1letprefer_goalsc=-(prefer_non_goalsc)letprefer_processedc=ifC.is_backward_simplifiedcthen0else1letprefer_lambdasc=if(C.Seq.termsc|>Iter.exists(funt->Iter.exists(funt->Term.is_funt||Term.is_combt)(Term.Seq.subtermst)))then0else1letdefer_lambdasc=-(prefer_lambdasc)letprefer_formulasc=if(C.Seq.termsc|>Iter.exists(funt->Iter.existsTerm.is_formula(Term.Seq.subtermst)))then0else1letprefer_bool_neqc=C.Seq.litsc|>Iter.map(funlit->matchlitwith|Lit.Equation(lhs,rhs,false)->ifType.is_prop(Term.tylhs)&¬(Term.is_true_or_falserhs)then(2-(List.length(List.filterTerm.is_appbuiltin[lhs;rhs])))elsemax_int|_->max_int)|>Iter.min|>CCOpt.get_or~default:0letprefer_easy_hoc=letis_arg_cong_childc=letrecauxproof=letp_res,step=Proof.S.resultproof,Proof.S.stepproofinletparents=List.mapProof.Parent.proof(Proof.Step.parentsstep)in(* clause is not obtained by normalization *)ifProof.Step.is_simplstepthen((* Looking through single-step simplifications *)matchparentswith|[parent]->auxparent|_->false)elseifProof.Step.is_inferencestepthen(beginmatchProof.Step.rulestepwith|Somerule->String.equal(Proof.Rule.namerule)"ho_complete_eq"|None->falseend)elsefalseinletans=aux(C.proofc)inansinlethas_lam_eqc=C.Seq.litsc|>Iter.exists(funl->matchlwith|Literal.Equation(lhs,_,_)->Type.is_fun(Term.tylhs)|_->false)inletin_pattern_fragmentc=(* returns has_lambdas, is_pattern *)letrecauxt=matchTerm.viewtwith|App(hd,args)->if(Term.is_consthd)thenaux_largselse(false,List.for_allTerm.is_bvarargs)(* ignoring distinctness *)|AppBuiltin(_,args)->aux_largs|Const_|Var_|DB_->(false,true)|Fun_->let_,body=Term.open_funtin(true,snd@@auxbody)andaux_largs=CCList.fold_while(fun(has_lambda,is_pattern)arg->assert(is_pattern);leth_l',i_p'=auxarginifi_p'then(h_l'||has_lambda,true),`Continueelse(false,false),`Stop)(false,true)argsinC.Seq.termsc|>Iter.mapaux(* at least one subterm is functional and all subterms are patterns *)|>(funseq->Iter.existsfstseq&&Iter.for_allsndseq)inifis_arg_cong_childcthen0elseifhas_lam_eqc||in_pattern_fragmentcthen1elseifprefer_formulasc==1then2else3letdefer_formulasc=-(prefer_formulasc)letprefer_short_trailc=ifTrail.is_empty(C.trailc)thenmax_intelseTrail.length(C.trailc)letprefer_empty_trailc=ifTrail.is_empty(C.trailc)then0else1letprefer_long_trailc=-(Trail.length(C.trailc))letprefer_foc=letrecalmost_fot=(* allows partial application, formulas and unapplied HO variables *)matchTerm.viewtwith|App(hd,args)->Term.is_consthd&&List.for_allalmost_foargs|AppBuiltin(_,args)->List.for_allalmost_foargs|Const_|Var_->true|Fun_|DB_->falseinletall_terms=Iter.filter(funt->not(Term.is_true_or_falset))(C.Seq.termsc)inletnum_terms=float_of_int(Iter.lengthall_terms)inletnum_fo_terms=float_of_int(Iter.filter_countalmost_foall_terms)inint_of_float@@(1.0-.(num_fo_terms/.num_terms))*.100.0letdefer_foc=-(prefer_foc)letprefer_groundc=ifC.is_groundcthen0else1letdefer_groundc=ifC.is_groundcthen1else0letdefer_sosc=ifC.proof_depthc=0||CCOpt.is_some(C.distance_to_goalc)then1else0letprefer_top_level_app_varc=letlits=C.litscinifArray.lengthlits>1thenmax_intelseifArray.lengthlits=0thenmin_intelse(letno_app_vars=Lit.Seq.termslits.(0)|>Iter.filterTerm.is_app_var|>Iter.lengthinifno_app_vars=0thenmax_intelseno_app_vars)letdefer_top_level_appc=-(prefer_top_level_app_varc)letprefer_shallow_app_varc=letapp_var_deptht=letrecauxdeptht=matchTerm.viewtwith|Term.DB_|Term.Const_|Term.Var_->0|Term.Fun(_,body)->aux(depth+1)body|Term.App(hd,args)whenTerm.is_varhd->maxdepth(aux_l(depth+1)args)|Term.App(hd,args)->aux_l(depth+1)(hd::args)|Term.AppBuiltin(_,args)->aux_l(depth+1)argsandaux_ldepth=function|[]->min_int|t::ts->max(auxdeptht)(aux_ldepthts)inaux0tinC.Seq.termsc|>Iter.mapapp_var_depth|>Iter.max|>CCOpt.get_or~default:min_intletby_app_var_numc=C.Seq.termsc|>Iter.flat_map(Term.Seq.subterms~include_builtin:true)|>Iter.filterTerm.is_app_var|>Iter.lengthletprefer_deep_app_varc=-(prefer_shallow_app_varc)letprefer_neg_unitc=matchC.litscwith|[|l|]whenLit.is_negativoidl->0|_->1letdefer_neg_unitc=-(prefer_neg_unitc)letby_neg_litc=abs@@Array.fold_left(funacclit->ifLit.is_positivoidlitthenacc+400elseifLit.is_groundlitthenacc-3elseacc-1)0(C.litsc)(* defer if there are no ho subterms *)letby_ho_depth?(modifier=(funx->x))~depth_func=letmax_optab=matcha,bwith|Somex,Somey->ifx>ythenaelseb|Somex,None->a|_->binC.Seq.termsc|>Iter.fold(funacct->max_optacc(depth_funt))None|>CCOpt.mapmodifier|>CCOpt.get_or~default:max_intletprefer_shallow_lambdasc=by_ho_depth~depth_fun:Term.lambda_depthcletprefer_deep_lambdasc=by_ho_depth~depth_fun:Term.lambda_depth~modifier:(funx->-x)cletprefer_shallow_combsc=by_ho_depth~depth_fun:Term.comb_depthcletprefer_deep_combsc=by_ho_depth~depth_fun:Term.comb_depth~modifier:(funx->-x)cletprefer_shallowc=Literals.Seq.terms(C.litsc)|>Iter.mapTerm.depth|>Iter.max|>CCOpt.get_or~default:0letdefer_shallowc=-(prefer_shallowc)(* Given a clause calculate how much was the size of it reduced (enlarged)
by the last normalization and prefer clauses which were reduced much
*)letby_normalization_factorc=letdefault=5000inletnorm_factc=letauxproof=letp_res,step=Proof.S.resultproof,Proof.S.stepproofin(* clause is not obtained by normalization *)ifnot(List.memProof.Tag.T_ho_norm(Proof.Step.tagsstep))thendefaultelse(assert(Proof.Step.is_simplstep);letparents=List.mapProof.Parent.proof(Proof.Step.parentsstep)inassert(List.lengthparents==1);letcalc_wpr=TypedSTerm.Seq.subterms(Proof.Result.to_form@@Proof.S.resultpr)|>Iter.length|>float_of_intinletnew_w=calc_w(C.proofc)inletold_w=calc_w(List.hdparents)inint_of_float((new_w/.old_w)*.(float_of_intdefault)))inaux(C.proofc)inletres=norm_factcinresletparsers=["const",(fun_->const_prio);"prefer-ho-steps",(fun_->prefer_ho_steps);"prefer-sos",(fun_->prefer_sos);"defer-sos",(fun_->defer_sos);"prefer-goals",(fun_->prefer_goals);"prefer-non-goals",(fun_->prefer_non_goals);"prefer-unit-ground-goals",(fun_->prefer_unit_ground_goals);"prefer-unit-ground-non-goals",(fun_->prefer_unit_ground_non_goals);"prefer-processed",(fun_->prefer_processed);"prefer-lambdas",(fun_->prefer_lambdas);"defer-lambdas",(fun_->defer_lambdas);"prefer-formulas",(fun_->prefer_formulas);"prefer-bool-neq",(fun_->prefer_bool_neq);"defer-formulas",(fun_->defer_formulas);"prefer-easy-ho",(fun_->prefer_easy_ho);"prefer-ground",(fun_->prefer_ground);"defer-ground",(fun_->defer_ground);"defer-fo",(fun_->defer_fo);"prefer-fo",(fun_->prefer_fo);"prefer-shallow",(fun_->prefer_shallow);"defer-shallow",(fun_->defer_shallow);"prefer-empty-trail",(fun_->prefer_empty_trail);"prefer-short-trail",(fun_->prefer_short_trail);"prefer-long-trail",(fun_->prefer_long_trail);"by-neg-lit",(fun_->by_neg_lit);"by-app-var-num",(fun_->by_app_var_num);"by-norm-factor",(fun_->by_normalization_factor);"prefer-top-level-appvars",(fun_->prefer_top_level_app_var);"defer-top-level-appvars",(fun_->prefer_top_level_app_var);"prefer-shallow-appvars",(fun_->prefer_shallow_app_var);"prefer-deep-appvars",(fun_->prefer_deep_app_var);"prefer-neg-unit",(fun_->prefer_neg_unit);"defer-neg-unit",(fun_->defer_neg_unit);"prefer-shallow-lambdas",(fun_->prefer_shallow_lambdas);"prefer-deep-lambdas",(fun_->prefer_deep_lambdas);"prefer-shallow-combs",(fun_->prefer_shallow_combs);"prefer-deep-combs",(fun_->prefer_deep_combs);]letof_strings=tryletf=List.assoc(String.lowercase_asciis)parserssin(func->letp=fcinUtil.debugf~section2" prio(%a)=%d"(funk->kC.ppcp);p)withNot_found->leterr_msg=CCFormat.sprintf"unknown priortity: %s.\noptions:@ {@[%a@]}"s(CCList.ppCCString.pp)(List.mapfstparsers)ininvalid_argerr_msgendmoduleH=CCHeap.Make(struct(* heap ordered by [priority, weight].
the lower the better. *)typet=(int*int*C.t)letleq(i10,i11,c1)(i20,i21,c2)=ifi10<i20thentrueelseif(i10=i20)then(ifi11<i21thentrueelseifi11=i21then(C.comparec1c2<0)elsefalse)elsefalseend)(** A priority queue of clauses + FIFO queue *)typet=|FIFOofC.tQueue.t|Mixedofmixedandmixed={mutableheaps:H.tarray;mutableweight_funs:(C.t->(int*int))array;tbl:unitC.Tbl.t;mutableratios:intarray;mutableratios_limit:int;mutablecurrent_step:int;mutablecurrent_heap_idx:int;}(** generic clause queue based on some ordering on clauses, given
by a weight function *)letis_empty_mixedq=C.Tbl.lengthq.tbl=0letis_empty(q:t)=matchqwith|FIFOq->Queue.is_emptyq|Mixedq->is_empty_mixedqletlengthq=matchqwith|FIFOq->Queue.lengthq|Mixedq->C.Tbl.lengthq.tblletaddqc=matchqwith|FIFOq->Queue.pushcq;true|Mixedq->ifnot(C.Tbl.memq.tblc)then(C.Tbl.addq.tblc();letweights=Array.map(funf->fc)q.weight_funsinletheaps=Array.mapi(funi(prio,weight)->letheap=Array.getq.heapsiinH.insert(prio,weight,c)heap)weightsinq.heaps<-heaps;true)elsefalseletadd_seqqhcs=Iter.iter(func->ignore(addqc))hcslet_initialized=reffalseletrectake_first_mixedq=if(not!_initialized)then(_initialized:=true;Signal.sendon_proof_state_init(C.Tbl.keysq.tbl););letmove_queueq=q.current_step<-q.current_step+1;ifq.current_step>=q.ratios_limitthen((* we have to choose the next heap *)if(q.current_heap_idx+1=Array.length(q.heaps))then((* cycled through all the heaps, starting over *)q.current_heap_idx<-0;q.current_step<-0;q.ratios_limit<-Array.getq.ratios0;)else((* moving to the next heap *)q.current_heap_idx<-q.current_heap_idx+1;q.ratios_limit<-q.ratios_limit+(Array.getq.ratiosq.current_heap_idx)))inifis_empty_mixedqthenraiseNot_found;(* find next clause *)letcurrent_heap=Array.getq.heapsq.current_heap_idxinletcurrent_heap,(_,_,c)=H.take_exncurrent_heapinArray.setq.heapsq.current_heap_idxcurrent_heap;letis_orphanedc=(!_ignoring_orphans&&C.is_orphanedc)||C.is_redundantcin(* if clause was picked by another queue
or it should be ignored, repeat clause choice. *)ifnot(C.Tbl.memq.tblc)then(Util.debugf~section2"clause is not in the table:@ @[%a@]@."(funk->kC.ppc);take_first_mixedq)elseifis_orphanedcthen(C.Tbl.removeq.tblc;Util.debugf~section2"ignoring orphaned clause:@ @[%a@]@."(funk->kC.ppc);Util.debugf~section5"proof:@ @[%a@]@."(funk->kProof.S.pp_tstp(C.proofc));take_first_mixedq)else(Util.debugf~section1"q:%d"(funk->kq.current_heap_idx);C.Tbl.removeq.tblc;move_queueq;c)letmixed_eval():mixed={heaps=CCArray.empty;weight_funs=CCArray.empty;tbl=C.Tbl.create16;ratios=CCArray.empty;ratios_limit=0;current_step=0;current_heap_idx=0;}letadd_to_mixed_eval~ratio~weight_funmixed_eval:unit=letwas_empty=CCArray.lengthmixed_eval.heaps=0inmixed_eval.heaps<-Array.appendmixed_eval.heaps([|H.empty|]);mixed_eval.weight_funs<-Array.appendmixed_eval.weight_funs([|weight_fun|]);mixed_eval.ratios<-Array.appendmixed_eval.ratios([|ratio|]);ifwas_emptythen(mixed_eval.ratios_limit<-ratio);()lettake_first=function|FIFOq->ifQueue.is_emptyqthenraiseNot_foundelseQueue.popq|Mixedq->take_first_mixedqletnameq=matchqwith|FIFO_->"bfs"|Mixedq->"mixed"(** {5 Combination of queues} *)letconst_prioritize_funwf=(func->wfc,1)letfifo_wfc=C.idc,1letgoal_oriented():t=letopenWeightFuninletweight=penalize(combine[default,4;favor_small_num_vars,2;favor_goal,1;favor_all_neg,1;])in(* make ~ratio:6 ~weight name *)letweight_fun=const_prioritize_funweightinletmixed=mixed_eval()inadd_to_mixed_eval~ratio:5~weight_funmixed;add_to_mixed_eval~ratio:1~weight_fun:fifo_wfmixed;Mixedmixedletbfs():t=FIFO(Queue.create())letalmost_bfs():t=letopenWeightFuninletweight=penalize(combine[default,3;])in(* make ~ratio:1 ~weight "almost_bfs" *)letweight_fun=const_prioritize_funweightinletmixed=mixed_eval()inadd_to_mixed_eval~ratio:1~weight_funmixed;add_to_mixed_eval~ratio:1~weight_fun:fifo_wfmixed;Mixedmixedletexplore():t=letopenWeightFunin(* make ~ratio:6 ~weight "explore" *)letweight_fun=const_prioritize_funexplore_funinletmixed=mixed_eval()inadd_to_mixed_eval~ratio:5~weight_funmixed;add_to_mixed_eval~ratio:1~weight_fun:fifo_wfmixed;Mixedmixedletground():t=letopenWeightFuninletweight=penalize(combine[favor_pos_unit,1;favor_ground,2;favor_small_num_vars,10;])in(* make ~ratio:6 ~weight "ground" *)letweight_fun=const_prioritize_funweightinletmixed=mixed_eval()inadd_to_mixed_eval~ratio:5~weight_funmixed;add_to_mixed_eval~ratio:1~weight_fun:fifo_wfmixed;Mixedmixedletdefault():t=letopenWeightFunin(* make ~ratio:6 ~weight "default" *)letweight_fun=const_prioritize_fundefault_funinletmixed=mixed_eval()inadd_to_mixed_eval~ratio:5~weight_funmixed;add_to_mixed_eval~ratio:1~weight_fun:fifo_wfmixed;Mixedmixedletconj_relative_mk():t=(* make ~ratio:6 ~weight:WeightFun.conj_relative "conj_relative" *)letweight_fun=const_prioritize_funWeightFun.conj_relativeinletmixed=mixed_eval()inadd_to_mixed_eval~ratio:5~weight_funmixed;add_to_mixed_eval~ratio:1~weight_fun:fifo_wfmixed;Mixedmixedletconj_var_relative_mk():t=(* make ~ratio:!cr_var_ratio ~weight:(WeightFun.conj_relative ~distinct_vars_mul:!cr_var_mul)
"conj_relative_var" *)letweight_fun=const_prioritize_fun(WeightFun.conj_relative~distinct_vars_mul:!cr_var_mul~parameters_magnitude:!parameters_magnitude~goal_penalty:!goal_penalty)inletmixed=mixed_eval()inadd_to_mixed_eval~ratio:!cr_var_ratio~weight_funmixed;add_to_mixed_eval~ratio:1~weight_fun:fifo_wfmixed;Mixedmixedletho_weight()=(* make ~ratio:4 ~weight:WeightFun.ho_weight_calc "ho-weight" *)letweight_fun=const_prioritize_funWeightFun.ho_weight_calcinletmixed=mixed_eval()inadd_to_mixed_eval~ratio:3~weight_funmixed;add_to_mixed_eval~ratio:1~weight_fun:fifo_wfmixed;Mixedmixedletho_weight_init()=(* make ~ratio:5 ~weight:WeightFun.ho_weight_initial "ho-weight-init" *)letweight_fun=const_prioritize_funWeightFun.ho_weight_initialinletmixed=mixed_eval()inadd_to_mixed_eval~ratio:4~weight_funmixed;add_to_mixed_eval~ratio:1~weight_fun:fifo_wfmixed;Mixedmixedletavoid_expensive_mk():t=(* make ~ratio:20 ~weight:WeightFun.avoid_expensive "avoid-expensive" *)letweight_fun=const_prioritize_funWeightFun.avoid_expensiveinletmixed=mixed_eval()inadd_to_mixed_eval~ratio:10~weight_funmixed;add_to_mixed_eval~ratio:1~weight_fun:fifo_wfmixed;Mixedmixedletof_profilep=letopenClauseQueue_intfinifCCList.is_empty!funs_to_parsethen(matchpwith|P_default->default()|P_bfs->bfs()|P_almost_bfs->almost_bfs()|P_explore->explore()|P_ground->ground()|P_goal->goal_oriented()|P_conj_rel->conj_relative_mk()|P_conj_rel_var->conj_var_relative_mk()|P_ho_weight->ho_weight()|P_ho_weight_init->ho_weight_init()|P_avoid_expensive->avoid_expensive_mk())else(letmixed=mixed_eval()inList.iter(fun(ratio,prio,weight)->letprio_fun=PriorityFun.of_stringprioinletweight_fun=WeightFun.of_stringweightinadd_to_mixed_eval~ratio~weight_fun:(func->prio_func,weight_func)mixed;)!funs_to_parse;Mixedmixed)letall_clausesq=matchqwith|FIFOq->CCSeq.to_iter(Queue.to_seqq)|Mixedq->Iter.mapfst(C.Tbl.to_iterq.tbl)letmem_clqcl=matchqwith|FIFOq->Iter.exists(C.equalcl)(CCSeq.to_iter(Queue.to_seqq))|Mixedq->C.Tbl.memq.tblclletremoveqcl=matchqwith|FIFOq->invalid_arg"legacy queue, removal unsupported"|Mixedq->ifC.Tbl.memq.tblclthen(C.Tbl.removeq.tblcl;true)elsefalseletppoutq=CCFormat.fprintfout"queue %s"(nameq)letto_string=CCFormat.to_stringppendletparse_wf_with_prioritys=letwf_with_prio_regex=Str.regexp"\\([0-9]+\\)|\\(.+\\)|\\(.+\\)"intryignore(Str.search_forwardwf_with_prio_regexs0);letratio=CCOpt.get_exn(CCInt.of_string(Str.matched_group1s))inletpriority_str=CCString.trim(Str.matched_group2s)inletweight_fun=CCString.trim(Str.matched_group3s)infuns_to_parse:=!funs_to_parse@[(ratio,priority_str,weight_fun)]withNot_found|Invalid_argument_->invalid_arg"weight function is of the form \"ratio:int|priority:name|weight:name(options..)\""let()=leto=Arg.Symbol("<custom>"::List.mapfstprofiles_,parse_profile)inletadd_queue=Arg.Stringparse_wf_with_priorityinParams.add_opts["--clause-queue",o," choose which set of clause queues to use (for selecting next active clause)";"-cq",o," alias for --clause-queue";"--add-queue",add_queue," create a new clause evaluation queue. Its description is of the form"^" RATIO|PRIORITY_FUN|WEIGHT_FUN";"-q",add_queue,"alias to --add-queue";"--ignore-orphans",Arg.Bool((:=)_ignoring_orphans)," whether to ignore the orphans during clause selection"];Params.add_to_modes["ho-pragmatic";"ho-competitive";"ho-complete-basic";"fo-complete-basic";"lambda-free-intensional";"lambda-free-extensional";"lambda-free-purify-intensional";"lambda-free-purify-extensional"](fun()->ifCCList.is_empty!funs_to_parsethen(_profile:=P_conj_rel_var;cr_var_ratio:=8;cr_var_mul:=1.05;));