]> matita.cs.unibo.it Git - helm.git/blob - matita/components/grafite_engine/grafiteEngine.ml
cic_unification removed
[helm.git] / matita / components / grafite_engine / grafiteEngine.ml
1 (* Copyright (C) 2005, HELM Team.
2  * 
3  * This file is part of HELM, an Hypertextual, Electronic
4  * Library of Mathematics, developed at the Computer Science
5  * Department, University of Bologna, Italy.
6  * 
7  * HELM is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * 
12  * HELM is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with HELM; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://helm.cs.unibo.it/
24  *)
25
26 (* $Id$ *)
27
28 exception Drop
29 (* mo file name, ma file name *)
30 exception IncludedFileNotCompiled of string * string 
31 exception Macro of
32  GrafiteAst.loc *
33   (Cic.context -> GrafiteTypes.status * (Cic.term,Cic.lazy_term) GrafiteAst.macro)
34 exception NMacro of GrafiteAst.loc * GrafiteAst.nmacro
35
36 type 'a disambiguator_input = string * int * 'a
37
38 type options = { 
39   do_heavy_checks: bool ; 
40 }
41
42 let concat_nuris uris nuris =
43    match uris,nuris with
44    | `New uris, `New nuris -> `New (nuris@uris)
45    | _ -> assert false
46 ;;
47 (** create a ProofEngineTypes.mk_fresh_name_type function which uses given
48   * names as long as they are available, then it fallbacks to name generation
49   * using FreshNamesGenerator module *)
50 let namer_of names =
51   let len = List.length names in
52   let count = ref 0 in
53   fun metasenv context name ~typ ->
54     if !count < len then begin
55       let name = match List.nth names !count with
56          | Some s -> Cic.Name s
57          | None   -> Cic.Anonymous
58       in
59       incr count;
60       name
61     end else
62       FreshNamesGenerator.mk_fresh_name ~subst:[] metasenv context name ~typ
63
64 type eval_ast =
65  {ea_go:
66   'term 'lazy_term 'reduction 'obj 'ident.
67
68   disambiguate_command:
69    (GrafiteTypes.status ->
70     (('term,'obj) GrafiteAst.command) disambiguator_input ->
71     GrafiteTypes.status * (Cic.term,Cic.obj) GrafiteAst.command) ->
72
73   disambiguate_macro:
74    (GrafiteTypes.status ->
75     (('term,'lazy_term) GrafiteAst.macro) disambiguator_input ->
76     Cic.context -> GrafiteTypes.status * (Cic.term,Cic.lazy_term) GrafiteAst.macro) ->
77
78   ?do_heavy_checks:bool ->
79   GrafiteTypes.status ->
80   (('term, 'lazy_term, 'reduction, 'obj, 'ident) GrafiteAst.statement)
81   disambiguator_input ->
82   GrafiteTypes.status * [`Old of UriManager.uri list | `New of NUri.uri list]
83  }
84
85 type 'a eval_command =
86  {ec_go: 'term 'obj.
87   disambiguate_command:
88    (GrafiteTypes.status -> (('term,'obj) GrafiteAst.command) disambiguator_input ->
89     GrafiteTypes.status * (Cic.term,Cic.obj) GrafiteAst.command) -> 
90   options -> GrafiteTypes.status -> 
91     (('term,'obj) GrafiteAst.command) disambiguator_input ->
92    GrafiteTypes.status * [`Old of UriManager.uri list | `New of NUri.uri list]
93  }
94
95 type 'a eval_comment =
96  {ecm_go: 'term 'lazy_term 'reduction_kind 'obj 'ident.
97   disambiguate_command:
98    (GrafiteTypes.status -> (('term,'obj) GrafiteAst.command) disambiguator_input ->
99     GrafiteTypes.status * (Cic.term,Cic.obj) GrafiteAst.command) -> 
100   options -> GrafiteTypes.status -> 
101     (('term,'lazy_term,'reduction_kind,'obj,'ident) GrafiteAst.comment) disambiguator_input ->
102    GrafiteTypes.status * [`Old of UriManager.uri list | `New of NUri.uri list]
103  }
104
105 type 'a eval_executable =
106  {ee_go: 'term 'lazy_term 'reduction 'obj 'ident.
107
108   disambiguate_command:
109    (GrafiteTypes.status ->
110     (('term,'obj) GrafiteAst.command) disambiguator_input ->
111     GrafiteTypes.status * (Cic.term,Cic.obj) GrafiteAst.command) ->
112
113   disambiguate_macro:
114    (GrafiteTypes.status ->
115     (('term,'lazy_term) GrafiteAst.macro) disambiguator_input ->
116     Cic.context -> GrafiteTypes.status * (Cic.term,Cic.lazy_term) GrafiteAst.macro) ->
117
118   options ->
119   GrafiteTypes.status ->
120   (('term, 'lazy_term, 'reduction, 'obj, 'ident) GrafiteAst.code) disambiguator_input ->
121   GrafiteTypes.status * [`Old of UriManager.uri list | `New of NUri.uri list]
122  }
123
124 type 'a eval_from_moo =
125  { efm_go: GrafiteTypes.status -> string -> GrafiteTypes.status }
126       
127 let coercion_moo_statement_of (uri,arity, saturations,_) =
128   GrafiteAst.Coercion
129    (HExtlib.dummy_floc, CicUtil.term_of_uri uri, false, arity, saturations)
130
131 let basic_eval_unification_hint (t,n) status =
132  NCicUnifHint.add_user_provided_hint status t n
133 ;;
134
135 let inject_unification_hint =
136  let basic_eval_unification_hint (t,n) 
137    ~refresh_uri_in_universe 
138    ~refresh_uri_in_term
139  =
140   let t = refresh_uri_in_term t in basic_eval_unification_hint (t,n)
141  in
142   NCicLibrary.Serializer.register#run "unification_hints"
143    object(_ : 'a NCicLibrary.register_type)
144      method run = basic_eval_unification_hint
145    end
146 ;;
147
148 let eval_unification_hint status t n = 
149  let metasenv,subst,status,t =
150   GrafiteDisambiguate.disambiguate_nterm None status [] [] [] ("",0,t) in
151  assert (metasenv=[]);
152  let t = NCicUntrusted.apply_subst subst [] t in
153  let status = basic_eval_unification_hint (t,n) status in
154  let dump = inject_unification_hint (t,n)::status#dump in
155  let status = status#set_dump dump in
156   status,`New []
157 ;;
158
159 let basic_index_obj l status =
160   status#set_auto_cache 
161     (List.fold_left
162       (fun t (ks,v) -> 
163          List.fold_left (fun t k ->
164            NDiscriminationTree.DiscriminationTree.index t k v)
165           t ks) 
166     status#auto_cache l) 
167 ;;     
168
169 let record_index_obj = 
170  let aux l 
171    ~refresh_uri_in_universe 
172    ~refresh_uri_in_term
173  =
174     basic_index_obj
175       (List.map 
176         (fun ks,v -> List.map refresh_uri_in_term ks, refresh_uri_in_term v) 
177       l)
178  in
179   NCicLibrary.Serializer.register#run "index_obj"
180    object(_ : 'a NCicLibrary.register_type)
181      method run = aux
182    end
183 ;;
184
185 let compute_keys status uri height kind = 
186  let mk_item ty spec =
187    let orig_ty = NTacStatus.mk_cic_term [] ty in
188    let status,keys = NnAuto.keys_of_type status orig_ty in
189    let keys =  
190      List.map 
191        (fun t -> 
192           snd (NTacStatus.term_of_cic_term status t (NTacStatus.ctx_of t)))
193        keys
194    in
195    keys,NCic.Const(NReference.reference_of_spec uri spec)
196  in
197  let data = 
198   match kind with
199   | NCic.Fixpoint (ind,ifl,_) -> 
200      HExtlib.list_mapi 
201        (fun (_,_,rno,ty,_) i -> 
202           if ind then mk_item ty (NReference.Fix (i,rno,height)) 
203           else mk_item ty (NReference.CoFix height)) ifl
204   | NCic.Inductive (b,lno,itl,_) -> 
205      HExtlib.list_mapi 
206        (fun (_,_,ty,_) i -> mk_item ty (NReference.Ind (b,i,lno))) itl 
207      @
208      List.map (fun ((_,_,ty),i,j) -> mk_item ty (NReference.Con (i,j+1,lno)))
209        (List.flatten (HExtlib.list_mapi 
210          (fun (_,_,_,cl) i -> HExtlib.list_mapi (fun x j-> x,i,j) cl)
211          itl))
212   | NCic.Constant (_,_,Some _, ty, _) -> 
213      [ mk_item ty (NReference.Def height) ]
214   | NCic.Constant (_,_,None, ty, _) ->
215      [ mk_item ty NReference.Decl ]
216  in
217   HExtlib.filter_map
218    (fun (keys, t) ->
219      let keys = List.filter
220        (function 
221          | (NCic.Meta _) 
222          | (NCic.Appl (NCic.Meta _::_)) -> false 
223          | _ -> true) 
224        keys
225      in
226      if keys <> [] then 
227       begin
228         HLog.debug ("Indexing:" ^ 
229           NCicPp.ppterm ~metasenv:[] ~subst:[] ~context:[] t);
230         HLog.debug ("With keys:" ^ String.concat "\n" (List.map (fun t ->
231           NCicPp.ppterm ~metasenv:[] ~subst:[] ~context:[] t) keys));
232         Some (keys,t) 
233       end
234      else 
235       begin
236         HLog.debug ("Not indexing:" ^ 
237           NCicPp.ppterm ~metasenv:[] ~subst:[] ~context:[] t);
238         None
239       end)
240     data
241 ;;
242
243 let index_obj_for_auto status (uri, height, _, _, kind) = 
244  (*prerr_endline (string_of_int height);*)
245   let data = compute_keys status uri height kind in
246   let status = basic_index_obj data status in
247   let dump = record_index_obj data :: status#dump in   
248   status#set_dump dump
249 ;; 
250
251 let index_eq uri status =
252   let eq_status = status#eq_cache in
253   let eq_status1 = NCicParamod.index_obj eq_status uri in
254     status#set_eq_cache eq_status1
255 ;;
256
257 let record_index_eq =
258  let basic_index_eq uri
259    ~refresh_uri_in_universe 
260    ~refresh_uri_in_term 
261    = index_eq (NCicLibrary.refresh_uri uri) 
262  in
263   NCicLibrary.Serializer.register#run "index_eq"
264    object(_ : 'a NCicLibrary.register_type)
265      method run = basic_index_eq
266    end
267 ;;
268
269 let index_eq_for_auto status uri =
270  if NnAuto.is_a_fact_obj status uri then
271    let newstatus = index_eq uri status in
272      if newstatus#eq_cache == status#eq_cache then status 
273      else
274        ((*prerr_endline ("recording " ^ (NUri.string_of_uri uri));*)
275         let dump = record_index_eq uri :: newstatus#dump 
276         in newstatus#set_dump dump)
277  else 
278    ((*prerr_endline "Not a fact";*)
279    status)
280 ;; 
281
282 let basic_eval_add_constraint (u1,u2) status =
283  NCicLibrary.add_constraint status u1 u2
284 ;;
285
286 let inject_constraint =
287  let basic_eval_add_constraint (u1,u2) 
288        ~refresh_uri_in_universe 
289        ~refresh_uri_in_term
290  =
291   let u1 = refresh_uri_in_universe u1 in 
292   let u2 = refresh_uri_in_universe u2 in 
293   basic_eval_add_constraint (u1,u2)
294  in
295   NCicLibrary.Serializer.register#run "constraints"
296    object(_:'a NCicLibrary.register_type)
297      method run = basic_eval_add_constraint 
298    end
299 ;;
300
301 let eval_add_constraint status u1 u2 = 
302  let status = basic_eval_add_constraint (u1,u2) status in
303  let dump = inject_constraint (u1,u2)::status#dump in
304  let status = status#set_dump dump in
305   status,`Old []
306 ;;
307
308 let add_coercions_of_lemmas lemmas status =
309   let moo_content = 
310     HExtlib.filter_map 
311       (fun uri ->
312         match CoercDb.is_a_coercion (Cic.Const (uri,[])) with
313         | None -> None
314         | Some (_,tgt,_,sat,_) ->
315             let arity = match tgt with CoercDb.Fun n -> n | _ -> 0 in
316             Some (coercion_moo_statement_of (uri,arity,sat,0)))
317       lemmas
318   in
319   let status = GrafiteTypes.add_moo_content moo_content status in 
320    status#set_coercions (CoercDb.dump ()), 
321   lemmas
322
323 let eval_ng_punct (_text, _prefix_len, punct) =
324   match punct with
325   | GrafiteAst.Dot _ -> NTactics.dot_tac 
326   | GrafiteAst.Semicolon _ -> fun x -> x
327   | GrafiteAst.Branch _ -> NTactics.branch_tac ~force:false
328   | GrafiteAst.Shift _ -> NTactics.shift_tac 
329   | GrafiteAst.Pos (_,l) -> NTactics.pos_tac l
330   | GrafiteAst.Wildcard _ -> NTactics.wildcard_tac 
331   | GrafiteAst.Merge _ -> NTactics.merge_tac 
332 ;;
333
334 let eval_ng_tac tac =
335  let rec aux f (text, prefix_len, tac) =
336   match tac with
337   | GrafiteAst.NApply (_loc, t) -> NTactics.apply_tac (text,prefix_len,t) 
338   | GrafiteAst.NSmartApply (_loc, t) -> 
339       NnAuto.smart_apply_tac (text,prefix_len,t) 
340   | GrafiteAst.NAssert (_loc, seqs) ->
341      NTactics.assert_tac
342       ((List.map
343         (function (hyps,concl) ->
344           List.map
345            (function
346               (id,`Decl t) -> id,`Decl (text,prefix_len,t)
347              |(id,`Def (b,t))->id,`Def((text,prefix_len,b),(text,prefix_len,t))
348            ) hyps,
349           (text,prefix_len,concl))
350        ) seqs)
351   | GrafiteAst.NAuto (_loc, (None,a)) -> 
352       NnAuto.auto_tac ~params:(None,a) ?trace_ref:None
353   | GrafiteAst.NAuto (_loc, (Some l,a)) ->
354       NnAuto.auto_tac
355         ~params:(Some List.map (fun x -> "",0,x) l,a) ?trace_ref:None
356   | GrafiteAst.NBranch _ -> NTactics.branch_tac ~force:false
357   | GrafiteAst.NCases (_loc, what, where) ->
358       NTactics.cases_tac 
359         ~what:(text,prefix_len,what)
360         ~where:(text,prefix_len,where)
361   | GrafiteAst.NCase1 (_loc,n) -> NTactics.case1_tac n
362   | GrafiteAst.NChange (_loc, pat, ww) -> 
363       NTactics.change_tac 
364        ~where:(text,prefix_len,pat) ~with_what:(text,prefix_len,ww) 
365   | GrafiteAst.NConstructor (_loc,num,args) -> 
366      NTactics.constructor_tac 
367        ?num ~args:(List.map (fun x -> text,prefix_len,x) args)
368   | GrafiteAst.NCut (_loc, t) -> NTactics.cut_tac (text,prefix_len,t) 
369 (*| GrafiteAst.NDiscriminate (_,what) -> NDestructTac.discriminate_tac ~what:(text,prefix_len,what)
370   | GrafiteAst.NSubst (_,what) -> NDestructTac.subst_tac ~what:(text,prefix_len,what)*)
371   | GrafiteAst.NDestruct (_,dom,skip) -> NDestructTac.destruct_tac dom skip
372   | GrafiteAst.NDot _ -> NTactics.dot_tac 
373   | GrafiteAst.NElim (_loc, what, where) ->
374       NTactics.elim_tac 
375         ~what:(text,prefix_len,what)
376         ~where:(text,prefix_len,where)
377   | GrafiteAst.NFocus (_,l) -> NTactics.focus_tac l
378   | GrafiteAst.NGeneralize (_loc, where) -> 
379       NTactics.generalize_tac ~where:(text,prefix_len,where)
380   | GrafiteAst.NId _ -> (fun x -> x)
381   | GrafiteAst.NIntro (_loc,n) -> NTactics.intro_tac n
382   | GrafiteAst.NIntros (_loc,ns) -> NTactics.intros_tac ns
383   | GrafiteAst.NInversion (_loc, what, where) ->
384       NTactics.inversion_tac 
385         ~what:(text,prefix_len,what)
386         ~where:(text,prefix_len,where)
387   | GrafiteAst.NLApply (_loc, t) -> NTactics.lapply_tac (text,prefix_len,t) 
388   | GrafiteAst.NLetIn (_loc,where,what,name) ->
389       NTactics.letin_tac ~where:(text,prefix_len,where) 
390         ~what:(text,prefix_len,what) name
391   | GrafiteAst.NMerge _ -> NTactics.merge_tac 
392   | GrafiteAst.NPos (_,l) -> NTactics.pos_tac l
393   | GrafiteAst.NPosbyname (_,s) -> NTactics.case_tac s
394   | GrafiteAst.NReduce (_loc, reduction, where) ->
395       NTactics.reduce_tac ~reduction ~where:(text,prefix_len,where)
396   | GrafiteAst.NRewrite (_loc,dir,what,where) ->
397      NTactics.rewrite_tac ~dir ~what:(text,prefix_len,what)
398       ~where:(text,prefix_len,where)
399   | GrafiteAst.NSemicolon _ -> fun x -> x
400   | GrafiteAst.NShift _ -> NTactics.shift_tac 
401   | GrafiteAst.NSkip _ -> NTactics.skip_tac
402   | GrafiteAst.NUnfocus _ -> NTactics.unfocus_tac
403   | GrafiteAst.NWildcard _ -> NTactics.wildcard_tac 
404   | GrafiteAst.NTry (_,tac) -> NTactics.try_tac
405       (aux f (text, prefix_len, tac))
406   | GrafiteAst.NAssumption _ -> NTactics.assumption_tac
407   | GrafiteAst.NBlock (_,l) -> 
408       NTactics.block_tac (List.map (fun x -> aux f (text,prefix_len,x)) l)
409   |GrafiteAst.NRepeat (_,tac) ->
410       NTactics.repeat_tac (f f (text, prefix_len, tac))
411  in
412   aux aux tac (* trick for non uniform recursion call *)
413 ;;
414       
415 let subst_metasenv_and_fix_names status =
416   let u,h,metasenv, subst,o = status#obj in
417   let o = 
418     NCicUntrusted.map_obj_kind ~skip_body:true 
419      (NCicUntrusted.apply_subst subst []) o
420   in
421    status#set_obj(u,h,NCicUntrusted.apply_subst_metasenv subst metasenv,subst,o)
422 ;;
423
424
425 let rec eval_ncommand opts status (text,prefix_len,cmd) =
426   match cmd with
427   | GrafiteAst.UnificationHint (loc, t, n) -> eval_unification_hint status t n
428   | GrafiteAst.NCoercion (loc, name, t, ty, source, target) ->
429       NCicCoercDeclaration.eval_ncoercion status name t ty source target
430   | GrafiteAst.NQed loc ->
431      if status#ng_mode <> `ProofMode then
432       raise (GrafiteTypes.Command_error "Not in proof mode")
433      else
434       let uri,height,menv,subst,obj_kind = status#obj in
435        if menv <> [] then
436         raise
437          (GrafiteTypes.Command_error"You can't Qed an incomplete theorem")
438        else
439         let obj_kind =
440          NCicUntrusted.map_obj_kind 
441           (NCicUntrusted.apply_subst subst []) obj_kind in
442         let height = NCicTypeChecker.height_of_obj_kind uri [] obj_kind in
443         (* fix the height inside the object *)
444         let rec fix () = function 
445           | NCic.Const (NReference.Ref (u,spec)) when NUri.eq u uri -> 
446              NCic.Const (NReference.reference_of_spec u
447               (match spec with
448               | NReference.Def _ -> NReference.Def height
449               | NReference.Fix (i,j,_) -> NReference.Fix(i,j,height)
450               | NReference.CoFix _ -> NReference.CoFix height
451               | NReference.Ind _ | NReference.Con _
452               | NReference.Decl as s -> s))
453           | t -> NCicUtils.map (fun _ () -> ()) () fix t
454         in
455         let obj_kind = 
456           match obj_kind with
457           | NCic.Fixpoint _ -> 
458               NCicUntrusted.map_obj_kind (fix ()) obj_kind 
459           | _ -> obj_kind
460         in
461         let obj = uri,height,[],[],obj_kind in
462         prerr_endline ("pp new obj \n"^NCicPp.ppobj obj);
463         let old_status = status in
464         let status = NCicLibrary.add_obj status obj in
465         let index_obj =
466          match obj_kind with
467             NCic.Constant (_,_,_,_,(_,`Example,_))
468           | NCic.Fixpoint (_,_,(_,`Example,_)) -> false
469           | _ -> true
470         in
471         let status =
472          if index_obj then
473           let status = index_obj_for_auto status obj in
474            (try index_eq_for_auto status uri
475            with _ -> status)
476          else
477           status in
478 (*
479           try 
480             index_eq uri status
481           with _ -> prerr_endline "got an exception"; status
482         in *)
483 (*         prerr_endline (NCicPp.ppobj obj); *)
484         HLog.message ("New object: " ^ NUri.string_of_uri uri);
485          (try
486        (*prerr_endline (NCicPp.ppobj obj);*)
487            let boxml = NCicElim.mk_elims obj in
488            let boxml = boxml @ NCicElim.mk_projections obj in
489 (*
490            let objs = [] in
491            let timestamp,uris_rev =
492              List.fold_left
493               (fun (status,uris_rev) (uri,_,_,_,_) as obj ->
494                 let status = NCicLibrary.add_obj status obj in
495                  status,uri::uris_rev
496               ) (status,[]) objs in
497            let uris = uri::List.rev uris_rev in
498 *)
499            let status = status#set_ng_mode `CommandMode in
500            let status = LexiconSync.add_aliases_for_objs status (`New [uri]) in
501            let status,uris =
502             List.fold_left
503              (fun (status,uris) boxml ->
504                try
505                 let nstatus,nuris =
506                  eval_ncommand opts status
507                   ("",0,GrafiteAst.NObj (HExtlib.dummy_floc,boxml))
508                 in
509                 if nstatus#ng_mode <> `CommandMode then
510                   begin
511                     (*HLog.warn "error in generating projection/eliminator";*)
512                     status, uris
513                   end
514                 else
515                   nstatus, concat_nuris uris nuris
516                with
517                | MultiPassDisambiguator.DisambiguationError _
518                | NCicTypeChecker.TypeCheckerFailure _ ->
519                   (*HLog.warn "error in generating projection/eliminator";*)
520                   status,uris
521              ) (status,`New [] (* uris *)) boxml in             
522            let _,_,_,_,nobj = obj in 
523            let status = match nobj with
524                NCic.Inductive (is_ind,leftno,[it],_) ->
525                  let _,ind_name,ty,cl = it in
526                  List.fold_left 
527                    (fun status outsort ->
528                       let status = status#set_ng_mode `ProofMode in
529                       try
530                        (let status,invobj =
531                          NInversion.mk_inverter 
532                           (ind_name ^ "_inv_" ^
533                             (snd (NCicElim.ast_of_sort outsort)))
534                           is_ind it leftno outsort status status#baseuri in
535                        let _,_,menv,_,_ = invobj in
536                        fst (match menv with
537                              [] -> eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
538                            | _ -> status,`New []))
539                        (* XXX *)
540                       with _ -> (*HLog.warn "error in generating inversion principle"; *)
541                                 let status = status#set_ng_mode `CommandMode in status)
542                   status
543                   (NCic.Prop::
544                     List.map (fun s -> NCic.Type s) (NCicEnvironment.get_universes ()))
545               | _ -> status
546            in
547            let coercions =
548             match obj with
549               _,_,_,_,NCic.Inductive
550                (true,leftno,[_,_,_,[_,_,_]],(_,`Record fields))
551                ->
552                 HExtlib.filter_map
553                  (fun (name,is_coercion,arity) ->
554                    if is_coercion then Some(name,leftno,arity) else None) fields
555             | _ -> [] in
556            let status,uris =
557             List.fold_left
558              (fun (status,uris) (name,cpos,arity) ->
559                try
560                  let metasenv,subst,status,t =
561                   GrafiteDisambiguate.disambiguate_nterm None status [] [] []
562                    ("",0,CicNotationPt.Ident (name,None)) in
563                  assert (metasenv = [] && subst = []);
564                  let status, nuris = 
565                    NCicCoercDeclaration.
566                      basic_eval_and_record_ncoercion_from_t_cpos_arity 
567                       status (name,t,cpos,arity)
568                  in
569                  let uris = concat_nuris nuris uris in
570                  status, uris
571                with MultiPassDisambiguator.DisambiguationError _-> 
572                  HLog.warn ("error in generating coercion: "^name);
573                  status, uris) 
574              (status,uris) coercions
575            in
576             status,uris
577           with
578            exn ->
579             NCicLibrary.time_travel old_status;
580             raise exn)
581   | GrafiteAst.NCopy (log,tgt,src_uri, map) ->
582      if status#ng_mode <> `CommandMode then
583       raise (GrafiteTypes.Command_error "Not in command mode")
584      else
585        let tgt_uri_ext, old_ok = 
586          match NCicEnvironment.get_checked_obj src_uri with
587          | _,_,[],[], (NCic.Inductive _ as ok) -> ".ind", ok
588          | _,_,[],[], (NCic.Fixpoint _ as ok) -> ".con", ok
589          | _,_,[],[], (NCic.Constant _ as ok) -> ".con", ok
590          | _ -> assert false
591        in
592        let tgt_uri = NUri.uri_of_string (status#baseuri^"/"^tgt^tgt_uri_ext) in
593        let map = (src_uri, tgt_uri) :: map in
594        let ok = 
595          let rec subst () = function
596            | NCic.Meta _ -> assert false
597            | NCic.Const (NReference.Ref (u,spec)) as t ->
598                (try NCic.Const 
599                  (NReference.reference_of_spec (List.assoc u map)spec)
600                with Not_found -> t)
601            | t -> NCicUtils.map (fun _ _ -> ()) () subst t
602          in
603          NCicUntrusted.map_obj_kind ~skip_body:false (subst ()) old_ok
604        in
605        let ninitial_stack = Continuationals.Stack.of_nmetasenv [] in
606        let status = status#set_obj (tgt_uri,0,[],[],ok) in
607        (*prerr_endline (NCicPp.ppobj (tgt_uri,0,[],[],ok));*)
608        let status = status#set_stack ninitial_stack in
609        let status = subst_metasenv_and_fix_names status in
610        let status = status#set_ng_mode `ProofMode in
611        eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
612   | GrafiteAst.NObj (loc,obj) ->
613      if status#ng_mode <> `CommandMode then
614       raise (GrafiteTypes.Command_error "Not in command mode")
615      else
616       let status,obj =
617        GrafiteDisambiguate.disambiguate_nobj status
618         ~baseuri:status#baseuri (text,prefix_len,obj) in
619       let uri,height,nmenv,nsubst,nobj = obj in
620       let ninitial_stack = Continuationals.Stack.of_nmetasenv nmenv in
621       let status = status#set_obj obj in
622       let status = status#set_stack ninitial_stack in
623       let status = subst_metasenv_and_fix_names status in
624       let status = status#set_ng_mode `ProofMode in
625       (match nmenv with
626           [] ->
627            eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
628         | _ -> status,`New [])
629   | GrafiteAst.NDiscriminator (_,_) -> assert false (*(loc, indty) ->
630       if status#ng_mode <> `CommandMode then
631         raise (GrafiteTypes.Command_error "Not in command mode")
632       else
633         let status = status#set_ng_mode `ProofMode in
634         let metasenv,subst,status,indty =
635           GrafiteDisambiguate.disambiguate_nterm None status [] [] [] (text,prefix_len,indty) in
636         let indtyno, (_,_,tys,_,_) = match indty with
637             NCic.Const ((NReference.Ref (_,NReference.Ind (_,indtyno,_))) as r) ->
638               indtyno, NCicEnvironment.get_checked_indtys r
639           | _ -> prerr_endline ("engine: indty expected... (fix this error message)"); assert false in
640         let it = List.nth tys indtyno in
641         let status,obj =  NDestructTac.mk_discriminator it status in
642         let _,_,menv,_,_ = obj in
643           (match menv with
644                [] -> eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
645              | _ -> prerr_endline ("Discriminator: non empty metasenv");
646                     status, `New []) *)
647   | GrafiteAst.NInverter (loc, name, indty, selection, sort) ->
648      if status#ng_mode <> `CommandMode then
649       raise (GrafiteTypes.Command_error "Not in command mode")
650      else
651       let metasenv,subst,status,sort = match sort with
652         | None -> [],[],status,NCic.Sort NCic.Prop
653         | Some s -> GrafiteDisambiguate.disambiguate_nterm None status [] [] []
654                       (text,prefix_len,s) 
655       in
656       assert (metasenv = []);
657       let sort = NCicReduction.whd ~subst [] sort in
658       let sort = match sort with 
659           NCic.Sort s -> s
660         | _ ->  raise (Invalid_argument (Printf.sprintf "ninverter: found target %s, which is not a sort" 
661                                            (NCicPp.ppterm ~metasenv ~subst ~context:[] sort)))
662       in
663       let status = status#set_ng_mode `ProofMode in
664       let metasenv,subst,status,indty =
665        GrafiteDisambiguate.disambiguate_nterm None status [] [] subst (text,prefix_len,indty) in
666       let indtyno,(_,leftno,tys,_,_) = match indty with
667           NCic.Const ((NReference.Ref (_,NReference.Ind (_,indtyno,_))) as r) -> 
668             indtyno, NCicEnvironment.get_checked_indtys r
669         | _ -> prerr_endline ("engine: indty ="  ^ NCicPp.ppterm ~metasenv:[] ~subst:[] ~context:[] indty) ; assert false in
670       let it = List.nth tys indtyno in
671      let status,obj = NInversion.mk_inverter name true it leftno ?selection sort 
672                         status status#baseuri in
673      let _,_,menv,_,_ = obj in
674      (match menv with
675         [] ->
676           eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
677       | _ -> assert false)
678   | GrafiteAst.NUnivConstraint (loc,u1,u2) ->
679       eval_add_constraint status [`Type,u1] [`Type,u2]
680 ;;
681
682 let rec eval_command = {ec_go = fun ~disambiguate_command opts status
683 (text,prefix_len,cmd) ->
684  let status,cmd = disambiguate_command status (text,prefix_len,cmd) in
685  let status,uris =
686   match cmd with
687   | GrafiteAst.Default (loc, what, uris) as cmd ->
688      LibraryObjects.set_default what uris;
689      GrafiteTypes.add_moo_content [cmd] status,`Old []
690   | GrafiteAst.Drop loc -> raise Drop
691   | GrafiteAst.Include (loc, mode, new_or_old, baseuri) ->
692      (* Old Include command is not recursive; new one is *)
693      let status =
694       if new_or_old = `OldAndNew then
695        let moopath_rw, moopath_r = 
696         LibraryMisc.obj_file_of_baseuri 
697           ~must_exist:false ~baseuri ~writable:true,
698         LibraryMisc.obj_file_of_baseuri 
699           ~must_exist:false ~baseuri ~writable:false in
700        let moopath = 
701         if Sys.file_exists moopath_r then moopath_r else
702           if Sys.file_exists moopath_rw then moopath_rw else
703             raise (IncludedFileNotCompiled (moopath_rw,baseuri))
704        in
705         eval_from_moo.efm_go status moopath
706       else
707        status
708      in
709       let status =
710        NCicLibrary.Serializer.require ~baseuri:(NUri.uri_of_string baseuri)
711         status in
712       let status =
713        GrafiteTypes.add_moo_content
714         [GrafiteAst.Include (loc,mode,`New,baseuri)] status
715       in
716        status,`Old []
717   | GrafiteAst.Print (_,_) -> status,`Old []
718   | GrafiteAst.Set (loc, name, value) -> status, `Old []
719 (*       GrafiteTypes.set_option status name value,[] *)
720   | GrafiteAst.Obj (loc,obj) -> (* MATITA 1.0 *) assert false
721  in
722   status,uris
723
724 } and eval_executable = {ee_go = fun ~disambiguate_command
725 ~disambiguate_macro opts status (text,prefix_len,ex) ->
726   match ex with
727   | GrafiteAst.NTactic (_(*loc*), tacl) ->
728       if status#ng_mode <> `ProofMode then
729        raise (GrafiteTypes.Command_error "Not in proof mode")
730       else
731        let status =
732         List.fold_left 
733           (fun status tac ->
734             let status = eval_ng_tac (text,prefix_len,tac) status in
735             subst_metasenv_and_fix_names status)
736           status tacl
737        in
738         status,`New []
739   | GrafiteAst.Command (_, cmd) ->
740       eval_command.ec_go ~disambiguate_command opts status (text,prefix_len,cmd)
741   | GrafiteAst.NCommand (_, cmd) ->
742       eval_ncommand opts status (text,prefix_len,cmd)
743   | GrafiteAst.Macro (loc, macro) ->
744      raise (Macro (loc,disambiguate_macro status (text,prefix_len,macro)))
745   | GrafiteAst.NMacro (loc, macro) ->
746      raise (NMacro (loc,macro))
747
748 } and eval_from_moo = {efm_go = fun status fname ->
749   let ast_of_cmd cmd =
750     ("",0,GrafiteAst.Executable (HExtlib.dummy_floc,
751       GrafiteAst.Command (HExtlib.dummy_floc,
752         cmd)))
753   in
754   let moo = GrafiteMarshal.load_moo fname in
755   List.fold_left 
756     (fun status ast -> 
757       let ast = ast_of_cmd ast in
758       let status,lemmas =
759        eval_ast.ea_go
760          ~disambiguate_command:(fun status (_,_,cmd) -> status,cmd)
761          ~disambiguate_macro:(fun _ _ -> assert false)
762          status ast
763       in
764        assert (lemmas=`Old []);
765        status)
766     status moo
767 } and eval_ast = {ea_go = fun ~disambiguate_command
768 ~disambiguate_macro ?(do_heavy_checks=false) status
769 (text,prefix_len,st)
770 ->
771   let opts = { do_heavy_checks = do_heavy_checks ; } in
772   match st with
773   | GrafiteAst.Executable (_,ex) ->
774      eval_executable.ee_go ~disambiguate_command
775       ~disambiguate_macro opts status (text,prefix_len,ex)
776   | GrafiteAst.Comment (_,c) -> 
777       eval_comment.ecm_go ~disambiguate_command opts status (text,prefix_len,c) 
778 } and eval_comment = { ecm_go = fun ~disambiguate_command opts status (text,prefix_len,c) -> 
779     status, `Old []
780 }
781 ;;
782
783
784 let eval_ast = eval_ast.ea_go