From d5696c2f11fdddfca4e867823f118c97bc33cf1c Mon Sep 17 00:00:00 2001 From: Patrick Baudin <patrick.baudin@cea.fr> Date: Tue, 18 Jan 2022 13:39:44 +0100 Subject: [PATCH] [WP] improves the simplifier dedicated to eq_sequence --- src/plugins/wp/Vlist.ml | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/plugins/wp/Vlist.ml b/src/plugins/wp/Vlist.ml index 85fc0db85f9..827c189d43e 100644 --- a/src/plugins/wp/Vlist.ml +++ b/src/plugins/wp/Vlist.ml @@ -327,20 +327,20 @@ let rewrite_is_nil ~nil a = (* \concat (s1,...,sn)==[] <==> (s1==[] && ... && sn==[]) *) F.p_all p_is_nil es | L.Fun(elt,[_]) when elt == f_elt -> F.p_false (* [x]==[] <==> false *) - | L.Fun(repeat,[u;n]) when repeat == f_repeat -> + | L.Fun(repeat,[s;n]) when repeat == f_repeat -> (* (s *^ n)==[] <==> (s==[] || n<=0) *) - F.p_or (F.p_leq n F.e_zero) (p_is_nil u) + F.p_or (F.p_leq n F.e_zero) (p_is_nil s) | _ -> raise Not_found (* Ensures xs to be a sub-sequence of ys, otherwise raise Not_found In such a case, (concat xs = concat ys) <==> (forall r in result, r = nil) *) let rec subsequence xs ys = - match xs , ys with - | [],ys -> ys - | x::rxs, y::rys -> - if (F.decide (e_eq x y)) then subsequence rxs rys else y :: subsequence xs rys - | _ -> raise Not_found + match xs , ys with + | [],ys -> ys + | x::rxs, y::rys -> + if (F.decide (e_eq x y)) then subsequence rxs rys else y :: subsequence xs rys + | _ -> raise Not_found let elements a = match F.repr a with @@ -367,9 +367,19 @@ let rewrite_eq a b = Lang.F.pp_term a Lang.F.pp_term b pp_pattern a pp_pattern b; match F.repr a , F.repr b with - | _ when a == b -> F.p_true | L.Fun(nil,[]) , _ when nil == f_nil -> rewrite_is_nil ~nil:a b | _ , L.Fun(nil,[]) when nil == f_nil -> rewrite_is_nil ~nil:b a + | L.Fun(repeat_a, [x;n]), L.Fun(repeat_b, [y;m]) + when repeat_a == f_repeat && + repeat_b == f_repeat && + F.decide ( + let nil_a = v_nil (F.typeof a) in + let nil_b = v_nil (F.typeof b) in + F.e_or [ F.e_and [ F.e_eq x y; F.e_eq n m]; + F.e_and [F.e_eq a nil_b; F.e_eq nil_a b]] + ) -> + (* x *^ n == [] && y *^ m == []) || (x == y && n == m) ==> x *^ n == y *^ m *) + F.p_true | _ -> try leftmost_eq a b with Not_found -> try rightmost_eq a b with Not_found -> -- GitLab