X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=matita%2Fcontribs%2Fformal_topology%2Fbin%2Ftheory_explorer.ml;h=39a021c9dc19abfbe805220c1fb85824248e38a4;hb=2aedc9a14cddce5c5bd86a796ff6ff5a02bf2059;hp=fb9949b731aa3de594b858259a11e336aad20da6;hpb=9792fcde6fe68dea5c99c5362438883b3d7c56e5;p=helm.git diff --git a/matita/contribs/formal_topology/bin/theory_explorer.ml b/matita/contribs/formal_topology/bin/theory_explorer.ml index fb9949b73..39a021c9d 100644 --- a/matita/contribs/formal_topology/bin/theory_explorer.ml +++ b/matita/contribs/formal_topology/bin/theory_explorer.ml @@ -1,3 +1,31 @@ +(**** PROFILING ****) +let ok_time = ref 0.0;; +let ko_time = ref 0.0;; + +let profile f x = + let before = Unix.gettimeofday () in + let res = f x in + let after = Unix.gettimeofday () in + let delta = after -. before in + if res then + ok_time := !ok_time +. delta + else + ko_time := !ko_time +. delta; + res +;; + +let _ = + Sys.catch_break true; + at_exit + (function () -> + prerr_endline + ("\nTIME SPENT IN CHECKING GOOD CONJECTURES: " ^ string_of_float !ok_time); + prerr_endline + ("TIME SPENT IN CHECKING BAD CONJECTURES: " ^ string_of_float !ko_time);) +;; + +(**** END PROFILING ****) + type rel = Equal | SubsetEqual | SupersetEqual let string_of_rel = @@ -9,11 +37,8 @@ let string_of_rel = (* operator *) type op = I | C | M -let string_of_op = - function - I -> "i" - | C -> "c" - | M -> "-" +let string_of_op = function I -> "i" | C -> "c" | M -> "-" +let matita_of_op = function I -> "i" | C -> "c" | M -> "m" (* compound operator *) type compound_operator = op list @@ -23,12 +48,26 @@ let string_of_cop op = let dot_of_cop op = "\"" ^ string_of_cop op ^ "\"" -let rec matita_of_cop v = - function - | [] -> v - | I::tl -> "i (" ^ matita_of_cop v tl ^ ")" - | C::tl -> "c (" ^ matita_of_cop v tl ^ ")" - | M::tl -> "m (" ^ matita_of_cop v tl ^ ")" +let matita_of_cop v = + let rec aux = + function + | [] -> v + | [op] -> matita_of_op op ^ " " ^ v + | op::tl -> matita_of_op op ^ " (" ^ aux tl ^ ")" + in + aux + +let name_of_theorem cop rel cop' = + let cop,rel,cop' = + match rel with + Equal -> cop,"eq",cop' + | SubsetEqual -> cop,"leq",cop' + | SupersetEqual -> cop',"leq",cop + in + rel ^ "_" ^ + String.concat "" (List.map matita_of_op cop) ^ "_" ^ + String.concat "" (List.map matita_of_op cop') +;; (* representative, other elements in the equivalence class, leq classes, geq classes *) @@ -120,13 +159,64 @@ let ps_of_set (to_be_considered,under_consideration,news) ?processing (s,inf,sup (*ignore (read_line ())*) ;; +(******** communication with matitawiki ************) +let min_ch,mout_ch = Unix.open_process "../../../matitawiki.opt 2> /dev/null";; + +let exec_cmd ?(undo=false) s = + let un = if undo then "un" else "" in +(*prerr_endline ("<" ^ un ^ "doitem>" ^ s ^ "\n");*) + output_string mout_ch ("<" ^ un ^ "doitem>" ^ s ^ "\n"); + flush mout_ch; + let rec aux v = + let l = input_line min_ch in + let last = String.length l - 1 in + assert (last > 0); + if l.[last] = Char.chr 249 then + int_of_string (String.sub l 0 last) + else + aux l + in + aux "x" +;; + +let exec_cmds = + let rec aux undopos = + function + [] -> true + | he::tl -> + let pos = exec_cmd he in + if pos = -1 then + begin + match undopos with + None -> assert false + | Some undopos -> + assert (exec_cmd ~undo:true (string_of_int (undopos - 1)) <> -1); + false + end + else + match undopos with + None -> aux (Some pos) tl + | _ -> aux undopos tl + in + aux None + +let _ = + assert (exec_cmd "set \"baseuri\" \"cic:/matita/theory_former\"." <> -1); + assert (exec_cmd "include \"formal_topology.ma\"." <> -1); +;; + +(********* testing a conjecture *******************) + let test to_be_considered_and_now ((s,_,_) as set) rel candidate repr = ps_of_set to_be_considered_and_now ~processing:(candidate,rel,repr) set; print_string (string_of_cop candidate ^ " " ^ string_of_rel rel ^ " " ^ string_of_cop repr ^ "? "); flush stdout; - assert (Unix.system "cp formal_topology.ma xxx.ma" = Unix.WEXITED 0); +(* + assert (Unix.system "cat log.ma | sed s/^theorem/axiom/g | sed 's/\\. intros.*qed\\././g' > xxx.ma" = Unix.WEXITED 0); let ch = open_out_gen [Open_append] 0 "xxx.ma" in +*) +(* let i = ref 0 in List.iter (function (repr,others,leq,_) -> @@ -147,21 +237,39 @@ let test to_be_considered_and_now ((s,_,_) as set) rel candidate repr = matita_of_cop "A" repr ^ " ⊆ " ^ matita_of_cop "A" repr' ^ ".\n"); ) !leq; ) s; +*) let candidate',rel',repr' = match rel with SupersetEqual -> repr,SubsetEqual,candidate | Equal - | SubsetEqual -> candidate,rel,repr - in - output_string ch - ("theorem foo: \\forall A." ^ matita_of_cop "A" candidate' ^ + | SubsetEqual -> candidate,rel,repr in + let query1 = + let name = name_of_theorem candidate' rel' repr' in + ("theorem " ^ name ^ ": \\forall A." ^ matita_of_cop "A" candidate' ^ " " ^ string_of_rel rel' ^ " " ^ - matita_of_cop "A" repr' ^ ". intros; auto size=6 depth=4. qed.\n"); + matita_of_cop "A" repr' ^ ".") in + let query2 = "intros;" in + let query3 = "autobatch size=8 depth=3 width=2." in + let query4 = "qed." in + let query = query1 ^ query2 ^ query3 ^ query4 in +(* + output_string ch (query ^ "\n"); close_out ch; +*) + let res = profile exec_cmds [query1; query2; query3; query4] in +(* let res = (*Unix.system "../../../matitac.opt xxx.ma >> log 2>&1" = Unix.WEXITED 0*) - Unix.system "../../../matitac.opt xxx.ma > /dev/null 2>&1" = Unix.WEXITED 0 + profile Unix.system "../../../matitac.opt xxx.ma > /dev/null 2>&1" = Unix.WEXITED 0 in +*) + ignore (Unix.system "echo '(*' >> log.ma && cat xxx.dot >> log.ma && echo '*)' >> log.ma"); + let ch = open_out_gen [Open_append] 0o0600 "log.ma" in + if res then + output_string ch (query ^ "\n") + else + output_string ch ("(* " ^ query ^ "*)\n"); + close_out ch; print_endline (if res then "y" else "n"); res @@ -235,69 +343,97 @@ let rec geq_reachable node = | (_,_,_,geq)::tl -> geq_reachable node (!geq@tl) ;; -let locate_using_leq to_be_considered_and_now ((repr,_,leq,_) as node) +exception SameEquivalenceClass of set * equivalence_class * equivalence_class;; + +let locate_using_leq to_be_considered_and_now ((repr,_,leq,geq) as node) set start = - let rec aux is_sup ((nodes,inf,sup) as set) = + let rec aux ((nodes,inf,sup) as set) already_visited = function - [] -> - if is_sup then - nodes,inf,sup@@node - else - set + [] -> set | (repr',_,_,geq') as node' :: tl -> - if repr=repr' then aux is_sup set (!geq'@tl) + if List.exists (function n -> n===node') already_visited then + aux set already_visited tl + else if repr=repr' then aux set (node'::already_visited) (!geq'@tl) else if leq_reachable node' !leq then - aux is_sup set tl + aux set (node'::already_visited) (!geq'@tl) + else if (List.exists (function n -> not (geq_reachable n [node'])) !geq) + then + aux set (node'::already_visited) tl else if test to_be_considered_and_now set SubsetEqual repr repr' then begin - let inf = if !geq' = [] then (remove node' inf)@@node else inf in - leq_transitive_closure node node'; - aux false (nodes,inf,sup) (!geq'@tl) + if List.exists (function n -> n===node') !geq then + (* We have found two equal nodes! *) + raise (SameEquivalenceClass (set,node,node')) + else + begin + let sup = remove node sup in + let inf = + if !geq' = [] then + let inf = remove node' inf in + if !geq = [] then + inf@@node + else + inf + else + inf + in + leq_transitive_closure node node'; + aux (nodes,inf,sup) (node'::already_visited) (!geq'@tl) + end end else - aux is_sup set tl + aux set (node'::already_visited) tl in - aux true set start + aux set [] start ;; -exception SameEquivalenceClass of equivalence_class * equivalence_class;; - let locate_using_geq to_be_considered_and_now ((repr,_,leq,geq) as node) set start = - let rec aux is_inf ((nodes,inf,sup) as set) = + let rec aux ((nodes,inf,sup) as set) already_visited = function - [] -> - if is_inf then - nodes,inf@@node,sup - else - set + [] -> set | (repr',_,leq',_) as node' :: tl -> - if repr=repr' then aux is_inf set (!leq'@tl) + if List.exists (function n -> n===node') already_visited then + aux set already_visited tl + else if repr=repr' then aux set (node'::already_visited) (!leq'@tl) else if geq_reachable node' !geq then - aux is_inf set tl + aux set (node'::already_visited) (!leq'@tl) + else if (List.exists (function n -> not (leq_reachable n [node'])) !leq) + then + aux set (node'::already_visited) tl else if test to_be_considered_and_now set SupersetEqual repr repr' then begin if List.exists (function n -> n===node') !leq then (* We have found two equal nodes! *) - raise (SameEquivalenceClass (node,node')) + raise (SameEquivalenceClass (set,node,node')) else begin - let sup = if !leq' = [] then (remove node' sup)@@node else sup in + let inf = remove node inf in + let sup = + if !leq' = [] then + let sup = remove node' sup in + if !leq = [] then + sup@@node + else + sup + else + sup + in geq_transitive_closure node node'; - aux false (nodes,inf,sup) (!leq'@tl) + aux (nodes,inf,sup) (node'::already_visited) (!leq'@tl) end end else - aux is_inf set tl + aux set (node'::already_visited) tl in - aux true set start + aux set [] start ;; let analyze_one to_be_considered repr hecandidate (news,((nodes,inf,sup) as set)) = -assert (List.for_all (fun (_,_,leq,geq) -> !geq = [] && let rec check_sups = function [] -> true | (_,_,leq,_) as node::tl -> if !leq = [] then List.exists (fun n -> n===node) sup && check_sups tl else check_sups (!leq@tl) in check_sups !leq) inf); -assert (List.for_all (fun (_,_,leq,geq) -> !leq = [] && let rec check_infs = function [] -> true | (_,_,_,geq) as node::tl -> if !geq = [] then List.exists (fun n -> n===node) inf && check_infs tl else check_infs (!geq@tl) in check_infs !geq) sup); +if not (List.for_all (fun ((_,_,_,geq) as node) -> !geq = [] && let rec check_sups = function [] -> true | (_,_,leq,_) as node::tl -> if !leq = [] then List.exists (fun n -> n===node) sup && check_sups tl else check_sups (!leq@tl) in check_sups [node]) inf) then ((*ps_of_set ([],None,[]) set;*) assert false); +if not (List.for_all (fun ((_,_,leq,_) as node) -> !leq = [] && let rec check_infs = function [] -> true | (_,_,_,geq) as node::tl -> if !geq = [] then List.exists (fun n -> n===node) inf && check_infs tl else check_infs (!geq@tl) in check_infs [node]) sup) then (ps_of_set ([],None,[]) set; assert false); let candidate = hecandidate::repr in if List.length (List.filter ((=) M) candidate) > 1 then news,set @@ -307,54 +443,92 @@ assert (List.for_all (fun (_,_,leq,geq) -> !leq = [] && let rec check_infs = fun let geq = ref [] in let node = candidate,[],leq,geq in let nodes = nodes@[node] in - let set = nodes,inf,sup in - let start_inf,start_sup = + let set = nodes,inf@[node],sup@[node] in + let set,start_inf,start_sup = let repr_node = match List.filter (fun (repr',_,_,_) -> repr=repr') nodes with [node] -> node | _ -> assert false in -inf,sup(* - match hecandidate with - I -> inf,[repr_node] - | C -> [repr_node],sup - | M -> inf,sup -*) + match hecandidate,repr with + I, I::_ -> raise (SameEquivalenceClass (set,node,repr_node)) + | I, _ -> + add_leq_arc node repr_node; + (nodes,remove repr_node inf@[node],sup),inf,sup + | C, C::_ -> raise (SameEquivalenceClass (set,node,repr_node)) + | C, _ -> + add_geq_arc node repr_node; + (nodes,inf,remove repr_node sup@[node]),inf,sup + | M, M::M::_ -> raise (SameEquivalenceClass (set,node,repr_node)) + | M, _ -> set,inf,sup in let set = locate_using_leq (to_be_considered,Some repr,news) node set start_sup in +( +let _,inf,sup = set in +if not (List.for_all (fun ((_,_,_,geq) as node) -> !geq = [] && let rec check_sups = function [] -> true | (_,_,leq,_) as node::tl -> if !leq = [] then List.exists (fun n -> n===node) sup && check_sups tl else check_sups (!leq@tl) in check_sups [node]) inf) then (ps_of_set ([],None,[]) set; assert false); +if not (List.for_all (fun ((_,_,leq,_) as node) -> !leq = [] && let rec check_infs = function [] -> true | (_,_,_,geq) as node::tl -> if !geq = [] then List.exists (fun n -> n===node) inf && check_infs tl else check_infs (!geq@tl) in check_infs [node]) sup) then (ps_of_set ([],None,[]) set; assert false); +); let set = locate_using_geq (to_be_considered,Some repr,news) node set start_inf in +( +let _,inf,sup = set in +if not (List.for_all (fun ((_,_,_,geq) as node) -> !geq = [] && let rec check_sups = function [] -> true | (_,_,leq,_) as node::tl -> if !leq = [] then List.exists (fun n -> n===node) sup && check_sups tl else check_sups (!leq@tl) in check_sups [node]) inf) then (ps_of_set ([],None,[]) set; assert false); +if not (List.for_all (fun ((_,_,leq,_) as node) -> !leq = [] && let rec check_infs = function [] -> true | (_,_,_,geq) as node::tl -> if !geq = [] then List.exists (fun n -> n===node) inf && check_infs tl else check_infs (!geq@tl) in check_infs [node]) sup) then ((*ps_of_set ([],None,[]) set;*) assert false); +); news@[candidate],set with - SameEquivalenceClass ((_,_,leq_d,geq_d) as node_to_be_deleted,node') -> - let rec clean = + SameEquivalenceClass ((nodes,inf,sup) as set,((r,_,leq_d,geq_d) as node_to_be_deleted),node')-> +( +let _,inf,sup = set in +if not (List.for_all (fun ((_,_,_,geq) as node) -> !geq = [] && let rec check_sups = function [] -> true | (_,_,leq,_) as node::tl -> if !leq = [] then List.exists (fun n -> n===node) sup && check_sups tl else check_sups (!leq@tl) in check_sups [node]) inf) then (ps_of_set ([],None,[]) set; assert false); +if not (List.for_all (fun ((_,_,leq,_) as node) -> !leq = [] && let rec check_infs = function [] -> true | (_,_,_,geq) as node::tl -> if !geq = [] then List.exists (fun n -> n===node) inf && check_infs tl else check_infs (!geq@tl) in check_infs [node]) sup) then ((*ps_of_set ([],None,[]) set;*) assert false); +); + let rec clean inf sup res = function - [] -> [] + [] -> inf,sup,res + | node::tl when node===node_to_be_deleted -> + clean inf sup res tl | (repr',others,leq,geq) as node::tl -> leq := - List.fold_right - (fun node l -> - if node_to_be_deleted <=> node then - node::l - else - !leq_d@l - ) !leq []; + (let rec aux res = + function + [] -> res + | (_,_,leq,_) as node::tl -> + if node_to_be_deleted <=> node then + aux (res@[node]) tl + else + (List.filter (fun n ->not (leq_reachable n (res@tl))) !leq)@tl + in + aux [] !leq); + let sup = if !leq = [] then sup@@node else sup in geq := - List.fold_right - (fun node l -> - if node_to_be_deleted <=> node then - node::l - else - !geq_d@l - ) !geq []; + (let rec aux res = + function + [] -> res + | (_,_,_,geq) as node::tl -> + if node_to_be_deleted <=> node then + aux (res@[node]) tl + else + (List.filter (fun n ->not (geq_reachable n (res@tl))) !geq)@tl + in + aux [] !geq); + let inf = if !geq = [] then inf@@node else inf in if node===node' then - (repr',others@[candidate],leq,geq)::clean tl + clean inf sup ((repr',others@[candidate],leq,geq)::res) tl else - node::clean tl + clean inf sup (node::res) tl in - let nodes = clean nodes in + let inf,sup,nodes = clean inf sup [] nodes in + let inf = remove node_to_be_deleted inf in + let sup = remove node_to_be_deleted sup in +let set = nodes,inf,sup in +( +let _,inf,sup = set in +if not (List.for_all (fun ((_,_,_,geq) as node) -> !geq = [] && let rec check_sups = function [] -> true | (_,_,leq,_) as node::tl -> if !leq = [] then List.exists (fun n -> n===node) sup && check_sups tl else check_sups (!leq@tl) in check_sups [node]) inf) then (ps_of_set ([],None,[]) set; assert false); +if not (List.for_all (fun ((_,_,leq,_) as node) -> !leq = [] && let rec check_infs = function [] -> true | (_,_,_,geq) as node::tl -> if !geq = [] then List.exists (fun n -> n===node) inf && check_infs tl else check_infs (!geq@tl) in check_infs [node]) sup) then (ps_of_set ([],None,[]) set; assert false); +); news,(nodes,inf,sup) ;; @@ -388,6 +562,7 @@ in print_endline ("PRIMA ITERAZIONE, i=0, j=0"); print_endline (string_of_set set ^ "\n----------------"); (*ignore (Unix.system "rm -f log");*) + assert (Unix.system "cp formal_topology.ma log.ma" = Unix.WEXITED 0); ps_of_set ([id],None,[]) set; explore 1 set [id] ;;