]> matita.cs.unibo.it Git - helm.git/blob - matita/components/grafite_engine/grafiteEngine.ml
acic_procedural and tactics 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_coercion status ~add_composites uri arity saturations =
324  let uri = 
325    try CicUtil.uri_of_term uri 
326    with Invalid_argument _ -> 
327      raise (Invalid_argument "coercion can only be constants/constructors")
328  in
329  let status, lemmas =
330   GrafiteSync.add_coercion ~add_composites 
331     ~pack_coercion_obj:CicRefine.pack_coercion_obj
332    status uri arity saturations status#baseuri in
333  let moo_content = coercion_moo_statement_of (uri,arity,saturations,0) in
334  let status = GrafiteTypes.add_moo_content [moo_content] status in 
335   add_coercions_of_lemmas lemmas status
336
337 let eval_prefer_coercion status c =
338  let uri = 
339    try CicUtil.uri_of_term c 
340    with Invalid_argument _ -> 
341      raise (Invalid_argument "coercion can only be constants/constructors")
342  in
343  let status = GrafiteSync.prefer_coercion status uri in
344  let moo_content = GrafiteAst.PreferCoercion (HExtlib.dummy_floc,c) in
345  let status = GrafiteTypes.add_moo_content [moo_content] status in 
346  status, `Old []
347
348 let eval_ng_punct (_text, _prefix_len, punct) =
349   match punct with
350   | GrafiteAst.Dot _ -> NTactics.dot_tac 
351   | GrafiteAst.Semicolon _ -> fun x -> x
352   | GrafiteAst.Branch _ -> NTactics.branch_tac ~force:false
353   | GrafiteAst.Shift _ -> NTactics.shift_tac 
354   | GrafiteAst.Pos (_,l) -> NTactics.pos_tac l
355   | GrafiteAst.Wildcard _ -> NTactics.wildcard_tac 
356   | GrafiteAst.Merge _ -> NTactics.merge_tac 
357 ;;
358
359 let eval_ng_tac tac =
360  let rec aux f (text, prefix_len, tac) =
361   match tac with
362   | GrafiteAst.NApply (_loc, t) -> NTactics.apply_tac (text,prefix_len,t) 
363   | GrafiteAst.NSmartApply (_loc, t) -> 
364       NnAuto.smart_apply_tac (text,prefix_len,t) 
365   | GrafiteAst.NAssert (_loc, seqs) ->
366      NTactics.assert_tac
367       ((List.map
368         (function (hyps,concl) ->
369           List.map
370            (function
371               (id,`Decl t) -> id,`Decl (text,prefix_len,t)
372              |(id,`Def (b,t))->id,`Def((text,prefix_len,b),(text,prefix_len,t))
373            ) hyps,
374           (text,prefix_len,concl))
375        ) seqs)
376   | GrafiteAst.NAuto (_loc, (None,a)) -> 
377       NnAuto.auto_tac ~params:(None,a) ?trace_ref:None
378   | GrafiteAst.NAuto (_loc, (Some l,a)) ->
379       NnAuto.auto_tac
380         ~params:(Some List.map (fun x -> "",0,x) l,a) ?trace_ref:None
381   | GrafiteAst.NBranch _ -> NTactics.branch_tac ~force:false
382   | GrafiteAst.NCases (_loc, what, where) ->
383       NTactics.cases_tac 
384         ~what:(text,prefix_len,what)
385         ~where:(text,prefix_len,where)
386   | GrafiteAst.NCase1 (_loc,n) -> NTactics.case1_tac n
387   | GrafiteAst.NChange (_loc, pat, ww) -> 
388       NTactics.change_tac 
389        ~where:(text,prefix_len,pat) ~with_what:(text,prefix_len,ww) 
390   | GrafiteAst.NConstructor (_loc,num,args) -> 
391      NTactics.constructor_tac 
392        ?num ~args:(List.map (fun x -> text,prefix_len,x) args)
393   | GrafiteAst.NCut (_loc, t) -> NTactics.cut_tac (text,prefix_len,t) 
394 (*| GrafiteAst.NDiscriminate (_,what) -> NDestructTac.discriminate_tac ~what:(text,prefix_len,what)
395   | GrafiteAst.NSubst (_,what) -> NDestructTac.subst_tac ~what:(text,prefix_len,what)*)
396   | GrafiteAst.NDestruct (_,dom,skip) -> NDestructTac.destruct_tac dom skip
397   | GrafiteAst.NDot _ -> NTactics.dot_tac 
398   | GrafiteAst.NElim (_loc, what, where) ->
399       NTactics.elim_tac 
400         ~what:(text,prefix_len,what)
401         ~where:(text,prefix_len,where)
402   | GrafiteAst.NFocus (_,l) -> NTactics.focus_tac l
403   | GrafiteAst.NGeneralize (_loc, where) -> 
404       NTactics.generalize_tac ~where:(text,prefix_len,where)
405   | GrafiteAst.NId _ -> (fun x -> x)
406   | GrafiteAst.NIntro (_loc,n) -> NTactics.intro_tac n
407   | GrafiteAst.NIntros (_loc,ns) -> NTactics.intros_tac ns
408   | GrafiteAst.NInversion (_loc, what, where) ->
409       NTactics.inversion_tac 
410         ~what:(text,prefix_len,what)
411         ~where:(text,prefix_len,where)
412   | GrafiteAst.NLApply (_loc, t) -> NTactics.lapply_tac (text,prefix_len,t) 
413   | GrafiteAst.NLetIn (_loc,where,what,name) ->
414       NTactics.letin_tac ~where:(text,prefix_len,where) 
415         ~what:(text,prefix_len,what) name
416   | GrafiteAst.NMerge _ -> NTactics.merge_tac 
417   | GrafiteAst.NPos (_,l) -> NTactics.pos_tac l
418   | GrafiteAst.NPosbyname (_,s) -> NTactics.case_tac s
419   | GrafiteAst.NReduce (_loc, reduction, where) ->
420       NTactics.reduce_tac ~reduction ~where:(text,prefix_len,where)
421   | GrafiteAst.NRewrite (_loc,dir,what,where) ->
422      NTactics.rewrite_tac ~dir ~what:(text,prefix_len,what)
423       ~where:(text,prefix_len,where)
424   | GrafiteAst.NSemicolon _ -> fun x -> x
425   | GrafiteAst.NShift _ -> NTactics.shift_tac 
426   | GrafiteAst.NSkip _ -> NTactics.skip_tac
427   | GrafiteAst.NUnfocus _ -> NTactics.unfocus_tac
428   | GrafiteAst.NWildcard _ -> NTactics.wildcard_tac 
429   | GrafiteAst.NTry (_,tac) -> NTactics.try_tac
430       (aux f (text, prefix_len, tac))
431   | GrafiteAst.NAssumption _ -> NTactics.assumption_tac
432   | GrafiteAst.NBlock (_,l) -> 
433       NTactics.block_tac (List.map (fun x -> aux f (text,prefix_len,x)) l)
434   |GrafiteAst.NRepeat (_,tac) ->
435       NTactics.repeat_tac (f f (text, prefix_len, tac))
436  in
437   aux aux tac (* trick for non uniform recursion call *)
438 ;;
439       
440 let subst_metasenv_and_fix_names status =
441   let u,h,metasenv, subst,o = status#obj in
442   let o = 
443     NCicUntrusted.map_obj_kind ~skip_body:true 
444      (NCicUntrusted.apply_subst subst []) o
445   in
446    status#set_obj(u,h,NCicUntrusted.apply_subst_metasenv subst metasenv,subst,o)
447 ;;
448
449
450 let rec eval_ncommand opts status (text,prefix_len,cmd) =
451   match cmd with
452   | GrafiteAst.UnificationHint (loc, t, n) -> eval_unification_hint status t n
453   | GrafiteAst.NCoercion (loc, name, t, ty, source, target) ->
454       NCicCoercDeclaration.eval_ncoercion status name t ty source target
455   | GrafiteAst.NQed loc ->
456      if status#ng_mode <> `ProofMode then
457       raise (GrafiteTypes.Command_error "Not in proof mode")
458      else
459       let uri,height,menv,subst,obj_kind = status#obj in
460        if menv <> [] then
461         raise
462          (GrafiteTypes.Command_error"You can't Qed an incomplete theorem")
463        else
464         let obj_kind =
465          NCicUntrusted.map_obj_kind 
466           (NCicUntrusted.apply_subst subst []) obj_kind in
467         let height = NCicTypeChecker.height_of_obj_kind uri [] obj_kind in
468         (* fix the height inside the object *)
469         let rec fix () = function 
470           | NCic.Const (NReference.Ref (u,spec)) when NUri.eq u uri -> 
471              NCic.Const (NReference.reference_of_spec u
472               (match spec with
473               | NReference.Def _ -> NReference.Def height
474               | NReference.Fix (i,j,_) -> NReference.Fix(i,j,height)
475               | NReference.CoFix _ -> NReference.CoFix height
476               | NReference.Ind _ | NReference.Con _
477               | NReference.Decl as s -> s))
478           | t -> NCicUtils.map (fun _ () -> ()) () fix t
479         in
480         let obj_kind = 
481           match obj_kind with
482           | NCic.Fixpoint _ -> 
483               NCicUntrusted.map_obj_kind (fix ()) obj_kind 
484           | _ -> obj_kind
485         in
486         let obj = uri,height,[],[],obj_kind in
487         prerr_endline ("pp new obj \n"^NCicPp.ppobj obj);
488         let old_status = status in
489         let status = NCicLibrary.add_obj status obj in
490         let index_obj =
491          match obj_kind with
492             NCic.Constant (_,_,_,_,(_,`Example,_))
493           | NCic.Fixpoint (_,_,(_,`Example,_)) -> false
494           | _ -> true
495         in
496         let status =
497          if index_obj then
498           let status = index_obj_for_auto status obj in
499            (try index_eq_for_auto status uri
500            with _ -> status)
501          else
502           status in
503 (*
504           try 
505             index_eq uri status
506           with _ -> prerr_endline "got an exception"; status
507         in *)
508 (*         prerr_endline (NCicPp.ppobj obj); *)
509         HLog.message ("New object: " ^ NUri.string_of_uri uri);
510          (try
511        (*prerr_endline (NCicPp.ppobj obj);*)
512            let boxml = NCicElim.mk_elims obj in
513            let boxml = boxml @ NCicElim.mk_projections obj in
514 (*
515            let objs = [] in
516            let timestamp,uris_rev =
517              List.fold_left
518               (fun (status,uris_rev) (uri,_,_,_,_) as obj ->
519                 let status = NCicLibrary.add_obj status obj in
520                  status,uri::uris_rev
521               ) (status,[]) objs in
522            let uris = uri::List.rev uris_rev in
523 *)
524            let status = status#set_ng_mode `CommandMode in
525            let status = LexiconSync.add_aliases_for_objs status (`New [uri]) in
526            let status,uris =
527             List.fold_left
528              (fun (status,uris) boxml ->
529                try
530                 let nstatus,nuris =
531                  eval_ncommand opts status
532                   ("",0,GrafiteAst.NObj (HExtlib.dummy_floc,boxml))
533                 in
534                 if nstatus#ng_mode <> `CommandMode then
535                   begin
536                     (*HLog.warn "error in generating projection/eliminator";*)
537                     status, uris
538                   end
539                 else
540                   nstatus, concat_nuris uris nuris
541                with
542                | MultiPassDisambiguator.DisambiguationError _
543                | NCicTypeChecker.TypeCheckerFailure _ ->
544                   (*HLog.warn "error in generating projection/eliminator";*)
545                   status,uris
546              ) (status,`New [] (* uris *)) boxml in             
547            let _,_,_,_,nobj = obj in 
548            let status = match nobj with
549                NCic.Inductive (is_ind,leftno,[it],_) ->
550                  let _,ind_name,ty,cl = it in
551                  List.fold_left 
552                    (fun status outsort ->
553                       let status = status#set_ng_mode `ProofMode in
554                       try
555                        (let status,invobj =
556                          NInversion.mk_inverter 
557                           (ind_name ^ "_inv_" ^
558                             (snd (NCicElim.ast_of_sort outsort)))
559                           is_ind it leftno outsort status status#baseuri in
560                        let _,_,menv,_,_ = invobj in
561                        fst (match menv with
562                              [] -> eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
563                            | _ -> status,`New []))
564                        (* XXX *)
565                       with _ -> (*HLog.warn "error in generating inversion principle"; *)
566                                 let status = status#set_ng_mode `CommandMode in status)
567                   status
568                   (NCic.Prop::
569                     List.map (fun s -> NCic.Type s) (NCicEnvironment.get_universes ()))
570               | _ -> status
571            in
572            let coercions =
573             match obj with
574               _,_,_,_,NCic.Inductive
575                (true,leftno,[_,_,_,[_,_,_]],(_,`Record fields))
576                ->
577                 HExtlib.filter_map
578                  (fun (name,is_coercion,arity) ->
579                    if is_coercion then Some(name,leftno,arity) else None) fields
580             | _ -> [] in
581            let status,uris =
582             List.fold_left
583              (fun (status,uris) (name,cpos,arity) ->
584                try
585                  let metasenv,subst,status,t =
586                   GrafiteDisambiguate.disambiguate_nterm None status [] [] []
587                    ("",0,CicNotationPt.Ident (name,None)) in
588                  assert (metasenv = [] && subst = []);
589                  let status, nuris = 
590                    NCicCoercDeclaration.
591                      basic_eval_and_record_ncoercion_from_t_cpos_arity 
592                       status (name,t,cpos,arity)
593                  in
594                  let uris = concat_nuris nuris uris in
595                  status, uris
596                with MultiPassDisambiguator.DisambiguationError _-> 
597                  HLog.warn ("error in generating coercion: "^name);
598                  status, uris) 
599              (status,uris) coercions
600            in
601             status,uris
602           with
603            exn ->
604             NCicLibrary.time_travel old_status;
605             raise exn)
606   | GrafiteAst.NCopy (log,tgt,src_uri, map) ->
607      if status#ng_mode <> `CommandMode then
608       raise (GrafiteTypes.Command_error "Not in command mode")
609      else
610        let tgt_uri_ext, old_ok = 
611          match NCicEnvironment.get_checked_obj src_uri with
612          | _,_,[],[], (NCic.Inductive _ as ok) -> ".ind", ok
613          | _,_,[],[], (NCic.Fixpoint _ as ok) -> ".con", ok
614          | _,_,[],[], (NCic.Constant _ as ok) -> ".con", ok
615          | _ -> assert false
616        in
617        let tgt_uri = NUri.uri_of_string (status#baseuri^"/"^tgt^tgt_uri_ext) in
618        let map = (src_uri, tgt_uri) :: map in
619        let ok = 
620          let rec subst () = function
621            | NCic.Meta _ -> assert false
622            | NCic.Const (NReference.Ref (u,spec)) as t ->
623                (try NCic.Const 
624                  (NReference.reference_of_spec (List.assoc u map)spec)
625                with Not_found -> t)
626            | t -> NCicUtils.map (fun _ _ -> ()) () subst t
627          in
628          NCicUntrusted.map_obj_kind ~skip_body:false (subst ()) old_ok
629        in
630        let ninitial_stack = Continuationals.Stack.of_nmetasenv [] in
631        let status = status#set_obj (tgt_uri,0,[],[],ok) in
632        (*prerr_endline (NCicPp.ppobj (tgt_uri,0,[],[],ok));*)
633        let status = status#set_stack ninitial_stack in
634        let status = subst_metasenv_and_fix_names status in
635        let status = status#set_ng_mode `ProofMode in
636        eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
637   | GrafiteAst.NObj (loc,obj) ->
638      if status#ng_mode <> `CommandMode then
639       raise (GrafiteTypes.Command_error "Not in command mode")
640      else
641       let status,obj =
642        GrafiteDisambiguate.disambiguate_nobj status
643         ~baseuri:status#baseuri (text,prefix_len,obj) in
644       let uri,height,nmenv,nsubst,nobj = obj in
645       let ninitial_stack = Continuationals.Stack.of_nmetasenv nmenv in
646       let status = status#set_obj obj in
647       let status = status#set_stack ninitial_stack in
648       let status = subst_metasenv_and_fix_names status in
649       let status = status#set_ng_mode `ProofMode in
650       (match nmenv with
651           [] ->
652            eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
653         | _ -> status,`New [])
654   | GrafiteAst.NDiscriminator (_,_) -> assert false (*(loc, indty) ->
655       if status#ng_mode <> `CommandMode then
656         raise (GrafiteTypes.Command_error "Not in command mode")
657       else
658         let status = status#set_ng_mode `ProofMode in
659         let metasenv,subst,status,indty =
660           GrafiteDisambiguate.disambiguate_nterm None status [] [] [] (text,prefix_len,indty) in
661         let indtyno, (_,_,tys,_,_) = match indty with
662             NCic.Const ((NReference.Ref (_,NReference.Ind (_,indtyno,_))) as r) ->
663               indtyno, NCicEnvironment.get_checked_indtys r
664           | _ -> prerr_endline ("engine: indty expected... (fix this error message)"); assert false in
665         let it = List.nth tys indtyno in
666         let status,obj =  NDestructTac.mk_discriminator it status in
667         let _,_,menv,_,_ = obj in
668           (match menv with
669                [] -> eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
670              | _ -> prerr_endline ("Discriminator: non empty metasenv");
671                     status, `New []) *)
672   | GrafiteAst.NInverter (loc, name, indty, selection, sort) ->
673      if status#ng_mode <> `CommandMode then
674       raise (GrafiteTypes.Command_error "Not in command mode")
675      else
676       let metasenv,subst,status,sort = match sort with
677         | None -> [],[],status,NCic.Sort NCic.Prop
678         | Some s -> GrafiteDisambiguate.disambiguate_nterm None status [] [] []
679                       (text,prefix_len,s) 
680       in
681       assert (metasenv = []);
682       let sort = NCicReduction.whd ~subst [] sort in
683       let sort = match sort with 
684           NCic.Sort s -> s
685         | _ ->  raise (Invalid_argument (Printf.sprintf "ninverter: found target %s, which is not a sort" 
686                                            (NCicPp.ppterm ~metasenv ~subst ~context:[] sort)))
687       in
688       let status = status#set_ng_mode `ProofMode in
689       let metasenv,subst,status,indty =
690        GrafiteDisambiguate.disambiguate_nterm None status [] [] subst (text,prefix_len,indty) in
691       let indtyno,(_,leftno,tys,_,_) = match indty with
692           NCic.Const ((NReference.Ref (_,NReference.Ind (_,indtyno,_))) as r) -> 
693             indtyno, NCicEnvironment.get_checked_indtys r
694         | _ -> prerr_endline ("engine: indty ="  ^ NCicPp.ppterm ~metasenv:[] ~subst:[] ~context:[] indty) ; assert false in
695       let it = List.nth tys indtyno in
696      let status,obj = NInversion.mk_inverter name true it leftno ?selection sort 
697                         status status#baseuri in
698      let _,_,menv,_,_ = obj in
699      (match menv with
700         [] ->
701           eval_ncommand opts status ("",0,GrafiteAst.NQed Stdpp.dummy_loc)
702       | _ -> assert false)
703   | GrafiteAst.NUnivConstraint (loc,u1,u2) ->
704       eval_add_constraint status [`Type,u1] [`Type,u2]
705 ;;
706
707 let rec eval_command = {ec_go = fun ~disambiguate_command opts status
708 (text,prefix_len,cmd) ->
709  let status,cmd = disambiguate_command status (text,prefix_len,cmd) in
710  let status,uris =
711   match cmd with
712   | GrafiteAst.PreferCoercion (loc, coercion) ->
713      eval_prefer_coercion status coercion
714   | GrafiteAst.Coercion (loc, uri, add_composites, arity, saturations) ->
715      let res,uris =
716       eval_coercion status ~add_composites uri arity saturations
717      in
718       res,`Old uris
719   | GrafiteAst.Default (loc, what, uris) as cmd ->
720      LibraryObjects.set_default what uris;
721      GrafiteTypes.add_moo_content [cmd] status,`Old []
722   | GrafiteAst.Drop loc -> raise Drop
723   | GrafiteAst.Include (loc, mode, new_or_old, baseuri) ->
724      (* Old Include command is not recursive; new one is *)
725      let status =
726       if new_or_old = `OldAndNew then
727        let moopath_rw, moopath_r = 
728         LibraryMisc.obj_file_of_baseuri 
729           ~must_exist:false ~baseuri ~writable:true,
730         LibraryMisc.obj_file_of_baseuri 
731           ~must_exist:false ~baseuri ~writable:false in
732        let moopath = 
733         if Sys.file_exists moopath_r then moopath_r else
734           if Sys.file_exists moopath_rw then moopath_rw else
735             raise (IncludedFileNotCompiled (moopath_rw,baseuri))
736        in
737         eval_from_moo.efm_go status moopath
738       else
739        status
740      in
741       let status =
742        NCicLibrary.Serializer.require ~baseuri:(NUri.uri_of_string baseuri)
743         status in
744       let status =
745        GrafiteTypes.add_moo_content
746         [GrafiteAst.Include (loc,mode,`New,baseuri)] status
747       in
748        status,`Old []
749   | GrafiteAst.Print (_,_) -> status,`Old []
750   | GrafiteAst.Set (loc, name, value) -> status, `Old []
751 (*       GrafiteTypes.set_option status name value,[] *)
752   | GrafiteAst.Obj (loc,obj) -> (* MATITA 1.0 *) assert false
753  in
754   status,uris
755
756 } and eval_executable = {ee_go = fun ~disambiguate_command
757 ~disambiguate_macro opts status (text,prefix_len,ex) ->
758   match ex with
759   | GrafiteAst.NTactic (_(*loc*), tacl) ->
760       if status#ng_mode <> `ProofMode then
761        raise (GrafiteTypes.Command_error "Not in proof mode")
762       else
763        let status =
764         List.fold_left 
765           (fun status tac ->
766             let status = eval_ng_tac (text,prefix_len,tac) status in
767             subst_metasenv_and_fix_names status)
768           status tacl
769        in
770         status,`New []
771   | GrafiteAst.Command (_, cmd) ->
772       eval_command.ec_go ~disambiguate_command opts status (text,prefix_len,cmd)
773   | GrafiteAst.NCommand (_, cmd) ->
774       eval_ncommand opts status (text,prefix_len,cmd)
775   | GrafiteAst.Macro (loc, macro) ->
776      raise (Macro (loc,disambiguate_macro status (text,prefix_len,macro)))
777   | GrafiteAst.NMacro (loc, macro) ->
778      raise (NMacro (loc,macro))
779
780 } and eval_from_moo = {efm_go = fun status fname ->
781   let ast_of_cmd cmd =
782     ("",0,GrafiteAst.Executable (HExtlib.dummy_floc,
783       GrafiteAst.Command (HExtlib.dummy_floc,
784         cmd)))
785   in
786   let moo = GrafiteMarshal.load_moo fname in
787   List.fold_left 
788     (fun status ast -> 
789       let ast = ast_of_cmd ast in
790       let status,lemmas =
791        eval_ast.ea_go
792          ~disambiguate_command:(fun status (_,_,cmd) -> status,cmd)
793          ~disambiguate_macro:(fun _ _ -> assert false)
794          status ast
795       in
796        assert (lemmas=`Old []);
797        status)
798     status moo
799 } and eval_ast = {ea_go = fun ~disambiguate_command
800 ~disambiguate_macro ?(do_heavy_checks=false) status
801 (text,prefix_len,st)
802 ->
803   let opts = { do_heavy_checks = do_heavy_checks ; } in
804   match st with
805   | GrafiteAst.Executable (_,ex) ->
806      eval_executable.ee_go ~disambiguate_command
807       ~disambiguate_macro opts status (text,prefix_len,ex)
808   | GrafiteAst.Comment (_,c) -> 
809       eval_comment.ecm_go ~disambiguate_command opts status (text,prefix_len,c) 
810 } and eval_comment = { ecm_go = fun ~disambiguate_command opts status (text,prefix_len,c) -> 
811     status, `Old []
812 }
813 ;;
814
815
816 let eval_ast = eval_ast.ea_go