+(* glimpse often fails on large queries. We can safely remove arguments of
+&& as long as we don't remove all of them (note that there is no negation).
+This tries just removing one of them and then orders the results by
+increasing number of ors (ors are long, increasing the chance of failure,
+and are less restrictive, possibly increasing the chance of irrelevant
+code. *)
+let reduce_glimpse x =
+ let rec loop x k q =
+ match x with
+ Elem _ -> q()
+ | And [x] -> loop x (function changed_l -> k (And [changed_l])) q
+ | And l ->
+ kloop l
+ (function changed_l -> k (And changed_l))
+ (function _ ->
+ let rec rloop l k =
+ match l with
+ [] -> q()
+ | x::xs ->
+ (k xs) ::
+ rloop xs (function changed_xs -> k (x :: changed_xs)) in
+ rloop l (function changed_l -> k (And changed_l)))
+ | Or l -> kloop l (function changed_l -> k (Or changed_l)) q
+ | _ -> failwith "not possible"
+ and kloop l k q =
+ match l with
+ [] -> q()
+ | x::xs ->
+ loop x
+ (function changed_x -> k (changed_x::xs))
+ (function _ ->
+ kloop xs
+ (function changed_xs -> k (x :: changed_xs))
+ q) in
+ let rec count_ors = function
+ Elem _ -> 0
+ | And l -> List.fold_left (+) 0 (List.map count_ors l)
+ | Or l ->
+ ((List.length l) - 1) +
+ (List.fold_left (+) 0 (List.map count_ors l))
+ | _ -> failwith "not possible" in
+ let res = loop x (function x -> x) (function _ -> []) in
+ let res = List.map (function x -> (count_ors x,x)) res in
+ let res = List.sort compare res in
+ List.map (function (_,x) -> x) res
+