From 31cc45507f90db7d5aebbc281cade93db16e433e Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Thu, 6 Jan 2022 14:37:27 +0100 Subject: [PATCH] [wp] New tactic Mod-Mask --- headers/header_spec.txt | 2 + src/plugins/wp/Cint.mli | 5 ++ src/plugins/wp/Makefile.in | 2 +- src/plugins/wp/TacModMask.ml | 123 ++++++++++++++++++++++++++++++++++ src/plugins/wp/TacModMask.mli | 23 +++++++ 5 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 src/plugins/wp/TacModMask.ml create mode 100644 src/plugins/wp/TacModMask.mli diff --git a/headers/header_spec.txt b/headers/header_spec.txt index bfb81802ef8..f2b7746849a 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -1754,6 +1754,8 @@ src/plugins/wp/TacInstance.ml: CEA_WP src/plugins/wp/TacInstance.mli: CEA_WP src/plugins/wp/TacLemma.ml: CEA_WP src/plugins/wp/TacLemma.mli: CEA_WP +src/plugins/wp/TacModMask.ml: CEA_WP +src/plugins/wp/TacModMask.mli: CEA_WP src/plugins/wp/TacNormalForm.ml: CEA_WP src/plugins/wp/TacNormalForm.mli: CEA_WP src/plugins/wp/TacOverflow.ml: CEA_WP diff --git a/src/plugins/wp/Cint.mli b/src/plugins/wp/Cint.mli index b4868c855f4..e889cc7d286 100644 --- a/src/plugins/wp/Cint.mli +++ b/src/plugins/wp/Cint.mli @@ -77,6 +77,11 @@ val f_bits : lfun list (** All bit-test functions *) val bit_test : term -> int -> term +(** Matchers *) + +val match_power2 : term -> term +val match_power2_minus1 : term -> term + (** Simplifiers *) val is_cint_simplifier: simplifier diff --git a/src/plugins/wp/Makefile.in b/src/plugins/wp/Makefile.in index 72ad09daf3b..d9c8c5f2903 100644 --- a/src/plugins/wp/Makefile.in +++ b/src/plugins/wp/Makefile.in @@ -90,7 +90,7 @@ PLUGIN_CMO:= \ TacArray TacCompound TacUnfold \ TacHavoc TacInstance TacLemma \ TacFilter TacCut WpTac TacNormalForm \ - TacRewrite TacBitwised TacBitrange TacBittest TacShift \ + TacRewrite TacBitwised TacBitrange TacBittest TacModMask TacShift \ TacSequence \ TacCongruence TacOverflow Auto \ ProofSession ProofScript ProofEngine \ diff --git a/src/plugins/wp/TacModMask.ml b/src/plugins/wp/TacModMask.ml new file mode 100644 index 00000000000..ac36c191eb8 --- /dev/null +++ b/src/plugins/wp/TacModMask.ml @@ -0,0 +1,123 @@ +(**************************************************************************) +(* *) +(* This file is part of WP plug-in of Frama-C. *) +(* *) +(* Copyright (C) 2007-2021 *) +(* 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). *) +(* *) +(**************************************************************************) + +open Tactical + +let title_no_revert = "Revert (current: a & m -> a % m+1)" +let title_revert = "Revert (current: m & a -> a % m+1)" + +let v_revert,p_revert = + Tactical.checkbox ~id:"Wp.modmask.revert" + ~title:title_no_revert + ~descr:"Changes operands for modulo" + ~default:false () + +class modmask = + object(self) + inherit Tactical.make + ~id:"Wp.modmask" + ~title:"Mod-Mask" + ~descr:"Converts modulo from/to bitmask" + ~params:[p_revert] + + method select feedback selection = + let open Lang.N in + let open Lang.F in + let open Qed.Logic in + + let e = Tactical.selected selection in + let at = Tactical.at selection in + + let on_cond = Tactical.condition in + let replace_with d v = Tactical.rewrite ?at [ d, Lang.F.p_true, e, v ] in + + let update_title ~hard = + feedback#set_title "Mod-Mask%s" (if hard then " (hard)" else "") + in + let update_field ~enabled = + let revert = self#get_field v_revert in + let title = if revert then title_revert else title_no_revert in + feedback#update_field ~enabled v_revert ; + feedback#update_field ~title v_revert + in + let update_display ~hard ~active_field = + update_title ~hard ; + update_field ~enabled:active_field + in + match Lang.F.repr e with + | Mod(a, m) -> + begin + try + let m = Cint.l_lsl e_one @@ Cint.match_power2 m in + let n = Cint.l_and a (m - e_one) in + let cond = a >= e_zero in + + update_display ~hard:false ~active_field:false ; + Applicable (on_cond "Mask Guard" cond @@ replace_with "Mask" n) + + with Not_found -> + let power_of_2 = + let v = Lang.freshvar ~basename:"n" Lang.t_int in + let tv = e_var v in + p_exists [v] (e_zero <= tv && m = Cint.l_lsl e_one tv) + in + let cond = (a >= e_zero && e_zero < m && power_of_2) in + let n = Cint.l_and a (m - e_one) in + + update_display ~hard:true ~active_field:false ; + Applicable (on_cond "Mask Guard" cond @@ replace_with "Mask" n) + end + + | Fun( f , [ a ; b ] ) when Lang.Fun.equal f Cint.f_land -> + begin + try + let a, m = + try b, Cint.match_power2_minus1 a + with Not_found -> a, Cint.match_power2_minus1 b + in + + let cond = a >= e_zero in + let n = a mod (Cint.l_lsl e_one m) in + + update_display ~hard:false ~active_field:false ; + Applicable (on_cond "Mod Guard" cond @@ replace_with "Mod" n) + + with Not_found -> + let a, m = if self#get_field v_revert then b, a else a, b in + let plus_1_power_of_2 = + let v = Lang.freshvar ~basename:"n" Lang.t_int in + let tv = e_var v in + p_exists [v] (e_zero <= tv && m + e_one = Cint.l_lsl e_one tv) + in + let cond = (a >= e_zero && e_zero <= m && plus_1_power_of_2) in + let n = a mod (m + e_one) in + + update_display ~hard:true ~active_field:true ; + Applicable (on_cond "Mod Guard" cond @@ replace_with "Mod" n) + end + + | _ -> + update_display ~hard:false ~active_field:false ; + Not_applicable + end + +let modmask = Tactical.export (new modmask) diff --git a/src/plugins/wp/TacModMask.mli b/src/plugins/wp/TacModMask.mli new file mode 100644 index 00000000000..fb0f0f4daf1 --- /dev/null +++ b/src/plugins/wp/TacModMask.mli @@ -0,0 +1,23 @@ +(**************************************************************************) +(* *) +(* This file is part of WP plug-in of Frama-C. *) +(* *) +(* Copyright (C) 2007-2021 *) +(* 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). *) +(* *) +(**************************************************************************) + +val modmask : Tactical.tactical -- GitLab