123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289(**************************************************************************)(* *)(* This file is part of WP plug-in of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* 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). *)(* *)(**************************************************************************)openFactoryopenGuiSource(* ------------------------------------------------------------------------ *)(* --- RUN WP --- *)(* ------------------------------------------------------------------------ *)exceptionStopletupdate_callback=ref(fun()->())leton_updatef=update_callback:=fletupdate()=!update_callback()letreload_callback=ref(fun()->())leton_reloadf=reload_callback:=fletreload()=!reload_callback()letwith_modelactionkf=letsetup=Factory.parse(Wp_parameters.Model.get())inletdriver=Driver.load_driver()inletmodel=Factory.instancesetupdriverinlethypotheses_computer=WpContext.compute_hypothesesmodelinletname=WpContext.MODEL.idmodelinactionkfnamehypotheses_computerletwarn_memory_contextkfs=ifWp_parameters.MemoryContext.get()thenbeginKernel_function.Set.iter(funkf->with_modelMemoryContext.warnkf)kfsendletpopulate_memory_contextkfs=ifWp_parameters.CheckMemoryContext.get()thenbeginKernel_function.Set.iter(funkf->with_modelMemoryContext.add_behaviorkf)kfsendletspawnproversvcs=ifnot(Bag.is_emptyvcs)thenletprovers=Why3.Whyconf.Sprover.elementsprovers#getinVC.command~provers~tip:truevcslettreat_hypothesesselection=letkf=matchselectionwith|S_none->None|S_funkf->Somekf|S_propip->Property.get_kfip|S_calls->Some(Kernel_function.find_englobing_kfs.s_stmt)inletkfs=matchkfwith|Somekf->WpTarget.with_calleeskf|None->Kernel_function.Set.emptyinwarn_memory_contextkfs;populate_memory_contextkfsletrun_and_prove(main:Design.main_window_extension_points)(provers:GuiConfig.provers)(selection:GuiSource.selection)=begintrybegintreat_hypothesesselection;matchselectionwith|S_none->raiseStop|S_funkf->spawnprovers(VC.generate_kfkf)|S_propip->spawnprovers(VC.generate_ipip)|S_calls->spawnprovers(VC.generate_calls.s_stmt)end;main#redisplay()withStop->()end(* ------------------------------------------------------------------------ *)(* --- Model Panel --- *)(* ------------------------------------------------------------------------ *)typememory=TREE|HOARE|TYPED|REGION|EVAclassmodel_selector(main:Design.main_window_extension_points)=letdialog=newWpane.dialog~title:"WP Memory Model"~window:main#main_window()inletmemory=newWidget.groupHOAREinletr_hoare=memory#add_radio~label:"Hoare Memory Model"~value:HOARE()inletr_typed=memory#add_radio~label:"Typed Memory Model"~value:TYPED()inletr_eva=memory#add_radio~label:"Eva Memory Model"~value:EVA()inletc_casts=newWidget.checkbox~label:"Unsafe casts"()inletc_byref=newWidget.checkbox~label:"Reference Arguments"()inletc_ctxt=newWidget.checkbox~label:"Context Arguments (Caveat)"()inletc_cint=newWidget.checkbox~label:"Machine Integers"()inletc_cfloat=newWidget.checkbox~label:"Floating Points"()inletm_label=newWidget.label~style:`Title()inobject(self)initializerbegindialog#add_rowr_hoare#coerce;dialog#add_rowr_typed#coerce;dialog#add_rowr_eva#coerce;dialog#add_rowc_casts#coerce;dialog#add_rowc_byref#coerce;dialog#add_rowc_ctxt#coerce;dialog#add_rowc_cint#coerce;dialog#add_rowc_cfloat#coerce;dialog#add_rowm_label#coerce;dialog#button~label:"Cancel"~icon:`CANCEL~action:(`CANCEL)();dialog#button~label:"Apply"~icon:`APPLY~action:(`APPLY)();memory#on_checkTYPEDc_casts#set_enabled;memory#on_eventself#connect;c_casts#on_eventself#connect;c_byref#on_eventself#connect;c_ctxt#on_eventself#connect;c_cint#on_eventself#connect;c_cfloat#on_eventself#connect;dialog#on_value`APPLYself#update;endmethodupdate()=Wp_parameters.Model.set[Factory.identself#get]methodset(s:setup)=begin(matchs.mheapwith|ZeroAlias->memory#setTREE|Region->memory#setREGION|Hoare->memory#setHOARE|Typedm->memory#setTYPED;c_casts#set(m=MemTyped.Unsafe)|Eva->memory#setEVA);c_byref#set(s.mvar=Ref);c_ctxt#set(s.mvar=Caveat);c_cint#set(s.cint=Cint.Machine);c_cfloat#set(s.cfloat=Cfloat.Float);endmethodget:setup=letm=matchmemory#getwith|TREE->ZeroAlias|REGION->Region|HOARE->Hoare|TYPED->Typed(ifc_casts#getthenMemTyped.UnsafeelseMemTyped.Fits)|EVA->Evain{mheap=m;mvar=ifc_ctxt#getthenCaveatelseifc_byref#getthenRefelseVar;cint=ifc_cint#getthenCint.MachineelseCint.Natural;cfloat=ifc_cfloat#getthenCfloat.FloatelseCfloat.Real;}methodconnect()=beginm_label#set_text(Factory.descrself#get);c_byref#set_enabled(notc_ctxt#get);endmethodrun=beginlets=Factory.parse(Wp_parameters.Model.get())inself#sets;self#connect();dialog#run();endend(* ------------------------------------------------------------------------ *)(* --- WP Panel --- *)(* ------------------------------------------------------------------------ *)letwp_configure_modelmain()=(newmodel_selectormain)#runletwp_panel~(main:Design.main_window_extension_points)~(configure_provers:unit->unit)=letvbox=GPack.vbox()inletdemon=Gtk_form.demon()inletpacking=vbox#packinletcontrol=GPack.table~columns:2~col_spacings:8~rows:2~packing()inletaddcontrollinecolw=control#attach~left:(col-1)~top:(line-1)~expand:`NONEwinGtk_form.label~text:"timeout"~packing:(addcontrol12)();Gtk_form.spinner~lower:0~upper:100000~tooltip:"Timeout for proving one proof obligation"~packing:(addcontrol11)Wp_parameters.Timeout.getWp_parameters.Timeout.setdemon;Gtk_form.label~text:"process"~packing:(addcontrol22)();Gtk_form.spinner~lower:1~upper:32~tooltip:"Maximum number of parallel running provers"~packing:(addcontrol21)Wp_parameters.Procs.get(funn->Wp_parameters.Procs.setn;ignore(ProverTask.server())(* to make server procs updated is server exists *))demon;lethbox=GPack.hbox~packing()inletmodel_cfg=newWidget.button~label:"Model..."~tooltip:"Configure WP Model"()inmodel_cfg#connect(wp_configure_modelmain);hbox#packmodel_cfg#coerce;letprover_cfg=newWidget.button~label:"Provers..."~tooltip:"Detect WP Provers"()inprover_cfg#connectconfigure_provers;hbox#packprover_cfg#coerce;Gtk_form.menu["No Cache",Cache.NoCache;"Update",Cache.Update;"Cleanup",Cache.Cleanup;"Rebuild",Cache.Rebuild;"Replay",Cache.Replay;"Offline",Cache.Offline;]~packing:hbox#pack~tooltip:"Proof Cache Mode"Cache.get_modeCache.set_modedemon;letpbox=GPack.hbox~packing~show:false()inletprogress=GRange.progress_bar~packing:(pbox#pack~expand:true~fill:true)()inletcancel=GButton.button~packing:(pbox#pack~expand:false)~stock:`STOP()incancel#misc#set_sensitivefalse;letserver=ProverTask.server()inignore(cancel#connect#released~callback:(fun()->Task.cancel_allserver));letinactive=(0,0)inletstate=refinactiveinTask.on_server_activityserver(fun()->letscheduled=Task.scheduledserverinletterminated=Task.terminatedserverinletremaining=scheduled-terminatedinifremaining<=0then(pbox#misc#hide();state:=inactive;cancel#misc#set_sensitivefalse)elsebeginif!state=inactivethen(pbox#misc#show();cancel#misc#set_sensitivetrue);lets_term,s_sched=!stateinifs_term<>terminatedthenupdate();ifs_sched<>scheduled||s_term<>terminatedthenbeginprogress#set_text(Printf.sprintf"%d / %d"terminatedscheduled);progress#set_fraction(ifscheduled=0then1.0else(floatterminated/.floatscheduled));end;state:=(terminated,remaining);end);Task.on_server_stopserverupdate;begin"WP",vbox#coerce,Some(Gtk_form.refreshdemon);endletregister~main~configure_provers=main#register_panel(funmain->wp_panel~main~configure_provers)(* -------------------------------------------------------------------------- *)