]> matita.cs.unibo.it Git - helm.git/blob - matita/components/grafite_engine/grafiteEngine.ml
urimanager 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 NMacro of GrafiteAst.loc * GrafiteAst.nmacro
32
33 type 'a disambiguator_input = string * int * 'a
34
35 type options = { 
36   do_heavy_checks: bool ; 
37 }
38
39 let basic_eval_unification_hint (t,n) status =
40  NCicUnifHint.add_user_provided_hint status t n
41 ;;
42
43 let inject_unification_hint =
44  let basic_eval_unification_hint (t,n) 
45    ~refresh_uri_in_universe 
46    ~refresh_uri_in_term
47  =
48   let t = refresh_uri_in_term t in basic_eval_unification_hint (t,n)
49  in
50   NCicLibrary.Serializer.register#run "unification_hints"
51    object(_ : 'a NCicLibrary.register_type)
52      method run = basic_eval_unification_hint
53    end
54 ;;
55
56 let eval_unification_hint status t n = 
57  let metasenv,subst,status,t =
58   GrafiteDisambiguate.disambiguate_nterm None status [] [] [] ("",0,t) in
59  assert (metasenv=[]);
60  let t = NCicUntrusted.apply_subst subst [] t in
61  let status = basic_eval_unification_hint (t,n) status in
62  let dump = inject_unification_hint (t,n)::status#dump in
63  let status = status#set_dump dump in
64   status,[]
65 ;;
66
67 let basic_index_obj l status =
68   status#set_auto_cache 
69     (List.fold_left
70       (fun t (ks,v) -> 
71          List.fold_left (fun t k ->
72            NDiscriminationTree.DiscriminationTree.index t k v)
73           t ks) 
74     status#auto_cache l) 
75 ;;     
76
77 let record_index_obj = 
78  let aux l 
79    ~refresh_uri_in_universe 
80    ~refresh_uri_in_term
81  =
82     basic_index_obj
83       (List.map 
84         (fun ks,v -> List.map refresh_uri_in_term ks, refresh_uri_in_term v) 
85       l)
86  in
87   NCicLibrary.Serializer.register#run "index_obj"
88    object(_ : 'a NCicLibrary.register_type)
89      method run = aux
90    end
91 ;;
92
93 let compute_keys status uri height kind = 
94  let mk_item ty spec =
95    let orig_ty = NTacStatus.mk_cic_term [] ty in
96    let status,keys = NnAuto.keys_of_type status orig_ty in
97    let keys =  
98      List.map 
99        (fun t -> 
100           snd (NTacStatus.term_of_cic_term status t (NTacStatus.ctx_of t)))
101        keys
102    in
103    keys,NCic.Const(NReference.reference_of_spec uri spec)
104  in
105  let data = 
106   match kind with
107   | NCic.Fixpoint (ind,ifl,_) -> 
108      HExtlib.list_mapi 
109        (fun (_,_,rno,ty,_) i -> 
110           if ind then mk_item ty (NReference.Fix (i,rno,height)) 
111           else mk_item ty (NReference.CoFix height)) ifl
112   | NCic.Inductive (b,lno,itl,_) -> 
113      HExtlib.list_mapi 
114        (fun (_,_,ty,_) i -> mk_item ty (NReference.Ind (b,i,lno))) itl 
115      @
116      List.map (fun ((_,_,ty),i,j) -> mk_item ty (NReference.Con (i,j+1,lno)))
117        (List.flatten (HExtlib.list_mapi 
118          (fun (_,_,_,cl) i -> HExtlib.list_mapi (fun x j-> x,i,j) cl)
119          itl))
120   | NCic.Constant (_,_,Some _, ty, _) -> 
121      [ mk_item ty (NReference.Def height) ]
122   | NCic.Constant (_,_,None, ty, _) ->
123      [ mk_item ty NReference.Decl ]
124  in
125   HExtlib.filter_map
126    (fun (keys, t) ->
127      let keys = List.filter
128        (function 
129          | (NCic.Meta _) 
130          | (NCic.Appl (NCic.Meta _::_)) -> false 
131          | _ -> true) 
132        keys
133      in
134      if keys <> [] then 
135       begin
136         HLog.debug ("Indexing:" ^ 
137           NCicPp.ppterm ~metasenv:[] ~subst:[] ~context:[] t);
138         HLog.debug ("With keys:" ^ String.concat "\n" (List.map (fun t ->
139           NCicPp.ppterm ~metasenv:[] ~subst:[] ~context:[] t) keys));
140         Some (keys,t) 
141       end
142      else 
143       begin
144         HLog.debug ("Not indexing:" ^ 
145           NCicPp.ppterm ~metasenv:[] ~subst:[] ~context:[] t);
146         None
147       end)
148     data
149 ;;
150
151 let index_obj_for_auto status (uri, height, _, _, kind) = 
152  (*prerr_endline (string_of_int height);*)
153   let data = compute_keys status uri height kind in
154   let status = basic_index_obj data status in
155   let dump = record_index_obj data :: status#dump in   
156   status#set_dump dump
157 ;; 
158
159 let index_eq uri status =
160   let eq_status = status#eq_cache in
161   let eq_status1 = NCicParamod.index_obj eq_status uri in
162     status#set_eq_cache eq_status1
163 ;;
164
165 let record_index_eq =
166  let basic_index_eq uri
167    ~refresh_uri_in_universe 
168    ~refresh_uri_in_term 
169    = index_eq (NCicLibrary.refresh_uri uri) 
170  in
171   NCicLibrary.Serializer.register#run "index_eq"
172    object(_ : 'a NCicLibrary.register_type)
173      method run = basic_index_eq
174    end
175 ;;
176
177 let index_eq_for_auto status uri =
178  if NnAuto.is_a_fact_obj status uri then
179    let newstatus = index_eq uri status in
180      if newstatus#eq_cache == status#eq_cache then status 
181      else
182        ((*prerr_endline ("recording " ^ (NUri.string_of_uri uri));*)
183         let dump = record_index_eq uri :: newstatus#dump 
184         in newstatus#set_dump dump)
185  else 
186    ((*prerr_endline "Not a fact";*)
187    status)
188 ;; 
189
190 let basic_eval_add_constraint (u1,u2) status =
191  NCicLibrary.add_constraint status u1 u2
192 ;;
193
194 let inject_constraint =
195  let basic_eval_add_constraint (u1,u2) 
196        ~refresh_uri_in_universe 
197        ~refresh_uri_in_term
198  =
199   let u1 = refresh_uri_in_universe u1 in 
200   let u2 = refresh_uri_in_universe u2 in 
201   basic_eval_add_constraint (u1,u2)
202  in
203   NCicLibrary.Serializer.register#run "constraints"
204    object(_:'a NCicLibrary.register_type)
205      method run = basic_eval_add_constraint 
206    end
207 ;;
208
209 let eval_add_constraint status u1 u2 = 
210  let status = basic_eval_add_constraint (u1,u2) status in
211  let dump = inject_constraint (u1,u2)::status#dump in
212  let status = status#set_dump dump in
213   status,[]
214 ;;
215
216 let eval_ng_tac tac =
217  let rec aux f (text, prefix_len, tac) =
218   match tac with
219   | GrafiteAst.NApply (_loc, t) -> NTactics.apply_tac (text,prefix_len,t) 
220   | GrafiteAst.NSmartApply (_loc, t) -> 
221       NnAuto.smart_apply_tac (text,prefix_len,t) 
222   | GrafiteAst.NAssert (_loc, seqs) ->
223      NTactics.assert_tac
224       ((List.map
225         (function (hyps,concl) ->
226           List.map
227            (function
228               (id,`Decl t) -> id,`Decl (text,prefix_len,t)
229              |(id,`Def (b,t))->id,`Def((text,prefix_len,b),(text,prefix_len,t))
230            ) hyps,
231           (text,prefix_len,concl))
232        ) seqs)
233   | GrafiteAst.NAuto (_loc, (None,a)) -> 
234       NnAuto.auto_tac ~params:(None,a) ?trace_ref:None
235   | GrafiteAst.NAuto (_loc, (Some l,a)) ->
236       NnAuto.auto_tac
237         ~params:(Some List.map (fun x -> "",0,x) l,a) ?trace_ref:None
238   | GrafiteAst.NBranch _ -> NTactics.branch_tac ~force:false
239   | GrafiteAst.NCases (_loc, what, where) ->
240       NTactics.cases_tac 
241         ~what:(text,prefix_len,what)
242         ~where:(text,prefix_len,where)
243   | GrafiteAst.NCase1 (_loc,n) -> NTactics.case1_tac n
244   | GrafiteAst.NChange (_loc, pat, ww) -> 
245       NTactics.change_tac 
246        ~where:(text,prefix_len,pat) ~with_what:(text,prefix_len,ww) 
247   | GrafiteAst.NConstructor (_loc,num,args) -> 
248      NTactics.constructor_tac 
249        ?num ~args:(List.map (fun x -> text,prefix_len,x) args)
250   | GrafiteAst.NCut (_loc, t) -> NTactics.cut_tac (text,prefix_len,t) 
251 (*| GrafiteAst.NDiscriminate (_,what) -> NDestructTac.discriminate_tac ~what:(text,prefix_len,what)
252   | GrafiteAst.NSubst (_,what) -> NDestructTac.subst_tac ~what:(text,prefix_len,what)*)
253   | GrafiteAst.NDestruct (_,dom,skip) -> NDestructTac.destruct_tac dom skip
254   | GrafiteAst.NDot _ -> NTactics.dot_tac 
255   | GrafiteAst.NElim (_loc, what, where) ->
256       NTactics.elim_tac 
257         ~what:(text,prefix_len,what)
258         ~where:(text,prefix_len,where)
259   | GrafiteAst.NFocus (_,l) -> NTactics.focus_tac l
260   | GrafiteAst.NGeneralize (_loc, where) -> 
261       NTactics.generalize_tac ~where:(text,prefix_len,where)
262   | GrafiteAst.NId _ -> (fun x -> x)
263   | GrafiteAst.NIntro (_loc,n) -> NTactics.intro_tac n
264   | GrafiteAst.NIntros (_loc,ns) -> NTactics.intros_tac ns
265   | GrafiteAst.NInversion (_loc, what, where) ->
266       NTactics.inversion_tac 
267         ~what:(text,prefix_len,what)
268         ~where:(text,prefix_len,where)
269   | GrafiteAst.NLApply (_loc, t) -> NTactics.lapply_tac (text,prefix_len,t) 
270   | GrafiteAst.NLetIn (_loc,where,what,name) ->
271       NTactics.letin_tac ~where:(text,prefix_len,where) 
272         ~what:(text,prefix_len,what) name
273   | GrafiteAst.NMerge _ -> NTactics.merge_tac 
274   | GrafiteAst.NPos (_,l) -> NTactics.pos_tac l
275   | GrafiteAst.NPosbyname (_,s) -> NTactics.case_tac s
276   | GrafiteAst.NReduce (_loc, reduction, where) ->
277       NTactics.reduce_tac ~reduction ~where:(text,prefix_len,where)
278   | GrafiteAst.NRewrite (_loc,dir,what,where) ->
279      NTactics.rewrite_tac ~dir ~what:(text,prefix_len,what)
280       ~where:(text,prefix_len,where)
281   | GrafiteAst.NSemicolon _ -> fun x -> x
282   | GrafiteAst.NShift _ -> NTactics.shift_tac 
283   | GrafiteAst.NSkip _ -> NTactics.skip_tac
284   | GrafiteAst.NUnfocus _ -> NTactics.unfocus_tac
285   | GrafiteAst.NWildcard _ -> NTactics.wildcard_tac 
286   | GrafiteAst.NTry (_,tac) -> NTactics.try_tac
287       (aux f (text, prefix_len, tac))
288   | GrafiteAst.NAssumption _ -> NTactics.assumption_tac
289   | GrafiteAst.NBlock (_,l) -> 
290       NTactics.block_tac (List.map (fun x -> aux f (text,prefix_len,x)) l)
291   |GrafiteAst.NRepeat (_,tac) ->
292       NTactics.repeat_tac (f f (text, prefix_len, tac))
293  in
294   aux aux tac (* trick for non uniform recursion call *)
295 ;;
296       
297 let subst_metasenv_and_fix_names status =
298   let u,h,metasenv, subst,o = status#obj in
299   let o = 
300     NCicUntrusted.map_obj_kind ~skip_body:true 
301      (NCicUntrusted.apply_subst subst []) o
302   in
303    status#set_obj(u,h,NCicUntrusted.apply_subst_metasenv subst metasenv,subst,o)
304 ;;
305
306
307 let rec eval_ncommand opts status (text,prefix_len,cmd) =
308   match cmd with
309   | GrafiteAst.UnificationHint (loc, t, n) -> eval_unification_hint status t n
310   | GrafiteAst.NCoercion (loc, name, t, ty, source, target) ->
311       NCicCoercDeclaration.eval_ncoercion status name t ty source target
312   | GrafiteAst.NQed loc ->
313      if status#ng_mode <> `ProofMode then
314       raise (GrafiteTypes.Command_error "Not in proof mode")
315      else
316       let uri,height,menv,subst,obj_kind = status#obj in
317        if menv <> [] then
318         raise
319          (GrafiteTypes.Command_error"You can't Qed an incomplete theorem")
320        else
321         let obj_kind =
322          NCicUntrusted.map_obj_kind 
323           (NCicUntrusted.apply_subst subst []) obj_kind in
324         let height = NCicTypeChecker.height_of_obj_kind uri [] obj_kind in
325         (* fix the height inside the object *)
326         let rec fix () = function 
327           | NCic.Const (NReference.Ref (u,spec)) when NUri.eq u uri -> 
328              NCic.Const (NReference.reference_of_spec u
329               (match spec with
330               | NReference.Def _ -> NReference.Def height
331               | NReference.Fix (i,j,_) -> NReference.Fix(i,j,height)
332               | NReference.CoFix _ -> NReference.CoFix height
333               | NReference.Ind _ | NReference.Con _
334               | NReference.Decl as s -> s))
335           | t -> NCicUtils.map (fun _ () -> ()) () fix t
336         in
337         let obj_kind = 
338           match obj_kind with
339           | NCic.Fixpoint _ -> 
340               NCicUntrusted.map_obj_kind (fix ()) obj_kind 
341           | _ -> obj_kind
342         in
343         let obj = uri,height,[],[],obj_kind in
344         prerr_endline ("pp new obj \n"^NCicPp.ppobj obj);
345         let old_status = status in
346         let status = NCicLibrary.add_obj status obj in
347         let index_obj =
348          match obj_kind with
349             NCic.Constant (_,_,_,_,(_,`Example,_))
350           | NCic.Fixpoint (_,_,(_,`Example,_)) -> false
351           | _ -> true
352         in
353         let status =
354          if index_obj then
355           let status = index_obj_for_auto status obj in
356            (try index_eq_for_auto status uri
357            with _ -> status)
358          else
359           status in
360 (*
361           try 
362             index_eq uri status
363           with _ -> prerr_endline "got an exception"; status
364         in *)
365 (*         prerr_endline (NCicPp.ppobj obj); *)
366         HLog.message ("New object: " ^ NUri.string_of_uri uri);
367          (try
368        (*prerr_endline (NCicPp.ppobj obj);*)
369            let boxml = NCicElim.mk_elims obj in
370            let boxml = boxml @ NCicElim.mk_projections obj in
371 (*
372            let objs = [] in
373            let timestamp,uris_rev =
374              List.fold_left
375               (fun (status,uris_rev) (uri,_,_,_,_) as obj ->
376                 let status = NCicLibrary.add_obj status obj in
377                  status,uri::uris_rev
378               ) (status,[]) objs in
379            let uris = uri::List.rev uris_rev in
380 *)
381            let status = status#set_ng_mode `CommandMode in
382            let status = LexiconSync.add_aliases_for_objs status [uri] in
383            let status,uris =
384             List.fold_left
385              (fun (status,uris) boxml ->
386                try
387                 let nstatus,nuris =
388                  eval_ncommand opts status
389                   ("",0,GrafiteAst.NObj (HExtlib.dummy_floc,boxml))
390                 in
391                 if nstatus#ng_mode <> `CommandMode then
392                   begin
393                     (*HLog.warn "error in generating projection/eliminator";*)
394                     status, uris
395                   end
396                 else
397                   nstatus, uris@nuris
398                with
399                | MultiPassDisambiguator.DisambiguationError _
400                | NCicTypeChecker.TypeCheckerFailure _ ->
401                   (*HLog.warn "error in generating projection/eliminator";*)
402                   status,uris
403              ) (status,[] (* uris *)) boxml in             
404            let _,_,_,_,nobj = obj in 
405            let status = match nobj with
406                NCic.Inductive (is_ind,leftno,[it],_) ->
407                  let _,ind_name,ty,cl = it in
408                  List.fold_left 
409                    (fun status outsort ->
410                       let status = status#set_ng_mode `ProofMode in
411                       try
412                        (let status,invobj =
413                          NInversion.mk_inverter 
414                           (ind_name ^ "_inv_" ^
415                             (snd (NCicElim.ast_of_sort outsort)))
416                           is_ind it leftno outsort status status#baseuri in
417                        let _,_,menv,_,_ = invobj in
418                        fst (match menv with
419                              [] -> eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
420                            | _ -> status,[]))
421                        (* XXX *)
422                       with _ -> (*HLog.warn "error in generating inversion principle"; *)
423                                 let status = status#set_ng_mode `CommandMode in status)
424                   status
425                   (NCic.Prop::
426                     List.map (fun s -> NCic.Type s) (NCicEnvironment.get_universes ()))
427               | _ -> status
428            in
429            let coercions =
430             match obj with
431               _,_,_,_,NCic.Inductive
432                (true,leftno,[_,_,_,[_,_,_]],(_,`Record fields))
433                ->
434                 HExtlib.filter_map
435                  (fun (name,is_coercion,arity) ->
436                    if is_coercion then Some(name,leftno,arity) else None) fields
437             | _ -> [] in
438            let status,uris =
439             List.fold_left
440              (fun (status,uris) (name,cpos,arity) ->
441                try
442                  let metasenv,subst,status,t =
443                   GrafiteDisambiguate.disambiguate_nterm None status [] [] []
444                    ("",0,NotationPt.Ident (name,None)) in
445                  assert (metasenv = [] && subst = []);
446                  let status, nuris = 
447                    NCicCoercDeclaration.
448                      basic_eval_and_record_ncoercion_from_t_cpos_arity 
449                       status (name,t,cpos,arity)
450                  in
451                  let uris = nuris@uris in
452                  status, uris
453                with MultiPassDisambiguator.DisambiguationError _-> 
454                  HLog.warn ("error in generating coercion: "^name);
455                  status, uris) 
456              (status,uris) coercions
457            in
458             status,uris
459           with
460            exn ->
461             NCicLibrary.time_travel old_status;
462             raise exn)
463   | GrafiteAst.NCopy (log,tgt,src_uri, map) ->
464      if status#ng_mode <> `CommandMode then
465       raise (GrafiteTypes.Command_error "Not in command mode")
466      else
467        let tgt_uri_ext, old_ok = 
468          match NCicEnvironment.get_checked_obj src_uri with
469          | _,_,[],[], (NCic.Inductive _ as ok) -> ".ind", ok
470          | _,_,[],[], (NCic.Fixpoint _ as ok) -> ".con", ok
471          | _,_,[],[], (NCic.Constant _ as ok) -> ".con", ok
472          | _ -> assert false
473        in
474        let tgt_uri = NUri.uri_of_string (status#baseuri^"/"^tgt^tgt_uri_ext) in
475        let map = (src_uri, tgt_uri) :: map in
476        let ok = 
477          let rec subst () = function
478            | NCic.Meta _ -> assert false
479            | NCic.Const (NReference.Ref (u,spec)) as t ->
480                (try NCic.Const 
481                  (NReference.reference_of_spec (List.assoc u map)spec)
482                with Not_found -> t)
483            | t -> NCicUtils.map (fun _ _ -> ()) () subst t
484          in
485          NCicUntrusted.map_obj_kind ~skip_body:false (subst ()) old_ok
486        in
487        let ninitial_stack = Continuationals.Stack.of_nmetasenv [] in
488        let status = status#set_obj (tgt_uri,0,[],[],ok) in
489        (*prerr_endline (NCicPp.ppobj (tgt_uri,0,[],[],ok));*)
490        let status = status#set_stack ninitial_stack in
491        let status = subst_metasenv_and_fix_names status in
492        let status = status#set_ng_mode `ProofMode in
493        eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
494   | GrafiteAst.NObj (loc,obj) ->
495      if status#ng_mode <> `CommandMode then
496       raise (GrafiteTypes.Command_error "Not in command mode")
497      else
498       let status,obj =
499        GrafiteDisambiguate.disambiguate_nobj status
500         ~baseuri:status#baseuri (text,prefix_len,obj) in
501       let uri,height,nmenv,nsubst,nobj = obj in
502       let ninitial_stack = Continuationals.Stack.of_nmetasenv nmenv in
503       let status = status#set_obj obj in
504       let status = status#set_stack ninitial_stack in
505       let status = subst_metasenv_and_fix_names status in
506       let status = status#set_ng_mode `ProofMode in
507       (match nmenv with
508           [] ->
509            eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
510         | _ -> status,[])
511   | GrafiteAst.NDiscriminator (_,_) -> assert false (*(loc, indty) ->
512       if status#ng_mode <> `CommandMode then
513         raise (GrafiteTypes.Command_error "Not in command mode")
514       else
515         let status = status#set_ng_mode `ProofMode in
516         let metasenv,subst,status,indty =
517           GrafiteDisambiguate.disambiguate_nterm None status [] [] [] (text,prefix_len,indty) in
518         let indtyno, (_,_,tys,_,_) = match indty with
519             NCic.Const ((NReference.Ref (_,NReference.Ind (_,indtyno,_))) as r) ->
520               indtyno, NCicEnvironment.get_checked_indtys r
521           | _ -> prerr_endline ("engine: indty expected... (fix this error message)"); assert false in
522         let it = List.nth tys indtyno in
523         let status,obj =  NDestructTac.mk_discriminator it status in
524         let _,_,menv,_,_ = obj in
525           (match menv with
526                [] -> eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
527              | _ -> prerr_endline ("Discriminator: non empty metasenv");
528                     status, []) *)
529   | GrafiteAst.NInverter (loc, name, indty, selection, sort) ->
530      if status#ng_mode <> `CommandMode then
531       raise (GrafiteTypes.Command_error "Not in command mode")
532      else
533       let metasenv,subst,status,sort = match sort with
534         | None -> [],[],status,NCic.Sort NCic.Prop
535         | Some s -> GrafiteDisambiguate.disambiguate_nterm None status [] [] []
536                       (text,prefix_len,s) 
537       in
538       assert (metasenv = []);
539       let sort = NCicReduction.whd ~subst [] sort in
540       let sort = match sort with 
541           NCic.Sort s -> s
542         | _ ->  raise (Invalid_argument (Printf.sprintf "ninverter: found target %s, which is not a sort" 
543                                            (NCicPp.ppterm ~metasenv ~subst ~context:[] sort)))
544       in
545       let status = status#set_ng_mode `ProofMode in
546       let metasenv,subst,status,indty =
547        GrafiteDisambiguate.disambiguate_nterm None status [] [] subst (text,prefix_len,indty) in
548       let indtyno,(_,leftno,tys,_,_) = match indty with
549           NCic.Const ((NReference.Ref (_,NReference.Ind (_,indtyno,_))) as r) -> 
550             indtyno, NCicEnvironment.get_checked_indtys r
551         | _ -> prerr_endline ("engine: indty ="  ^ NCicPp.ppterm ~metasenv:[] ~subst:[] ~context:[] indty) ; assert false in
552       let it = List.nth tys indtyno in
553      let status,obj = NInversion.mk_inverter name true it leftno ?selection sort 
554                         status status#baseuri in
555      let _,_,menv,_,_ = obj in
556      (match menv with
557         [] ->
558           eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
559       | _ -> assert false)
560   | GrafiteAst.NUnivConstraint (loc,u1,u2) ->
561       eval_add_constraint status [`Type,u1] [`Type,u2]
562 ;;
563
564 let eval_comment ~disambiguate_command opts status (text,prefix_len,c) =
565  status, []
566
567 let rec eval_command ~disambiguate_command opts status (text,prefix_len,cmd) =
568  let status,cmd = disambiguate_command status (text,prefix_len,cmd) in
569  let status,uris =
570   match cmd with
571   | GrafiteAst.Include (loc, baseuri) ->
572      let status =
573       let moopath_rw, moopath_r = 
574        LibraryMisc.obj_file_of_baseuri 
575          ~must_exist:false ~baseuri ~writable:true,
576        LibraryMisc.obj_file_of_baseuri 
577          ~must_exist:false ~baseuri ~writable:false in
578       let moopath = 
579        if Sys.file_exists moopath_r then moopath_r else
580          if Sys.file_exists moopath_rw then moopath_rw else
581            raise (IncludedFileNotCompiled (moopath_rw,baseuri))
582       in
583        eval_from_moo status moopath
584      in
585       let status =
586        NCicLibrary.Serializer.require ~baseuri:(NUri.uri_of_string baseuri)
587         status in
588       let status =
589        GrafiteTypes.add_moo_content
590         [GrafiteAst.Include (loc,baseuri)] status
591       in
592        status,[]
593   | GrafiteAst.Print (_,_) -> status,[]
594   | GrafiteAst.Set (loc, name, value) -> status, []
595  in
596   status,uris
597
598 and eval_executable ~disambiguate_command opts status (text,prefix_len,ex) =
599   match ex with
600   | GrafiteAst.NTactic (_(*loc*), tacl) ->
601       if status#ng_mode <> `ProofMode then
602        raise (GrafiteTypes.Command_error "Not in proof mode")
603       else
604        let status =
605         List.fold_left 
606           (fun status tac ->
607             let status = eval_ng_tac (text,prefix_len,tac) status in
608             subst_metasenv_and_fix_names status)
609           status tacl
610        in
611         status,[]
612   | GrafiteAst.Command (_, cmd) ->
613       eval_command ~disambiguate_command opts status (text,prefix_len,cmd)
614   | GrafiteAst.NCommand (_, cmd) ->
615       eval_ncommand opts status (text,prefix_len,cmd)
616   | GrafiteAst.NMacro (loc, macro) ->
617      raise (NMacro (loc,macro))
618
619 and eval_from_moo status fname =
620   let ast_of_cmd cmd =
621     ("",0,GrafiteAst.Executable (HExtlib.dummy_floc,
622       GrafiteAst.Command (HExtlib.dummy_floc,
623         cmd)))
624   in
625   let moo = GrafiteMarshal.load_moo fname in
626   List.fold_left 
627     (fun status ast -> 
628       let ast = ast_of_cmd ast in
629       let status,lemmas =
630        eval_ast ~disambiguate_command:(fun status (_,_,cmd) -> status,cmd)
631          status ast
632       in
633        assert (lemmas=[]);
634        status)
635     status moo
636
637 and eval_ast ~disambiguate_command ?(do_heavy_checks=false) status
638 (text,prefix_len,st)
639 =
640   let opts = { do_heavy_checks = do_heavy_checks ; } in
641   match st with
642   | GrafiteAst.Executable (_,ex) ->
643      eval_executable ~disambiguate_command opts status (text,prefix_len,ex)
644   | GrafiteAst.Comment (_,c) -> 
645       eval_comment ~disambiguate_command opts status (text,prefix_len,c) 
646 ;;