]> matita.cs.unibo.it Git - helm.git/blob - helm/software/components/ng_kernel/nCicEnvironment.ml
in the new kernel you can type Type[i] to mean Type_i, and Type is interpreted as
[helm.git] / helm / software / components / ng_kernel / nCicEnvironment.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 (* $Id$ *)
13
14 module C = NCic
15 module Ref = NReference
16
17 exception CircularDependency of string Lazy.t;;
18 exception ObjectNotFound of string Lazy.t;;
19 exception BadDependency of string Lazy.t * exn;;
20 exception BadConstraint of string Lazy.t;;
21
22 let type0 = []
23
24 let max l1 l2 =
25  HExtlib.list_uniq ~eq:(fun (b1,u1) (b2,u2) -> b1=b2 && NUri.eq u1 u2)
26   (List.sort (fun (b1,u1) (b2,u2) ->
27     let res = compare b1 b2 in if res = 0 then NUri.compare u1 u2 else res)
28       (l1 @ l2))
29
30 let le_constraints = ref [] (* strict,a,b *)
31
32 let resolve_universe u =
33   HExtlib.list_findopt 
34     (fun (_,a,b) _ -> 
35       prerr_endline (NUri.name_of_uri a);
36            if NUri.name_of_uri a = u then Some a 
37       else if NUri.name_of_uri b = u then Some b
38       else None) 
39     !le_constraints
40 ;;
41
42 let rec le_path_uri avoid strict a b =
43  (not strict && NUri.eq a b) ||
44  List.exists
45   (fun (strict',x,y) ->
46      NUri.eq y b && not (List.exists (NUri.eq x) avoid) &&
47        le_path_uri (x::avoid) (strict && not strict') a x
48   ) !le_constraints
49 ;;
50
51 let leq_path a b = le_path_uri [b] (fst a) (snd a) b;;
52
53 let universe_leq a b = 
54   match a, b with
55   | a,[(false,b)] -> List.for_all (fun a -> leq_path a b) a
56   | _,_ ->
57      raise (BadConstraint
58       (lazy "trying to check if a universe is less or equal than an inferred universe"))
59
60 let universe_eq a b = 
61   match a,b with 
62   | [(false,_)], [(false,_)] -> universe_leq b a && universe_leq a b
63   | _, [(false,_)]
64   | [(false,_)],_ -> false
65   | _ ->
66      raise (BadConstraint
67       (lazy "trying to check if two inferred universes are equal"))
68 ;;
69
70 let pp_constraint b x y =  
71   NUri.name_of_uri x ^ (if b then " < " else " <= ") ^ NUri.name_of_uri y
72 ;;
73
74 let pp_constraints () =
75   String.concat "\n" (List.map (fun (b,x,y) -> pp_constraint b x y) !le_constraints)
76 ;;
77
78 let universes = ref [];;
79
80 let add_constraint strict a b = 
81   match a,b with
82   | [false,a2],[false,b2] -> 
83       if not (le_path_uri [] strict a2 b2) then (
84         if le_path_uri [] (not strict) b2 a2 then
85          (raise(BadConstraint(lazy("universe inconsistency adding "^pp_constraint strict a2 b2
86            ^ " to:\n" ^ pp_constraints ()))));
87         universes := a2 :: b2 :: 
88           List.filter (fun x -> not (NUri.eq x a2 || NUri.eq x b2)) !universes;
89         le_constraints := (strict,a2,b2) :: !le_constraints)
90   | _ -> raise (BadConstraint
91           (lazy "trying to add a constraint on an inferred universe"))
92 ;;
93
94 let sup l =
95   match l with
96   | [false,_] -> Some l
97   | l ->
98    let bigger_than acc (s1,n1) = List.filter (le_path_uri [] s1 n1) acc in
99    let solutions = List.fold_left bigger_than !universes l in
100    let rec aux = function
101      | [] -> None
102      | u :: tl ->
103          if List.exists (fun x -> le_path_uri [] true x u) solutions then aux tl
104          else Some [false,u]
105    in
106     aux solutions
107 ;;
108
109
110
111 let typecheck_obj,already_set = ref (fun _ -> assert false), ref false;;
112 let set_typecheck_obj f =
113  if !already_set then
114   assert false
115  else
116   begin
117    typecheck_obj := f;
118    already_set := true
119   end
120 ;;
121
122 let cache = NUri.UriHash.create 313;;
123 let frozen_list = ref [];;
124
125 exception Propagate of NUri.uri * exn;;
126
127 let get_checked_obj u =
128  if List.exists (fun (k,_) -> NUri.eq u k) !frozen_list
129  then
130   raise (CircularDependency (lazy (NUri.string_of_uri u)))
131  else
132   let obj =
133    try NUri.UriHash.find cache u
134    with
135     Not_found ->
136      let saved_frozen_list = !frozen_list in
137      try
138       let obj =
139        try NCicLibrary.get_obj u
140        with
141         NCicLibrary.ObjectNotFound m -> raise (ObjectNotFound m)
142       in
143         frozen_list := (u,obj)::saved_frozen_list;
144         !typecheck_obj obj;
145         frozen_list := saved_frozen_list;
146         let obj = `WellTyped obj in
147         NUri.UriHash.add cache u obj;
148         obj
149      with
150         Sys.Break as e ->
151          frozen_list := saved_frozen_list;
152          raise e
153       | Propagate (u',old_exn) as e' ->
154          frozen_list := saved_frozen_list;
155          let exn = `Exn (BadDependency (lazy (NUri.string_of_uri u ^
156            " depends (recursively) on " ^ NUri.string_of_uri u' ^
157            " which is not well-typed"), 
158            match old_exn with BadDependency (_,e) -> e | _ -> old_exn)) in
159          NUri.UriHash.add cache u exn;
160          if saved_frozen_list = [] then
161           exn
162          else
163           raise e'
164       | e ->
165          frozen_list := saved_frozen_list;
166          let exn = `Exn e in
167          NUri.UriHash.add cache u exn;
168          if saved_frozen_list = [] then
169           exn
170          else
171           raise (Propagate (u,e))
172   in
173    match obj with
174       `WellTyped o -> o
175     | `Exn e -> raise e
176 ;;
177
178 let get_checked_decl = function
179   | Ref.Ref (uri, Ref.Decl) ->
180       (match get_checked_obj uri with
181       | _,height,_,_, C.Constant (rlv,name,None,ty,att) ->
182           rlv,name,ty,att,height
183       | _,_,_,_, C.Constant (_,_,Some _,_,_) ->
184           prerr_endline "get_checked_decl on a definition"; assert false
185       | _ -> prerr_endline "get_checked_decl on a non decl 2"; assert false)
186   | _ -> prerr_endline "get_checked_decl on a non decl"; assert false
187 ;;
188
189 let get_checked_def = function
190   | Ref.Ref (uri, Ref.Def _) ->
191       (match get_checked_obj uri with
192       | _,height,_,_, C.Constant (rlv,name,Some bo,ty,att) ->
193           rlv,name,bo,ty,att,height
194       | _,_,_,_, C.Constant (_,_,None,_,_) ->
195           prerr_endline "get_checked_def on an axiom"; assert false
196       | _ -> prerr_endline "get_checked_def on a non def 2"; assert false)
197   | _ -> prerr_endline "get_checked_def on a non def"; assert false
198 ;;
199
200 let get_checked_indtys = function
201   | Ref.Ref (uri, (Ref.Ind (_,n,_)|Ref.Con (n,_,_))) ->
202       (match get_checked_obj uri with
203       | _,_,_,_, C.Inductive (inductive,leftno,tys,att) ->
204         inductive,leftno,tys,att,n
205       | _ -> prerr_endline "get_checked_indtys on a non ind 2"; assert false)
206   | _ -> prerr_endline "get_checked_indtys on a non ind"; assert false
207 ;;
208
209 let get_checked_fixes_or_cofixes = function
210   | Ref.Ref (uri, (Ref.Fix _|Ref.CoFix _))->
211       (match get_checked_obj uri with
212       | _,height,_,_, C.Fixpoint (_,funcs,att) ->
213          funcs, att, height
214       | _ ->prerr_endline "get_checked_(co)fix on a non (co)fix 2";assert false)
215   | _ -> prerr_endline "get_checked_(co)fix on a non (co)fix"; assert false
216 ;;
217
218 let get_relevance (Ref.Ref (_, infos) as r) =
219   match infos with
220      Ref.Def _ -> let res,_,_,_,_,_ = get_checked_def r in res
221    | Ref.Decl -> let res,_,_,_,_ = get_checked_decl r in res
222    | Ref.Ind _ ->
223        let _,_,tl,_,n = get_checked_indtys r in
224        let res,_,_,_ = List.nth tl n in
225          res
226     | Ref.Con (_,i,_) ->
227        let _,_,tl,_,n = get_checked_indtys r in
228        let _,_,_,cl = List.nth tl n in
229        let res,_,_ = List.nth cl (i - 1) in
230          res
231     | Ref.Fix (fixno,_,_)
232     | Ref.CoFix fixno ->
233         let fl,_,_ = get_checked_fixes_or_cofixes r in
234         let res,_,_,_,_ = List.nth fl fixno in
235           res
236 ;;
237
238
239 let invalidate _ = 
240   assert (!frozen_list = []);
241   NUri.UriHash.clear cache
242 ;;