123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199(**************************************************************************)(* *)(* SPDX-License-Identifier LGPL-2.1 *)(* Copyright (C) *)(* CEA (Commissariat à l'énergie atomique et aux énergies alternatives) *)(* *)(**************************************************************************)openWhy3(* -------------------------------------------------------------------------- *)(* --- Why3 Config --- *)(* -------------------------------------------------------------------------- *)letwhy3_version=Why3.Config.versionletfile()=letparam=Wp_parameters.Why3Config.get()inifFilepath.is_emptyparamthenNoneelseSome(Filepath.to_string_absparam)(* brittle but the best we can do with the current API *)letextend_configconfig=letdata=Why3.Autodetection.read_auto_detection_dataconfiginletprovers=Why3.Autodetection.find_proversdatainletto_rcprovers=letto_section(path,name,version)=letset_stringfvs=Why3.Rc.set_stringsfvinWhy3.Rc.empty_section|>set_string"name"name|>set_string"path"path|>set_string"version"versioninletsections=List.mapto_sectionproversinWhy3.Rc.set_simple_familyWhy3.Rc.empty"partial_prover"sectionsin!Whyconf.provers_from_detected_proversconfig(to_rcprovers)letthe_config=refNonelet()=letmust_reload_config__=the_config:=NoneinWp_parameters.Why3Config.add_update_hookmust_reload_config;Wp_parameters.Why3ExtraConfig.add_update_hookmust_reload_configletconfig()=ifOption.is_none!the_configthenbegintryletfile=file()inletextra_config=Wp_parameters.Why3ExtraConfig.get()inletconfig=Why3.Whyconf.init_config~extra_configfileinletauto_detect=Wp_parameters.Why3Autodetect.get()inletconfig=ifauto_detectthenextend_configconfigelseconfiginthe_config:=Someconfig;withexn->Wp_parameters.abort"%a"Why3.Exn_printer.exn_printerexnend;Option.get!the_configletflags_changed=reftruelet()=letmust_reconfigure__=flags_changed:=trueinWp_parameters.Why3Flags.add_update_hookmust_reconfigureletconfigure=beginfun()->if!flags_changedthenbeginletcommands="why3"::Wp_parameters.Why3Flags.get()inletargs=Array.of_listcommandsinbegintry(* Ensure that an error message generating directly by why3 is
reported as coming from Why3, not from Frama-C. *)Why3.Getopt.commands:=commands;Why3.Getopt.parse_all(Why3.Debug.Args.[desc_debug;desc_debug_all;desc_debug_list])(funopt->raise(Arg.Bad("unknown option: "^opt)))argswithArg.Bads|Arg.Helps->Wp_parameters.abort"%s"send;ignore(Why3.Debug.Args.option_list());Why3.Debug.Args.set_flags_selected();flags_changed:=falseendendletset_procs=Why3.Controller_itp.set_session_max_tasks(* -------------------------------------------------------------------------- *)(* --- Why3 Provers --- *)(* -------------------------------------------------------------------------- *)typet=Why3.Whyconf.proverletident_why3=Why3.Whyconf.prover_parseable_formatletident_wps=letname=Why3.Whyconf.prover_parseable_formatsinletprv=String.split_on_char','nameinString.concat":"prvlettitle?(version=true)p=ifversionthenPretty_utils.to_stringWhy3.Whyconf.print_proverpelsep.Why3.Whyconf.prover_nameletcompare=Why3.Whyconf.Prover.compareletequal=Why3.Whyconf.Prover.equallethash=Why3.Whyconf.Prover.hashletnamep=p.Why3.Whyconf.prover_nameletversionp=p.Why3.Whyconf.prover_versionletis_mainstreamp=p.Why3.Whyconf.prover_version<>""&&p.Why3.Whyconf.prover_altern=""letis_auto(p:t)=matchp.prover_namewith|"Coq"|"Isabelle"->false|"Alt-Ergo"|"Z3"|"CVC4"|"CVC5"|"Colibri2"->true|_->letconfig=config()intryletprover_config=Why3.Whyconf.get_prover_configconfigpinnotprover_config.interactivewithNot_found->truelethas_counter_examplesp=List.mem"counterexamples"@@String.split_on_char'+'p.Why3.Whyconf.prover_alternletprovers()=Why3.Whyconf.Mprover.keys(Why3.Whyconf.get_provers(config()))letis_availablep=Why3.Whyconf.Mprover.memp(Why3.Whyconf.get_provers(config()))letwith_counter_examplesp=ifhas_counter_examplespthenSomepelseletname=p.prover_nameinletversion=p.prover_versioninList.find_opt(fun(q:t)->q.prover_name=name&&q.prover_version=version&&has_counter_examplesq)@@provers()(* -------------------------------------------------------------------------- *)(* --- Prover Lookup --- *)(* -------------------------------------------------------------------------- *)(* semantical version comparison *)typesem=Vofint|Sofstringletsems=tryV(int_of_strings)withFailure_->Ssletcmpxy=matchx,ywith|Va,Vb->b-a|V_,S_->(-1)|S_,V_->(+1)|Sa,Sb->String.compareabletscmpuv=cmp(semu)(semv)letvcmpuv=List.comparescmp(String.split_on_char'.'u)(String.split_on_char'.'v)letby_version(p:t)(q:t)=vcmpp.prover_versionq.prover_versionletfilter~name?version(p:t)=p.prover_altern=""&&String.lowercase_asciip.prover_name=name&&matchversionwithNone->true|Somev->p.prover_version=vletselect~name?version()=matchList.sortby_version@@List.filter(filter~name?version)@@provers()withp::_->Somep|[]->Noneletlookup?(fallback=false)prover_name=matchString.split_on_char':'@@String.lowercase_asciiprover_namewith|[name]->select~name()|[name;version]->beginmatchselect~name~version()with|Some_asres->res|None->iffallbackthenmatchselect~name()with|None->None|Somepasres->Wp_parameters.warning~once:true~current:false"Prover %s not found, fallback to %s"prover_name(ident_wpp);reselseNoneend|_->None(* -------------------------------------------------------------------------- *)(* --- Models --- *)(* -------------------------------------------------------------------------- *)typemodel=Why3.Model_parser.concrete_syntax_termletpp_model=Why3.Model_parser.print_concrete_term(* -------------------------------------------------------------------------- *)