]> matita.cs.unibo.it Git - helm.git/blob - helm/software/components/ng_kernel/nCicEnvironment.ml
ddfe2ca52361506466db29377d5a3be13bd705ea
[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 exception CircularDependency of string Lazy.t;;
15 exception ObjectNotFound of string Lazy.t;;
16 exception BadDependency of string Lazy.t;;
17 exception BadConstraint of string Lazy.t;;
18
19 let type0 = [false, NUri.uri_of_string ("cic:/matita/pts/Type.univ")]
20
21 let le_constraints = ref [] (* strict,a,b *)
22
23 let rec le_path_uri strict a b = 
24  if strict then
25   List.exists (fun (strict,x,y) -> NUri.eq y b &&
26    if strict then le_path_uri false a x else le_path_uri strict a x)
27     !le_constraints
28  else
29   NUri.eq a b ||
30    List.exists (fun (_,x,y) -> NUri.eq y b && le_path_uri false a x)
31      !le_constraints
32 ;;
33
34 let leq_path a b = le_path_uri (fst a) (snd a) b;;
35
36 let universe_leq a b = 
37   match a, b with
38   | a,[(false,b)] -> List.for_all (fun a -> leq_path a b) a
39   | _,_ ->
40      raise (BadConstraint
41       (lazy "trying to check if a universe is less or equal than an inferred universe"))
42
43 let universe_eq a b = universe_leq b a || universe_leq a b
44
45 let add_le_constraint strict a b = 
46   match a,b with
47   | [false,a2],[false,b2] -> 
48       if le_path_uri (not strict) b2 a2 then
49        (raise (BadConstraint (lazy "universe inconsistency")));
50       le_constraints := (strict,a2,b2) :: !le_constraints  
51   | _ -> raise (BadConstraint
52           (lazy "trying to add a constraint on an inferred universe"))
53 ;;
54
55 let typecheck_obj,already_set = ref (fun _ -> assert false), ref false;;
56 let set_typecheck_obj f =
57  if !already_set then
58   assert false
59  else
60   begin
61    typecheck_obj := f;
62    already_set := true
63   end
64 ;;
65
66 let cache = NUri.UriHash.create 313;;
67 let frozen_list = ref [];;
68
69 exception Propagate of NUri.uri * exn;;
70
71 let get_checked_obj u =
72  if List.exists (fun (k,_) -> NUri.eq u k) !frozen_list
73  then
74   raise (CircularDependency (lazy (NUri.string_of_uri u)))
75  else
76   let obj =
77    try NUri.UriHash.find cache u
78    with
79     Not_found ->
80      let saved_frozen_list = !frozen_list in
81      try
82       let obj =
83        try NCicLibrary.get_obj u
84        with
85         NCicLibrary.ObjectNotFound m -> raise (ObjectNotFound m)
86       in
87         frozen_list := (u,obj)::saved_frozen_list;
88         !typecheck_obj obj;
89         frozen_list := saved_frozen_list;
90         let obj = `WellTyped obj in
91         NUri.UriHash.add cache u obj;
92         obj
93      with
94         Sys.Break as e ->
95          frozen_list := saved_frozen_list;
96          raise e
97       | Propagate (u',_) as e' ->
98          frozen_list := saved_frozen_list;
99          let exn = `Exn (BadDependency (lazy (NUri.string_of_uri u ^
100            " depends (recursively) on " ^ NUri.string_of_uri u' ^
101            " which is not well-typed"))) in
102          NUri.UriHash.add cache u exn;
103          if saved_frozen_list = [] then
104           exn
105          else
106           raise e'
107       | e ->
108          frozen_list := saved_frozen_list;
109          let exn = `Exn e in
110          NUri.UriHash.add cache u exn;
111          if saved_frozen_list = [] then
112           exn
113          else
114           raise (Propagate (u,e))
115   in
116    match obj with
117       `WellTyped o -> o
118     | `Exn e -> raise e
119 ;;
120
121 let get_checked_decl = function
122   | NReference.Ref (uri, NReference.Decl) ->
123       (match get_checked_obj uri with
124       | _,height,_,_, NCic.Constant (rlv,name,None,ty,att) ->
125           rlv,name,ty,att,height
126       | _,_,_,_, NCic.Constant (_,_,Some _,_,_) ->
127           prerr_endline "get_checked_decl on a definition"; assert false
128       | _ -> prerr_endline "get_checked_decl on a non decl 2"; assert false)
129   | _ -> prerr_endline "get_checked_decl on a non decl"; assert false
130 ;;
131
132 let get_checked_def = function
133   | NReference.Ref (uri, NReference.Def _) ->
134       (match get_checked_obj uri with
135       | _,height,_,_, NCic.Constant (rlv,name,Some bo,ty,att) ->
136           rlv,name,bo,ty,att,height
137       | _,_,_,_, NCic.Constant (_,_,None,_,_) ->
138           prerr_endline "get_checked_def on an axiom"; assert false
139       | _ -> prerr_endline "get_checked_def on a non def 2"; assert false)
140   | _ -> prerr_endline "get_checked_def on a non def"; assert false
141 ;;
142
143 let get_checked_indtys = function
144   | NReference.Ref (uri, (NReference.Ind (_,n)|NReference.Con (n,_))) ->
145       (match get_checked_obj uri with
146       | _,_,_,_, NCic.Inductive (inductive,leftno,tys,att) ->
147         inductive,leftno,tys,att,n
148       | _ -> prerr_endline "get_checked_indtys on a non ind 2"; assert false)
149   | _ -> prerr_endline "get_checked_indtys on a non ind"; assert false
150 ;;
151
152 let get_checked_fixes_or_cofixes = function
153   | NReference.Ref (uri, (NReference.Fix (fixno,_,_)|NReference.CoFix fixno))->
154       (match get_checked_obj uri with
155       | _,height,_,_, NCic.Fixpoint (_,funcs,att) ->
156          funcs, att, height
157       | _ ->prerr_endline "get_checked_(co)fix on a non (co)fix 2";assert false)
158   | r -> prerr_endline ("get_checked_(co)fix on " ^ NReference.string_of_reference r); assert false
159 ;;
160
161 let get_indty_leftno = function 
162   | NReference.Ref (uri, NReference.Ind _) 
163   | NReference.Ref (uri, NReference.Con _) ->
164       (match get_checked_obj uri with
165       | _,_,_,_, NCic.Inductive (_,left,_,_) -> left
166       | _ ->prerr_endline "get_indty_leftno called on a non ind 2";assert false)
167   | _ -> prerr_endline "get_indty_leftno called on a non indty";assert false
168 ;;
169
170 let get_relevance (NReference.Ref (_, infos) as r) =
171   match infos with
172      NReference.Def _ -> let res,_,_,_,_,_ = get_checked_def r in res
173    | NReference.Decl -> let res,_,_,_,_ = get_checked_decl r in res
174    | NReference.Ind _ ->
175        let _,_,tl,_,n = get_checked_indtys r in
176        let res,_,_,_ = List.nth tl n in
177          res
178     | NReference.Con (_,i) ->
179        let _,_,tl,_,n = get_checked_indtys r in
180        let _,_,_,cl = List.nth tl n in
181        let res,_,_ = List.nth cl (i - 1) in
182          res
183     | NReference.Fix (fixno,_,_)
184     | NReference.CoFix fixno ->
185         let fl,_,_ = get_checked_fixes_or_cofixes r in
186         let res,_,_,_,_ = List.nth fl fixno in
187           res
188 ;;
189
190
191 let invalidate _ = 
192   assert (!frozen_list = []);
193   NUri.UriHash.clear cache
194 ;;