123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213(* SPDX-License-Identifier: MIT *)(* Copyright (C) 2023-2024 formalsec *)(* Written by Hichem Rami Ait El Hara *)openSmtzilla_utilsopenMappings_intfletavailable_models:(string*Regression_model.t)list=letenv_var="MODEL_FILE_PATH"inmatchBos.OS.Env.varenv_varwith|Somepath->Regression_model.read_models_from_filepath|None->Regression_model_default.default_modelsmoduleFresh=structmoduleMake()=structtypesolver_instance=|SolverInst:(moduleSwithtypesolver='s)*'s->solver_instancetypestmt=|AssertionsofExpr.tlist|Push|Popofinttypesolver={solver_instances:(string,solver_instance)Hashtbl.t;mutableexpr_acc:Expr.tlist;mutablestmts:stmtlist;mutablelast_solver:stringoption}typemodel=|Model:(moduleSwithtypesolver='sandtypemodel='m)*'s*'m->modeltypeoptimize=unittypehandle=unitmoduleSolver=structletmake?params:_?logic:_()={solver_instances=Hashtbl.create16;expr_acc=[];stmts=[];last_solver=None}letaddsnew_exprs=Hashtbl.iter(fun_(SolverInst((moduleS),instance))->S.Solver.addinstancenew_exprs)s.solver_instances;s.expr_acc<-List.rev_appendnew_exprss.expr_acc;s.stmts<-Assertionsnew_exprs::s.stmtsletget_best_solverexprs:string=letfeats=Feature_extraction.extract_featsexprsinletscores=List.map(fun(name,model)->letscore=Regression_model.predictfeatsmodelin(score,name))available_modelsinletname=Regression_model.choose_bestscoresinLog.info(funk->k"Selected solver %s"name);nameletget_solver_instancesname=matchHashtbl.find_opts.solver_instancesnamewith|Somes->s|None->let(moduleS):(moduleMappings.S_with_fresh)=matchnamewith|"z3"->(moduleZ3_mappings)|"bitwuzla"->(moduleBitwuzla_mappings)|_->Fmt.failwith"SMTZilla: Unknown solver %s"nameinletinstance=S.Solver.make()inList.iter(function|Assertionsexprs->S.Solver.addinstanceexprs|Push->S.Solver.pushinstance|Popn->S.Solver.popinstancen)(List.revs.stmts);letsolver_inst=SolverInst((moduleS),instance)inHashtbl.adds.solver_instancesnamesolver_inst;solver_inst(* TODO: Need to move some declarations around to be able to use
`Solver_type.t` instead of strings, mayba SMTZilla should not be
one of the solver types? *)letchecks~assumptions=letbest_solver_name=get_best_solver(s.expr_acc@assumptions)in(* TODO: (s.expr_acc @ assumptions) is not really correct as s.expr_acc
does not take into account pushes and pops. *)s.last_solver<-Somebest_solver_name;let(SolverInst((moduleS),solver_inst))=get_solver_instancesbest_solver_nameinS.Solver.checksolver_inst~assumptionsletmodels=matchs.last_solverwith|None->None|Somename->(matchHashtbl.find_opts.solver_instancesnamewith|None->assertfalse|Some(SolverInst((moduleS),s))->(matchS.Solver.modelswith|Somem->Some(Model((moduleS),s,m))|None->None))letpushs=Hashtbl.iter(fun_(SolverInst((moduleS),instance))->S.Solver.pushinstance)s.solver_instances;s.stmts<-Push::s.stmtsletpopsn=Hashtbl.iter(fun_(SolverInst((moduleS),instance))->S.Solver.popinstancen)s.solver_instances;s.stmts<-Popn::s.stmtsletresets=Hashtbl.iter(fun_(SolverInst((moduleS),instance))->S.Solver.resetinstance)s.solver_instancesletclones={swithsolver_instances=(letsolver_instances=Hashtbl.create16inHashtbl.iter(funname(SolverInst((moduleS),instance))->Hashtbl.addsolver_instancesname(SolverInst((moduleS),S.Solver.cloneinstance)))s.solver_instances;solver_instances);stmts=s.stmts}letinterrupts=Hashtbl.iter(fun_(SolverInst((moduleS),instance))->S.Solver.interruptinstance)s.solver_instancesletadd_simplifiers=Hashtbl.filter_map_inplace(fun_(SolverInst((moduleS),instance))->letinstance=S.Solver.add_simplifierinstanceinSome(SolverInst((moduleS),instance)))s.solver_instances;sletget_statisticss=Hashtbl.fold(fun_(SolverInst((moduleS),instance))acc->Statistics.merge(S.Solver.get_statisticsinstance)acc)s.solver_instancesStatistics.Map.emptyendletvalue(Model((moduleS),_,m))expr=S.valuemexprletvalues_of_model?symbols(Model((moduleS),_,m))=S.values_of_model?symbolsmletset_debug_=()letdie()=Fmt.failwith"Unsupported with SMTZilla"moduleOptimizer=structletmake_=die()letpush_=die()letpop_=die()letadd_=die()letcheck_=die()letmodel_=die()letmaximize_=die()letminimize_=die()letinterrupt_=die()letget_statistics_=die()endmoduleSmtlib=structletpp?name:_?logic:_?status:__fmt_=die()endendendletis_available=matchavailable_modelswith|[]->false|[(name,_)]->Fmt.failwith"SMTZilla: the loaded model was only trained on %s, you should either \
use a model that is trained on more than one model, or use %s solver \
directly"namename|_->trueincludeFresh.Make()