~ubuntu-branches/ubuntu/wily/coq-doc/wily

« back to all changes in this revision

Viewing changes to ide/coq.ml

  • Committer: Bazaar Package Importer
  • Author(s): Stéphane Glondu, Stéphane Glondu, Samuel Mimram
  • Date: 2010-01-07 22:50:39 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100107225039-n3cq82589u0qt0s2
Tags: 8.2pl1-1
[ Stéphane Glondu ]
* New upstream release (Closes: #563669)
  - remove patches
* Packaging overhaul:
  - use git, advertise it in Vcs-* fields of debian/control
  - use debhelper 7 and dh with override
  - use source format 3.0 (quilt)
* debian/control:
  - set Maintainer to d-o-m, set Uploaders to Sam and myself
  - add Homepage field
  - bump Standards-Version to 3.8.3
* Register PDF documentation into doc-base
* Add debian/watch
* Update debian/copyright

[ Samuel Mimram ]
* Change coq-doc's description to mention that it provides documentation in
  pdf format, not postscript, closes: #543545.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(************************************************************************)
 
2
(*  v      *   The Coq Proof Assistant  /  The Coq Development Team     *)
 
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
 
4
(*   \VV/  **************************************************************)
 
5
(*    //   *      This file is distributed under the terms of the       *)
 
6
(*         *       GNU Lesser General Public License Version 2.1        *)
 
7
(************************************************************************)
 
8
 
 
9
(* $Id: coq.ml 11948 2009-02-27 16:01:53Z glondu $ *)
 
10
 
 
11
open Vernac
 
12
open Vernacexpr
 
13
open Pfedit
 
14
open Pp
 
15
open Util
 
16
open Names
 
17
open Term
 
18
open Printer
 
19
open Environ
 
20
open Evarutil
 
21
open Evd
 
22
open Decl_mode
 
23
open Hipattern
 
24
open Tacmach
 
25
open Reductionops
 
26
open Termops
 
27
open Ideutils
 
28
 
 
29
let prerr_endline s = if !debug then prerr_endline s else ()
 
30
 
 
31
let output = ref (Format.formatter_of_out_channel stdout)
 
32
 
 
33
let msg m = 
 
34
  let b =  Buffer.create 103 in
 
35
  Pp.msg_with (Format.formatter_of_buffer b) m;
 
36
  Buffer.contents b
 
37
 
 
38
let msgnl m = 
 
39
  (msg m)^"\n"
 
40
 
 
41
let init () = 
 
42
  (* To hide goal in lower window. 
 
43
     Problem: should not hide "xx is assumed"
 
44
     messages *)
 
45
(**)
 
46
  Flags.make_silent true;
 
47
  (* don't set a too large undo stack because Edit.create allocates an array *)
 
48
  Pfedit.set_undo (Some 5000);
 
49
(**)
 
50
  Coqtop.init_ide ()
 
51
 
 
52
 
 
53
let i = ref 0
 
54
 
 
55
let get_version_date () =
 
56
  let date =
 
57
    if Glib.Utf8.validate Coq_config.date
 
58
    then Coq_config.date
 
59
    else "<date not printable>" in
 
60
  try
 
61
    let ch = open_in (Coq_config.coqsrc^"/revision") in
 
62
    let ver = input_line ch in
 
63
    let rev = input_line ch in
 
64
    (ver,rev)
 
65
  with _ -> (Coq_config.version,date)
 
66
 
 
67
let short_version () =
 
68
  let (ver,date) = get_version_date () in
 
69
  Printf.sprintf "The Coq Proof Assistant, version %s (%s)\n" ver date
 
70
 
 
71
let version () =
 
72
  let (ver,date) = get_version_date () in
 
73
    Printf.sprintf 
 
74
      "The Coq Proof Assistant, version %s (%s)\
 
75
       \nArchitecture %s running %s operating system\
 
76
       \nGtk version is %s\
 
77
       \nThis is the %s version (%s is the best one for this architecture and OS)\
 
78
       \n"
 
79
      ver date
 
80
      Coq_config.arch Sys.os_type
 
81
      (let x,y,z = GMain.Main.version in Printf.sprintf "%d.%d.%d" x y z)
 
82
    (if Mltop.is_native then "native" else "bytecode") 
 
83
    (if Coq_config.best="opt" then "native" else "bytecode") 
 
84
 
 
85
let is_in_coq_lib dir = 
 
86
  prerr_endline ("Is it a coq theory ? : "^dir);
 
87
  let is_same_file = same_file dir in
 
88
  List.exists 
 
89
    (fun s -> 
 
90
      let fdir =
 
91
        Filename.concat (Envars.coqlib ()) (Filename.concat "theories" s) in
 
92
      prerr_endline (" Comparing to: "^fdir);
 
93
      if is_same_file fdir then (prerr_endline " YES";true)
 
94
      else (prerr_endline"NO";false))
 
95
    Coq_config.theories_dirs
 
96
 
 
97
let is_in_loadpath dir =
 
98
  Library.is_in_load_paths (System.physical_path_of_string dir)
 
99
 
 
100
let is_in_coq_path f = 
 
101
  try 
 
102
  let base = Filename.chop_extension (Filename.basename f) in
 
103
  let _ = Library.locate_qualified_library false
 
104
            (Libnames.make_qualid Names.empty_dirpath 
 
105
               (Names.id_of_string base)) in
 
106
  prerr_endline (f ^ " is in coq path");
 
107
  true
 
108
  with _ ->  
 
109
    prerr_endline (f ^ " is NOT in coq path");
 
110
    false  
 
111
 
 
112
let is_in_proof_mode () = 
 
113
  match Decl_mode.get_current_mode () with
 
114
      Decl_mode.Mode_none -> false
 
115
    | _ -> true
 
116
 
 
117
let user_error_loc l s =
 
118
  raise (Stdpp.Exc_located (l, Util.UserError ("CoqIde", s)))
 
119
 
 
120
type printing_state = {
 
121
  mutable printing_implicit : bool;
 
122
  mutable printing_coercions : bool;
 
123
  mutable printing_raw_matching : bool;
 
124
  mutable printing_no_notation : bool;
 
125
  mutable printing_all : bool;
 
126
  mutable printing_evar_instances : bool;
 
127
  mutable printing_universes : bool;
 
128
  mutable printing_full_all : bool
 
129
}
 
130
 
 
131
let printing_state = {
 
132
  printing_implicit = false;
 
133
  printing_coercions = false;
 
134
  printing_raw_matching = false;
 
135
  printing_no_notation = false;
 
136
  printing_all = false;
 
137
  printing_evar_instances = false;
 
138
  printing_universes = false;
 
139
  printing_full_all = false;
 
140
}
 
141
 
 
142
let printing_implicit_data = ["Printing";"Implicit"], false
 
143
let printing_coercions_data = ["Printing";"Coercions"], false
 
144
let printing_raw_matching_data = ["Printing";"Matching"], true
 
145
let printing_no_synth_data = ["Printing";"Synth"], true
 
146
let printing_no_notation_data = ["Printing";"Notations"], true
 
147
let printing_all_data = ["Printing";"All"], false
 
148
let printing_evar_instances_data = ["Printing";"Existential";"Instances"],false
 
149
let printing_universes_data = ["Printing";"Universes"], false
 
150
 
 
151
let known_options = ref []
 
152
 
 
153
let prepare_option (l,dft) =
 
154
  known_options := l :: !known_options;
 
155
  let set = (String.concat " " ("Set"::l)) ^ "." in
 
156
  let unset = (String.concat " " ("Unset"::l)) ^ "." in
 
157
  if dft then unset,set else set,unset
 
158
 
 
159
let coqide_known_option = function
 
160
  | Goptions.TertiaryTable (a,b,c) -> List.mem [a;b;c] !known_options
 
161
  | Goptions.SecondaryTable (a,b) -> List.mem [a;b] !known_options
 
162
  | Goptions.PrimaryTable a -> List.mem [a] !known_options
 
163
 
 
164
let with_printing_implicit = prepare_option printing_implicit_data
 
165
let with_printing_coercions = prepare_option printing_coercions_data
 
166
let with_printing_raw_matching = prepare_option printing_raw_matching_data
 
167
let with_printing_no_synth = prepare_option printing_no_synth_data
 
168
let with_printing_no_notation = prepare_option printing_no_notation_data
 
169
let with_printing_all = prepare_option printing_all_data
 
170
let with_printing_evar_instances = prepare_option printing_evar_instances_data
 
171
let with_printing_universes = prepare_option printing_universes_data
 
172
 
 
173
let make_option_commands () =
 
174
  let p = printing_state in
 
175
  (if p.printing_implicit then [with_printing_implicit] else [])@
 
176
  (if p.printing_coercions then [with_printing_coercions] else [])@
 
177
  (if p.printing_raw_matching then [with_printing_raw_matching;with_printing_no_synth] else [])@
 
178
  (if p.printing_no_notation then [with_printing_no_notation] else [])@
 
179
  (if p.printing_all then [with_printing_all] else [])@
 
180
  (if p.printing_evar_instances then [with_printing_evar_instances] else [])@
 
181
  (if p.printing_universes then [with_printing_universes] else [])@
 
182
  (if p.printing_full_all then [with_printing_all;with_printing_evar_instances;with_printing_universes] else [])
 
183
 
 
184
let make_option_commands () =
 
185
  let l = make_option_commands () in
 
186
  List.iter (fun (a,b) -> prerr_endline a; prerr_endline b) l;
 
187
  l
 
188
 
 
189
type command_attribute =
 
190
    NavigationCommand | QueryCommand | DebugCommand | KnownOptionCommand
 
191
  | OtherStatePreservingCommand | GoalStartingCommand | SolveCommand
 
192
  | ProofEndingCommand
 
193
 
 
194
let rec attribute_of_vernac_command = function
 
195
  (* Control *)
 
196
  | VernacTime com -> attribute_of_vernac_command com
 
197
  | VernacList _ -> [] (* unsupported *)
 
198
  | VernacLoad _ -> []
 
199
 
 
200
  (* Syntax *)
 
201
  | VernacTacticNotation _ -> []
 
202
  | VernacSyntaxExtension _ -> []
 
203
  | VernacDelimiters _ -> []
 
204
  | VernacBindScope _ -> []
 
205
  | VernacOpenCloseScope _ -> []
 
206
  | VernacArgumentsScope _ -> []
 
207
  | VernacInfix _ -> []
 
208
  | VernacNotation _ -> []
 
209
 
 
210
  (* Gallina *)
 
211
  | VernacDefinition (_,_,DefineBody _,_) -> []
 
212
  | VernacDefinition (_,_,ProveBody _,_) -> [GoalStartingCommand]
 
213
  | VernacStartTheoremProof _ -> [GoalStartingCommand]
 
214
  | VernacEndProof _ -> [ProofEndingCommand]
 
215
  | VernacExactProof _ -> [ProofEndingCommand]
 
216
 
 
217
  | VernacAssumption _ -> []
 
218
  | VernacInductive _ -> []
 
219
  | VernacFixpoint _ -> []
 
220
  | VernacCoFixpoint _ -> []
 
221
  | VernacScheme _ -> []
 
222
  | VernacCombinedScheme _ -> []
 
223
 
 
224
  (* Modules *)
 
225
  | VernacDeclareModule _ -> []
 
226
  | VernacDefineModule _  -> []
 
227
  | VernacDeclareModuleType _ -> []
 
228
  | VernacInclude _ -> []
 
229
 
 
230
  (* Gallina extensions *)
 
231
  | VernacBeginSection _ -> []
 
232
  | VernacEndSegment _ -> []
 
233
  | VernacRequire _ -> []
 
234
  | VernacImport _ -> []
 
235
  | VernacCanonical _ -> []
 
236
  | VernacCoercion _ -> []
 
237
  | VernacIdentityCoercion _ -> []
 
238
 
 
239
  (* Type classes *)
 
240
  | VernacInstance _ -> []
 
241
  | VernacContext _ -> []
 
242
  | VernacDeclareInstance _ -> []
 
243
 
 
244
  (* Solving *)
 
245
  | VernacSolve _ -> [SolveCommand]
 
246
  | VernacSolveExistential _ -> [SolveCommand]
 
247
 
 
248
  (* MMode *)
 
249
  | VernacDeclProof -> [SolveCommand]
 
250
  | VernacReturn -> [SolveCommand]
 
251
  | VernacProofInstr _ -> [SolveCommand]
 
252
 
 
253
  (* Auxiliary file and library management *)
 
254
  | VernacRequireFrom _ -> []
 
255
  | VernacAddLoadPath _ -> []
 
256
  | VernacRemoveLoadPath _ -> []
 
257
  | VernacAddMLPath _ -> []
 
258
  | VernacDeclareMLModule _ -> []
 
259
  | VernacChdir _ -> [OtherStatePreservingCommand]
 
260
 
 
261
  (* State management *)
 
262
  | VernacWriteState _ -> []
 
263
  | VernacRestoreState _ -> []
 
264
 
 
265
  (* Resetting *)
 
266
  | VernacRemoveName _ -> [NavigationCommand]
 
267
  | VernacResetName _ -> [NavigationCommand]
 
268
  | VernacResetInitial -> [NavigationCommand]
 
269
  | VernacBack _ -> [NavigationCommand]
 
270
  | VernacBackTo _ -> [NavigationCommand]
 
271
 
 
272
  (* Commands *)
 
273
  | VernacDeclareTacticDefinition _ -> []
 
274
  | VernacCreateHintDb _ -> []
 
275
  | VernacHints _ -> []
 
276
  | VernacSyntacticDefinition _ -> []
 
277
  | VernacDeclareImplicits _ -> []
 
278
  | VernacReserve _ -> []
 
279
  | VernacSetOpacity _ -> []
 
280
  | VernacSetOption (Goptions.SecondaryTable ("Ltac","Debug"), _) -> 
 
281
      [DebugCommand]
 
282
  | VernacSetOption (o,BoolValue true) | VernacUnsetOption o ->
 
283
      if coqide_known_option o then [KnownOptionCommand] else []
 
284
  | VernacSetOption _ -> []
 
285
  | VernacRemoveOption _ -> []
 
286
  | VernacAddOption _ -> []
 
287
  | VernacMemOption _ -> [QueryCommand]
 
288
 
 
289
  | VernacPrintOption _ -> [QueryCommand]
 
290
  | VernacCheckMayEval _ -> [QueryCommand]
 
291
  | VernacGlobalCheck _ -> [QueryCommand]
 
292
  | VernacPrint _ -> [QueryCommand]
 
293
  | VernacSearch _ -> [QueryCommand]
 
294
  | VernacLocate _ -> [QueryCommand]
 
295
 
 
296
  | VernacComments _ -> [OtherStatePreservingCommand]
 
297
  | VernacNop -> [OtherStatePreservingCommand]
 
298
 
 
299
  (* Proof management *)
 
300
  | VernacGoal _ -> [GoalStartingCommand]
 
301
 
 
302
  | VernacAbort _ -> [NavigationCommand]
 
303
  | VernacAbortAll -> [NavigationCommand]
 
304
  | VernacRestart -> [NavigationCommand]
 
305
  | VernacSuspend -> [NavigationCommand]
 
306
  | VernacResume _ -> [NavigationCommand]
 
307
  | VernacUndo _ -> [NavigationCommand]
 
308
  | VernacUndoTo _ -> [NavigationCommand]
 
309
  | VernacBacktrack _ -> [NavigationCommand]
 
310
 
 
311
  | VernacFocus _ -> [SolveCommand]
 
312
  | VernacUnfocus -> [SolveCommand]
 
313
  | VernacGo _ -> []
 
314
  | VernacShow _ -> [OtherStatePreservingCommand]
 
315
  | VernacCheckGuard -> [OtherStatePreservingCommand]
 
316
  | VernacProof (Tacexpr.TacId []) -> [OtherStatePreservingCommand]
 
317
  | VernacProof _ -> []
 
318
 
 
319
  (* Toplevel control *)
 
320
  | VernacToplevelControl _ -> []
 
321
 
 
322
  (* Extensions *)
 
323
  | VernacExtend ("Subtac_Obligations", _) -> [GoalStartingCommand]
 
324
  | VernacExtend _ -> []
 
325
 
 
326
let is_vernac_goal_starting_command com =
 
327
  List.mem GoalStartingCommand (attribute_of_vernac_command com)
 
328
 
 
329
let is_vernac_navigation_command com =
 
330
  List.mem NavigationCommand (attribute_of_vernac_command com)
 
331
 
 
332
let is_vernac_query_command com =
 
333
  List.mem QueryCommand (attribute_of_vernac_command com)
 
334
 
 
335
let is_vernac_known_option_command com =
 
336
  List.mem KnownOptionCommand (attribute_of_vernac_command com)
 
337
 
 
338
let is_vernac_debug_command com =
 
339
  List.mem DebugCommand (attribute_of_vernac_command com)
 
340
 
 
341
let is_vernac_goal_printing_command com =
 
342
  let attribute = attribute_of_vernac_command com in
 
343
  List.mem GoalStartingCommand attribute or
 
344
  List.mem SolveCommand attribute
 
345
 
 
346
let is_vernac_state_preserving_command com =
 
347
  let attribute = attribute_of_vernac_command com in
 
348
  List.mem OtherStatePreservingCommand attribute or
 
349
  List.mem QueryCommand attribute
 
350
 
 
351
let is_vernac_tactic_command com =
 
352
  List.mem SolveCommand (attribute_of_vernac_command com)
 
353
 
 
354
let is_vernac_proof_ending_command com =
 
355
  List.mem ProofEndingCommand (attribute_of_vernac_command com)
 
356
 
 
357
type undo_info = identifier list
 
358
 
 
359
let undo_info () = Pfedit.get_all_proof_names ()
 
360
 
 
361
type reset_mark =
 
362
  | ResetToId of Names.identifier     (* Relying on identifiers only *)
 
363
  | ResetToState of Libnames.object_name (* Relying on states if any *)
 
364
 
 
365
type reset_status =
 
366
  | NoReset
 
367
  | ResetAtSegmentStart of Names.identifier
 
368
  | ResetAtRegisteredObject of reset_mark
 
369
 
 
370
type reset_info = reset_status * undo_info * bool ref
 
371
 
 
372
 
 
373
let reset_mark id = match Lib.has_top_frozen_state () with
 
374
  | Some sp -> 
 
375
      prerr_endline ("On top of state "^Libnames.string_of_path (fst sp));
 
376
      ResetToState sp
 
377
  | None -> ResetToId id
 
378
 
 
379
let compute_reset_info = function 
 
380
  | VernacBeginSection id 
 
381
  | VernacDefineModule (_,id, _, _, _) 
 
382
  | VernacDeclareModule (_,id, _, _)
 
383
  | VernacDeclareModuleType (id, _, _) ->
 
384
      ResetAtSegmentStart (snd id), undo_info(), ref true
 
385
 
 
386
  | VernacDefinition (_, (_,id), DefineBody _, _)
 
387
  | VernacAssumption (_,_ ,(_,((_,id)::_,_))::_)
 
388
  | VernacInductive (_, (((_,(_,id)),_,_,_,_),_) :: _) ->
 
389
      ResetAtRegisteredObject (reset_mark id), undo_info(), ref true
 
390
 
 
391
  | com when is_vernac_proof_ending_command com -> NoReset, undo_info(), ref true
 
392
  | VernacEndSegment _ -> NoReset, undo_info(), ref true
 
393
 
 
394
  | com when is_vernac_tactic_command com -> NoReset, undo_info(), ref true
 
395
  | _ ->
 
396
      (match Lib.has_top_frozen_state () with
 
397
      | Some sp -> 
 
398
          prerr_endline ("On top of state "^Libnames.string_of_path (fst sp));
 
399
          ResetAtRegisteredObject (ResetToState sp)
 
400
      | None -> NoReset), undo_info(), ref true
 
401
 
 
402
let reset_initial () = 
 
403
  prerr_endline "Reset initial called"; flush stderr;
 
404
  Vernacentries.abort_refine Lib.reset_initial ()
 
405
 
 
406
let reset_to = function
 
407
  | ResetToId id ->
 
408
      prerr_endline ("Reset called with "^(string_of_id id));
 
409
      Lib.reset_name (Util.dummy_loc,id)
 
410
  | ResetToState sp ->
 
411
      prerr_endline
 
412
        ("Reset called with state "^(Libnames.string_of_path (fst sp)));
 
413
      Lib.reset_to_state sp
 
414
 
 
415
let reset_to_mod id = 
 
416
  prerr_endline ("Reset called to Mod/Sect with "^(string_of_id id)); 
 
417
  Lib.reset_mod (Util.dummy_loc,id)
 
418
 
 
419
let raw_interp s =
 
420
  Vernac.raw_do_vernac (Pcoq.Gram.parsable (Stream.of_string s))
 
421
 
 
422
let interp_with_options verbosely options s = 
 
423
  prerr_endline "Starting interp...";
 
424
  prerr_endline s;
 
425
  let pa = Pcoq.Gram.parsable (Stream.of_string s) in
 
426
  let pe = Pcoq.Gram.Entry.parse Pcoq.main_entry pa in
 
427
  (* Temporary hack to make coqide.byte work (WTF???) *)
 
428
  Pervasives.prerr_endline "";
 
429
  match pe with 
 
430
    | None -> assert false
 
431
    | Some((loc,vernac) as last) ->
 
432
        if is_vernac_debug_command vernac then
 
433
          user_error_loc loc (str "Debug mode not available within CoqIDE");
 
434
        if is_vernac_navigation_command vernac then
 
435
          user_error_loc loc (str "Use CoqIDE navigation instead");
 
436
        if is_vernac_known_option_command vernac then
 
437
          user_error_loc loc (str "Use CoqIDE display menu instead");
 
438
        if is_vernac_query_command vernac then 
 
439
          !flash_info
 
440
            "Warning: query commands should not be inserted in scripts";
 
441
        if not (is_vernac_goal_printing_command vernac) then
 
442
          (* Verbose if in small step forward and not a tactic *)
 
443
          Flags.make_silent (not verbosely);
 
444
        let reset_info = compute_reset_info vernac in
 
445
        List.iter (fun (set_option,_) -> raw_interp set_option) options;
 
446
        raw_interp s;
 
447
        Flags.make_silent true;
 
448
        List.iter (fun (_,unset_option) -> raw_interp unset_option) options;
 
449
        prerr_endline ("...Done with interp of : "^s);
 
450
        reset_info,last
 
451
 
 
452
let interp verbosely phrase =
 
453
  interp_with_options verbosely (make_option_commands ()) phrase
 
454
 
 
455
let interp_and_replace s = 
 
456
  let result = interp false s in
 
457
  let msg = read_stdout () in
 
458
  result,msg
 
459
 
 
460
let nb_subgoals pf =
 
461
  List.length (fst (Refiner.frontier (Tacmach.proof_of_pftreestate pf)))
 
462
 
 
463
type tried_tactic = 
 
464
  | Interrupted
 
465
  | Success of int (* nb of goals after *)
 
466
  | Failed
 
467
 
 
468
let try_interptac s = 
 
469
  try
 
470
    prerr_endline ("Starting try_interptac: "^s);
 
471
    let pf = get_pftreestate () in
 
472
    let pe = Pcoq.Gram.Entry.parse 
 
473
               Pcoq.main_entry 
 
474
               (Pcoq.Gram.parsable (Stream.of_string s)) 
 
475
    in match pe with 
 
476
    | Some (loc,(VernacSolve (n, tac, _))) ->
 
477
        let tac = Tacinterp.interp tac in
 
478
        let pf' = solve_nth_pftreestate n tac pf in
 
479
        prerr_endline "Success";
 
480
        let nb_goals = nb_subgoals pf' - nb_subgoals pf in
 
481
        Success nb_goals
 
482
    | _ ->
 
483
        prerr_endline "try_interptac: not a tactic"; Failed
 
484
  with 
 
485
  | Sys.Break | Stdpp.Exc_located (_,Sys.Break)
 
486
      -> prerr_endline "try_interp: interrupted"; Interrupted
 
487
  | Stdpp.Exc_located (_,e) -> prerr_endline ("try_interp: failed ("^(Printexc.to_string e)); Failed
 
488
  | e -> Failed   
 
489
 
 
490
let rec is_pervasive_exn = function
 
491
  | Out_of_memory | Stack_overflow | Sys.Break -> true
 
492
  | Error_in_file (_,_,e) -> is_pervasive_exn e
 
493
  | Stdpp.Exc_located (_,e) -> is_pervasive_exn e
 
494
  | DuringCommandInterp (_,e) -> is_pervasive_exn e
 
495
  | _ -> false
 
496
 
 
497
let print_toplevel_error exc =
 
498
  let (dloc,exc) =
 
499
    match exc with
 
500
      | DuringCommandInterp (loc,ie) ->
 
501
          if loc = dummy_loc then (None,ie) else (Some loc, ie)
 
502
      | _ -> (None, exc) 
 
503
  in
 
504
  let (loc,exc) =
 
505
    match exc with
 
506
      | Stdpp.Exc_located (loc, ie) -> (Some loc),ie
 
507
      | Error_in_file (s, (_,fname, loc), ie) -> None, ie
 
508
      | _ -> dloc,exc
 
509
  in
 
510
  match exc with
 
511
    | End_of_input  ->  str "Please report: End of input",None
 
512
    | Vernacexpr.ProtectedLoop -> 
 
513
        str "ProtectedLoop  not allowed by coqide!",None
 
514
    | Vernacexpr.Drop ->  str "Drop is not allowed by coqide!",None
 
515
    | Vernacexpr.Quit -> str "Quit is not allowed by coqide! Use menus.",None
 
516
    | _ -> 
 
517
        (try Cerrors.explain_exn exc with e -> 
 
518
           str "Failed to explain error. This is an internal Coq error. Please report.\n"
 
519
           ++ str (Printexc.to_string  e)),
 
520
        (if is_pervasive_exn exc then None else loc)
 
521
 
 
522
let process_exn e = let s,loc= print_toplevel_error e in (msgnl s,loc)
 
523
 
 
524
let interp_last last = 
 
525
  prerr_string "*";
 
526
  try
 
527
    vernac_com (States.with_heavy_rollback Vernacentries.interp) last;
 
528
    Lib.add_frozen_state()
 
529
  with e ->
 
530
    let s,_ = process_exn e in prerr_endline ("Replay during undo failed because: "^s);
 
531
    raise e
 
532
 
 
533
 
 
534
type hyp = env * evar_map *
 
535
           ((identifier * string) * constr option * constr) * 
 
536
           (string * string)
 
537
type concl = env * evar_map * constr * string
 
538
type meta = env * evar_map * string
 
539
type goal = hyp list * concl
 
540
 
 
541
let prepare_hyp sigma env ((i,c,d) as a) =
 
542
  env, sigma,
 
543
  ((i,string_of_id i),c,d), 
 
544
  (msg (pr_var_decl env a), msg (pr_ltype_env env d))
 
545
 
 
546
let prepare_hyps sigma env =
 
547
  assert (rel_context env = []);
 
548
  let hyps =
 
549
    fold_named_context
 
550
      (fun env d acc -> let hyp = prepare_hyp sigma env d in hyp :: acc)
 
551
      env ~init:[] 
 
552
  in
 
553
  List.rev hyps
 
554
 
 
555
let prepare_goal_main sigma g =
 
556
  let env = evar_env g in
 
557
  (prepare_hyps sigma env,
 
558
   (env, sigma, g.evar_concl, msg (pr_ltype_env_at_top env g.evar_concl)))
 
559
 
 
560
let prepare_goal sigma g =
 
561
  let options = make_option_commands () in
 
562
  List.iter (fun (set_option,_) -> raw_interp set_option) options;
 
563
  let x = prepare_goal_main sigma g in
 
564
  List.iter (fun (_,unset_option) -> raw_interp unset_option) options;
 
565
  x
 
566
 
 
567
let get_current_pm_goal () =
 
568
  let pfts = get_pftreestate ()  in
 
569
  let gls = try nth_goal_of_pftreestate 1 pfts with _ -> raise Not_found in
 
570
  let sigma= sig_sig gls in
 
571
  let gl = sig_it gls in
 
572
    prepare_goal sigma gl
 
573
 
 
574
 
 
575
let get_current_goals () = 
 
576
    let pfts = get_pftreestate () in
 
577
    let gls = fst (Refiner.frontier (Tacmach.proof_of_pftreestate pfts)) in 
 
578
    let sigma = Tacmach.evc_of_pftreestate pfts in
 
579
    List.map (prepare_goal sigma) gls
 
580
 
 
581
let get_current_goals_nb () = 
 
582
  try List.length (get_current_goals ()) with _ -> 0
 
583
  
 
584
let print_no_goal () =
 
585
    let pfts = get_pftreestate () in
 
586
    let gls = fst (Refiner.frontier (Tacmach.proof_of_pftreestate pfts)) in 
 
587
    assert (gls = []);
 
588
    let sigma = Tacmach.project (Tacmach.top_goal_of_pftreestate pfts) in
 
589
    msg (Printer.pr_subgoals (Decl_mode.get_end_command pfts) sigma gls)
 
590
 
 
591
 
 
592
let hyp_menu (env, sigma, ((coqident,ident),_,ast),(s,pr_ast)) =
 
593
  [("clear "^ident),("clear "^ident^".");
 
594
   
 
595
   ("apply "^ident),
 
596
   ("apply "^ident^".");
 
597
   
 
598
   ("exact "^ident),
 
599
   ("exact "^ident^".");
 
600
 
 
601
   ("generalize "^ident),
 
602
   ("generalize "^ident^".");
 
603
   
 
604
   ("absurd <"^ident^">"),
 
605
   ("absurd "^
 
606
    pr_ast
 
607
    ^".") ] @
 
608
 
 
609
   (if is_equation ast then
 
610
      [ "discriminate "^ident, "discriminate "^ident^".";
 
611
        "injection "^ident, "injection "^ident^"." ]
 
612
    else
 
613
      []) @
 
614
   
 
615
   (let _,t = splay_prod env sigma ast in
 
616
    if is_equation t then 
 
617
      [ "rewrite "^ident, "rewrite "^ident^".";
 
618
        "rewrite <- "^ident, "rewrite <- "^ident^"." ]
 
619
    else
 
620
      []) @
 
621
   
 
622
  [("elim "^ident),
 
623
   ("elim "^ident^".");
 
624
   
 
625
   ("inversion "^ident),
 
626
   ("inversion "^ident^".");
 
627
   
 
628
   ("inversion clear "^ident),
 
629
   ("inversion_clear "^ident^".")] 
 
630
 
 
631
let concl_menu (_,_,concl,_) = 
 
632
  let is_eq = is_equation concl in
 
633
  ["intro", "intro.";
 
634
   "intros", "intros.";
 
635
   "intuition","intuition." ] @
 
636
   
 
637
   (if is_eq then 
 
638
      ["reflexivity", "reflexivity.";
 
639
       "discriminate", "discriminate.";
 
640
       "symmetry", "symmetry." ]
 
641
    else 
 
642
      []) @
 
643
 
 
644
  ["assumption" ,"assumption.";
 
645
   "omega", "omega.";
 
646
   "ring", "ring.";
 
647
   "auto with *", "auto with *.";
 
648
   "eauto with *", "eauto with *.";
 
649
   "tauto", "tauto.";
 
650
   "trivial", "trivial.";
 
651
   "decide equality", "decide equality.";
 
652
 
 
653
   "simpl", "simpl.";
 
654
   "subst", "subst.";
 
655
 
 
656
   "red", "red.";
 
657
   "split", "split.";
 
658
   "left", "left.";
 
659
   "right", "right.";
 
660
  ]
 
661
 
 
662
 
 
663
let id_of_name = function 
 
664
  | Names.Anonymous -> id_of_string "x" 
 
665
  | Names.Name x -> x
 
666
 
 
667
let make_cases s = 
 
668
  let qualified_name = Libnames.qualid_of_string s in
 
669
  let glob_ref = Nametab.locate qualified_name in
 
670
  match glob_ref with
 
671
    | Libnames.IndRef i -> 
 
672
        let {Declarations.mind_nparams = np},
 
673
        {Declarations.mind_consnames = carr ;
 
674
         Declarations.mind_nf_lc = tarr } 
 
675
        = Global.lookup_inductive i 
 
676
        in
 
677
        Util.array_fold_right2 
 
678
          (fun n t l ->  
 
679
             let (al,_) = Term.decompose_prod t in
 
680
             let al,_ = Util.list_chop (List.length al - np) al in
 
681
             let rec rename avoid = function 
 
682
               | [] -> []
 
683
               | (n,_)::l -> 
 
684
                   let n' = next_global_ident_away true
 
685
                              (id_of_name n) 
 
686
                              avoid
 
687
                   in (string_of_id n')::(rename (n'::avoid) l)
 
688
             in
 
689
             let al' = rename [] (List.rev al) in
 
690
             (string_of_id n :: al') :: l
 
691
          )
 
692
          carr 
 
693
          tarr
 
694
          []
 
695
    | _ -> raise Not_found
 
696
 
 
697
let current_status () = 
 
698
  let path = msg (Libnames.pr_dirpath (Lib.cwd ())) in
 
699
  let path = if path = "Top" then "Ready" else "Ready in " ^ String.sub path 4 (String.length path - 4) in
 
700
  try
 
701
    path ^ ", proving " ^ (Names.string_of_id (Pfedit.get_current_proof_name ()))
 
702
  with _ -> path