let discriminant ?(bottom=false) ?(highest=true) evalsel vl constraints =
let eval_constr = Hashtbl.create 17 in
let constr_eval = Hashtbl.create 17 in
let candidates = range ~bottom vl in
List.iter (fun target ->
let eval = List.map (evalsel target) constraints in
try
let v_rep = Hashtbl.find eval_constr eval in
let l = Hashtbl.find constr_eval v_rep in
Hashtbl.replace constr_eval v_rep (target::l)
with Not_found -> begin
Hashtbl.add eval_constr eval target;
Hashtbl.add constr_eval target []
end
) (if highest then List.rev candidates else candidates) ;
(Hashtbl.fold (fun k v acc -> (k,v)::acc) constr_eval [])