]> matita.cs.unibo.it Git - helm.git/blob - helm/software/lambda-delta/basic_ag/bagType.ml
80b883ff44612101b47dcead611ef55aa88b438a
[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          assert false
59       | B.Bind (l, id, B.Abst w, t)    ->
60          let f ww =
61             let f tt = f (S.sh2 w ww t tt x (B.bind_abst l id)) in
62             add f t
63          in
64          add f w
65       | B.Bind (l, id, B.Abbr v, t)    ->
66          let f vv =
67             let f tt = f (S.sh2 v vv t tt x (B.bind_abbr l id)) in
68             add f t
69          in
70          add f v
71       | B.Bind (l, id, B.Void, t)      ->
72          let f tt = f (S.sh1 t tt x (B.bind l id B.Void)) in
73          add f t
74    in
75    add f t
76
77 let add_coercions f = C.list_fold_left f add_coercion
78
79 (* Interface functions ******************************************************)
80
81 let rec b_type_of f g c x = 
82    L.log O.specs level (L.ct_items1 "Now checking" c x);
83    match x with
84    | B.Sort h                    ->
85       let f h = f x (B.Sort h) in H.apply f g h
86    | B.LRef i                    ->
87       let f = function
88          | Some (_, B.Abst w)               -> f x w
89          | Some (_, B.Abbr (B.Cast (w, v))) -> f x w
90          | Some (_, B.Abbr _)               -> assert false
91          | Some (_, B.Void)                 -> 
92             error1 "reference to excluded variable" c x
93          | None                             ->
94             error1 "variable not found" c x      
95       in
96       B.get f c i
97    | B.GRef uri                  ->
98       let f = function
99          | _, _, B.Abst w               -> f x w
100          | _, _, B.Abbr (B.Cast (w, v)) -> f x w
101          | _, _, B.Abbr _               -> assert false
102          | _, _, B.Void                 ->
103             error1 "reference to excluded object" c x
104       in
105       E.get_obj f uri   
106    | B.Bind (l, id, B.Abbr v, t) ->
107       let f xv xt tt =
108          f (S.sh2 v xv t xt x (B.bind_abbr l id)) (B.bind_abbr l id xv tt)
109       in
110       let f xv cc = b_type_of (f xv) g cc t in
111       let f xv = B.push (f xv) c l id (B.Abbr xv) in
112       let f xv vv = match xv with 
113          | B.Cast _ -> f xv
114          | _        -> f (B.Cast (vv, xv))
115       in
116       type_of f g c v
117    | B.Bind (l, id, B.Abst u, t) ->
118       let f xu xt tt =
119          f (S.sh2 u xu t xt x (B.bind_abst l id)) (B.bind_abst l id xu tt)
120       in
121       let f xu cc = b_type_of (f xu) g cc t in
122       let f xu _ = B.push (f xu) c l id (B.Abst xu) in
123       type_of f g c u
124    | B.Bind (l, id, B.Void, t)   ->
125       let f xt tt = 
126          f (S.sh1 t xt x (B.bind l id B.Void)) (B.bind l id B.Void tt)
127       in
128       let f cc = b_type_of f g cc t in
129       B.push f c l id B.Void   
130    | B.Appl (v, t)            ->
131       let h xv vv xt tt cc = function
132          | R.Sort _ -> error1 "not a function" c xt
133          | R.Abst w -> 
134             L.box (succ level);
135             L.log O.specs (succ level) (L.ct_items1 "Just scanned" cc w);
136             L.unbox (succ level);
137             let f = function
138                | Some l -> f (S.sh2 v xv t xt x B.appl) (B.appl xv tt)
139                | None   -> error2 "the term" cc xv "must be of type" cc w
140             in
141             R.are_convertible f cc w vv     
142       in
143       let f xv vv xt = function
144 (* inserting a missing "modus ponens" *)      
145          | B.Appl (y2, B.Appl (y1, B.GRef uri)) when U.eq uri I.imp ->
146             b_type_of f g c (mk_gref I.mp [y1; y2; xv; xt])
147          | B.Appl (y1, B.GRef uri) when U.eq uri I.not ->
148             b_type_of f g c (mk_gref I.mp [y1; B.GRef I.con; xv; xt])    
149          | tt -> R.ho_whd (h xv vv xt tt) c tt
150       in
151       let f xv vv = b_type_of (f xv vv) g c t in
152       type_of f g c v
153    | B.Cast (u, t)            ->
154       let f xu xt = function 
155          | Some [] -> f (S.sh2 u xu t xt x B.cast) xu
156          | Some l  ->
157             let f xt = type_of f g c (S.sh2 u xu t xt x B.cast) in
158             add_coercions f xt l
159          | None    -> error2 "the term" c xt "must be of type" c xu
160       in
161       let f xu xt tt = R.are_convertible (f xu xt) c xu tt in
162       let f xu _ = b_type_of (f xu) g c t in
163       type_of f g c u
164
165 and type_of f g c x =
166    let f t u = L.unbox level; f t u in
167    L.box level; b_type_of f g c x
168