123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899(**************************************************************************)(* *)(* 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). *)(* *)(**************************************************************************)openLangopenConditionsopenTactical(** Useful **)letstr_case="Case"letsub_casesphi=function|[]->List.map(funt->phistr_case(F.p_boolt))|[descr]->List.map(funt->phidescr(F.p_boolt))|infos->List.map2(funinfot->phiinfo(F.p_boolt))infos(* split into n sequents: [hyps] |- [subcases]_i *)letf_replace_goalinfossubcases(hyps,_)=letsub_casedescrp=descr,(hyps,p)insub_casessub_caseinfossubcases(* split into n sequents: [subcases]_i, hyps/[hyp] |- goal
in fact, [hyp] is replaced by [subcases]_i *)letf_replace_hyphypinfossubcasessequent=letsub_casedescrp=descr,Conditions.(replace~at:hyp.id(update_condhyp~descr(Whenp))sequent)insub_casessub_caseinfossubcases(* -------------------------------------------------------------------------- *)(* --- FNC (goal) and FND (hyp) tacticals --- *)(* -------------------------------------------------------------------------- *)letnf_conj_argse=matchF.reprewith|Qed.Logic.Andxs->xs|_->[e]letnf_disj_argse=matchF.reprewith|Qed.Logic.Orxs->xs|_->[e]letf_nf_goale~depth=f_replace_goal["CNF"](nf_conj_args(WpTac.e_cnf~depthe))letf_nf_hypse~depth=f_replace_hyps["DNF"](nf_disj_args(WpTac.e_dnf~depthe))letmatch_selection=function|Clause(Goalp)->lete=Lang.F.e_proppinifWpTac.is_cnfethenNoneelseSome(true,e,f_nf_goale)|Clause(Steps)->beginmatchs.conditionwith|(Typep|Havep|Whenp|Corep|Initp)->lete=Lang.F.e_proppinifWpTac.is_dnfethenNoneelseSome(false,e,f_nf_hypse)|_->Noneend|Inside(_,_)|Compose_|Empty|Multi_->Noneclassnormal_form=objectinheritTactical.make~id:"Wp.normal_form"~title:"Intuition"~descr:"Decompose with Conjunctive/Disjunctive Normal Form"~params:[]methodselectfeedback(s:Tactical.selection)=matchmatch_selectionswith|Some(pol,_,continuation)->feedback#set_title(ifpolthen"Intuition (CNF)"else"Intuition (DNF)");letdepth=(-1)inApplicable(continuation~depth)|_->Not_applicableendlettactical=Tactical.export(newnormal_form)letstrategy=Strategy.maketactical~arguments:[](* -------------------------------------------------------------------------- *)