123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167(**************************************************************************)(* *)(* 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). *)(* *)(**************************************************************************)(* -------------------------------------------------------------------------- *)(* --- Variables Cleaning --- *)(* -------------------------------------------------------------------------- *)openQed.LogicopenLangopenLang.F(* -------------------------------------------------------------------------- *)(* --- Lattice --- *)(* -------------------------------------------------------------------------- *)type'aoccur=|TOP|TRUE|FALSE|EQof'aletcupeqay=matchawith|EQxwheneqxy->a|_->TOPletcup_true=function|TRUE->TRUE|_->TOPletcup_false=function|FALSE->FALSE|_->TOPletset_topmp=Vars.fold(funxm->Vmap.addxTOPm)(F.varspp)mletaddeqxdm=Vmap.addx(trycupeq(Vmap.findxm)dwithNot_found->EQd)mletadd_truemx=Vmap.addx(trycup_true(Vmap.findxm)withNot_found->TRUE)mletadd_falsemx=Vmap.addx(trycup_false(Vmap.findxm)withNot_found->FALSE)mletadd_var=addVar.equalletadd_fun=addFun.equal(* -------------------------------------------------------------------------- *)(* --- Collector --- *)(* -------------------------------------------------------------------------- *)letrecadd_predmp=matchF.p_exprpwith|Andps->List.fold_leftadd_predmps|If(e,a,b)->add_pred(add_pred(set_topme)a)b|Eq(a,b)->beginmatchF.p_expra,F.p_exprbwith|Fvarx,Fvary->add_varxy(add_varyxm)|_->set_topmpend|Fvarx->add_truemx|Notp->beginmatchF.p_exprpwith|Fvarx->add_falsemx|_->set_topmpend|_->set_topmpletrecadd_typemp=matchF.p_exprpwith|Andps->List.fold_leftadd_typemps|Fun(f,[e])->beginmatchF.e_exprewith|Fvarx->add_funxfm|_->set_topmpend|_->set_topmp(* -------------------------------------------------------------------------- *)(* --- Usage --- *)(* -------------------------------------------------------------------------- *)typeusage={mutableeq_var:varoccurVmap.t;mutableeq_fun:lfunoccurVmap.t;}letcreate()={eq_var=Vmap.empty;eq_fun=Vmap.empty}letas_atommp=m.eq_var<-set_topm.eq_varpletas_havemp=m.eq_var<-add_predm.eq_varpletas_initmp=m.eq_fun<-add_typem.eq_funpletas_typemp=m.eq_fun<-add_typem.eq_funp(* -------------------------------------------------------------------------- *)(* --- Extraction --- *)(* -------------------------------------------------------------------------- *)letgetxm=trySome(Vmap.findxm)withNot_found->Noneletis_truexm=trymatchVmap.findxmwithTRUE->true|_->falsewithNot_found->falseletis_falsexm=trymatchVmap.findxmwithFALSE->true|_->falsewithNot_found->falseletis_varxm=trymatchVmap.findxm.eq_varwith|EQy->beginmatchgetxm.eq_fun,getym.eq_funwith|None,_->true(* we eliminate x, which has no guard... *)|Some(EQf),Some(EQg)->Fun.equalfg|_->falseend|_->falsewithNot_found->false(* -------------------------------------------------------------------------- *)(* --- Filtering --- *)(* -------------------------------------------------------------------------- *)letrecfilter_predmp=matchF.p_exprpwith|Andps->F.p_all(filter_predm)ps|If(e,a,b)->p_ife(filter_predma)(filter_predmb)|Eq(a,b)->beginmatchF.p_expra,F.p_exprbwith|Fvarx,Fvarywhenis_varxm||is_varym->p_true|_->pend|Fvarxwhenis_truexm.eq_var->p_true|Notq->beginmatchF.p_exprqwith|Fvarxwhenis_falsexm.eq_var->p_true|_->pend|_->pletrecfilter_typemp=matchF.p_exprpwith|Andps->F.p_all(filter_typem)ps|Fun(_,[e])->beginmatchF.p_exprewith|Fvarxwhenis_varxm->p_true|_->pend|_->p