]> matita.cs.unibo.it Git - helm.git/blob - matita/components/binaries/matex/engine.ml
- ground_2: support for relocation updated
[helm.git] / matita / components / binaries / matex / engine.ml
1 (*
2     ||M||  This file is part of HELM, an Hypertextual, Electronic        
3     ||A||  Library of Mathematics, developed at the Computer Science     
4     ||T||  Department, University of Bologna, Italy.                     
5     ||I||                                                                
6     ||T||  HELM is free software; you can redistribute it and/or         
7     ||A||  modify it under the terms of the GNU General Public License   
8     \   /  version 2 or (at your option) any later version.      
9      \ /   This software is distributed as is, NO WARRANTY.     
10       V_______________________________________________________________ *)
11
12 module F = Filename
13 module L = List
14 module P = Printf
15 module S = String
16
17 module U = NUri
18 module R = NReference
19 module C = NCic
20 module E = NCicEnvironment
21 module V = NCicTypeChecker
22
23 module X = Ground
24 module G = Options
25 module K = Kernel
26 module T = TeX
27 module O = TeXOutput
28 module A = Anticipate
29
30 type status = {
31    n: string;   (* reference name *)
32    s: int list; (* scope *)
33
34
35 (* internal functions *******************************************************)
36
37 let alpha c s = s
38
39 let internal s =
40    X.error ("engine: malformed stack: " ^ s)
41
42 let malformed s =
43    X.error ("engine: malformed term: " ^ s)
44
45 (* generic term processing *)
46
47 let proc_sort = function
48    | C.Prop             -> [T.Macro "PROP"]
49    | C.Type [`Type, u]  -> [T.Macro "TYPE"; T.arg (U.string_of_uri u)]
50    | C.Type [`CProp, u] -> [T.Macro "CROP"; T.arg (U.string_of_uri u)]
51    | C.Type _           -> malformed "T1"
52
53 let rec proc_term c = function
54    | C.Appl []
55    | C.Meta _
56    | C.Implicit _           -> malformed "T2" 
57    | C.Rel m                ->
58       let name = K.resolve_lref c m in
59       [T.Macro "LREF"; T.arg name; T.free name]
60    | C.Appl ts              ->
61       let riss = L.rev_map (proc_term c) ts in
62       T.Macro "APPL" :: T.mk_rev_args riss
63    | C.Prod (s, w, t)       ->
64       let s = alpha c s in
65       let is_w = proc_term c w in
66       let is_t = proc_term (K.add_dec s w c) t in
67       T.Macro "PROD" :: T.arg s :: T.Group is_w :: is_t
68    | C.Lambda (s, w, t)     -> 
69       let s = alpha c s in
70       let is_w = proc_term c w in
71       let is_t = proc_term (K.add_dec s w c) t in
72       T.Macro "ABST" :: T.arg s :: T.Group is_w :: is_t
73    | C.LetIn (s, w, v, t)   -> 
74       let s = alpha c s in
75       let is_w = proc_term c w in
76       let is_v = proc_term c v in
77       let is_t = proc_term (K.add_def s w v c) t in
78       T.Macro "ABBR" :: T.arg s :: T.Group is_w :: T.Group is_v :: is_t
79    | C.Sort s               ->
80       proc_sort s
81    | C.Const (R.Ref (u, r)) ->
82       let ss = K.segments_of_uri u in
83       let _, _, _, _, obj = E.get_checked_obj G.status u in  
84       let ss, name = K.name_of_reference ss (obj, r) in
85       [T.Macro "GREF"; T.arg name; T.free (X.rev_map_concat X.id "." "type" ss)]
86    | C.Match (w, u, v, ts)  ->
87       let is_w = proc_term c (C.Const w) in
88       let is_u = proc_term c u in
89       let is_v = proc_term c v in
90       let riss = L.rev_map (proc_term c) ts in
91       T.Macro "CASE" :: T.Group is_w :: T.Group is_u :: T.Group is_v :: T.mk_rev_args riss
92
93 let proc_term c t = try proc_term c t with
94    | E.ObjectNotFound _ 
95    | Invalid_argument "List.nth"
96    | Failure "nth" 
97    | Failure "name_of_reference" -> malformed "T3"
98
99 (* proof processing *)
100
101 let typeof c = function
102    | C.Appl [t]
103    | t          -> A.typeof c t
104
105 let init () = {
106    n =  ""; s = [1]
107 }
108
109 let push st n = {
110    n = n; s = 1 :: st.s;
111 }
112
113 let next st = {
114    n = ""; s = match st.s with [] -> failwith "hd" | i :: tl -> succ i :: tl
115 }
116
117 let scope st =
118    X.rev_map_concat string_of_int "." "" (L.tl st.s)
119
120 let mk_exit st ris =
121    if st.n <> "" || L.tl st.s = [] then ris else
122    T.free (scope st) :: T.Macro "EXIT" :: ris
123
124 let mk_open st ris =
125    if st.n = "" then ris else
126    T.free (scope st) :: T.free st.n :: T.arg st.n :: T.Macro "OPEN" :: ris
127
128 let mk_dec kind w s ris =
129    let w = if !G.no_types then [] else w in
130    T.Group w :: T.free s :: T.arg s :: T.Macro kind :: ris
131
132 let mk_inferred st c t ris =
133    let u = typeof c t in
134    let is_u = proc_term c u in
135    mk_dec "DECL" is_u st.n ris
136
137 let rec proc_proof st ris c t = match t with
138    | C.Appl []
139    | C.Meta _
140    | C.Implicit _  
141    | C.Sort _
142    | C.Prod _              -> malformed "P1"
143    | C.Const _
144    | C.Rel _               -> proc_proof st ris c (C.Appl [t])
145    | C.Lambda (s, w, t)    -> 
146       let s = alpha c s in
147       let is_w = proc_term c w in
148       let ris = mk_open st ris in
149       proc_proof (next st) (mk_dec "PRIM" is_w s ris) (K.add_dec s w c) t
150    | C.Appl ts              ->
151       let rts = X.rev_neg_filter (A.not_prop2 c) [] ts in
152       let ris = T.Macro "STEP" :: mk_inferred st c t ris in
153       let tts = L.rev_map (proc_term c) rts in
154       mk_exit st (T.rev_mk_args tts ris)
155    | C.Match (w, u, v, ts) ->
156       let rts = X.rev_neg_filter (A.not_prop2 c) [v] ts in
157       let ris = T.Macro "DEST" :: mk_inferred st c t ris in
158       let tts = L.rev_map (proc_term c) rts in
159       mk_exit st (T.rev_mk_args tts ris)
160    | C.LetIn (s, w, v, t)  -> 
161       let s = alpha c s in
162       let is_w = proc_term c w in
163       let ris = mk_open st ris in
164       if A.not_prop1 c w then
165          let is_v = proc_term c v in
166          let ris = T.Group is_v :: T.Macro "BODY" :: mk_dec "DECL" is_w s ris in
167          proc_proof (next st) ris (K.add_def s w v c) t
168       else
169          let ris_v = proc_proof (push st s) ris c v in
170          proc_proof (next st) ris_v (K.add_def s w v c) t
171
172 let proc_proof rs c t = try proc_proof (init ()) rs c t with 
173    | E.ObjectNotFound _ 
174    | Invalid_argument "List.nth"
175    | Failure "nth"
176    | Failure "name_of_reference" -> malformed "P2"
177    | V.TypeCheckerFailure s
178    | V.AssertFailure s           -> malformed (Lazy.force s)
179    | Failure "hd"
180    | Failure "tl"                -> internal "P2"
181
182 (* top level processing *)
183
184 let proc_top_type s t = 
185    [T.Macro "Object"; T.arg s; T.free s; T.Group (proc_term [] t)]
186
187 let proc_top_body s t = proc_term [] t
188
189 let proc_top_proof s t =
190    let tt = A.process_top_term s t in (* anticipation *)
191    L.rev (T.arg "proof" :: T.Macro "end" :: proc_proof [T.arg "proof"; T.Macro "begin"] [] tt)
192
193 let open_out_tex s =
194    open_out (F.concat !G.out_dir (s ^ T.file_ext))
195
196 let proc_pair s ss u xt =
197    let name = X.rev_map_concat X.id "." "type" ss in
198    let och = open_out_tex name in
199    O.out_text och (proc_top_type s u);
200    close_out och;
201    match xt with
202       | None   -> ()
203       | Some t ->
204          let name = X.rev_map_concat X.id "." "body" ss in
205          let och = open_out_tex name in
206          let text = if A.not_prop1 [] u then proc_top_body else proc_top_proof in
207          O.out_text och (text s t);
208          close_out och
209
210 let proc_fun ss (r, s, i, u, t) =
211    proc_pair s (s :: ss) u (Some t)
212
213 let proc_constructor ss (r, s, u) =
214    proc_pair s (s :: ss) u None
215
216 let proc_type ss (r, s, u, cs) =
217    proc_pair s (s :: ss) u None;
218    L.iter (proc_constructor ss) cs
219
220 let proc_obj u =
221    let ss = K.segments_of_uri u in
222    let _, _, _, _, obj = E.get_checked_obj G.status u in 
223    match obj with 
224       | C.Constant (_, s, xt, u, _) -> proc_pair s ss u xt
225       | C.Fixpoint (_, fs, _)       -> L.iter (proc_fun ss) fs
226       | C.Inductive (_, _, ts, _)   -> L.iter (proc_type ss) ts
227
228 (* interface functions ******************************************************)
229
230 let process = proc_obj