From 30345328df6fae16c4007e0e7ffc4874230ce766 Mon Sep 17 00:00:00 2001 From: Patrick Baudin <patrick.baudin@cea.fr> Date: Tue, 18 Jan 2022 10:56:49 +0100 Subject: [PATCH] [WP] rewrites the part of eq_sequence relative to subsequence comparison --- src/plugins/wp/Vlist.ml | 52 +++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/plugins/wp/Vlist.ml b/src/plugins/wp/Vlist.ml index 6120190ef6d..85fc0db85f9 100644 --- a/src/plugins/wp/Vlist.ml +++ b/src/plugins/wp/Vlist.ml @@ -332,24 +332,35 @@ let rewrite_is_nil ~nil a = F.p_or (F.p_leq n F.e_zero) (p_is_nil u) | _ -> raise Not_found -let elements a = - match F.repr a with - | L.Fun( nil , [] ) when nil == f_nil -> [] - | L.Fun( concat , es ) when concat == f_concat -> es - | _ -> [a] -(* [omit rs x ys]: if ys = u.x.v returns (rs+u,v) with r in reverse order *) +(* 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 -let rec omit rs x = function - | [] -> raise Not_found - | y::ys -> if x == y then rs,ys else omit (y::rs) x ys +let elements a = + match F.repr a with + | L.Fun(concat,es) when concat == f_concat -> true, es + | _ -> false, [ a ] + +(* Ensures that [a] or [b] is a sub-sequence of the other, otherwise [raise Not_found] + In such a case, (concat xs = concat ys) <==> (forall r in result, r = nil) *) +let subsequence a b = + let destruct_a, xs = elements a in + let destruct_b, ys = elements b in + if not (destruct_a || destruct_b) then raise Not_found; + let shortest,xs,ys = if List.length xs <= List.length ys then a,xs,ys else b,ys,xs in + let es = subsequence xs ys in + (* xs=ys <==> forall s in es ; s = nil *) + let nil = v_nil (F.typeof shortest) in + (* [s] are elements of [ys] (the longest sequence) and [nil] has the same type than the [shortest] sequence *) + let p_is_nil s = F.p_equal nil s in + F.p_all p_is_nil es -let rec subsequence xs rs ys = - match xs with - | [] -> List.rev_append rs ys - | x::xs -> - let rs,ys = omit rs x ys in - subsequence xs rs ys let rewrite_eq a b = debug "Vlist.rewrite_eq: tries to rewrite %a@ = %a@.- left pattern: %a@.- right pattern: %a@." @@ -362,16 +373,7 @@ let rewrite_eq a b = | _ -> try leftmost_eq a b with Not_found -> try rightmost_eq a b with Not_found -> - let xs = elements a in - let ys = elements b in - let rs = if List.length xs < List.length ys - then subsequence xs [] ys - else subsequence ys [] xs - in - let pred = F.p_all (fun s -> F.p_equal s (v_nil (F.typeof s))) rs in - if F.decide (e_prop pred) - then F.p_true - else raise Not_found + subsequence a b (* All Simplifications *) -- GitLab