X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2FgTopLevel%2FgTopLevel.ml;h=a1254be54f4a4c4677273f1fe9e8f0d383e1713b;hb=c28e63f31a446c994c69cb00c060e39ed48d8066;hp=7c01b4d75879b95771bbeea27b51278cdf0ad07d;hpb=2329c7fd13fb6c88f9f82ccad6b25a67c9ce7acf;p=helm.git diff --git a/helm/gTopLevel/gTopLevel.ml b/helm/gTopLevel/gTopLevel.ml index 7c01b4d75..a1254be54 100644 --- a/helm/gTopLevel/gTopLevel.ml +++ b/helm/gTopLevel/gTopLevel.ml @@ -1,4 +1,4 @@ -(* Copyright (C) 2000, HELM Team. +(* Copyright (C) 2000-2002, HELM Team. * * This file is part of HELM, an Hypertextual, Electronic * Library of Mathematics, developed at the Computer Science @@ -33,6 +33,18 @@ (* *) (******************************************************************************) + +(* CSC: quick fix: a function from [uri#xpointer(path)] to [uri#path] *) +let wrong_xpointer_format_from_wrong_xpointer_format' uri = + try + let index_sharp = String.index uri '#' in + let index_rest = index_sharp + 10 in + let baseuri = String.sub uri 0 index_sharp in + let rest = String.sub uri index_rest (String.length uri - index_rest - 1) in + baseuri ^ "#" ^ rest + with Not_found -> uri +;; + (* GLOBAL CONSTANTS *) let helmns = Gdome.domString "http://www.cs.unibo.it/helm";; @@ -47,17 +59,328 @@ let htmlfooter = "" ;; +(* +let prooffile = "/home/tassi/miohelm/tmp/currentproof";; +let prooffile = "/public/sacerdot/currentproof";; +*) + +let prooffile = "/public/sacerdot/currentproof";; +let prooffiletype = "/public/sacerdot/currentprooftype";; + +(*CSC: the getter should handle the innertypes, not the FS *) +(* +let innertypesfile = "/home/tassi/miohelm/tmp/innertypes";; +let innertypesfile = "/public/sacerdot/innertypes";; +*) + +let innertypesfile = "/public/sacerdot/innertypes";; +let constanttypefile = "/public/sacerdot/constanttype";; + +let empty_id_to_uris = ([],function _ -> None);; + + (* GLOBAL REFERENCES (USED BY CALLBACKS) *) let htmlheader_and_content = ref htmlheader;; -let filename4uwobo = "/public/sacerdot/prova.xml";; - let current_cic_infos = ref None;; +let current_goal_infos = ref None;; +let current_scratch_infos = ref None;; + +let id_to_uris = ref empty_id_to_uris;; + +let check_term = ref (fun _ _ _ -> assert false);; + +exception RenderingWindowsNotInitialized;; + +let set_rendering_window,rendering_window = + let rendering_window_ref = ref None in + (function rw -> rendering_window_ref := Some rw), + (function () -> + match !rendering_window_ref with + None -> raise RenderingWindowsNotInitialized + | Some rw -> rw + ) +;; + +exception SettingsWindowsNotInitialized;; + +let set_settings_window,settings_window = + let settings_window_ref = ref None in + (function rw -> settings_window_ref := Some rw), + (function () -> + match !settings_window_ref with + None -> raise SettingsWindowsNotInitialized + | Some rw -> rw + ) +;; + +(* COMMAND LINE OPTIONS *) + +let usedb = ref true + +let argspec = + [ + "-nodb", Arg.Clear usedb, "disable use of MathQL DB" + ] +in +Arg.parse argspec ignore "" (* MISC FUNCTIONS *) +let cic_textual_parser_uri_of_string uri' = + (* Constant *) + if String.sub uri' (String.length uri' - 4) 4 = ".con" then + CicTextualParser0.ConUri (UriManager.uri_of_string uri') + else + if String.sub uri' (String.length uri' - 4) 4 = ".var" then + CicTextualParser0.VarUri (UriManager.uri_of_string uri') + else + (try + (* Inductive Type *) + let uri'',typeno = CicTextualLexer.indtyuri_of_uri uri' in + CicTextualParser0.IndTyUri (uri'',typeno) + with + _ -> + (* Constructor of an Inductive Type *) + let uri'',typeno,consno = + CicTextualLexer.indconuri_of_uri uri' + in + CicTextualParser0.IndConUri (uri'',typeno,consno) + ) +;; + +let term_of_cic_textual_parser_uri uri = + let module C = Cic in + let module CTP = CicTextualParser0 in + match uri with + CTP.ConUri uri -> C.Const (uri,[]) + | CTP.VarUri uri -> C.Var (uri,[]) + | CTP.IndTyUri (uri,tyno) -> C.MutInd (uri,tyno,[]) + | CTP.IndConUri (uri,tyno,consno) -> C.MutConstruct (uri,tyno,consno,[]) +;; + +let string_of_cic_textual_parser_uri uri = + let module C = Cic in + let module CTP = CicTextualParser0 in + let uri' = + match uri with + CTP.ConUri uri -> UriManager.string_of_uri uri + | CTP.VarUri uri -> UriManager.string_of_uri uri + | CTP.IndTyUri (uri,tyno) -> + UriManager.string_of_uri uri ^ "#1/" ^ string_of_int (tyno + 1) + | CTP.IndConUri (uri,tyno,consno) -> + UriManager.string_of_uri uri ^ "#1/" ^ string_of_int (tyno + 1) ^ "/" ^ + string_of_int consno + in + (* 4 = String.length "cic:" *) + String.sub uri' 4 (String.length uri' - 4) +;; + +(* UTILITY FUNCTIONS TO DISAMBIGUATE AN URI *) + +exception NoChoice;; + +let interactive_user_uri_choice ?(cancel="Cancel") ~title ~msg uris = + let choice = ref None in + let window = GWindow.dialog ~modal:true ~title () in + let lMessage = + GMisc.label ~text:msg ~packing:window#vbox#add () in + let vbox = GPack.vbox ~border_width:10 + ~packing:(window#action_area#pack ~expand:true ~padding:4) () in + let hbox1 = GPack.hbox ~border_width:10 ~packing:vbox#add () in + let combo = + GEdit.combo ~popdown_strings:uris ~packing:hbox1#add () in + let checkb = + GButton.button ~label:"Check" + ~packing:(hbox1#pack ~expand:false ~fill:false ~padding:5) () in + let hbox = GPack.hbox ~border_width:10 ~packing:vbox#add () in + let okb = + GButton.button ~label:"Ok" + ~packing:(hbox#pack ~expand:false ~fill:false ~padding:5) () in + let cancelb = + GButton.button ~label:cancel + ~packing:(hbox#pack ~expand:false ~fill:false ~padding:5) () in + (* actions *) + let ok_callback () = + choice := Some combo#entry#text ; + window#destroy () + in + let check_callback () = + !check_term [] [] + (term_of_cic_textual_parser_uri + (cic_textual_parser_uri_of_string combo#entry#text)) + in + ignore (window#connect#destroy GMain.Main.quit) ; + ignore (cancelb#connect#clicked window#destroy) ; + ignore (okb#connect#clicked ok_callback) ; + ignore (checkb#connect#clicked check_callback) ; + window#set_position `CENTER ; + window#show () ; + GMain.Main.main () ; + match !choice with + None -> raise NoChoice + | Some uri -> uri +;; + +(* MISC FUNCTIONS *) + +(* CSC: IMPERATIVE AND NOT VERY CLEAN, TO GET THE LAST ISSUED QUERY *) +let get_last_query = + let query = ref "" in + MQueryGenerator.set_confirm_query + (function q -> query := MQueryUtil.text_of_query q ; true) ; + function result -> !query ^ "

Result:

" ^ MQueryUtil.text_of_result result "
" +;; + +let register_alias (id,uri) = + let dom,resolve_id = !id_to_uris in + id_to_uris := + (if List.mem id dom then dom else id::dom), + function id' -> if id' = id then Some uri else resolve_id id' +;; + +let output_html outputhtml msg = + htmlheader_and_content := !htmlheader_and_content ^ msg ; + outputhtml#source (!htmlheader_and_content ^ htmlfooter) ; + outputhtml#set_topline (-1) +;; + +let locate_one_id id = + let result = MQueryGenerator.locate id in + let uris = + List.map + (function uri,_ -> + wrong_xpointer_format_from_wrong_xpointer_format' uri + ) result in + let html= "

Locate Query:

" ^ get_last_query result ^ "
" in + output_html (rendering_window ())#outputhtml html ; + let uris' = + match uris with + [] -> + (match + (GToolbox.input_string ~title:"Unknown input" + ("No URI matching \"" ^ id ^ "\" found. Please enter its URI")) + with + None -> raise NoChoice + | Some uri -> ["cic:" ^ uri] + ) + | [uri] -> [uri] + | _ -> + try + [interactive_user_uri_choice + ~cancel:"Try every possibility." + ~title:"Ambiguous input." + ~msg: + ("Ambiguous input \"" ^ id ^ + "\". Please, choose one interpretation:") + uris + ] + with + NoChoice -> uris + in + List.map cic_textual_parser_uri_of_string uris' +;; + +exception ThereDoesNotExistAnyWellTypedInterpretationOfTheInput;; +exception AmbiguousInput;; + +let disambiguate_input context metasenv dom mk_metasenv_and_expr = + let known_ids,resolve_id = !id_to_uris in + let dom' = + let rec filter = + function + [] -> [] + | he::tl -> + if List.mem he known_ids then filter tl else he::(filter tl) + in + filter dom + in + (* for each id in dom' we get the list of uris associated to it *) + let list_of_uris = List.map locate_one_id dom' in + (* and now we compute the list of all possible assignments from id to uris *) + let resolve_ids = + let rec aux ids list_of_uris = + match ids,list_of_uris with + [],[] -> [resolve_id] + | id::idtl,uris::uristl -> + let resolves = aux idtl uristl in + List.concat + (List.map + (function uri -> + List.map + (function f -> + function id' -> if id = id' then Some uri else f id' + ) resolves + ) uris + ) + | _,_ -> assert false + in + aux dom' list_of_uris + in +prerr_endline ("##### NE DISAMBIGUO: " ^ string_of_int (List.length resolve_ids)) ; + (* now we select only the ones that generates well-typed terms *) + let resolve_ids' = + let rec filter = + function + [] -> [] + | resolve::tl -> + let metasenv',expr = mk_metasenv_and_expr resolve in + try +(*CSC: Bug here: we do not try to typecheck also the metasenv' *) + ignore + (CicTypeChecker.type_of_aux' metasenv context expr) ; + resolve::(filter tl) + with + _ -> filter tl + in + filter resolve_ids + in + let resolve_id' = + match resolve_ids' with + [] -> raise ThereDoesNotExistAnyWellTypedInterpretationOfTheInput + | [resolve_id] -> resolve_id + | _ -> + let choices = + List.map + (function resolve -> + String.concat " ; " + (List.map + (function id -> + id ^ " := " ^ + match resolve id with + None -> assert false + | Some uri -> + match uri with + CicTextualParser0.ConUri uri + | CicTextualParser0.VarUri uri -> + UriManager.string_of_uri uri + | CicTextualParser0.IndTyUri (uri,tyno) -> + UriManager.string_of_uri uri ^ "#xpointer(1/" ^ + string_of_int (tyno+1) ^ ")" + | CicTextualParser0.IndConUri (uri,tyno,consno) -> + UriManager.string_of_uri uri ^ "#xpointer(1/" ^ + string_of_int (tyno+1) ^ "/" ^ string_of_int consno ^ ")" + ) dom + ) + ) resolve_ids' + in + let choice = + GToolbox.question_box ~title:"Ambiguous input." + ~buttons:choices + ~default:1 "Ambiguous input. Please, choose one interpretation." + in + if choice > 0 then + List.nth resolve_ids' (choice - 1) + else + (* No choice from the user *) + raise NoChoice + in + id_to_uris := known_ids @ dom', resolve_id' ; + mk_metasenv_and_expr resolve_id' +;; + let domImpl = Gdome.domImplementation ();; let parseStyle name = @@ -80,12 +403,9 @@ let c1 = parseStyle "rootcontent.xsl";; let g = parseStyle "genmmlid.xsl";; let c2 = parseStyle "annotatedpres.xsl";; -(* -let processorURL = "http://phd.cs.unibo.it:8080/helm/servelt/uwobo/";; -let getterURL = "http://phd.cs.unibo.it:8081/";; -*) -let processorURL = "http://localhost:8080/helm/servelt/uwobo/";; -let getterURL = "http://localhost:8081/";; + +let getterURL = Configuration.getter_url;; +let processorURL = Configuration.processor_url;; let mml_styles = [d_c ; c1 ; g ; c2 ; l];; let mml_args = @@ -99,8 +419,9 @@ let mml_args = "media-type", "'text/html'" ; "keys", "'d_c%2CC1%2CG%2CC2%2CL'" ; "interfaceURL", "'http%3A//phd.cs.unibo.it/helm/html/cic/index.html'" ; - "naturalLanguage", "'no'" ; + "naturalLanguage", "'yes'" ; "annotations", "'no'" ; + "explodeall", "'true()'" ; "topurl", "'http://phd.cs.unibo.it/helm'" ; "CICURI", "'cic:/Coq/Init/Datatypes/bool_ind.con'" ] ;; @@ -119,6 +440,7 @@ let sequent_args = "interfaceURL", "'http%3A//phd.cs.unibo.it/helm/html/cic/index.html'" ; "naturalLanguage", "'no'" ; "annotations", "'no'" ; + "explodeall", "'true()'" ; "topurl", "'http://phd.cs.unibo.it/helm'" ; "CICURI", "'cic:/Coq/Init/Datatypes/bool_ind.con'" ] ;; @@ -140,108 +462,857 @@ let applyStylesheets input styles args = input styles ;; -let mml_of_cic acic = -prerr_endline "BBB CREAZIONE" ; - let xml = - Cic2Xml.print_term (UriManager.uri_of_string "cic:/dummy.con") acic +let mml_of_cic_object uri annobj ids_to_inner_sorts ids_to_inner_types = +(*CSC: ????????????????? *) + let xml, bodyxml = + Cic2Xml.print_object uri ~ids_to_inner_sorts annobj in - Xml.pp ~quiet:true xml (Some filename4uwobo) ; -prerr_endline "BBB PARSING" ; - let input = domImpl#createDocumentFromURI ~uri:filename4uwobo () in -prerr_endline "BBB STYLESHEETS" ; + let xmlinnertypes = + Cic2Xml.print_inner_types uri ~ids_to_inner_sorts + ~ids_to_inner_types + in + let input = + match bodyxml with + None -> Xml2Gdome.document_of_xml domImpl xml + | Some bodyxml' -> + Xml.pp xml (Some constanttypefile) ; + Xml2Gdome.document_of_xml domImpl bodyxml' + in +(*CSC: We save the innertypes to disk so that we can retrieve them in the *) +(*CSC: stylesheet. This DOES NOT work when UWOBO and/or the getter are not *) +(*CSC: local. *) + Xml.pp xmlinnertypes (Some innertypesfile) ; let output = applyStylesheets input mml_styles mml_args in -prerr_endline "BBB RESA" ; -ignore(domImpl#saveDocumentToFile ~doc:output ~name:"/tmp/xxxyyyzzz" ()) ; - output + output ;; (* CALLBACKS *) -let exact rendering_window () = - let inputt = (rendering_window#inputt : GEdit.text) in +exception RefreshSequentException of exn;; +exception RefreshProofException of exn;; + +let refresh_proof (output : GMathView.math_view) = + try + let uri,currentproof = + match !ProofEngine.proof with + None -> assert false + | Some (uri,metasenv,bo,ty) -> + (*CSC: Wrong: [] is just plainly wrong *) + uri,(Cic.CurrentProof (UriManager.name_of_uri uri, metasenv, bo, ty, [])) + in + let + (acic,ids_to_terms,ids_to_father_ids,ids_to_inner_sorts, + ids_to_inner_types,ids_to_conjectures,ids_to_hypotheses) + = + Cic2acic.acic_object_of_cic_object currentproof + in + let mml = + mml_of_cic_object uri acic ids_to_inner_sorts ids_to_inner_types + in + output#load_tree mml ; + current_cic_infos := + Some (ids_to_terms,ids_to_father_ids,ids_to_conjectures,ids_to_hypotheses) + with + e -> + match !ProofEngine.proof with + None -> assert false + | Some (uri,metasenv,bo,ty) -> +prerr_endline ("Offending proof: " ^ CicPp.ppobj (Cic.CurrentProof ("questa",metasenv,bo,ty,[]))) ; flush stderr ; + raise (RefreshProofException e) +;; + +let refresh_sequent ?(empty_notebook=true) notebook = + try + match !ProofEngine.goal with + None -> + if empty_notebook then + begin + notebook#remove_all_pages ; + notebook#set_empty_page + end + else + notebook#proofw#unload + | Some metano -> + let metasenv = + match !ProofEngine.proof with + None -> assert false + | Some (_,metasenv,_,_) -> metasenv + in + let currentsequent = List.find (function (m,_,_) -> m=metano) metasenv in + let sequent_gdome,ids_to_terms,ids_to_father_ids,ids_to_hypotheses = + SequentPp.XmlPp.print_sequent metasenv currentsequent + in + let sequent_doc = + Xml2Gdome.document_of_xml domImpl sequent_gdome + in + let sequent_mml = + applyStylesheets sequent_doc sequent_styles sequent_args + in + if empty_notebook then + begin + notebook#remove_all_pages ; + List.iter (function (m,_,_) -> notebook#add_page m) metasenv ; + end ; + notebook#set_current_page metano ; + notebook#proofw#load_tree ~dom:sequent_mml ; + current_goal_infos := + Some (ids_to_terms,ids_to_father_ids,ids_to_hypotheses) + with + e -> +let metano = + match !ProofEngine.goal with + None -> assert false + | Some m -> m +in +let metasenv = + match !ProofEngine.proof with + None -> assert false + | Some (_,metasenv,_,_) -> metasenv +in +let currentsequent = List.find (function (m,_,_) -> m=metano) metasenv in +prerr_endline ("Offending sequent: " ^ SequentPp.TextualPp.print_sequent currentsequent) ; flush stderr ; + raise (RefreshSequentException e) +;; + +(* +ignore(domImpl#saveDocumentToFile ~doc:sequent_doc + ~name:"/home/galata/miohelm/guruguru1" ~indent:true ()) ; +*) + +let mml_of_cic_term metano term = + let metasenv = + match !ProofEngine.proof with + None -> [] + | Some (_,metasenv,_,_) -> metasenv + in + let context = + match !ProofEngine.goal with + None -> [] + | Some metano -> + let (_,canonical_context,_) = + List.find (function (m,_,_) -> m=metano) metasenv + in + canonical_context + in + let sequent_gdome,ids_to_terms,ids_to_father_ids,ids_to_hypotheses = + SequentPp.XmlPp.print_sequent metasenv (metano,context,term) + in + let sequent_doc = + Xml2Gdome.document_of_xml domImpl sequent_gdome + in + let res = + applyStylesheets sequent_doc sequent_styles sequent_args ; + in + current_scratch_infos := + Some (term,ids_to_terms,ids_to_father_ids,ids_to_hypotheses) ; + res +;; + +(***********************) +(* TACTICS *) +(***********************) + +let call_tactic tactic () = + let notebook = (rendering_window ())#notebook in + let output = ((rendering_window ())#output : GMathView.math_view) in + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + let savedproof = !ProofEngine.proof in + let savedgoal = !ProofEngine.goal in + begin + try + tactic () ; + refresh_sequent notebook ; + refresh_proof output + with + RefreshSequentException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "sequent: " ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + refresh_sequent notebook + | RefreshProofException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "proof: " ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + refresh_sequent notebook ; + refresh_proof output + | e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + end +;; + +let call_tactic_with_input tactic () = + let notebook = (rendering_window ())#notebook in + let output = ((rendering_window ())#output : GMathView.math_view) in + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + let inputt = ((rendering_window ())#inputt : GEdit.text) in + let savedproof = !ProofEngine.proof in + let savedgoal = !ProofEngine.goal in (*CSC: Gran cut&paste da sotto... *) let inputlen = inputt#length in let input = inputt#get_chars 0 inputlen ^ "\n" in let lexbuf = Lexing.from_string input in + let curi = + match !ProofEngine.proof with + None -> assert false + | Some (curi,_,_,_) -> curi + in + let uri,metasenv,bo,ty = + match !ProofEngine.proof with + None -> assert false + | Some (uri,metasenv,bo,ty) -> uri,metasenv,bo,ty + in + let canonical_context = + match !ProofEngine.goal with + None -> assert false + | Some metano -> + let (_,canonical_context,_) = + List.find (function (m,_,_) -> m=metano) metasenv + in + canonical_context + in + let context = + List.map + (function + Some (n,_) -> Some n + | None -> None + ) canonical_context + in try while true do - (* Execute the actions *) - match CicTextualParser.main CicTextualLexer.token lexbuf with + match + CicTextualParserContext.main context metasenv CicTextualLexer.token + lexbuf register_alias + with None -> () - | Some expr -> - try -(*??? Ma servira' da qualche parte! - let ty = CicTypeChecker.type_of_aux' [] expr in -*) - let (acic, ids_to_terms, ids_to_father_ids) = - Cic2acic.acic_of_cic expr - in -(*CSC: chiamare la vera tattica exact qui! *) - () - with - e -> - print_endline ("? " ^ CicPp.ppterm expr) ; - raise e + | Some (dom,mk_metasenv_and_expr) -> + let (metasenv',expr) = + disambiguate_input canonical_context metasenv dom + mk_metasenv_and_expr + in + ProofEngine.proof := Some (uri,metasenv',bo,ty) ; + tactic expr ; + refresh_sequent notebook ; + refresh_proof output done with CicTextualParser0.Eof -> inputt#delete_text 0 inputlen -(*CSC: fare qualcosa di utile *) + | RefreshSequentException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "sequent: " ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + refresh_sequent notebook + | RefreshProofException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "proof: " ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + refresh_sequent notebook ; + refresh_proof output | e -> - print_endline ("Error: " ^ Printexc.to_string e) ; flush stdout + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; ;; -let proveit rendering_window () = +let call_tactic_with_goal_input tactic () = + let module L = LogicalOperations in let module G = Gdome in - match rendering_window#output#get_selection with - Some node -> - let xpath = - ((node : Gdome.element)#getAttributeNS - (*CSC: OCAML DIVERGE - ((element : G.element)#getAttributeNS - *) - ~namespaceURI:helmns - ~localName:(G.domString "xref"))#to_string - in - if xpath = "" then assert false (* "ERROR: No xref found!!!" *) - else + let notebook = (rendering_window ())#notebook in + let output = ((rendering_window ())#output : GMathView.math_view) in + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + let savedproof = !ProofEngine.proof in + let savedgoal = !ProofEngine.goal in + match notebook#proofw#get_selection with + Some node -> + let xpath = + ((node : Gdome.element)#getAttributeNS + ~namespaceURI:helmns + ~localName:(G.domString "xref"))#to_string + in + if xpath = "" then assert false (* "ERROR: No xref found!!!" *) + else + begin + try + match !current_goal_infos with + Some (ids_to_terms, ids_to_father_ids,_) -> + let id = xpath in + tactic (Hashtbl.find ids_to_terms id) ; + refresh_sequent notebook ; + refresh_proof output + | None -> assert false (* "ERROR: No current term!!!" *) + with + RefreshSequentException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "sequent: " ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + refresh_sequent notebook + | RefreshProofException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "proof: " ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + refresh_sequent notebook ; + refresh_proof output + | e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + end + | None -> + output_html outputhtml + ("

No term selected

") +;; + +let call_tactic_with_input_and_goal_input tactic () = + let module L = LogicalOperations in + let module G = Gdome in + let notebook = (rendering_window ())#notebook in + let output = ((rendering_window ())#output : GMathView.math_view) in + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + let inputt = ((rendering_window ())#inputt : GEdit.text) in + let savedproof = !ProofEngine.proof in + let savedgoal = !ProofEngine.goal in + match notebook#proofw#get_selection with + Some node -> + let xpath = + ((node : Gdome.element)#getAttributeNS + ~namespaceURI:helmns + ~localName:(G.domString "xref"))#to_string + in + if xpath = "" then assert false (* "ERROR: No xref found!!!" *) + else + begin + try + match !current_goal_infos with + Some (ids_to_terms, ids_to_father_ids,_) -> + let id = xpath in + (* Let's parse the input *) + let inputlen = inputt#length in + let input = inputt#get_chars 0 inputlen ^ "\n" in + let lexbuf = Lexing.from_string input in + let curi = + match !ProofEngine.proof with + None -> assert false + | Some (curi,_,_,_) -> curi + in + let uri,metasenv,bo,ty = + match !ProofEngine.proof with + None -> assert false + | Some (uri,metasenv,bo,ty) -> uri,metasenv,bo,ty + in + let canonical_context = + match !ProofEngine.goal with + None -> assert false + | Some metano -> + let (_,canonical_context,_) = + List.find (function (m,_,_) -> m=metano) metasenv + in + canonical_context in + let context = + List.map + (function + Some (n,_) -> Some n + | None -> None + ) canonical_context + in + begin + try + while true do + match + CicTextualParserContext.main context metasenv + CicTextualLexer.token lexbuf register_alias + with + None -> () + | Some (dom,mk_metasenv_and_expr) -> + let (metasenv',expr) = + disambiguate_input canonical_context metasenv dom + mk_metasenv_and_expr + in + ProofEngine.proof := Some (uri,metasenv',bo,ty) ; + tactic ~goal_input:(Hashtbl.find ids_to_terms id) + ~input:expr ; + refresh_sequent notebook ; + refresh_proof output + done + with + CicTextualParser0.Eof -> + inputt#delete_text 0 inputlen + end + | None -> assert false (* "ERROR: No current term!!!" *) + with + RefreshSequentException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "sequent: " ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + refresh_sequent notebook + | RefreshProofException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "proof: " ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + refresh_sequent notebook ; + refresh_proof output + | e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + end + | None -> + output_html outputhtml + ("

No term selected

") +;; + +let call_tactic_with_goal_input_in_scratch tactic scratch_window () = + let module L = LogicalOperations in + let module G = Gdome in + let mmlwidget = (scratch_window#mmlwidget : GMathView.math_view) in + let outputhtml = (scratch_window#outputhtml : GHtml.xmhtml) in + let savedproof = !ProofEngine.proof in + let savedgoal = !ProofEngine.goal in + match mmlwidget#get_selection with + Some node -> + let xpath = + ((node : Gdome.element)#getAttributeNS + ~namespaceURI:helmns + ~localName:(G.domString "xref"))#to_string + in + if xpath = "" then assert false (* "ERROR: No xref found!!!" *) + else + begin + try + match !current_scratch_infos with + (* term is the whole goal in the scratch_area *) + Some (term,ids_to_terms, ids_to_father_ids,_) -> + let id = xpath in + let expr = tactic term (Hashtbl.find ids_to_terms id) in + let mml = mml_of_cic_term 111 expr in + scratch_window#show () ; + scratch_window#mmlwidget#load_tree ~dom:mml + | None -> assert false (* "ERROR: No current term!!!" *) + with + e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") + end + | None -> + output_html outputhtml + ("

No term selected

") +;; + +let call_tactic_with_hypothesis_input tactic () = + let module L = LogicalOperations in + let module G = Gdome in + let notebook = (rendering_window ())#notebook in + let output = ((rendering_window ())#output : GMathView.math_view) in + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + let savedproof = !ProofEngine.proof in + let savedgoal = !ProofEngine.goal in + match notebook#proofw#get_selection with + Some node -> + let xpath = + ((node : Gdome.element)#getAttributeNS + ~namespaceURI:helmns + ~localName:(G.domString "xref"))#to_string + in + if xpath = "" then assert false (* "ERROR: No xref found!!!" *) + else + begin + try + match !current_goal_infos with + Some (_,_,ids_to_hypotheses) -> + let id = xpath in + tactic (Hashtbl.find ids_to_hypotheses id) ; + refresh_sequent notebook ; + refresh_proof output + | None -> assert false (* "ERROR: No current term!!!" *) + with + RefreshSequentException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "sequent: " ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + refresh_sequent notebook + | RefreshProofException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "proof: " ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + refresh_sequent notebook ; + refresh_proof output + | e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") ; + ProofEngine.proof := savedproof ; + ProofEngine.goal := savedgoal ; + end + | None -> + output_html outputhtml + ("

No term selected

") +;; + + +let intros = call_tactic ProofEngine.intros;; +let exact = call_tactic_with_input ProofEngine.exact;; +let apply = call_tactic_with_input ProofEngine.apply;; +let elimsimplintros = call_tactic_with_input ProofEngine.elim_simpl_intros;; +let elimtype = call_tactic_with_input ProofEngine.elim_type;; +let whd = call_tactic_with_goal_input ProofEngine.whd;; +let reduce = call_tactic_with_goal_input ProofEngine.reduce;; +let simpl = call_tactic_with_goal_input ProofEngine.simpl;; +let fold = call_tactic_with_input ProofEngine.fold;; +let cut = call_tactic_with_input ProofEngine.cut;; +let change = call_tactic_with_input_and_goal_input ProofEngine.change;; +let letin = call_tactic_with_input ProofEngine.letin;; +let ring = call_tactic ProofEngine.ring;; +let clearbody = call_tactic_with_hypothesis_input ProofEngine.clearbody;; +let clear = call_tactic_with_hypothesis_input ProofEngine.clear;; +let fourier = call_tactic ProofEngine.fourier;; +let rewritesimpl = call_tactic_with_input ProofEngine.rewrite_simpl;; +let reflexivity = call_tactic ProofEngine.reflexivity;; +let symmetry = call_tactic ProofEngine.symmetry;; +let transitivity = call_tactic_with_input ProofEngine.transitivity;; +let left = call_tactic ProofEngine.left;; +let right = call_tactic ProofEngine.right;; +let assumption = call_tactic ProofEngine.assumption;; + +let whd_in_scratch scratch_window = + call_tactic_with_goal_input_in_scratch ProofEngine.whd_in_scratch + scratch_window +;; +let reduce_in_scratch scratch_window = + call_tactic_with_goal_input_in_scratch ProofEngine.reduce_in_scratch + scratch_window +;; +let simpl_in_scratch scratch_window = + call_tactic_with_goal_input_in_scratch ProofEngine.simpl_in_scratch + scratch_window +;; + + + +(**********************) +(* END OF TACTICS *) +(**********************) + +exception OpenConjecturesStillThere;; +exception WrongProof;; + +let qed () = + match !ProofEngine.proof with + None -> assert false + | Some (uri,[],bo,ty) -> + if + CicReduction.are_convertible [] + (CicTypeChecker.type_of_aux' [] [] bo) ty + then begin - match !current_cic_infos with - Some (ids_to_terms, ids_to_father_ids) -> - let id = xpath in - let sequent = - LogicalOperations.to_sequent id ids_to_terms ids_to_father_ids - in - SequentPp.TextualPp.print_sequent sequent ; - let sequent_gdome = SequentPp.XmlPp.print_sequent sequent in - let sequent_doc = - Xml2Gdome.document_of_xml domImpl sequent_gdome - in - let sequent_mml = - applyStylesheets sequent_doc sequent_styles sequent_args - in - rendering_window#proofw#load_tree ~dom:sequent_mml ; -ignore(domImpl#saveDocumentToFile ~doc:sequent_doc - ~name:"/public/sacerdot/guruguru1" ~indent:true ()) ; -ignore(domImpl#saveDocumentToFile ~doc:sequent_mml - ~name:"/public/sacerdot/guruguru2" ~indent:true ()) - | None -> assert false (* "ERROR: No current term!!!" *) + (*CSC: Wrong: [] is just plainly wrong *) + let proof = Cic.Constant (UriManager.name_of_uri uri,Some bo,ty,[]) in + let + (acic,ids_to_terms,ids_to_father_ids,ids_to_inner_sorts, + ids_to_inner_types,ids_to_conjectures,ids_to_hypotheses) + = + Cic2acic.acic_object_of_cic_object proof + in + let mml = + mml_of_cic_object uri acic ids_to_inner_sorts ids_to_inner_types + in + ((rendering_window ())#output : GMathView.math_view)#load_tree mml ; + current_cic_infos := + Some + (ids_to_terms,ids_to_father_ids,ids_to_conjectures, + ids_to_hypotheses) end - | None -> assert false (* "ERROR: No selection!!!" *) + else + raise WrongProof + | _ -> raise OpenConjecturesStillThere ;; -let output_html outputhtml msg = - htmlheader_and_content := !htmlheader_and_content ^ msg ; - outputhtml#source (!htmlheader_and_content ^ htmlfooter) +(*???? +let dtdname = "http://www.cs.unibo.it/helm/dtd/cic.dtd";; +let dtdname = "/home/tassi/miohelm/helm/dtd/cic.dtd";; +*) +let dtdname = "/projects/helm/V7_mowgli/dtd/cic.dtd";; + +let save () = + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + match !ProofEngine.proof with + None -> assert false + | Some (uri, metasenv, bo, ty) -> + let currentproof = + (*CSC: Wrong: [] is just plainly wrong *) + Cic.CurrentProof (UriManager.name_of_uri uri,metasenv,bo,ty,[]) + in + let (acurrentproof,_,_,ids_to_inner_sorts,_,_,_) = + Cic2acic.acic_object_of_cic_object currentproof + in + let xml, bodyxml = + match Cic2Xml.print_object uri ~ids_to_inner_sorts acurrentproof with + xml,Some bodyxml -> xml,bodyxml + | _,None -> assert false + in + Xml.pp ~quiet:true xml (Some prooffiletype) ; + output_html outputhtml + ("

Current proof type saved to " ^ + prooffiletype ^ "

") ; + Xml.pp ~quiet:true bodyxml (Some prooffile) ; + output_html outputhtml + ("

Current proof body saved to " ^ + prooffile ^ "

") +;; + +(* Used to typecheck the loaded proofs *) +let typecheck_loaded_proof metasenv bo ty = + let module T = CicTypeChecker in + ignore ( + List.fold_left + (fun metasenv ((_,context,ty) as conj) -> + ignore (T.type_of_aux' metasenv context ty) ; + metasenv @ [conj] + ) [] metasenv) ; + ignore (T.type_of_aux' metasenv [] ty) ; + ignore (T.type_of_aux' metasenv [] bo) +;; + +let load () = + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + let output = ((rendering_window ())#output : GMathView.math_view) in + let notebook = (rendering_window ())#notebook in + try + let uri = UriManager.uri_of_string "cic:/dummy.con" in + match CicParser.obj_of_xml prooffiletype (Some prooffile) with + Cic.CurrentProof (_,metasenv,bo,ty,_) -> + typecheck_loaded_proof metasenv bo ty ; + ProofEngine.proof := + Some (uri, metasenv, bo, ty) ; + ProofEngine.goal := + (match metasenv with + [] -> None + | (metano,_,_)::_ -> Some metano + ) ; + refresh_proof output ; + refresh_sequent notebook ; + output_html outputhtml + ("

Current proof type loaded from " ^ + prooffiletype ^ "

") ; + output_html outputhtml + ("

Current proof body loaded from " ^ + prooffile ^ "

") + | _ -> assert false + with + RefreshSequentException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "sequent: " ^ Printexc.to_string e ^ "

") + | RefreshProofException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "proof: " ^ Printexc.to_string e ^ "

") + | e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") ; +;; + +let edit_aliases () = + let inputt = ((rendering_window ())#inputt : GEdit.text) in + let dom,resolve_id = !id_to_uris in + let inputlen = inputt#length in + inputt#delete_text 0 inputlen ; + let _ = + inputt#insert_text ~pos:0 + (String.concat "\n" + (List.map + (function v -> + let uri = + match resolve_id v with + None -> assert false + | Some uri -> uri + in + "alias " ^ v ^ " " ^ + (string_of_cic_textual_parser_uri uri) + ) dom)) + in + id_to_uris := empty_id_to_uris +;; + +let proveit () = + let module L = LogicalOperations in + let module G = Gdome in + let notebook = (rendering_window ())#notebook in + let output = (rendering_window ())#output in + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + match (rendering_window ())#output#get_selection with + Some node -> + let xpath = + ((node : Gdome.element)#getAttributeNS + (*CSC: OCAML DIVERGE + ((element : G.element)#getAttributeNS + *) + ~namespaceURI:helmns + ~localName:(G.domString "xref"))#to_string + in + if xpath = "" then assert false (* "ERROR: No xref found!!!" *) + else + begin + try + match !current_cic_infos with + Some (ids_to_terms, ids_to_father_ids, _, _) -> + let id = xpath in + L.to_sequent id ids_to_terms ids_to_father_ids ; + refresh_proof output ; + refresh_sequent notebook + | None -> assert false (* "ERROR: No current term!!!" *) + with + RefreshSequentException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "sequent: " ^ Printexc.to_string e ^ "

") + | RefreshProofException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "proof: " ^ Printexc.to_string e ^ "

") + | e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") + end + | None -> assert false (* "ERROR: No selection!!!" *) +;; + +let focus () = + let module L = LogicalOperations in + let module G = Gdome in + let notebook = (rendering_window ())#notebook in + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + match (rendering_window ())#output#get_selection with + Some node -> + let xpath = + ((node : Gdome.element)#getAttributeNS + (*CSC: OCAML DIVERGE + ((element : G.element)#getAttributeNS + *) + ~namespaceURI:helmns + ~localName:(G.domString "xref"))#to_string + in + if xpath = "" then assert false (* "ERROR: No xref found!!!" *) + else + begin + try + match !current_cic_infos with + Some (ids_to_terms, ids_to_father_ids, _, _) -> + let id = xpath in + L.focus id ids_to_terms ids_to_father_ids ; + refresh_sequent notebook + | None -> assert false (* "ERROR: No current term!!!" *) + with + RefreshSequentException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "sequent: " ^ Printexc.to_string e ^ "

") + | RefreshProofException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "proof: " ^ Printexc.to_string e ^ "

") + | e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") + end + | None -> assert false (* "ERROR: No selection!!!" *) ;; -let execute rendering_window () = - let inputt = (rendering_window#inputt : GEdit.text) in - let oldinputt = (rendering_window#oldinputt : GEdit.text) in - let outputhtml = (rendering_window#outputhtml : GHtml.xmhtml) in - let output = (rendering_window#output : GMathView.math_view) in - let proofw = (rendering_window#proofw : GMathView.math_view) in +exception NoPrevGoal;; +exception NoNextGoal;; + +let setgoal metano = + let module L = LogicalOperations in + let module G = Gdome in + let notebook = (rendering_window ())#notebook in + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + let metasenv = + match !ProofEngine.proof with + None -> assert false + | Some (_,metasenv,_,_) -> metasenv + in + try + ProofEngine.goal := Some metano ; + refresh_sequent ~empty_notebook:false notebook ; + with + RefreshSequentException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "sequent: " ^ Printexc.to_string e ^ "

") + | e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") +;; + +exception NotADefinition;; + +let open_ () = + let inputt = ((rendering_window ())#inputt : GEdit.text) in + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + let output = ((rendering_window ())#output : GMathView.math_view) in + let notebook = (rendering_window ())#notebook in + let inputlen = inputt#length in + let input = inputt#get_chars 0 inputlen in + try + let uri = UriManager.uri_of_string ("cic:" ^ input) in + CicTypeChecker.typecheck uri ; + let metasenv,bo,ty = + match CicEnvironment.get_cooked_obj uri with + Cic.Constant (_,Some bo,ty,_) -> [],bo,ty + | Cic.CurrentProof (_,metasenv,bo,ty,_) -> metasenv,bo,ty + | Cic.Constant _ + | Cic.Variable _ + | Cic.InductiveDefinition _ -> raise NotADefinition + in + ProofEngine.proof := + Some (uri, metasenv, bo, ty) ; + ProofEngine.goal := None ; + refresh_sequent notebook ; + refresh_proof output ; + inputt#delete_text 0 inputlen + with + RefreshSequentException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "sequent: " ^ Printexc.to_string e ^ "

") + | RefreshProofException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "proof: " ^ Printexc.to_string e ^ "

") + | e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") ; +;; + +let state () = + let inputt = ((rendering_window ())#inputt : GEdit.text) in + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + let output = ((rendering_window ())#output : GMathView.math_view) in + let notebook = (rendering_window ())#notebook in let inputlen = inputt#length in let input = inputt#get_chars 0 inputlen ^ "\n" in (* Do something interesting *) @@ -249,37 +1320,221 @@ let execute rendering_window () = try while true do (* Execute the actions *) - match CicTextualParser.main CicTextualLexer.token lexbuf with + match + CicTextualParserContext.main [] [] CicTextualLexer.token + lexbuf register_alias + with None -> () - | Some expr -> - try - let ty = CicTypeChecker.type_of_aux' [] expr in - let whd = CicReduction.whd expr in - - let (acic, ids_to_terms, ids_to_father_ids) = - Cic2acic.acic_of_cic expr - in - let mml = mml_of_cic acic in - output#load_tree mml ; -prerr_endline "BBB FINE RESA" ; - current_cic_infos := Some (ids_to_terms,ids_to_father_ids) ; -print_endline ("? " ^ CicPp.ppterm expr) ; -print_endline (">> " ^ CicPp.ppterm whd) ; -print_endline (": " ^ CicPp.ppterm ty) ; -flush stdout ; - with - e -> - print_endline ("? " ^ CicPp.ppterm expr) ; - raise e + | Some (dom,mk_metasenv_and_expr) -> + let metasenv,expr = + disambiguate_input [] [] dom mk_metasenv_and_expr + in + let _ = CicTypeChecker.type_of_aux' metasenv [] expr in + ProofEngine.proof := + Some (UriManager.uri_of_string "cic:/dummy.con", + (1,[],expr)::metasenv, Cic.Meta (1,[]), expr) ; + ProofEngine.goal := Some 1 ; + refresh_sequent notebook ; + refresh_proof output ; done with CicTextualParser0.Eof -> - inputt#delete_text 0 inputlen ; - ignore(oldinputt#insert_text input oldinputt#length) ; + inputt#delete_text 0 inputlen + | RefreshSequentException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "sequent: " ^ Printexc.to_string e ^ "

") + | RefreshProofException e -> + output_html outputhtml + ("

Exception raised during the refresh of the " ^ + "proof: " ^ Printexc.to_string e ^ "

") | e -> - print_endline ("Error: " ^ Printexc.to_string e) ; flush stdout + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") ; +;; + +let check_term_in_scratch scratch_window metasenv context expr = + try + let ty = CicTypeChecker.type_of_aux' metasenv context expr in + let mml = mml_of_cic_term 111 (Cic.Cast (expr,ty)) in +prerr_endline ("### " ^ CicPp.ppterm expr ^ " ==> " ^ CicPp.ppterm ty) ; + scratch_window#show () ; + scratch_window#mmlwidget#load_tree ~dom:mml + with + e -> + print_endline ("? " ^ CicPp.ppterm expr) ; + raise e ;; +let check scratch_window () = + let inputt = ((rendering_window ())#inputt : GEdit.text) in + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + let inputlen = inputt#length in + let input = inputt#get_chars 0 inputlen ^ "\n" in + let curi,metasenv = + match !ProofEngine.proof with + None -> UriManager.uri_of_string "cic:/dummy.con", [] + | Some (curi,metasenv,_,_) -> curi,metasenv + in + let context,names_context = + let context = + match !ProofEngine.goal with + None -> [] + | Some metano -> + let (_,canonical_context,_) = + List.find (function (m,_,_) -> m=metano) metasenv + in + canonical_context + in + context, + List.map + (function + Some (n,_) -> Some n + | None -> None + ) context + in + let lexbuf = Lexing.from_string input in + try + while true do + (* Execute the actions *) + match + CicTextualParserContext.main names_context metasenv CicTextualLexer.token + lexbuf register_alias + with + None -> () + | Some (dom,mk_metasenv_and_expr) -> + let (metasenv',expr) = + disambiguate_input context metasenv dom mk_metasenv_and_expr + in + check_term_in_scratch scratch_window metasenv' context expr + done + with + CicTextualParser0.Eof -> () + | e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") ; +;; + +exception NoObjectsLocated;; + +let user_uri_choice ~title ~msg uris = + let uri = + match uris with + [] -> raise NoObjectsLocated + | [uri] -> uri + | uris -> + interactive_user_uri_choice ~title ~msg uris + in + String.sub uri 4 (String.length uri - 4) +;; + +let locate () = + let inputt = ((rendering_window ())#inputt : GEdit.text) in + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + let inputlen = inputt#length in + let input = inputt#get_chars 0 inputlen in + try + match Str.split (Str.regexp "[ \t]+") input with + [] -> () + | head :: tail -> + inputt#delete_text 0 inputlen ; + let result = MQueryGenerator.locate head in + let uris = + List.map + (function uri,_ -> wrong_xpointer_format_from_wrong_xpointer_format' uri) + result in + let html = ("

Locate Query:

" ^ get_last_query result ^ "
") in + output_html outputhtml html ; + let uri' = + user_uri_choice ~title:"Ambiguous input." + ~msg: + ("Ambiguous input \"" ^ head ^ + "\". Please, choose one interpetation:") + uris + in + ignore ((inputt#insert_text uri') ~pos:0) + with + e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") +;; + +let searchPattern () = + let outputhtml = ((rendering_window ())#outputhtml : GHtml.xmhtml) in + let inputt = ((rendering_window ())#inputt : GEdit.text) in + let inputlen = inputt#length in + let input = inputt#get_chars 0 inputlen in + let level = int_of_string input in + let metasenv = + match !ProofEngine.proof with + None -> assert false + | Some (_,metasenv,_,_) -> metasenv + in + try + match !ProofEngine.goal with + None -> () + | Some metano -> + let (_, ey ,ty) = List.find (function (m,_,_) -> m=metano) metasenv in + let result = MQueryGenerator.searchPattern metasenv ey ty level in + let uris = + List.map + (function uri,_ -> wrong_xpointer_format_from_wrong_xpointer_format' uri) + result in + let html = + "

Backward Query:

" ^ + "

Levels:

" ^ + MQueryGenerator.string_of_levels + (MQueryGenerator.levels_of_term metasenv ey ty) "
" ^ + "
" ^ get_last_query result ^ "
" + in + output_html outputhtml html ; + let uris',exc = + let rec filter_out = + function + [] -> [],"" + | uri::tl -> + let tl',exc = filter_out tl in + try + if + ProofEngine.can_apply + (term_of_cic_textual_parser_uri + (cic_textual_parser_uri_of_string uri)) + then + uri::tl',exc + else + tl',exc + with + e -> + let exc' = + "

^ Exception raised trying to apply " ^ + uri ^ ": " ^ Printexc.to_string e ^ "

" ^ exc + in + tl',exc' + in + filter_out uris + in + let html' = + "

Objects that can actually be applied:

" ^ + String.concat "
" uris' ^ exc ^ + "

Number of false matches: " ^ + string_of_int (List.length uris - List.length uris') ^ "

" ^ + "

Number of good matches: " ^ + string_of_int (List.length uris') ^ "

" + in + output_html outputhtml html' ; + let uri' = + user_uri_choice ~title:"Ambiguous input." + ~msg:"Many lemmas can be successfully applied. Please, choose one:" + uris' + in + inputt#delete_text 0 inputlen ; + ignore ((inputt#insert_text uri') ~pos:0) + with + e -> + output_html outputhtml + ("

" ^ Printexc.to_string e ^ "

") +;; + let choose_selection (mmlwidget : GMathView.math_view) (element : Gdome.element option) = @@ -307,12 +1562,20 @@ let choose_selection (* Stuff for the widget settings *) -let export_to_postscript (output : GMathView.math_view) () = - output#export_to_postscript ~filename:"output.ps" (); +let export_to_postscript (output : GMathView.math_view) = + let lastdir = ref (Unix.getcwd ()) in + function () -> + match + GToolbox.select_file ~title:"Export to PostScript" + ~dir:lastdir ~filename:"screenshot.ps" () + with + None -> () + | Some filename -> + output#export_to_postscript ~filename:filename (); ;; let activate_t1 (output : GMathView.math_view) button_set_anti_aliasing - button_set_kerning button_set_transparency button_export_to_postscript + button_set_kerning button_set_transparency export_to_postscript_menu_item button_t1 () = let is_set = button_t1#active in @@ -323,14 +1586,14 @@ let activate_t1 (output : GMathView.math_view) button_set_anti_aliasing button_set_anti_aliasing#misc#set_sensitive true ; button_set_kerning#misc#set_sensitive true ; button_set_transparency#misc#set_sensitive true ; - button_export_to_postscript#misc#set_sensitive true ; + export_to_postscript_menu_item#misc#set_sensitive true ; end else begin button_set_anti_aliasing#misc#set_sensitive false ; button_set_kerning#misc#set_sensitive false ; button_set_transparency#misc#set_sensitive false ; - button_export_to_postscript#misc#set_sensitive false ; + export_to_postscript_menu_item#misc#set_sensitive false ; end ;; @@ -355,7 +1618,7 @@ let set_log_verbosity output log_verbosity_spinb () = ;; class settings_window (output : GMathView.math_view) sw - button_export_to_postscript selection_changed_callback + export_to_postscript_menu_item selection_changed_callback = let settings_window = GWindow.window ~title:"GtkMathView settings" () in let vbox = @@ -412,7 +1675,7 @@ object(self) (* Signals connection *) ignore(button_t1#connect#clicked (activate_t1 output button_set_anti_aliasing button_set_kerning - button_set_transparency button_export_to_postscript button_t1)) ; + button_set_transparency export_to_postscript_menu_item button_t1)) ; ignore(font_size_spinb#connect#changed (changefont output font_size_spinb)) ; ignore(button_set_anti_aliasing#connect#toggled (set_anti_aliasing output button_set_anti_aliasing)); @@ -425,83 +1688,329 @@ object(self) ignore(closeb#connect#clicked settings_window#misc#hide) end;; -(* Main windows *) +(* Scratch window *) -class rendering_window output proofw (label : GMisc.label) = +class scratch_window outputhtml = let window = GWindow.window ~title:"MathML viewer" ~border_width:2 () in - let hbox0 = - GPack.hbox ~packing:window#add () in let vbox = - GPack.vbox ~packing:(hbox0#pack ~expand:false ~fill:false ~padding:5) () in - let _ = vbox#pack ~expand:false ~fill:false ~padding:5 label#coerce in - let scrolled_window0 = + GPack.vbox ~packing:window#add () in + let hbox = + GPack.hbox ~packing:(vbox#pack ~expand:false ~fill:false ~padding:5) () in + let whdb = + GButton.button ~label:"Whd" + ~packing:(hbox#pack ~expand:false ~fill:false ~padding:5) () in + let reduceb = + GButton.button ~label:"Reduce" + ~packing:(hbox#pack ~expand:false ~fill:false ~padding:5) () in + let simplb = + GButton.button ~label:"Simpl" + ~packing:(hbox#pack ~expand:false ~fill:false ~padding:5) () in + let scrolled_window = GBin.scrolled_window ~border_width:10 ~packing:(vbox#pack ~expand:true ~padding:5) () in - let _ = scrolled_window0#add output#coerce in - let hbox1 = - GPack.hbox ~packing:(vbox#pack ~expand:false ~fill:false ~padding:5) () in - let settingsb = - GButton.button ~label:"Settings" - ~packing:(hbox1#pack ~expand:false ~fill:false ~padding:5) () in - let button_export_to_postscript = - GButton.button ~label:"export_to_postscript" - ~packing:(hbox1#pack ~expand:false ~fill:false ~padding:5) () in - let closeb = - GButton.button ~label:"Close" - ~packing:(hbox1#pack ~expand:false ~fill:false ~padding:5) () in - let hbox2 = - GPack.hbox ~packing:(vbox#pack ~expand:false ~fill:false ~padding:5) () in - let proveitb = - GButton.button ~label:"Prove It" - ~packing:(hbox2#pack ~expand:false ~fill:false ~padding:5) () in - let oldinputt = GEdit.text ~editable:false ~width:400 ~height:180 - ~packing:(vbox#pack ~padding:5) () in - let executeb = - GButton.button ~label:"Execute" - ~packing:(vbox#pack ~expand:false ~fill:false ~padding:5) () in - let inputt = GEdit.text ~editable:true ~width:400 ~height: 100 - ~packing:(vbox#pack ~padding:5) () in - let vbox1 = - GPack.vbox ~packing:(hbox0#pack ~expand:false ~fill:false ~padding:5) () in + let mmlwidget = + GMathView.math_view + ~packing:(scrolled_window#add) ~width:400 ~height:280 () in +object(self) + method outputhtml = outputhtml + method mmlwidget = mmlwidget + method show () = window#misc#hide () ; window#show () + initializer + ignore(mmlwidget#connect#selection_changed (choose_selection mmlwidget)) ; + ignore(window#event#connect#delete (fun _ -> window#misc#hide () ; true )) ; + ignore(whdb#connect#clicked (whd_in_scratch self)) ; + ignore(reduceb#connect#clicked (reduce_in_scratch self)) ; + ignore(simplb#connect#clicked (simpl_in_scratch self)) +end;; + +class page () = + let vbox1 = GPack.vbox () in let scrolled_window1 = GBin.scrolled_window ~border_width:10 ~packing:(vbox1#pack ~expand:true ~padding:5) () in - let _ = scrolled_window1#add proofw#coerce in + let proofw = + GMathView.math_view ~width:400 ~height:275 + ~packing:(scrolled_window1#add) () in let hbox3 = GPack.hbox ~packing:(vbox1#pack ~expand:false ~fill:false ~padding:5) () in let exactb = GButton.button ~label:"Exact" ~packing:(hbox3#pack ~expand:false ~fill:false ~padding:5) () in + let introsb = + GButton.button ~label:"Intros" + ~packing:(hbox3#pack ~expand:false ~fill:false ~padding:5) () in + let applyb = + GButton.button ~label:"Apply" + ~packing:(hbox3#pack ~expand:false ~fill:false ~padding:5) () in + let elimsimplintrosb = + GButton.button ~label:"ElimSimplIntros" + ~packing:(hbox3#pack ~expand:false ~fill:false ~padding:5) () in + let elimtypeb = + GButton.button ~label:"ElimType" + ~packing:(hbox3#pack ~expand:false ~fill:false ~padding:5) () in + let whdb = + GButton.button ~label:"Whd" + ~packing:(hbox3#pack ~expand:false ~fill:false ~padding:5) () in + let reduceb = + GButton.button ~label:"Reduce" + ~packing:(hbox3#pack ~expand:false ~fill:false ~padding:5) () in + let simplb = + GButton.button ~label:"Simpl" + ~packing:(hbox3#pack ~expand:false ~fill:false ~padding:5) () in + let foldb = + GButton.button ~label:"Fold" + ~packing:(hbox3#pack ~expand:false ~fill:false ~padding:5) () in + let cutb = + GButton.button ~label:"Cut" + ~packing:(hbox3#pack ~expand:false ~fill:false ~padding:5) () in + let hbox4 = + GPack.hbox ~packing:(vbox1#pack ~expand:false ~fill:false ~padding:5) () in + let changeb = + GButton.button ~label:"Change" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let letinb = + GButton.button ~label:"Let ... In" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let ringb = + GButton.button ~label:"Ring" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let clearbodyb = + GButton.button ~label:"ClearBody" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let clearb = + GButton.button ~label:"Clear" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let fourierb = + GButton.button ~label:"Fourier" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let rewritesimplb = + GButton.button ~label:"RewriteSimpl ->" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let reflexivityb = + GButton.button ~label:"Reflexivity" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let hbox5 = + GPack.hbox ~packing:(vbox1#pack ~expand:false ~fill:false ~padding:5) () in + let symmetryb = + GButton.button ~label:"Symmetry" + ~packing:(hbox5#pack ~expand:false ~fill:false ~padding:5) () in + let transitivityb = + GButton.button ~label:"Transitivity" + ~packing:(hbox5#pack ~expand:false ~fill:false ~padding:5) () in + let leftb = + GButton.button ~label:"Left" + ~packing:(hbox5#pack ~expand:false ~fill:false ~padding:5) () in + let rightb = + GButton.button ~label:"Right" + ~packing:(hbox5#pack ~expand:false ~fill:false ~padding:5) () in + let assumptionb = + GButton.button ~label:"Assumption" + ~packing:(hbox5#pack ~expand:false ~fill:false ~padding:5) () in +object + method proofw = proofw + method content = vbox1 + initializer + ignore(exactb#connect#clicked exact) ; + ignore(applyb#connect#clicked apply) ; + ignore(elimsimplintrosb#connect#clicked elimsimplintros) ; + ignore(elimtypeb#connect#clicked elimtype) ; + ignore(whdb#connect#clicked whd) ; + ignore(reduceb#connect#clicked reduce) ; + ignore(simplb#connect#clicked simpl) ; + ignore(foldb#connect#clicked fold) ; + ignore(cutb#connect#clicked cut) ; + ignore(changeb#connect#clicked change) ; + ignore(letinb#connect#clicked letin) ; + ignore(ringb#connect#clicked ring) ; + ignore(clearbodyb#connect#clicked clearbody) ; + ignore(clearb#connect#clicked clear) ; + ignore(fourierb#connect#clicked fourier) ; + ignore(rewritesimplb#connect#clicked rewritesimpl) ; + ignore(reflexivityb#connect#clicked reflexivity) ; + ignore(symmetryb#connect#clicked symmetry) ; + ignore(transitivityb#connect#clicked transitivity) ; + ignore(leftb#connect#clicked left) ; + ignore(rightb#connect#clicked right) ; + ignore(assumptionb#connect#clicked assumption) ; + ignore(introsb#connect#clicked intros) ; + initializer + ignore(proofw#connect#selection_changed (choose_selection proofw)) ; +end +;; + +class notebook = +object(self) + val notebook = GPack.notebook () + val pages = ref [] + val mutable skip_switch_page_event = false + method notebook = notebook + method add_page n = + let new_page = new page () in + pages := !pages @ [n,new_page] ; + notebook#append_page + ~tab_label:((GMisc.label ~text:("?" ^ string_of_int n) ())#coerce) + new_page#content#coerce + method remove_all_pages = + List.iter (function _ -> notebook#remove_page 0) !pages ; + pages := [] ; + method set_current_page n = + let (_,page) = List.find (function (m,_) -> m=n) !pages in + let new_page = notebook#page_num page#content#coerce in + if new_page <> notebook#current_page then + skip_switch_page_event <- true ; + notebook#goto_page new_page + method set_empty_page = self#add_page (-1) + method proofw = + (snd (List.nth !pages notebook#current_page))#proofw + initializer + ignore + (notebook#connect#switch_page + (function i -> + let skip = skip_switch_page_event in + skip_switch_page_event <- false ; + if not skip then + try + let metano = fst (List.nth !pages i) in + setgoal metano + with _ -> () + )) +end +;; + +(* Main window *) + +class rendering_window output (notebook : notebook) = + let window = + GWindow.window ~title:"MathML viewer" ~border_width:2 + ~allow_shrink:false () in + let vbox_for_menu = GPack.vbox ~packing:window#add () in + (* menus *) + let menubar = GMenu.menu_bar ~packing:vbox_for_menu#pack () in + let factory0 = new GMenu.factory menubar in + let accel_group = factory0#accel_group in + (* file menu *) + let file_menu = factory0#add_submenu "File" in + let factory1 = new GMenu.factory file_menu ~accel_group in + let export_to_postscript_menu_item = + begin + ignore + (factory1#add_item "Load" ~key:GdkKeysyms._L ~callback:load) ; + ignore (factory1#add_item "Save" ~key:GdkKeysyms._S ~callback:save) ; + ignore (factory1#add_separator ()) ; + let export_to_postscript_menu_item = + factory1#add_item "Export to PostScript..." ~key:GdkKeysyms._E + ~callback:(export_to_postscript output) in + ignore (factory1#add_separator ()) ; + ignore + (factory1#add_item "Exit" ~key:GdkKeysyms._C ~callback:GMain.Main.quit) ; + export_to_postscript_menu_item + end in + (* edit menu *) + let edit_menu = factory0#add_submenu "Edit" in + let factory2 = new GMenu.factory edit_menu ~accel_group in + let focus_and_proveit_set_sensitive = ref (function _ -> assert false) in + let proveit_menu_item = + factory2#add_item "Prove It" ~key:GdkKeysyms._I + ~callback:(function () -> proveit ();!focus_and_proveit_set_sensitive false) + in + let focus_menu_item = + factory2#add_item "Focus" ~key:GdkKeysyms._F + ~callback:(function () -> focus () ; !focus_and_proveit_set_sensitive false) + in + let _ = + focus_and_proveit_set_sensitive := + function b -> + proveit_menu_item#misc#set_sensitive b ; + focus_menu_item#misc#set_sensitive b + in + let _ = factory2#add_separator () in + let _ = factory2#add_item "Qed" ~key:GdkKeysyms._Q ~callback:qed in + let _ = !focus_and_proveit_set_sensitive false in + (* settings menu *) + let settings_menu = factory0#add_submenu "Settings" in + let factory3 = new GMenu.factory settings_menu ~accel_group in + let _ = + factory3#add_item "Edit Aliases" ~key:GdkKeysyms._A + ~callback:edit_aliases in + let _ = factory3#add_separator () in + let _ = + factory3#add_item "MathML Widget Preferences..." ~key:GdkKeysyms._P + ~callback:(function _ -> (settings_window ())#show ()) in + (* accel group *) + let _ = window#add_accel_group accel_group in + (* end of menus *) + let hbox0 = + GPack.hbox + ~packing:(vbox_for_menu#pack ~expand:true ~fill:true ~padding:5) () in + let vbox = + GPack.vbox ~packing:(hbox0#pack ~expand:true ~fill:true ~padding:5) () in + let scrolled_window0 = + GBin.scrolled_window ~border_width:10 + ~packing:(vbox#pack ~expand:true ~padding:5) () in + let _ = scrolled_window0#add output#coerce in + let hbox4 = + GPack.hbox ~packing:(vbox#pack ~expand:false ~fill:false ~padding:5) () in + let stateb = + GButton.button ~label:"State" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let openb = + GButton.button ~label:"Open" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let checkb = + GButton.button ~label:"Check" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let locateb = + GButton.button ~label:"Locate" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let searchpatternb = + GButton.button ~label:"SearchPattern" + ~packing:(hbox4#pack ~expand:false ~fill:false ~padding:5) () in + let scrolled_window1 = + GBin.scrolled_window ~border_width:10 + ~packing:(vbox#pack ~expand:true ~padding:5) () in + let inputt = GEdit.text ~editable:true ~width:400 ~height:100 + ~packing:scrolled_window1#add () in + let vboxl = + GPack.vbox ~packing:(hbox0#pack ~expand:true ~fill:true ~padding:5) () in + let _ = + vboxl#pack ~expand:true ~fill:true ~padding:5 notebook#notebook#coerce in + let frame = GBin.frame ~packing:(vboxl#pack ~expand:true ~padding:5) () in let outputhtml = GHtml.xmhtml ~source:"" - ~width:400 ~height: 200 - ~packing:(vbox1#pack ~expand:false ~fill:false ~padding:5) + ~width:400 ~height: 100 + ~border_width:20 + ~packing:frame#add ~show:true () in -object(self) + let scratch_window = new scratch_window outputhtml in +object method outputhtml = outputhtml - method oldinputt = oldinputt method inputt = inputt method output = (output : GMathView.math_view) - method proofw = (proofw : GMathView.math_view) - method show () = window#show () + method notebook = notebook + method show = window#show initializer - button_export_to_postscript#misc#set_sensitive false ; + notebook#set_empty_page ; + export_to_postscript_menu_item#misc#set_sensitive false ; + check_term := (check_term_in_scratch scratch_window) ; (* signal handlers here *) ignore(output#connect#selection_changed - (function elem -> proofw#unload ; choose_selection output elem)) ; - ignore(proofw#connect#selection_changed (choose_selection proofw)) ; - ignore(closeb#connect#clicked (fun _ -> GMain.Main.quit ())) ; + (function elem -> + notebook#proofw#unload ; + choose_selection output elem ; + !focus_and_proveit_set_sensitive true + )) ; let settings_window = new settings_window output scrolled_window0 - button_export_to_postscript (choose_selection output) in - ignore(settingsb#connect#clicked settings_window#show) ; - ignore(button_export_to_postscript#connect#clicked (export_to_postscript output)) ; - ignore(proveitb#connect#clicked (proveit self)) ; + export_to_postscript_menu_item (choose_selection output) in + set_settings_window settings_window ; ignore(window#event#connect#delete (fun _ -> GMain.Main.quit () ; true )) ; - ignore(executeb#connect#clicked (execute self)) ; - ignore(exactb#connect#clicked (exact self)) ; + ignore(stateb#connect#clicked state) ; + ignore(openb#connect#clicked open_) ; + ignore(checkb#connect#clicked (check scratch_window)) ; + ignore(locateb#connect#clicked locate) ; + ignore(searchpatternb#connect#clicked searchPattern) ; Logger.log_callback := (Logger.log_to_html ~print_and_flush:(output_html outputhtml)) end;; @@ -510,17 +2019,19 @@ end;; let initialize_everything () = let module U = Unix in - let output = GMathView.math_view ~width:400 ~height:280 () - and proofw = GMathView.math_view ~width:400 ~height:275 () - and label = GMisc.label ~text:"gTopLevel" () in - let rendering_window = - new rendering_window output proofw label - in - rendering_window#show () ; - GMain.Main.main () + let output = GMathView.math_view ~width:350 ~height:280 () in + let notebook = new notebook in + let rendering_window' = new rendering_window output notebook in + set_rendering_window rendering_window' ; + rendering_window'#show () ; + GMain.Main.main () ;; let _ = - CicCooking.init () ; - initialize_everything () + if !usedb then + Mqint.init "dbname=helm_mowgli" ; +(* Mqint.init "host=mowgli.cs.unibo.it dbname=helm_mowgli user=helm" ; *) + ignore (GtkMain.Main.init ()) ; + initialize_everything () ; + if !usedb then Mqint.close (); ;;