]> matita.cs.unibo.it Git - helm.git/blob - helm/software/lambda-delta/basic_ag/bagType.ml
8aee519202eac11501752fb8b2c75c0ee3e56dc7
[helm.git] / helm / software / lambda-delta / basic_ag / bagType.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 U = NUri
13 module C = Cps
14 module S = Share
15 module L = Log
16 module H = Hierarchy
17 module I = AutItem
18 module B = Bag
19 module O = BagOutput
20 module E = BagEnvironment
21 module R = BagReduction
22
23 exception TypeError of B.message
24
25 (* Internal functions *******************************************************)
26
27 let level = 4
28
29 let error1 s c t =
30    raise (TypeError (L.ct_items1 s c t))
31
32 let error2 s1 c1 t1 s2 c2 t2 =
33    raise (TypeError (L.ct_items2 s1 c1 t1 s2 c2 t2))
34
35 let mk_gref u l =
36    let map t v = B.Appl (v, t) in
37    List.fold_left map (B.GRef u) l
38
39 let add_coercion f t (i, uri, vs) =
40    let rec add f x = match x with
41       | B.Sort _
42       | B.LRef _
43       | B.GRef _                       -> f x
44       | B.Cast (u, t)                  -> 
45          let f uu =
46             let f tt = f (S.sh2 u uu t tt x B.cast) in
47             add f t
48          in
49          add f u
50       | B.Appl (v, t)                  ->
51          let f vv =
52             let f tt = f (S.sh2 v vv t tt x B.appl) in
53             add f t
54          in
55          add f v
56       | B.Bind (l, _, _, _) when i = l -> 
57          if U.eq uri I.imp then f (mk_gref I.mt (vs @ [x])) else
58          if U.eq uri I.all then f (mk_gref I.alli (vs @ [x])) else
59          assert false
60       | B.Bind (l, id, B.Abst w, t)    ->
61          let f ww =
62             let f tt = f (S.sh2 w ww t tt x (B.bind_abst l id)) in
63             add f t
64          in
65          add f w
66       | B.Bind (l, id, B.Abbr v, t)    ->
67          let f vv =
68             let f tt = f (S.sh2 v vv t tt x (B.bind_abbr l id)) in
69             add f t
70          in
71          add f v
72       | B.Bind (l, id, B.Void, t)      ->
73          let f tt = f (S.sh1 t tt x (B.bind l id B.Void)) in
74          add f t
75    in
76    add f t
77
78 let add_coercions f = C.list_fold_left f add_coercion
79
80 (* Interface functions ******************************************************)
81
82 let rec b_type_of f g c x = 
83    L.log O.specs level (L.ct_items1 "Now checking" c x);
84    match x with
85    | B.Sort h                    ->
86       let f h = f x (B.Sort h) in H.apply f g h
87    | B.LRef i                    ->
88       let f = function
89          | Some (_, B.Abst w)               -> f x w
90          | Some (_, B.Abbr (B.Cast (w, v))) -> f x w
91          | Some (_, B.Abbr _)               -> assert false
92          | Some (_, B.Void)                 -> 
93             error1 "reference to excluded variable" c x
94          | None                             ->
95             error1 "variable not found" c x      
96       in
97       B.get f c i
98    | B.GRef uri                  ->
99       let f = function
100          | _, _, B.Abst w               -> f x w
101          | _, _, B.Abbr (B.Cast (w, v)) -> f x w
102          | _, _, B.Abbr _               -> assert false
103          | _, _, B.Void                 ->
104             error1 "reference to excluded object" c x
105       in
106       E.get_obj f uri   
107    | B.Bind (l, id, B.Abbr v, t) ->
108       let f xv xt tt =
109          f (S.sh2 v xv t xt x (B.bind_abbr l id)) (B.bind_abbr l id xv tt)
110       in
111       let f xv cc = b_type_of (f xv) g cc t in
112       let f xv = B.push (f xv) c l id (B.Abbr xv) in
113       let f xv vv = match xv with 
114          | B.Cast _ -> f xv
115          | _        -> f (B.Cast (vv, xv))
116       in
117       type_of f g c v
118    | B.Bind (l, id, B.Abst u, t) ->
119       let f xu xt tt =
120          f (S.sh2 u xu t xt x (B.bind_abst l id)) (B.bind_abst l id xu tt)
121       in
122       let f xu cc = b_type_of (f xu) g cc t in
123       let f xu _ = B.push (f xu) c l id (B.Abst xu) in
124       type_of f g c u
125    | B.Bind (l, id, B.Void, t)   ->
126       let f xt tt = 
127          f (S.sh1 t xt x (B.bind l id B.Void)) (B.bind l id B.Void tt)
128       in
129       let f cc = b_type_of f g cc t in
130       B.push f c l id B.Void   
131    | B.Appl (v, t)            ->
132       let f xv vv xt tt = function
133          | R.Abst w                             -> 
134             L.box (succ level);
135             L.log O.specs (succ level) (L.ct_items1 "Just scanned" c w);
136             L.unbox (succ level);
137             let f = function
138                | Some [] -> f (S.sh2 v xv t xt x B.appl) (B.appl xv tt)
139                | Some l  ->
140                   L.log O.specs level (L.items1 "Rechecking coerced term");
141                   let f xv = b_type_of f g c (S.sh2 v xv t xt x B.appl) in
142                   add_coercions f xv l
143                | None   -> error2 "The term" c xv "must be of type" c w
144             in
145             R.are_convertible f c w vv
146 (* inserting a missing "modus ponens" *)
147          | R.GRef (uri, vs) when U.eq uri I.imp ->
148             L.log O.specs level (L.items1 "Rechecking coerced term");
149             b_type_of f g c (mk_gref I.mp (vs @ [xv; xt]))
150          | R.GRef (uri, vs) when U.eq uri I.all ->
151             L.log O.specs level (L.items1 "Rechecking coerced term");
152             b_type_of f g c (mk_gref I.alle (vs @ [xv; xt]))
153          | _                                    -> 
154             error1 "not a function" c xt
155       in
156       let f xv vv xt tt = R.ho_whd (f xv vv xt tt) c tt in
157       let f xv vv = b_type_of (f xv vv) g c t in
158       type_of f g c v
159    | B.Cast (u, t)            ->
160       let f xu xt = function 
161          | Some [] -> f (S.sh2 u xu t xt x B.cast) xu
162          | Some l  ->
163             L.log O.specs level (L.items1 "Rechecking coerced term");
164             let f xt = b_type_of f g c (S.sh2 u xu t xt x B.cast) in
165             add_coercions f xt l
166          | None    -> error2 "The term" c xt "must be of type" c xu
167       in
168       let f xu xt tt = R.are_convertible (f xu xt) c xu tt in
169       let f xu _ = b_type_of (f xu) g c t in
170       type_of f g c u
171
172 and type_of f g c x =
173    let f t u = L.unbox level; f t u in
174    L.box level; b_type_of f g c x
175