123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157(**************************************************************************)(* *)(* 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). *)(* *)(**************************************************************************)moduleF=Lang.F(* -------------------------------------------------------------------------- *)(* --- Lang Iterator --- *)(* -------------------------------------------------------------------------- *)letiterfe=letq=Queue.create()inQueue.addeq;whilenot(Queue.is_emptyq)dolete=Queue.popqinifF.lc_closedethenfe;F.lc_iter(fune->Queue.pusheq)edoneletoncefe=letq=Queue.create()inletm=refF.Tset.emptyinletonceme=ifF.Tset.meme!mthenfalseelse(m:=F.Tset.adde!m;true)inQueue.addeq;whilenot(Queue.is_emptyq)dolete=Queue.popqinifF.lc_closedethenfe;F.lc_iter(fune->ifoncemethenQueue.pusheq)edone(* -------------------------------------------------------------------------- *)(* --- Head Footprint --- *)(* -------------------------------------------------------------------------- *)lethead_fields=function|[]->""|(Lang.Mfield(mdt,_,_,_),_)::_->mdt.Lang.ext_debug|(Lang.Cfield(fd,_),_)::_->letopenCil_typesinfd.fcomp.cnameletheade=letopenQed.LogicinmatchF.reprewith|Kintz->Z.to_stringz|Krealr->Q.to_stringr|Fvarx->Printf.sprintf"$%s"(F.Var.basenamex)|Bvar(k,_)->Printf.sprintf"#%d"k|True->"T"|False->"F"|And_->"&"|Or_->"|"|Not_->"!"|Imply_->">"|Eq_->"="|Lt_->"<"|Leq_->"<="|Neq_->"~"|Add_->"+"|Mul_->"*"|Times(k,_)->Printf.sprintf".%s"(Z.to_stringk)|Div_->"/"|Mod_->"%"|If_->"?"|Aget_->"[]"|Acst_->"[.]"|Aset_->"[=]"|Rget(_,fd)->Format.asprintf".%a"Lang.Field.prettyfd|Rdeffds->Format.asprintf"{%s}"(head_fieldsfds)|Fun(f,_)->Pretty_utils.to_stringLang.Fun.prettyf|Apply_->"()"|Bind(Forall,_,_)->"\\F"|Bind(Exists,_,_)->"\\E"|Bind(Lambda,_,_)->"\\L"(* -------------------------------------------------------------------------- *)(* --- Term Footprint --- *)(* -------------------------------------------------------------------------- *)letpatterne=letbuffer=Buffer.create32in(tryiter(fune->Buffer.add_stringbuffer(heade);ifBuffer.lengthbuffer>=32thenraiseExit)ewithExit->());Buffer.contentsbuffer(* -------------------------------------------------------------------------- *)(* --- Term Matching --- *)(* -------------------------------------------------------------------------- *)let_prefixmkm'=letn=String.lengthminletn'=String.lengthm'ink+n'<=n&&(tryfori=0ton'-1doifm.[k+i]!=m'.[i]thenraiseExitdone;truewithExit->false)letmatchesfpe=letfe=patternein(*TODO: implement partial mach*)fp=fe(* -------------------------------------------------------------------------- *)(* --- Occurrence --- *)(* -------------------------------------------------------------------------- *)typeoccurrence=int*stringexceptionLocatedofoccurrenceexceptionFoundofF.termletlocate~select~inside=letk=ref0inletm=patternselectintryonce(fune->ife==selectthenraise(Located(!k,m));ifmatchesmethenincrk;)inside;raiseNot_foundwithLocatedfp->fpletlookup~occur~inside=letk=ref(succ(fstoccur))inletm=sndoccurintryonce(fune->ifmatchesmethendecrk;if!k=0thenraise(Founde);)inside;raiseNot_foundwithFounde->e(* -------------------------------------------------------------------------- *)