]> matita.cs.unibo.it Git - helm.git/blob - helm/software/matita/contribs/formal_topology/bin/comb.ml
922d39a7e4f9b21cb325843982010e37aa8a6bbc
[helm.git] / helm / software / matita / contribs / formal_topology / bin / comb.ml
1 type t = M | I | C
2 type w = t list
3 type eqclass = w list
4
5 type dir = Le | Ge
6
7 let rules =
8  [ [I],     Le, [];
9    [C],     Ge, [];
10    [I;I],   Ge, [I];
11    [C;C],   Le, [C];
12    [I],     Le, [I];
13    [I],     Ge, [I];
14    [C],     Le, [C];
15    [C],     Ge, [C];
16    [C;M],   Le, [M;I];
17    [C;M;I], Le, [M;I];  (* ??? *)
18    [I;M],   Le, [M;C];
19    [I;M;C], Ge, [I;M];  (* ??? *)
20    [M;M;M], Ge, [M];
21    [M;M],   Ge, [];
22    [M],     Le, [M];
23    [M],     Ge, [M];
24  ]
25 ;;
26
27 let swap = function Le -> Ge | Ge -> Le;;
28
29 let rec new_dir dir =
30  function
31     [] -> dir
32   | M::tl -> new_dir (swap dir) tl
33   | (C|I)::tl -> new_dir dir tl
34 ;;
35
36 let string_of_dir = function Le -> "<=" | Ge -> ">=";;
37
38 let string_of_w w =
39  String.concat ""
40   (List.map (function I -> "i" | C -> "c" | M -> "-") w)
41 ;;
42
43 let string_of_eqclass eqc =
44  let eqc = List.sort compare eqc in
45   String.concat "=" (List.map string_of_w eqc)
46 ;;
47
48 let print = List.iter (fun eqc -> prerr_endline (string_of_eqclass eqc));;
49
50 exception NoMatch;;
51
52 let (@@) l1 ll2 = List.map (function l2 -> l1 @ l2) ll2;;
53
54 let uniq l =
55  let rec aux l =
56   function
57      [] -> l
58    | he::tl -> aux (if List.mem he l then l else he::l) tl
59  in
60   aux [] l
61 ;;
62
63 let rec apply_rule_at_beginning (lhs,dir',rhs) (w,dir) =
64  if dir <> dir' then
65   raise NoMatch
66  else
67   let rec aux =
68    function
69       [],w -> w
70     | x::lhs,x'::w when x = x' -> aux (lhs,w)
71     | _,_ -> raise NoMatch
72   in
73    rhs @@ apply_rules (aux (lhs,w),new_dir dir lhs)
74 and apply_rules (w,_ as w_and_dir) =
75  if w = [] then [[]]
76  else
77   let rec aux =
78    function
79       [] -> []
80     | rule::tl ->
81        (try apply_rule_at_beginning rule w_and_dir
82         with NoMatch -> [])
83        @
84        aux tl
85   in
86    aux rules
87 ;;
88
89 let apply_rules (w,dir as w_and_dir) =
90  List.map (fun w' -> w,dir,w')
91   (uniq (apply_rules w_and_dir))
92 ;;
93
94 let step (l : w list) =
95  uniq
96   (List.flatten
97     (List.map
98      (function w -> List.map (fun x -> x@w) [[I];[C];(*[M];*)[]])
99      l))
100 ;;
101
102 let leq rels x y =
103  let rec aux avoid x y =
104   x = y
105   || List.exists
106       (fun (x',dir,z) ->
107         x=x' && dir = Le && not (List.mem z avoid) && aux (z::avoid) z y) rels
108   || List.exists
109       (fun (z,dir,x') ->
110         x=x' && dir = Ge && not (List.mem z avoid) && aux (z::avoid) z y) rels
111  in
112   aux [x] x y
113 ;;
114
115 let in_class rels eqc he =
116  match eqc with
117     [] -> assert false
118   | k::_ -> leq rels k he && leq rels he k
119 ;;
120
121 let add_class rels classes he =
122  let rec aux visited =
123   function
124      [] -> [he]::visited
125    | eqc::tl ->
126       if in_class rels eqc he then
127        (he::eqc)::tl@visited
128       else
129        aux (eqc::visited) tl
130  in
131   aux [] classes
132 ;;
133
134 let classify (l : w list) =
135 (*prerr_endline ("Classify: " ^ string_of_int (List.length l));*)
136  let rels =
137   List.flatten (List.map (fun x -> apply_rules (x,Le) @ apply_rules (x,Ge)) l)
138  in
139   let rec aux classes =
140    function
141       [] -> classes
142     | he::tl -> aux (add_class rels classes he) tl
143   in
144    aux [] l
145 ;;
146
147 let print_graph =
148  List.iter
149   (function (w,dir,w') ->
150     prerr_endline (string_of_w w ^ string_of_dir dir ^ string_of_w w'))
151 ;;
152
153 let print_graph' classes =
154  prerr_endline "=============================";
155  prerr_endline ("Numero di classi trovate: " ^ string_of_int (List.length classes));
156  List.iter (function eqc -> prerr_endline (string_of_eqclass eqc)) classes
157 ;;
158
159 let rec iter n l =
160  print_graph' (classify l);
161  if n > 0 then
162   iter (n - 1) (step l)
163 in
164  iter 4 [[]]
165 ;;