123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151(**************************************************************************)(* *)(* 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). *)(* *)(**************************************************************************)(* -------------------------------------------------------------------------- *)(* --- Lookup Selection --- *)(* -------------------------------------------------------------------------- *)openLangopenLang.FopenTacticalopenConditionstypelookup={target:Lang.F.term;mutablemarked:Tset.t;}letlookup_termenve=letrecwalkenve=ife==env.targetthenraiseExit;ifnot(Tset.memeenv.marked)thenbeginenv.marked<-Tset.addeenv.marked;Lang.F.lc_iter(walkenv)e;endintrywalkenve;falsewithExit->trueletoccurs_xxa=F.Vars.memx(F.varsa)letoccurs_yxp=F.Vars.memx(F.varspp)letoccurs_eab=lookup_term{target=a;marked=Tset.empty}bletoccurs_pap=occurs_ea(F.e_propp)letoccurs_qpq=occurs_e(F.e_propp)(F.e_propq)letlookup_stepenvqueues=matchs.conditionwith|State_->Empty|Whenp|Havep|Initp|Corep|Typep->letp=Lang.F.e_proppinifp==env.targetthenClause(Steps)elseiflookup_termenvpthenInside(Steps,env.target)elseEmpty|Branch(c,sa,sb)->letp=Lang.F.e_propciniflookup_termenvpthenInside(Steps,env.target)else(Queue.addsaqueue;Queue.addsbqueue;Empty)|Eithercs->List.iter(funs->Queue.addsqueue)cs;EmptyexceptionFoundofselectionletlookup_sequenceenvqueueseq=Conditions.iter(funs->matchlookup_stepenvqueueswith|Empty->()|sel->raise(Foundsel))seqletselect_e(sequence,goal)e=letg=Lang.F.e_propgoalinifg==ethenClause(Goalgoal)elseletenv={target=e;marked=Tset.empty}iniflookup_termenvgthenInside(Goalgoal,e)elsetryletqueue=Queue.create()inlookup_sequenceenvqueuesequence;whilenot(Queue.is_emptyqueue)dolookup_sequenceenvqueue(Queue.popqueue)done;EmptywithFoundsel->selletselect_pseqp=select_eseq(F.e_propp)(* -------------------------------------------------------------------------- *)(* --- Elementary Tactics --- *)(* -------------------------------------------------------------------------- *)typeargument=ARG:'afield*'a->argumenttypestrategy={priority:float;tactical:tactical;selection:selection;arguments:argumentlist;}andt=strategylethighestab=Stdlib.compareb.prioritya.priorityclasspool=objectvalpool:strategyVector.t=Vector.create()methodadd=Vector.addpoolmethodsort=leths=Vector.to_arraypoolinArray.stable_sorthighesths;hsendclasstypeheuristic=objectmethodid:stringmethodtitle:stringmethoddescr:stringmethodsearch:(strategy->unit)->sequent->unitendmoduleTmap=Map.Make(String)letregistry=refTmap.emptyletregisters=letid=s#idinifTmap.memid!registrythenWp_parameters.error"Strategy #%s already registered (skipped)"idelseregistry:=Tmap.addid(s:>heuristic)!registryletexports=registers;(s:>heuristic)letlookup~id=Tmap.findid!registryletiterf=Tmap.iter(fun_s->fs)!registryletargfdv=ARG(fd,v)letset_arg(tactical:#tactical)=functionARG(fd,v)->tactical#set_fieldfdvletset_argstacticalarguments=List.iter(set_argtactical)argumentsletmaketactical?(priority=1.0)?(arguments=[])selection={priority;tactical;selection;arguments}(* -------------------------------------------------------------------------- *)