X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Fsoftware%2Fmatita%2FmatitaScript.ml;h=aaa703348af1205c2c70a362a79d09a4c7a9ddf5;hb=3cb42e0873c101c6c5a8b9967d765b5135882685;hp=fca45c02628132a700ef92bcf3fd913da19e40f1;hpb=397b5f9d848e63a9703a1f90faf9869092ec8893;p=helm.git diff --git a/helm/software/matita/matitaScript.ml b/helm/software/matita/matitaScript.ml index fca45c026..aaa703348 100644 --- a/helm/software/matita/matitaScript.ml +++ b/helm/software/matita/matitaScript.ml @@ -69,24 +69,20 @@ type guistuff = { mathviewer:MatitaTypes.mathViewer; urichooser: UriManager.uri list -> UriManager.uri list; ask_confirmation: title:string -> message:string -> [`YES | `NO | `CANCEL]; - develcreator: containing:string option -> unit; - mutable filenamedata: string option * MatitamakeLib.development option } -let eval_with_engine guistuff lexicon_status grafite_status user_goal +let eval_with_engine include_paths guistuff grafite_status user_goal skipped_txt nonskipped_txt st = - let module TAPp = GrafiteAstPp in - let module DTE = DisambiguateTypes.Environment in - let module DP = DisambiguatePp in let parsed_text_length = String.length skipped_txt + String.length nonskipped_txt in let text = skipped_txt ^ nonskipped_txt in let prefix_len = MatitaGtkMisc.utf8_string_length skipped_txt in let enriched_history_fragment = - MatitaEngine.eval_ast ~do_heavy_checks:true - lexicon_status grafite_status (text,prefix_len,st) + MatitaEngine.eval_ast ~do_heavy_checks:(Helm_registry.get_bool + "matita.do_heavy_checks") + grafite_status (text,prefix_len,st) in let enriched_history_fragment = List.rev enriched_history_fragment in (* really fragile *) @@ -95,89 +91,37 @@ let eval_with_engine guistuff lexicon_status grafite_status user_goal (fun (acc, to_prepend) (status,alias) -> match alias with | None -> (status,to_prepend ^ nonskipped_txt)::acc,"" - | Some (k,((v,_) as value)) -> - let newtxt = DP.pp_environment (DTE.add k value DTE.empty) in + | Some (k,value) -> + let newtxt = LexiconAstPp.pp_alias value in (status,to_prepend ^ newtxt ^ "\n")::acc, "") ([],skipped_txt) enriched_history_fragment in res,"",parsed_text_length +;; -let wrap_with_developments guistuff f arg = - let compile_needed_and_go_on lexiconfile d exc = - let target = Pcre.replace ~pat:"lexicon$" ~templ:"moo" lexiconfile in - let target = Pcre.replace ~pat:"metadata$" ~templ:"moo" target in - let refresh_cb () = - while Glib.Main.pending () do ignore(Glib.Main.iteration false); done - in - if not(MatitamakeLib.build_development_in_bg ~target refresh_cb d) then - raise exc - else - f arg - in - let do_nothing () = raise (ActionCancelled "Inclusion not performed") in - let check_if_file_is_exists f = - assert(Pcre.pmatch ~pat:"ma$" f); - let pwd = Sys.getcwd () in - let f_pwd = pwd ^ "/" ^ f in - if not (HExtlib.is_regular f_pwd) then - raise (ActionCancelled ("File "^f_pwd^" does not exists!")) - else - raise - (ActionCancelled - ("Internal error: "^f_pwd^" exists but I'm unable to include it!")) - in - let handle_with_devel d lexiconfile mafile exc = - let name = MatitamakeLib.name_for_development d in - let title = "Unable to include " ^ lexiconfile in - let message = - mafile ^ " is handled by development " ^ name ^ ".\n\n" ^ - "Should I compile it and Its dependencies?" - in - (match guistuff.ask_confirmation ~title ~message with - | `YES -> compile_needed_and_go_on lexiconfile d exc - | `NO -> raise exc - | `CANCEL -> do_nothing ()) - in - let handle_without_devel mafilename exc = - let title = "Unable to include " ^ mafilename in - let message = - mafilename ^ " is not handled by a development.\n" ^ - "All dependencies are automatically solved for a development.\n\n" ^ - "Do you want to set up a development?" - in - (match guistuff.ask_confirmation ~title ~message with - | `YES -> - guistuff.develcreator ~containing:(Some (Filename.dirname mafilename)); - do_nothing () - | `NO -> raise exc - | `CANCEL -> do_nothing()) - in - try - f arg +(* this function calls the parser in a way that it does not perform inclusions, + * so that we can ensure the inclusion is performed after the included file + * is compiled (if needed). matitac does not need that, since it compiles files + * in the good order, here files may be compiled on demand. *) +let wrap_with_make include_paths (f : #LexiconEngine.status GrafiteParser.statement) x = + try + f ~never_include:true ~include_paths x with - | DependenciesParser.UnableToInclude mafilename -> - assert (Pcre.pmatch ~pat:"ma$" mafilename); - check_if_file_is_exists mafilename - | LexiconEngine.IncludedFileNotCompiled (xfilename,mafilename) - | GrafiteEngine.IncludedFileNotCompiled (xfilename,mafilename) as exn -> - assert (Pcre.pmatch ~pat:"ma$" mafilename); - assert (Pcre.pmatch ~pat:"lexicon$" xfilename || - Pcre.pmatch ~pat:"mo$" xfilename ); - (* we know that someone was able to include the .ma, get the baseuri - * but was unable to get the compilation output 'xfilename' *) - match MatitamakeLib.development_for_dir (Filename.dirname mafilename) with - | None -> handle_without_devel mafilename exn - | Some d -> handle_with_devel d xfilename mafilename exn -;; - -let eval_with_engine - guistuff lexicon_status grafite_status user_goal - skipped_txt nonskipped_txt st -= - wrap_with_developments guistuff - (eval_with_engine - guistuff lexicon_status grafite_status user_goal - skipped_txt nonskipped_txt) st + | GrafiteParser.NoInclusionPerformed mafilename -> + let root, buri, _, tgt = + try Librarian.baseuri_of_script ~include_paths mafilename + with Librarian.NoRootFor _ -> + HLog.error ("The included file '"^mafilename^"' has no root file,"); + HLog.error "please create it."; + raise (Failure ("No root file for "^mafilename)) + in + let b = MatitacLib.Make.make root [tgt] in + if b then + try f ~include_paths x with LexiconEngine.IncludedFileNotCompiled _ -> + raise + (Failure ("Including: "^tgt^ + "\nNothing to do... did you run matitadep?")) + else raise (Failure ("Compiling: " ^ tgt)) ;; let pp_eager_statement_ast = @@ -266,20 +210,20 @@ let cic2grafite context menv t = | Cic.Const _ as t -> PT.Ident (pp_t c t, None) | Cic.Appl l -> PT.Appl (List.map (aux c) l) - | Cic.Implicit _ -> PT.Implicit + | Cic.Implicit _ -> PT.Implicit `JustOne | Cic.Lambda (Cic.Name n, s, t) -> PT.Binder (`Lambda, (PT.Ident (n,None), Some (aux c s)), aux (Some (Cic.Name n, Cic.Decl s)::c) t) | Cic.Prod (Cic.Name n, s, t) -> PT.Binder (`Forall, (PT.Ident (n,None), Some (aux c s)), aux (Some (Cic.Name n, Cic.Decl s)::c) t) - | Cic.LetIn (Cic.Name n, s, t) -> + | Cic.LetIn (Cic.Name n, s, ty, t) -> PT.Binder (`Lambda, (PT.Ident (n,None), Some (aux c s)), - aux (Some (Cic.Name n, Cic.Def (s,None))::c) t) - | Cic.Meta _ -> PT.Implicit + aux (Some (Cic.Name n, Cic.Def (s,ty))::c) t) + | Cic.Meta _ -> PT.Implicit `JustOne | Cic.Sort (Cic.Type u) -> PT.Sort (`Type u) | Cic.Sort Cic.Set -> PT.Sort `Set - | Cic.Sort Cic.CProp -> PT.Sort `CProp + | Cic.Sort (Cic.CProp u) -> PT.Sort (`CProp u) | Cic.Sort Cic.Prop -> PT.Sort `Prop | _ as t -> PT.Ident ("ERROR: "^CicPp.ppterm t, None) in @@ -400,8 +344,8 @@ let cic2grafite context menv t = let width = max_int in let term_pp content_term = let pres_term = TermContentPres.pp_ast content_term in - let dummy_tbl = Hashtbl.create 1 in - let markup = CicNotationPres.render dummy_tbl pres_term in + let lookup_uri = fun _ -> None in + let markup = CicNotationPres.render ~lookup_uri pres_term in let s = "(" ^ BoxPp.render_to_string ~map_unicode_to_tex:(Helm_registry.get_bool "matita.paste_unicode_as_tex") @@ -421,43 +365,57 @@ let cic2grafite context menv t = prerr_endline script; stupid_indenter script ;; +let eval_nmacro include_paths (buffer : GText.buffer) guistuff grafite_status user_goal unparsed_text parsed_text script mac = + let parsed_text_length = String.length parsed_text in + match mac with + | TA.Screenshot (_,name) -> + let status = script#grafite_status in + let _,_,menv,subst,_ = status#obj in + let name = Filename.dirname (script#filename) ^ "/" ^ name in + let sequents = + let selected = Continuationals.Stack.head_goals status#stack in + List.filter (fun x,_ -> List.mem x selected) menv + in + guistuff.mathviewer#screenshot status sequents menv subst name; + [status, parsed_text], "", parsed_text_length + | TA.NCheck (_,t) -> + let status = script#grafite_status in + let _,_,menv,subst,_ = status#obj in + let ctx = + try let _,(_,ctx,_) = List.hd menv in ctx + with Failure "hd" -> [] + in + let m, s, status, t = + GrafiteDisambiguate.disambiguate_nterm + None status ctx menv subst (parsed_text,parsed_text_length, + CicNotationPt.Cast (t,CicNotationPt.Implicit `JustOne)) + (* XXX use the metasenv, if possible *) + in + guistuff.mathviewer#show_entry (`NCic (t,ctx,m,s)); + [], "", parsed_text_length -let rec eval_macro include_paths (buffer : GText.buffer) guistuff lexicon_status grafite_status user_goal unparsed_text parsed_text script mac = - let module TAPp = GrafiteAstPp in +let rec eval_macro include_paths (buffer : GText.buffer) guistuff grafite_status user_goal unparsed_text parsed_text script mac = let module MQ = MetadataQuery in - let module MDB = LibraryDb in let module CTC = CicTypeChecker in - let module CU = CicUniv in (* no idea why ocaml wants this *) let parsed_text_length = String.length parsed_text in let dbd = LibraryDb.instance () in - let pp_macro = - let f t = ProofEngineReduction.replace - ~equality:(fun _ t -> match t with Cic.Meta _ -> true | _ -> false) - ~what:[()] ~with_what:[Cic.Implicit None] ~where:t - in - let metasenv = GrafiteTypes.get_proof_metasenv grafite_status in - TAPp.pp_macro - ~term_pp:(fun x -> - ApplyTransformation.txt_of_cic_term max_int metasenv [] (f x) - ~map_unicode_to_tex:(Helm_registry.get_bool - "matita.paste_unicode_as_tex")) - in + let pp_macro = ApplyTransformation.txt_of_macro ~map_unicode_to_tex:true in match mac with (* WHELP's stuff *) | TA.WMatch (loc, term) -> let l = Whelp.match_term ~dbd term in - let entry = `Whelp (pp_macro mac, l) in + let entry = `Whelp (pp_macro [] [] mac, l) in guistuff.mathviewer#show_uri_list ~reuse:true ~entry l; [], "", parsed_text_length | TA.WInstance (loc, term) -> let l = Whelp.instance ~dbd term in - let entry = `Whelp (pp_macro mac, l) in + let entry = `Whelp (pp_macro [] [] mac, l) in guistuff.mathviewer#show_uri_list ~reuse:true ~entry l; [], "", parsed_text_length | TA.WLocate (loc, s) -> let l = Whelp.locate ~dbd s in - let entry = `Whelp (pp_macro mac, l) in + let entry = `Whelp (pp_macro [] [] mac, l) in guistuff.mathviewer#show_uri_list ~reuse:true ~entry l; [], "", parsed_text_length | TA.WElim (loc, term) -> @@ -467,18 +425,18 @@ let rec eval_macro include_paths (buffer : GText.buffer) guistuff lexicon_status | _ -> failwith "Not a MutInd" in let l = Whelp.elim ~dbd uri in - let entry = `Whelp (pp_macro mac, l) in + let entry = `Whelp (pp_macro [] [] mac, l) in guistuff.mathviewer#show_uri_list ~reuse:true ~entry l; [], "", parsed_text_length | TA.WHint (loc, term) -> let _subst = [] in - let s = ((None,[0,[],term], _subst, Cic.Meta (0,[]) ,term, []),0) in + let s = ((None,[0,[],term], _subst, lazy (Cic.Meta (0,[])) ,term, []),0) in let l = List.map fst (MQ.experimental_hint ~dbd s) in - let entry = `Whelp (pp_macro mac, l) in + let entry = `Whelp (pp_macro [] [] mac, l) in guistuff.mathviewer#show_uri_list ~reuse:true ~entry l; [], "", parsed_text_length (* REAL macro *) - | TA.Hint loc -> + | TA.Hint (loc, rewrite) -> let user_goal' = match user_goal with Some n -> n @@ -486,38 +444,72 @@ let rec eval_macro include_paths (buffer : GText.buffer) guistuff lexicon_status in let proof = GrafiteTypes.get_current_proof grafite_status in let proof_status = proof,user_goal' in - let l = List.map fst (MQ.experimental_hint ~dbd proof_status) in - let selected = guistuff.urichooser l in - (match selected with - | [] -> [], "", parsed_text_length - | [uri] -> - let suri = UriManager.string_of_uri uri in - let ast loc = - TA.Executable (loc, (TA.Tactic (loc, - Some (TA.Apply (loc, CicNotationPt.Uri (suri, None))), - TA.Dot loc))) in - let text = - comment parsed_text ^ "\n" ^ - pp_eager_statement_ast (ast HExtlib.dummy_floc) - ~map_unicode_to_tex:(Helm_registry.get_bool - "matita.paste_unicode_as_tex") - in - let text_len = MatitaGtkMisc.utf8_string_length text in - let loc = HExtlib.floc_of_loc (0,text_len) in - let statement = `Ast (GrafiteParser.LSome (ast loc),text) in - let res,_,_parsed_text_len = - eval_statement include_paths buffer guistuff lexicon_status - grafite_status user_goal script statement - in - (* we need to replace all the parsed_text *) - res,"",String.length parsed_text - | _ -> - HLog.error - "The result of the urichooser should be only 1 uri, not:\n"; - List.iter ( - fun u -> HLog.error (UriManager.string_of_uri u ^ "\n") - ) selected; - assert false) + if rewrite then + let l = MQ.equations_for_goal ~dbd proof_status in + let l = List.filter (fun u -> not (LibraryObjects.in_eq_URIs u)) l in + let entry = + `Whelp (pp_macro [] [] (TA.WHint(loc, Cic.Implicit None)), l) in + guistuff.mathviewer#show_uri_list ~reuse:true ~entry l; + [], "", parsed_text_length + else + let l = List.map fst (MQ.experimental_hint ~dbd proof_status) in + let selected = guistuff.urichooser l in + (match selected with + | [] -> [], "", parsed_text_length + | [uri] -> + let suri = UriManager.string_of_uri uri in + let ast loc = + TA.Executable (loc, (TA.Tactic (loc, + Some (TA.Apply (loc, CicNotationPt.Uri (suri, None))), + TA.Dot loc))) in + let text = + comment parsed_text ^ "\n" ^ + pp_eager_statement_ast (ast HExtlib.dummy_floc) + ~map_unicode_to_tex:(Helm_registry.get_bool + "matita.paste_unicode_as_tex") + in + let text_len = MatitaGtkMisc.utf8_string_length text in + let loc = HExtlib.floc_of_loc (0,text_len) in + let statement = `Ast (GrafiteParser.LSome (ast loc),text) in + let res,_,_parsed_text_len = + eval_statement include_paths buffer guistuff + grafite_status user_goal script statement + in + (* we need to replace all the parsed_text *) + res,"",String.length parsed_text + | _ -> + HLog.error + "The result of the urichooser should be only 1 uri, not:\n"; + List.iter ( + fun u -> HLog.error (UriManager.string_of_uri u ^ "\n") + ) selected; + assert false) + | TA.Eval (_, kind, term) -> + let metasenv = GrafiteTypes.get_proof_metasenv grafite_status in + let context = + match user_goal with + None -> [] + | Some n -> GrafiteTypes.get_proof_context grafite_status n in + let ty,_ = CTC.type_of_aux' metasenv context term CicUniv.empty_ugraph in + let term = + match kind with + | `Normalize -> + CicReduction.normalize ~delta:true ~subst:[] context term + | `Simpl -> + ProofEngineReduction.simpl context term + | `Unfold None -> + ProofEngineReduction.unfold ?what:None context term + | `Unfold (Some lazy_term) -> + let what, _, _ = + lazy_term context metasenv CicUniv.empty_ugraph in + ProofEngineReduction.unfold ~what context term + | `Whd -> + CicReduction.whd ~delta:true ~subst:[] context term + in + let t_and_ty = Cic.Cast (term,ty) in + guistuff.mathviewer#show_entry (`Cic (t_and_ty,metasenv)); + [(grafite_status#set_proof_status No_proof), parsed_text ],"", + parsed_text_length | TA.Check (_,term) -> let metasenv = GrafiteTypes.get_proof_metasenv grafite_status in let context = @@ -543,7 +535,8 @@ let rec eval_macro include_paths (buffer : GText.buffer) guistuff lexicon_status let (_,menv,subst,_,_,_), _ = ProofEngineTypes.apply_tactic (Auto.auto_tac ~dbd ~params - ~universe:grafite_status.GrafiteTypes.universe) proof_status + ~automation_cache:grafite_status#automation_cache) + proof_status in let proof_term = let irl = @@ -559,7 +552,7 @@ let rec eval_macro include_paths (buffer : GText.buffer) guistuff lexicon_status Auto.revision time size depth in let proof_script = - if List.exists (fun (s,_) -> s = "paramodulation") params then + if List.exists (fun (s,_) -> s = "paramodulation") (snd params) then let proof_term, how_many_lambdas = Auto.lambda_close ~prefix_name:"orrible_hack_" proof_term menv cc @@ -579,32 +572,18 @@ let rec eval_macro include_paths (buffer : GText.buffer) guistuff lexicon_status "matita.paste_unicode_as_tex") ~skip_thm_and_qed:true ~skip_initial_lambdas:how_many_lambdas - 80 GrafiteAst.Declarative "" obj + 80 [] obj else if true then (* use cic2grafite *) cic2grafite cc menv proof_term else (* alternative using FG stuff *) - let proof_term, how_many_lambdas = - Auto.lambda_close ~prefix_name:"orrible_hack_" - proof_term menv cc - in - let ty,_ = - CicTypeChecker.type_of_aux' - menv [] proof_term CicUniv.empty_ugraph - in - let obj = - Cic.Constant ("",Some proof_term, ty, [], [`Flavour `Lemma]) - in - Pcre.qreplace ~templ:"?" ~pat:"orrible_hack_[0-9]+" - (strip_comments - (ApplyTransformation.txt_of_cic_object - ~map_unicode_to_tex:(Helm_registry.get_bool - "matita.paste_unicode_as_tex") - ~skip_thm_and_qed:true - ~skip_initial_lambdas:how_many_lambdas - 80 (GrafiteAst.Procedural None) "" obj)) + let map_unicode_to_tex = + Helm_registry.get_bool "matita.paste_unicode_as_tex" + in + ApplyTransformation.procedural_txt_of_cic_term + ~map_unicode_to_tex 78 [] cc proof_term in let text = comment parsed_text ^ "\n" ^ proof_script ^ trailer in [],text,parsed_text_length @@ -612,47 +591,25 @@ let rec eval_macro include_paths (buffer : GText.buffer) guistuff lexicon_status ProofEngineTypes.Fail _ as exn -> raise exn (* [], comment parsed_text ^ "\nfail.\n", parsed_text_length *)) - | TA.Inline (_,style,suri,prefix) -> - let str = + | TA.Inline (_, suri, params) -> + let str = "\n\n" ^ ApplyTransformation.txt_of_inline_macro ~map_unicode_to_tex:(Helm_registry.get_bool "matita.paste_unicode_as_tex") - style suri prefix + params suri in [], str, String.length parsed_text and eval_executable include_paths (buffer : GText.buffer) guistuff -lexicon_status grafite_status user_goal unparsed_text skipped_txt nonskipped_txt +grafite_status user_goal unparsed_text skipped_txt nonskipped_txt script ex loc = - let module TAPp = GrafiteAstPp in - let module MD = GrafiteDisambiguator in - let module ML = MatitaMisc in try - begin - match ex with - | TA.Command (_,TA.Set (_,"baseuri",u)) -> - if Http_getter_storage.is_read_only u then - raise (ActionCancelled ("baseuri " ^ u ^ " is readonly")); - if not (Http_getter_storage.is_empty ~local:true u) then - (match - guistuff.ask_confirmation - ~title:"Baseuri redefinition" - ~message:( - "Baseuri " ^ u ^ " already exists.\n" ^ - "Do you want to redefine the corresponding "^ - "part of the library?") - with - | `YES -> LibraryClean.clean_baseuris [u] - | `NO -> () - | `CANCEL -> raise MatitaTypes.Cancel) - | _ -> () - end; ignore (buffer#move_mark (`NAME "beginning_of_statement") ~where:((buffer#get_iter_at_mark (`NAME "locked"))#forward_chars (Glib.Utf8.length skipped_txt))) ; - eval_with_engine - guistuff lexicon_status grafite_status user_goal skipped_txt nonskipped_txt + eval_with_engine include_paths + guistuff grafite_status user_goal skipped_txt nonskipped_txt (TA.Executable (loc, ex)) with MatitaTypes.Cancel -> [], "", 0 @@ -662,23 +619,27 @@ script ex loc None -> [] | Some n -> GrafiteTypes.get_proof_context grafite_status n in let grafite_status,macro = lazy_macro context in - eval_macro include_paths buffer guistuff lexicon_status grafite_status + eval_macro include_paths buffer guistuff grafite_status + user_goal unparsed_text (skipped_txt ^ nonskipped_txt) script macro + | GrafiteEngine.NMacro (_loc,macro) -> + eval_nmacro include_paths buffer guistuff grafite_status user_goal unparsed_text (skipped_txt ^ nonskipped_txt) script macro -and eval_statement include_paths (buffer : GText.buffer) guistuff lexicon_status + +and eval_statement include_paths (buffer : GText.buffer) guistuff grafite_status user_goal script statement = - let (lexicon_status,st), unparsed_text = + let (grafite_status,st), unparsed_text = match statement with | `Raw text -> if Pcre.pmatch ~rex:only_dust_RE text then raise Margin; let ast = - wrap_with_developments guistuff - (GrafiteParser.parse_statement - (Ulexing.from_utf8_string text) ~include_paths) lexicon_status + wrap_with_make include_paths + (GrafiteParser.parse_statement (Ulexing.from_utf8_string text)) + grafite_status in ast, text - | `Ast (st, text) -> (lexicon_status, st), text + | `Ast (st, text) -> (grafite_status, st), text in let text_of_loc floc = let nonskipped_txt,_ = MatitaGtkMisc.utf8_parsed_text unparsed_text floc in @@ -692,23 +653,32 @@ and eval_statement include_paths (buffer : GText.buffer) guistuff lexicon_status match st with | GrafiteParser.LNone loc -> let parsed_text, _, _, parsed_text_length = text_of_loc loc in - [(grafite_status,lexicon_status),parsed_text],"", + [grafite_status,parsed_text],"", parsed_text_length + | GrafiteParser.LSome (GrafiteAst.Executable (loc, ex)) -> + let _, nonskipped, skipped, parsed_text_length = text_of_loc loc in + eval_executable include_paths buffer guistuff + grafite_status user_goal unparsed_text skipped nonskipped script ex loc + | GrafiteParser.LSome (GrafiteAst.Comment (loc, GrafiteAst.Code (_, ex))) + (*when Helm_registry.get_bool "matita.literate" *) -> + let _, nonskipped, skipped, parsed_text_length = text_of_loc loc in + eval_executable include_paths buffer guistuff + grafite_status user_goal unparsed_text skipped nonskipped script ex loc | GrafiteParser.LSome (GrafiteAst.Comment (loc, _)) -> let parsed_text, _, _, parsed_text_length = text_of_loc loc in let remain_len = String.length unparsed_text - parsed_text_length in let s = String.sub unparsed_text parsed_text_length remain_len in let s,text,len = try - eval_statement include_paths buffer guistuff lexicon_status + eval_statement include_paths buffer guistuff grafite_status user_goal script (`Raw s) with HExtlib.Localized (floc, exn) -> HExtlib.raise_localized_exception ~offset:(MatitaGtkMisc.utf8_string_length parsed_text) floc exn - | GrafiteDisambiguator.DisambiguationError (offset,errorll) -> + | MultiPassDisambiguator.DisambiguationError (offset,errorll) -> raise - (GrafiteDisambiguator.DisambiguationError + (MultiPassDisambiguator.DisambiguationError (offset+parsed_text_length, errorll)) in assert (text=""); (* no macros inside comments, please! *) @@ -716,12 +686,6 @@ and eval_statement include_paths (buffer : GText.buffer) guistuff lexicon_status | (statuses,text)::tl -> (statuses,parsed_text ^ text)::tl,"",parsed_text_length + len | [] -> [], "", 0) - | GrafiteParser.LSome (GrafiteAst.Executable (loc, ex)) -> - let _, nonskipped, skipped, parsed_text_length = - text_of_loc loc - in - eval_executable include_paths buffer guistuff lexicon_status - grafite_status user_goal unparsed_text skipped nonskipped script ex loc let fresh_script_id = let i = ref 0 in @@ -732,52 +696,81 @@ class script ~(source_view: GSourceView.source_view) ~set_star ~ask_confirmation ~urichooser - ~develcreator () = let buffer = source_view#buffer in let source_buffer = source_view#source_buffer in -let initial_statuses () = - (* these include_paths are used only to load the initial notation *) - let include_paths = - Helm_registry.get_list Helm_registry.string "matita.includes" in +let initial_statuses baseuri = let lexicon_status = - CicNotation2.load_notation ~include_paths - BuildTimeConf.core_notation_script in - let grafite_status = GrafiteSync.init () in - grafite_status,lexicon_status + CicNotation2.load_notation ~include_paths:[] (new LexiconEngine.status) + BuildTimeConf.core_notation_script + in + let grafite_status = GrafiteSync.init lexicon_status baseuri in + grafite_status in +let read_include_paths file = + try + let root, _buri, _fname, _tgt = + Librarian.baseuri_of_script ~include_paths:[] file + in + let rc = + Str.split (Str.regexp " ") + (List.assoc "include_paths" (Librarian.load_root_file (root^"/root"))) + in + List.iter (HLog.debug) rc; rc + with Librarian.NoRootFor _ | Not_found -> [] +in +let default_buri = "cic:/matita/tests" in +let default_fname = ".unnamed.ma" in object (self) - val mutable include_paths = - Helm_registry.get_list Helm_registry.string "matita.includes" + val mutable include_paths_ = [] val scriptId = fresh_script_id () - + val guistuff = { mathviewer = mathviewer; urichooser = urichooser; ask_confirmation = ask_confirmation; - develcreator = develcreator; - filenamedata = (None, None)} - - method private getFilename = - match guistuff.filenamedata with Some f,_ -> f | _ -> assert false + } - method filename = self#getFilename - - method private ppFilename = - match guistuff.filenamedata with - | Some f,_ -> f - | None,_ -> sprintf ".unnamed%d.ma" scriptId + val mutable filename_ = (None : string option) + + method has_name = filename_ <> None + method include_paths = + include_paths_ @ + Helm_registry.get_list Helm_registry.string "matita.includes" + + method private curdir = + try + let root, _buri, _fname, _tgt = + Librarian.baseuri_of_script ~include_paths:self#include_paths + self#filename + in + root + with Librarian.NoRootFor _ -> Sys.getcwd () + + method buri_of_current_file = + match filename_ with + | None -> default_buri + | Some f -> + try + let _root, buri, _fname, _tgt = + Librarian.baseuri_of_script ~include_paths:self#include_paths f + in + buri + with Librarian.NoRootFor _ -> default_buri + + method filename = match filename_ with None -> default_fname | Some f -> f + initializer ignore (GMain.Timeout.add ~ms:300000 ~callback:(fun _ -> self#_saveToBackupFile ();true)); ignore (buffer#connect#modified_changed - (fun _ -> set_star (Filename.basename self#ppFilename) buffer#modified)) + (fun _ -> set_star buffer#modified)) val mutable statements = [] (** executed statements *) - val mutable history = [ initial_statuses () ] + val mutable history = [ initial_statuses default_buri ] (** list of states before having executed statements. Head element of this * list is the current state, last element is the state at the beginning of * the script. @@ -801,15 +794,15 @@ object (self) (* history can't be empty, the invariant above grant that it contains at * least the init grafite_status *) - method grafite_status = match history with (s,_)::_ -> s | _ -> assert false - method lexicon_status = match history with (_,ss)::_ -> ss | _ -> assert false + method grafite_status = match history with s::_ -> s | _ -> assert false method private _advance ?statement () = let s = match statement with Some s -> s | None -> self#getFuture in + if self#bos then LibraryClean.clean_baseuris [self#buri_of_current_file]; HLog.debug ("evaluating: " ^ first_line s ^ " ..."); let entries, newtext, parsed_len = try - eval_statement include_paths buffer guistuff self#lexicon_status + eval_statement self#include_paths buffer guistuff self#grafite_status userGoal self (`Raw s) with End_of_file -> raise Margin in @@ -835,20 +828,20 @@ object (self) buffer#insert ~iter:(buffer#get_iter_at_mark (`MARK locked_mark)) newtext; (* here we need to set the Goal in case we are going to cursor (or to bottom) and we will face a macro *) - match self#grafite_status.proof_status with + match self#grafite_status#proof_status with Incomplete_proof p -> userGoal <- (try Some (Continuationals.Stack.find_goal p.stack) with Failure _ -> None) | _ -> userGoal <- None - method private _retract offset lexicon_status grafite_status new_statements + method private _retract offset grafite_status new_statements new_history = - let cur_grafite_status,cur_lexicon_status = + let cur_grafite_status = match history with s::_ -> s | [] -> assert false in - LexiconSync.time_travel ~present:cur_lexicon_status ~past:lexicon_status; + LexiconSync.time_travel ~present:cur_grafite_status ~past:grafite_status; GrafiteSync.time_travel ~present:cur_grafite_status ~past:grafite_status; statements <- new_statements; history <- new_history; @@ -866,7 +859,7 @@ object (self) method retract () = try - let cmp,new_statements,new_history,(grafite_status,lexicon_status) = + let cmp,new_statements,new_history,grafite_status = match statements,history with stat::statements, _::(status::_ as history) -> assert (Glib.Utf8.validate stat); @@ -874,7 +867,7 @@ object (self) | [],[_] -> raise Margin | _,_ -> assert false in - self#_retract cmp lexicon_status grafite_status new_statements + self#_retract cmp grafite_status new_statements new_history; self#notify with @@ -883,9 +876,43 @@ object (self) | exc -> self#notify; raise exc method private getFuture = - buffer#get_text ~start:(buffer#get_iter_at_mark (`MARK locked_mark)) - ~stop:buffer#end_iter () + let lock = buffer#get_iter_at_mark (`MARK locked_mark) in + let text = buffer#get_text ~start:lock ~stop:buffer#end_iter () in + text + method expandAllVirtuals = + let lock = buffer#get_iter_at_mark (`MARK locked_mark) in + let text = buffer#get_text ~start:lock ~stop:buffer#end_iter () in + buffer#delete ~start:lock ~stop:buffer#end_iter; + let text = Pcre.replace ~pat:":=" ~templ:"\\def" text in + let text = Pcre.replace ~pat:"->" ~templ:"\\to" text in + let text = Pcre.replace ~pat:"=>" ~templ:"\\Rightarrow" text in + let text = + Pcre.substitute_substrings + ~subst:(fun str -> + let pristine = Pcre.get_substring str 0 in + let input = + if pristine.[0] = ' ' then + String.sub pristine 1 (String.length pristine -1) + else pristine + in + let input = + if input.[String.length input-1] = ' ' then + String.sub input 0 (String.length input -1) + else input + in + let before, after = + if input = "\\forall" || + input = "\\lambda" || + input = "\\exists" then "","" else " ", " " + in + try + before ^ Glib.Utf8.from_unichar + (snd (Virtuals.symbol_of_virtual input)) ^ after + with Virtuals.Not_a_virtual -> pristine) + ~pat:" ?\\\\[a-zA-Z]+ ?" text + in + buffer#insert ~iter:lock text (** @param rel_offset relative offset from current position of locked_mark *) method private moveMark rel_offset = @@ -917,13 +944,12 @@ object (self) val mutable observers = [] - method addObserver (o: LexiconEngine.status -> GrafiteTypes.status -> unit) = + method addObserver (o: GrafiteTypes.status -> unit) = observers <- o :: observers method private notify = - let lexicon_status = self#lexicon_status in let grafite_status = self#grafite_status in - List.iter (fun o -> o lexicon_status grafite_status) observers + List.iter (fun o -> o grafite_status) observers method loadFromString s = buffer#set_text s; @@ -934,32 +960,36 @@ object (self) buffer#set_text (HExtlib.input_file f); self#reset_buffer; buffer#set_modified false - + method assignFileName file = - let abspath = MatitaMisc.absolute_path file in - let dirname = Filename.dirname abspath in - let devel = MatitamakeLib.development_for_dir dirname in - guistuff.filenamedata <- Some abspath, devel; - let include_ = - match MatitamakeLib.development_for_dir dirname with - None -> [] - | Some devel -> [MatitamakeLib.root_for_development devel] in - let include_ = - include_ @ (Helm_registry.get_list Helm_registry.string "matita.includes") + let file = + match file with + | Some f -> Some (Librarian.absolutize f) + | None -> None in - include_paths <- include_ + self#goto_top; + filename_ <- file; + include_paths_ <- + (match file with Some file -> read_include_paths file | None -> []); + self#reset_buffer; + Sys.chdir self#curdir; + HLog.debug ("Moving to " ^ Sys.getcwd ()) method saveToFile () = - let oc = open_out self#getFilename in - output_string oc (buffer#get_text ~start:buffer#start_iter + if self#has_name then + let oc = open_out self#filename in + output_string oc (buffer#get_text ~start:buffer#start_iter ~stop:buffer#end_iter ()); - close_out oc; - buffer#set_modified false + close_out oc; + set_star false; + buffer#set_modified false + else + HLog.error "Can't save, no filename selected" method private _saveToBackupFile () = if buffer#modified then begin - let f = self#ppFilename ^ "~" in + let f = self#filename in let oc = open_out f in output_string oc (buffer#get_text ~start:buffer#start_iter ~stop:buffer#end_iter ()); @@ -968,21 +998,21 @@ object (self) end method private goto_top = - let grafite_status,lexicon_status = + let grafite_status = let rec last x = function | [] -> x | hd::tl -> last hd tl in - last (self#grafite_status,self#lexicon_status) history + last (self#grafite_status) history in (* FIXME: this is not correct since there is no undo for * library_objects.set_default... *) GrafiteSync.time_travel ~present:self#grafite_status ~past:grafite_status; - LexiconSync.time_travel ~present:self#lexicon_status ~past:lexicon_status + LexiconSync.time_travel ~present:self#grafite_status ~past:grafite_status method private reset_buffer = statements <- []; - history <- [ initial_statuses () ]; + history <- [ initial_statuses self#buri_of_current_file ]; userGoal <- None; self#notify; buffer#remove_tag locked_tag ~start:buffer#start_iter ~stop:buffer#end_iter; @@ -998,19 +1028,8 @@ object (self) method template () = let template = HExtlib.input_file BuildTimeConf.script_template in buffer#insert ~iter:(buffer#get_iter `START) template; - let development = MatitamakeLib.development_for_dir (Unix.getcwd ()) in - guistuff.filenamedata <- (None,development); - let include_ = - match development with - None -> [] - | Some devel -> [MatitamakeLib.root_for_development devel ] - in - let include_ = - include_ @ (Helm_registry.get_list Helm_registry.string "matita.includes") - in - include_paths <- include_ ; - buffer#set_modified false; - set_star (Filename.basename self#ppFilename) false + buffer#set_modified false; + set_star false method goto (pos: [`Top | `Bottom | `Cursor]) () = try @@ -1070,9 +1089,9 @@ object (self) in let rec back_until_cursor len = (* go backward until locked < cursor *) function - statements, ((grafite_status,lexicon_status)::_ as history) + statements, ((grafite_status)::_ as history) when len <= 0 -> - self#_retract (icmp - len) lexicon_status grafite_status statements + self#_retract (icmp - len) grafite_status statements history | statement::tl1, _::tl2 -> back_until_cursor (len - MatitaGtkMisc.utf8_string_length statement) (tl1,tl2) @@ -1097,7 +1116,7 @@ object (self) HLog.error "The script is too big!\n" method onGoingProof () = - match self#grafite_status.proof_status with + match self#grafite_status#proof_status with | No_proof | Proof _ -> false | Incomplete_proof _ -> true | Intermediate _ -> assert false @@ -1120,27 +1139,30 @@ object (self) method setGoal n = userGoal <- n method goal = userGoal + method bos = + match history with + | _::[] -> true + | _ -> false + method eos = let rec is_there_only_comments lexicon_status s = if Pcre.pmatch ~rex:only_dust_RE s then raise Margin; let lexicon_status,st = GrafiteParser.parse_statement (Ulexing.from_utf8_string s) - ~include_paths lexicon_status + ~include_paths:self#include_paths lexicon_status in match st with | GrafiteParser.LSome (GrafiteAst.Comment (loc,_)) -> let _,parsed_text_length = MatitaGtkMisc.utf8_parsed_text s loc in (* CSC: why +1 in the following lines ???? *) let parsed_text_length = parsed_text_length + 1 in -prerr_endline ("## " ^ string_of_int parsed_text_length); let remain_len = String.length s - parsed_text_length in let next = String.sub s parsed_text_length remain_len in is_there_only_comments lexicon_status next | GrafiteParser.LNone _ | GrafiteParser.LSome (GrafiteAst.Executable _) -> false in - try - is_there_only_comments self#lexicon_status self#getFuture + try is_there_only_comments self#grafite_status self#getFuture with | LexiconEngine.IncludedFileNotCompiled _ | HExtlib.Localized _ @@ -1154,19 +1176,15 @@ prerr_endline ("## " ^ string_of_int parsed_text_length); HLog.debug ("history size: " ^ string_of_int (List.length history)); HLog.debug (sprintf "%d statements:" (List.length statements)); List.iter HLog.debug statements; - HLog.debug ("Current file name: " ^ - (match guistuff.filenamedata with - |None,_ -> "[ no name ]" - | Some f,_ -> f)); - + HLog.debug ("Current file name: " ^ self#filename); end let _script = ref None -let script ~source_view ~mathviewer ~urichooser ~develcreator ~ask_confirmation ~set_star () +let script ~source_view ~mathviewer ~urichooser ~ask_confirmation ~set_star () = let s = new script - ~source_view ~mathviewer ~ask_confirmation ~urichooser ~develcreator ~set_star () + ~source_view ~mathviewer ~ask_confirmation ~urichooser ~set_star () in _script := Some s; s