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

« back to all changes in this revision

Viewing changes to contrib/interface/history.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
open Paths;;
 
2
 
 
3
type tree = {mutable index : int;
 
4
             parent : tree option;
 
5
             path_to_root : int list;
 
6
             mutable is_open : bool;
 
7
             mutable sub_proofs : tree list};;
 
8
 
 
9
type prf_info = {
 
10
    mutable prf_length : int;
 
11
    mutable ranks_and_goals : (int * int * tree) list;
 
12
    mutable border : tree list;
 
13
    prf_struct : tree};;
 
14
 
 
15
let theorem_proofs = ((Hashtbl.create 17): 
 
16
                        (string, prf_info) Hashtbl.t);;
 
17
 
 
18
 
 
19
let rec mk_trees_for_goals path tree rank k n =
 
20
  if k = (n + 1) then
 
21
    []
 
22
  else
 
23
    { index = rank;
 
24
      parent = tree;
 
25
      path_to_root = k::path;
 
26
      is_open = true;
 
27
      sub_proofs = [] } ::(mk_trees_for_goals  path tree rank (k+1) n);;
 
28
 
 
29
 
 
30
let push_command s rank ngoals =
 
31
  let ({prf_length = this_length;
 
32
        ranks_and_goals = these_ranks;
 
33
        border = this_border} as proof_info) =
 
34
         Hashtbl.find theorem_proofs s in
 
35
  let rec push_command_aux n = function
 
36
      [] -> failwith "the given rank was too large"
 
37
    | a::l ->
 
38
        if n = 1 then
 
39
         let {path_to_root = p} = a in
 
40
         let new_trees = mk_trees_for_goals p (Some a) (this_length + 1) 1 ngoals in
 
41
         new_trees,(new_trees@l),a
 
42
        else
 
43
          let new_trees, res, this_tree = push_command_aux (n-1) l in
 
44
          new_trees,(a::res),this_tree in
 
45
  let new_trees, new_border, this_tree =
 
46
      push_command_aux rank this_border in
 
47
  let new_length = this_length + 1 in
 
48
  begin
 
49
    proof_info.border <- new_border;
 
50
    proof_info.prf_length <- new_length;
 
51
    proof_info.ranks_and_goals <- (rank, ngoals, this_tree)::these_ranks;
 
52
    this_tree.index <- new_length;
 
53
    this_tree.is_open <- false;
 
54
    this_tree.sub_proofs <- new_trees
 
55
  end;;
 
56
 
 
57
let get_tree_for_rank thm_name rank = 
 
58
  let {ranks_and_goals=l;prf_length=n} = 
 
59
         Hashtbl.find theorem_proofs thm_name in
 
60
  let rec get_tree_aux = function
 
61
      [] ->
 
62
        failwith 
 
63
         "inconsistent values for thm_name and rank in get_tree_for_rank"
 
64
    | (_,_,({index=i} as tree))::tl ->
 
65
        if i = rank then
 
66
          tree
 
67
        else
 
68
          get_tree_aux tl in
 
69
  get_tree_aux l;;
 
70
 
 
71
let get_path_for_rank thm_name rank =
 
72
  let {path_to_root=l}=get_tree_for_rank thm_name rank in
 
73
  l;;
 
74
 
 
75
let rec list_descendants_aux l tree =
 
76
  let {index = i; is_open = open_status; sub_proofs = tl} = tree in
 
77
  let res = (List.fold_left list_descendants_aux  l tl) in
 
78
  if open_status then i::res else res;;
 
79
 
 
80
let list_descendants thm_name rank =
 
81
  list_descendants_aux [] (get_tree_for_rank thm_name rank);;
 
82
 
 
83
let parent_from_rank thm_name rank =
 
84
  let {parent=mommy} = get_tree_for_rank thm_name rank in
 
85
  match mommy with
 
86
   Some x -> Some x.index
 
87
  | None -> None;;
 
88
 
 
89
let first_child_command thm_name rank =
 
90
  let {sub_proofs = l} = get_tree_for_rank thm_name rank in
 
91
  let rec first_child_rec = function 
 
92
      [] -> None
 
93
    | {index=i;is_open=b}::l -> 
 
94
        if b then
 
95
          (first_child_rec l)
 
96
        else
 
97
          Some i in
 
98
  first_child_rec l;;
 
99
 
 
100
type index_or_rank = Is_index of int | Is_rank of int;;
 
101
 
 
102
let first_child_command_or_goal thm_name rank =
 
103
  let proof_info = Hashtbl.find theorem_proofs thm_name in
 
104
  let {sub_proofs=l}=get_tree_for_rank thm_name rank in
 
105
  match l with
 
106
    [] -> None
 
107
  | ({index=i;is_open=b} as t)::_ -> 
 
108
      if b then
 
109
        let rec get_rank n = function
 
110
            [] -> failwith "A goal is lost in first_child_command_or_goal"
 
111
          | a::l ->
 
112
              if a==t then
 
113
                n
 
114
              else
 
115
                get_rank (n + 1) l in
 
116
        Some(Is_rank(get_rank 1 proof_info.border))
 
117
      else
 
118
        Some(Is_index i);;
 
119
 
 
120
let next_sibling thm_name rank =
 
121
  let ({parent=mommy} as t)=get_tree_for_rank thm_name rank in
 
122
  match mommy with
 
123
    None -> None
 
124
  |  Some real_mommy ->
 
125
  let {sub_proofs=l}=real_mommy in
 
126
  let rec next_sibling_aux b = function
 
127
      (opt_first, []) -> 
 
128
        if b then
 
129
          opt_first
 
130
        else
 
131
          failwith "inconsistency detected in next_sibling"
 
132
    | (opt_first, {is_open=true}::l) -> 
 
133
        next_sibling_aux b (opt_first, l)
 
134
    | (Some(first),({index=i; is_open=false} as t')::l) ->
 
135
        if b then
 
136
          Some i
 
137
        else
 
138
          next_sibling_aux (t == t') (Some first,l)
 
139
    | None,({index=i;is_open=false} as t')::l ->
 
140
        next_sibling_aux (t == t') ((Some i), l)
 
141
  in
 
142
  Some (next_sibling_aux false (None, l));;
 
143
 
 
144
 
 
145
let prefix l1 l2 =
 
146
  let l1rev = List.rev l1 in
 
147
  let l2rev = List.rev l2 in
 
148
  is_prefix l1rev l2rev;;
 
149
 
 
150
let rec remove_all_prefixes p = function
 
151
    [] -> []
 
152
  | a::l -> 
 
153
      if is_prefix p a then
 
154
        (remove_all_prefixes p l)
 
155
      else
 
156
        a::(remove_all_prefixes p l);;
 
157
 
 
158
let recompute_border tree =
 
159
  let rec recompute_border_aux tree acc =
 
160
    let {is_open=b;sub_proofs=l}=tree in
 
161
    if b then
 
162
      tree::acc
 
163
    else
 
164
      List.fold_right recompute_border_aux l acc in
 
165
  recompute_border_aux tree [];;
 
166
 
 
167
   
 
168
let historical_undo thm_name rank =
 
169
  let ({ranks_and_goals=l} as proof_info)=
 
170
       Hashtbl.find theorem_proofs thm_name in
 
171
  let rec undo_aux acc = function
 
172
      [] ->  failwith "bad rank provided for undoing in historical_undo"
 
173
    | (r, n, ({index=i} as tree))::tl  ->
 
174
        let this_path_reversed = List.rev tree.path_to_root in
 
175
        let res = remove_all_prefixes this_path_reversed acc in
 
176
        if i = rank then
 
177
          begin
 
178
            proof_info.prf_length <- i-1;
 
179
            proof_info.ranks_and_goals <- tl;
 
180
            tree.is_open <- true;
 
181
            tree.sub_proofs <- [];
 
182
            proof_info.border <- recompute_border proof_info.prf_struct;
 
183
            this_path_reversed::res 
 
184
          end
 
185
        else
 
186
          begin
 
187
            tree.is_open <- true;
 
188
            tree.sub_proofs <- [];
 
189
            undo_aux (this_path_reversed::res) tl
 
190
          end
 
191
  in
 
192
  List.map List.rev (undo_aux [] l);;
 
193
 
 
194
(* The following function takes a list of trees and compute the
 
195
   number of elements whose path is lexically smaller or a suffixe of
 
196
   the path given as a first argument.  This works under the precondition that
 
197
   the list is lexicographically order. *)
 
198
 
 
199
let rec logical_undo_on_border the_tree rev_path = function
 
200
    [] -> (0,[the_tree])
 
201
  | ({path_to_root=p}as tree)::tl ->
 
202
    let p_rev = List.rev p in
 
203
    if is_prefix rev_path p_rev then
 
204
      let (k,res) = (logical_undo_on_border the_tree rev_path tl) in
 
205
          (k+1,res)
 
206
    else if lex_smaller p_rev rev_path then
 
207
      let (k,res) = (logical_undo_on_border the_tree rev_path tl) in
 
208
          (k,tree::res)
 
209
    else
 
210
          (0, the_tree::tree::tl);;
 
211
   
 
212
 
 
213
let logical_undo thm_name rank =
 
214
  let ({ranks_and_goals=l; border=last_border} as proof_info)=
 
215
           Hashtbl.find theorem_proofs thm_name in
 
216
  let ({path_to_root=ref_path} as ref_tree)=get_tree_for_rank thm_name rank in
 
217
  let rev_ref_path = List.rev ref_path in
 
218
  let rec logical_aux lex_smaller_offset family_width = function
 
219
      [] -> failwith "this case should never happen in logical_undo"
 
220
    | (r,n,({index=i;path_to_root=this_path; sub_proofs=these_goals} as tree))::
 
221
        tl ->
 
222
        let this_path_rev = List.rev this_path in
 
223
        let new_rank, new_offset, new_width, kept =
 
224
          if is_prefix rev_ref_path this_path_rev then
 
225
            (r + lex_smaller_offset), lex_smaller_offset,
 
226
              (family_width + 1 - n), false 
 
227
          else if lex_smaller this_path_rev rev_ref_path then
 
228
            r, (lex_smaller_offset -  1 + n), family_width, true
 
229
          else
 
230
            (r + 1 - family_width+ lex_smaller_offset),
 
231
            lex_smaller_offset, family_width, true in
 
232
        if i=rank then
 
233
          [i,new_rank],[], tl, rank
 
234
        else
 
235
          let ranks_undone, ranks_kept, ranks_and_goals, current_rank =
 
236
            (logical_aux new_offset new_width tl) in
 
237
          begin
 
238
            if kept then
 
239
              begin
 
240
                tree.index <- current_rank;
 
241
                ranks_undone, ((i,new_rank)::ranks_kept),
 
242
                ((new_rank, n, tree)::ranks_and_goals), 
 
243
                (current_rank + 1)
 
244
              end
 
245
            else
 
246
              ((i,new_rank)::ranks_undone), ranks_kept,
 
247
              ranks_and_goals, current_rank
 
248
          end in
 
249
  let number_suffix, new_border = 
 
250
     logical_undo_on_border ref_tree rev_ref_path last_border in
 
251
  let changed_ranks_undone, changed_ranks_kept, new_ranks_and_goals,
 
252
    new_length_plus_one = logical_aux 0 number_suffix l in
 
253
  let the_goal_index =
 
254
    let rec compute_goal_index n = function
 
255
        [] -> failwith "this case should never happen in logical undo (2)"
 
256
      | {path_to_root=path}::tl ->
 
257
          if List.rev path = (rev_ref_path) then
 
258
            n
 
259
          else
 
260
            compute_goal_index (n+1) tl in
 
261
    compute_goal_index 1 new_border in
 
262
  begin
 
263
    ref_tree.is_open <- true;
 
264
    ref_tree.sub_proofs <- [];
 
265
    proof_info.border <- new_border;
 
266
    proof_info.ranks_and_goals <- new_ranks_and_goals;
 
267
    proof_info.prf_length <- new_length_plus_one - 1;
 
268
    changed_ranks_undone, changed_ranks_kept, proof_info.prf_length, 
 
269
    the_goal_index
 
270
  end;;
 
271
        
 
272
let start_proof thm_name =
 
273
   let the_tree = 
 
274
      {index=0;parent=None;path_to_root=[];is_open=true;sub_proofs=[]} in
 
275
   Hashtbl.add theorem_proofs thm_name
 
276
     {prf_length=0;
 
277
      ranks_and_goals=[];
 
278
      border=[the_tree];
 
279
      prf_struct=the_tree};;
 
280
      
 
281
let dump_sequence chan s =
 
282
    match (Hashtbl.find theorem_proofs s) with
 
283
    {ranks_and_goals=l}->
 
284
      let rec dump_rec = function
 
285
          [] -> ()
 
286
        | (r,n,_)::tl ->
 
287
            dump_rec tl;
 
288
            output_string chan (string_of_int r);
 
289
            output_string chan ",";
 
290
            output_string chan (string_of_int n);
 
291
            output_string chan "\n" in
 
292
      begin
 
293
        dump_rec l;
 
294
        output_string chan "end\n"
 
295
      end;;
 
296
 
 
297
      
 
298
let proof_info_as_string s =
 
299
  let res = ref "" in
 
300
  match (Hashtbl.find theorem_proofs s) with
 
301
  {prf_struct=tree} ->
 
302
  let open_goal_counter = ref 0 in
 
303
  let rec dump_rec = function
 
304
    {index=i;sub_proofs=trees;parent=the_parent;is_open=op} ->
 
305
    begin
 
306
      (match the_parent with
 
307
         None ->
 
308
           if op then
 
309
             res := !res ^  "\"open goal\"\n"
 
310
       | Some {index=j} -> 
 
311
           begin
 
312
             res := !res ^  (string_of_int j);
 
313
             res := !res ^  " -> ";
 
314
             if op then
 
315
               begin
 
316
                 res := !res ^  "\"open goal ";
 
317
                 open_goal_counter := !open_goal_counter + 1;
 
318
                 res := !res ^  (string_of_int !open_goal_counter);
 
319
                 res := !res ^  "\"\n";
 
320
               end
 
321
             else
 
322
               begin
 
323
                 res := !res ^  (string_of_int i);
 
324
                 res := !res ^  "\n"
 
325
               end
 
326
           end);
 
327
        List.iter dump_rec trees
 
328
     end in
 
329
  dump_rec tree;
 
330
  !res;;
 
331
 
 
332
 
 
333
let dump_proof_info chan s = 
 
334
  match (Hashtbl.find theorem_proofs s) with
 
335
  {prf_struct=tree} ->
 
336
  let open_goal_counter = ref 0 in
 
337
  let rec dump_rec = function
 
338
    {index=i;sub_proofs=trees;parent=the_parent;is_open=op} ->
 
339
    begin
 
340
      (match the_parent with
 
341
         None ->
 
342
           if op then
 
343
             output_string chan "\"open goal\"\n"
 
344
       | Some {index=j} -> 
 
345
           begin
 
346
             output_string chan (string_of_int j);
 
347
             output_string chan " -> ";
 
348
             if op then
 
349
               begin
 
350
                 output_string chan "\"open goal ";
 
351
                 open_goal_counter := !open_goal_counter + 1;
 
352
                 output_string chan (string_of_int !open_goal_counter);
 
353
                 output_string chan "\"\n";
 
354
               end
 
355
             else
 
356
               begin
 
357
                 output_string chan (string_of_int i);
 
358
                 output_string chan "\n"
 
359
               end
 
360
           end);
 
361
        List.iter dump_rec trees
 
362
     end in
 
363
  dump_rec tree;;
 
364
 
 
365
let get_nth_open_path s n =
 
366
  match Hashtbl.find theorem_proofs s with
 
367
    {border=l} ->
 
368
    let {path_to_root=p}=List.nth l (n - 1) in
 
369
    p;;
 
370
 
 
371
let border_length s =
 
372
  match Hashtbl.find theorem_proofs s with
 
373
    {border=l} -> List.length l;;