]> matita.cs.unibo.it Git - helm.git/blob - helm/software/matita/contribs/formal_topology/bin/theory_explorer.ml
Unlinked nodes are now printed.
[helm.git] / helm / software / matita / contribs / formal_topology / bin / theory_explorer.ml
1 (* operator *)
2 type op = I | C | M
3
4 let string_of_op =
5  function
6     I -> "i"
7   | C -> "c"
8   | M -> "-"
9
10 (* compound operator *)
11 type compound_operator = op list
12
13 let string_of_cop op =
14  if op = [] then "id" else String.concat "" (List.map string_of_op op)
15
16 let dot_of_cop op = "\"" ^ string_of_cop op ^ "\""
17
18 let rec matita_of_cop v =
19  function
20   | [] -> v
21   | I::tl -> "i (" ^ matita_of_cop v tl ^ ")"
22   | C::tl -> "c (" ^ matita_of_cop v tl ^ ")"
23   | M::tl -> "m (" ^ matita_of_cop v tl ^ ")"
24
25 (* representative, other elements in the equivalence class,
26    leq classes, geq classes *)
27 type equivalence_class =
28  compound_operator * compound_operator list *
29   equivalence_class list ref * equivalence_class list ref
30
31 let string_of_equivalence_class (repr,others,leq,_) =
32  String.concat " = " (List.map string_of_cop (repr::others)) ^
33   (if !leq <> [] then
34     "\n" ^
35      String.concat "\n" 
36       (List.map
37         (function (repr',_,_,_) ->
38            string_of_cop repr ^ " <= " ^ string_of_cop repr') !leq)
39    else
40     "")
41
42 let dot_of_equivalence_class (repr,others,leq,_) =
43  (if others <> [] then
44    let eq = String.concat " = " (List.map string_of_cop (repr::others)) in
45     dot_of_cop repr ^ "[label=\"" ^ eq ^ "\"];" ^
46      if !leq = [] then "" else "\n"
47   else if !leq = [] then
48    dot_of_cop repr ^ ";"
49   else
50    "") ^
51    String.concat "\n" 
52     (List.map
53       (function (repr',_,_,_) ->
54          dot_of_cop repr' ^ " -> " ^ dot_of_cop repr ^ ";") !leq)
55
56 (* set of equivalence classes *)
57 type set = equivalence_class list
58
59 let string_of_set s =
60  String.concat "\n" (List.map string_of_equivalence_class s)
61
62 let ps_of_set ?processing s =
63  let ch = open_out "xxx.dot" in
64   output_string ch "digraph G {\n";
65   output_string ch (String.concat "\n" (List.map dot_of_equivalence_class s));
66   output_string ch "\n";
67   (match processing with
68       None -> ()
69     | Some (repr,rel,repr') ->
70        output_string ch
71         (dot_of_cop repr' ^ " -> " ^ dot_of_cop repr ^
72          " [" ^
73          (if rel="=" then "arrowhead=none " else "") ^
74          "style=dashed];\n"));
75   output_string ch "}\n";
76   close_out ch;
77   ignore (Unix.system "dot -Tps xxx.dot > xxx.ps")
78
79 let test set rel candidate repr =
80  ps_of_set ~processing:(candidate,rel,repr) set;
81  print_string
82   (string_of_cop candidate ^ " " ^ rel ^ " " ^ string_of_cop repr ^ "? ");
83  flush stdout;
84  assert (Unix.system "cp formal_topology.ma xxx.ma" = Unix.WEXITED 0);
85  let ch = open_out_gen [Open_append] 0 "xxx.ma" in
86  let i = ref 0 in
87   List.iter
88    (function (repr,others,leq,_) ->
89      List.iter
90       (function repr' ->
91         incr i;
92         output_string ch
93          ("axiom ax" ^ string_of_int !i ^
94           ": \\forall A." ^
95            matita_of_cop "A" repr ^ " = " ^ matita_of_cop "A" repr' ^ ".\n");
96       ) others;
97      List.iter
98       (function (repr',_,_,_) ->
99         incr i;
100         output_string ch
101          ("axiom ax" ^ string_of_int !i ^
102           ": \\forall A." ^
103            matita_of_cop "A" repr ^ " ⊆ " ^ matita_of_cop "A" repr' ^ ".\n");
104       ) !leq;
105    ) set;
106   output_string ch
107    ("theorem foo: \\forall A." ^ matita_of_cop "A" candidate ^ " " ^ rel ^ " " ^
108      matita_of_cop "A" repr ^ ". intros; auto size=6 depth=4. qed.\n");
109   close_out ch;
110   let res =
111    Unix.system "../../../matitac.opt xxx.ma >> log 2>&1" = Unix.WEXITED 0
112   in
113    print_endline (if res then "y" else "n");
114    res
115
116 let normalize candidate set =
117  let rec aux =
118   function
119      [] -> raise Not_found
120    | (repr,others,leq,geq) as eqclass :: tl ->
121        if test set "=" candidate repr then
122         (repr,others@[candidate],leq,geq)::tl
123        else
124         eqclass::(aux tl) 
125  in
126   aux set
127 ;;
128
129 let locate ((repr,_,leq,geq) as node) set =
130  let rec aux =
131   function
132      [] -> ()
133    | (repr',_,leq',geq') as node' :: tl ->
134        if repr = repr' then ()
135        else if test set "⊆" repr repr' then
136         begin
137          leq  := node' :: !leq;
138          geq' := node  :: !geq'
139         end
140        else if test set "⊆" repr' repr then
141         begin
142          geq  := node' :: !geq;
143          leq' := node  :: !leq'
144         end ;
145        aux tl
146  in
147   aux set
148 ;;
149
150 let analyze_one repr hecandidate (news,set) =
151  let candidate = hecandidate::repr in
152   if List.length (List.filter ((=) M) candidate) > 1 then
153    news,set
154   else
155    try
156     let set = normalize candidate set in
157      news,set
158    with
159     Not_found ->
160      let leq = ref [] in
161      let geq = ref [] in
162      let node = candidate,[],leq,geq in
163      let set = node::set in
164       locate node set;
165       candidate::news,set
166 ;;
167
168 let rec explore i set news =
169  let rec aux news set =
170   function
171      [] -> news,set
172    | repr::tl ->
173       let news,set =
174        List.fold_right (analyze_one repr) [I;C;M] (news,set)
175       in
176        aux news set tl
177  in
178   let news,set = aux [] set news in
179    if news = [] then
180     begin
181      print_endline ("PUNTO FISSO RAGGIUNTO! i=" ^ string_of_int i);
182      print_endline (string_of_set set ^ "\n----------------");
183      ps_of_set set
184     end
185    else
186     begin
187      print_endline ("NUOVA ITERAZIONE, i=" ^ string_of_int i);
188      print_endline (string_of_set set ^ "\n----------------");
189      explore (i+1) set news
190     end
191 in
192  let id = [] in
193  let set = [id,[],ref [], ref []] in
194   print_endline ("PRIMA ITERAZIONE, i=0, j=0");
195   print_endline (string_of_set set ^ "\n----------------");
196   ignore (Unix.system "rm -f log");
197   ps_of_set set;
198   explore 1 set [id]
199 ;;