-
Notifications
You must be signed in to change notification settings - Fork 0
/
coverproblem.ml
64 lines (58 loc) · 1.81 KB
/
coverproblem.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
(*#use "binword2.ml"
*)
let attrib_cover (x:binword) mintermes =
List.filter (is_cover x) mintermes
;;
let coverture (implicants:binword list) (mintermes:binword list) =
List.map (fun x -> (x, attrib_cover x mintermes)) implicants
;;
let find_max_cover cover_set =
let rec aux cover_set max n =
match cover_set with
| (x,l)::r ->
let m = List.length l in
if m > n then aux r (Some (x,l)) m
else aux r max n
| _ -> max
in aux cover_set None 0
;;
let extract_essential cover_set =
let rec aux cover_set accu unsuitable covered=
match cover_set with
| (x,l)::r ->
begin match l with
| [y] -> aux r (x::accu) unsuitable (y::covered)
| _ -> aux r accu ((x,l)::unsuitable) covered
end
| _ -> accu, unsuitable, covered
in
let (prime_essentiels, unsuitable, covered) = aux cover_set [] [] [] in
(prime_essentiels, List.map (
fun (x,l) -> (
x, List.filter (fun y -> List.mem y covered) l)
) unsuitable
)
;;
let compute_mincover implicants mintermes =
let minterm_cover = coverture implicants mintermes in
let essentials, cover = extract_essential minterm_cover in
(* TODO: filtrer impliquant premier *)
let rec aux m_cover accu =
if m_cover = [] then accu
else begin
let next_implicant = find_max_cover m_cover in
match next_implicant with
| None -> accu
| Some (x,implique) ->
(* SHORTCUT TRICK *)
(* on filtre m_cover pour supprimer l'impliquant qu'on a enlevé *)
(* puis on supprime les mintermes déjà couvert *)
let new_cover_set = List.filter (fun (z,_) -> z<>x) m_cover in
let new_cover_set2 = List.map
(fun (y,l) ->
(y, List.filter (fun z -> not (List.mem z implique)) l)
) new_cover_set
in aux new_cover_set2 (x::accu)
end
in aux cover essentials
;;