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