let merge_fun_callers get_list get_value merge is_top acc proj kf =
if is_top acc then acc
else begin
let acc = ref acc in
let table = ref VarinfoSet.empty in
try
let merge m =
acc := merge m !acc ;
if is_top !acc then
raise StopMerging
in
let rec merge_fun_callers kf =
let merge_fun_caller (kf,_) = merge_fun_callers kf in
let vf = Kernel_function.get_vi kf in
if VarinfoSet.mem vf !table
then ()
else
begin
table := VarinfoSet.add vf !table ;
List.iter (fun x -> merge (get_value x)) (get_list proj kf) ;
List.iter merge_fun_caller (!Db.Value.callers kf)
end
in merge_fun_callers kf ;
!acc
with StopMerging -> !acc
end