123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168(**************************************************************************)(* *)(* This file is part of WP plug-in of Frama-C. *)(* *)(* Copyright (C) 2007-2024 *)(* CEA (Commissariat a l'energie atomique et aux energies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)(* -------------------------------------------------------------------------- *)(* --- Why3 Config & Provers --- *)(* -------------------------------------------------------------------------- *)letcfg=lazybeginletextra_config=Wp_parameters.Why3ExtraConfig.get()intryWhy3.Whyconf.init_config~extra_configNonewithexn->Wp_parameters.abort"%a"Why3.Exn_printer.exn_printerexnendletwhy3_version=Why3.Config.versionletconfig()=Lazy.forcecfgletset_procs=Why3.Controller_itp.set_session_max_tasksletconfigure=lettodo=reftrueinbeginfun()->if!todothenbeginletcommands="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();todo:=falseendendtypet=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.compareletnamep=p.Why3.Whyconf.prover_nameletversionp=p.Why3.Whyconf.prover_versionletalternp=p.Why3.Whyconf.prover_alternletis_mainstreamp=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()))letprovers_set():Why3.Whyconf.Sprover.t=Why3.Whyconf.Mprover.domain(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(* -------------------------------------------------------------------------- *)