(* ||M|| This file is part of HELM, an Hypertextual, Electronic ||A|| Library of Mathematics, developed at the Computer Science ||T|| Department, University of Bologna, Italy. ||I|| ||T|| HELM is free software; you can redistribute it and/or ||A|| modify it under the terms of the GNU General Public License \ / version 2 or (at your option) any later version. \ / This software is distributed as is, NO WARRANTY. V_______________________________________________________________ *) (* $Id$ *) module C = NCic module Ref = NReference exception CircularDependency of string Lazy.t;; exception ObjectNotFound of string Lazy.t;; exception BadDependency of string Lazy.t;; exception BadConstraint of string Lazy.t;; let type0 = [] let le_constraints = ref [] (* strict,a,b *) let rec le_path_uri avoid strict a b = (not strict && NUri.eq a b) || List.exists (fun (strict',x,y) -> NUri.eq y b && not (List.exists (NUri.eq x) avoid) && le_path_uri (x::avoid) (strict && not strict') a x ) !le_constraints ;; let leq_path a b = le_path_uri [b] (fst a) (snd a) b;; let universe_leq a b = match a, b with | a,[(false,b)] -> List.for_all (fun a -> leq_path a b) a | _,_ -> raise (BadConstraint (lazy "trying to check if a universe is less or equal than an inferred universe")) let universe_eq a b = universe_leq b a && universe_leq a b let add_constraint strict a b = match a,b with | [false,a2],[false,b2] -> if not (le_path_uri [] strict a2 b2) then ( if le_path_uri [] (not strict) b2 a2 then (raise (BadConstraint (lazy "universe inconsistency"))); le_constraints := (strict,a2,b2) :: !le_constraints) | _ -> raise (BadConstraint (lazy "trying to add a constraint on an inferred universe")) ;; let typecheck_obj,already_set = ref (fun _ -> assert false), ref false;; let set_typecheck_obj f = if !already_set then assert false else begin typecheck_obj := f; already_set := true end ;; let cache = NUri.UriHash.create 313;; let frozen_list = ref [];; exception Propagate of NUri.uri * exn;; let get_checked_obj u = if List.exists (fun (k,_) -> NUri.eq u k) !frozen_list then raise (CircularDependency (lazy (NUri.string_of_uri u))) else let obj = try NUri.UriHash.find cache u with Not_found -> let saved_frozen_list = !frozen_list in try let obj = try NCicLibrary.get_obj u with NCicLibrary.ObjectNotFound m -> raise (ObjectNotFound m) in frozen_list := (u,obj)::saved_frozen_list; !typecheck_obj obj; frozen_list := saved_frozen_list; let obj = `WellTyped obj in NUri.UriHash.add cache u obj; obj with Sys.Break as e -> frozen_list := saved_frozen_list; raise e | Propagate (u',_) as e' -> frozen_list := saved_frozen_list; let exn = `Exn (BadDependency (lazy (NUri.string_of_uri u ^ " depends (recursively) on " ^ NUri.string_of_uri u' ^ " which is not well-typed"))) in NUri.UriHash.add cache u exn; if saved_frozen_list = [] then exn else raise e' | e -> frozen_list := saved_frozen_list; let exn = `Exn e in NUri.UriHash.add cache u exn; if saved_frozen_list = [] then exn else raise (Propagate (u,e)) in match obj with `WellTyped o -> o | `Exn e -> raise e ;; let get_checked_decl = function | Ref.Ref (uri, Ref.Decl) -> (match get_checked_obj uri with | _,height,_,_, C.Constant (rlv,name,None,ty,att) -> rlv,name,ty,att,height | _,_,_,_, C.Constant (_,_,Some _,_,_) -> prerr_endline "get_checked_decl on a definition"; assert false | _ -> prerr_endline "get_checked_decl on a non decl 2"; assert false) | _ -> prerr_endline "get_checked_decl on a non decl"; assert false ;; let get_checked_def = function | Ref.Ref (uri, Ref.Def _) -> (match get_checked_obj uri with | _,height,_,_, C.Constant (rlv,name,Some bo,ty,att) -> rlv,name,bo,ty,att,height | _,_,_,_, C.Constant (_,_,None,_,_) -> prerr_endline "get_checked_def on an axiom"; assert false | _ -> prerr_endline "get_checked_def on a non def 2"; assert false) | _ -> prerr_endline "get_checked_def on a non def"; assert false ;; let get_checked_indtys = function | Ref.Ref (uri, (Ref.Ind (_,n,_)|Ref.Con (n,_,_))) -> (match get_checked_obj uri with | _,_,_,_, C.Inductive (inductive,leftno,tys,att) -> inductive,leftno,tys,att,n | _ -> prerr_endline "get_checked_indtys on a non ind 2"; assert false) | _ -> prerr_endline "get_checked_indtys on a non ind"; assert false ;; let get_checked_fixes_or_cofixes = function | Ref.Ref (uri, (Ref.Fix (fixno,_,_)|Ref.CoFix fixno))-> (match get_checked_obj uri with | _,height,_,_, C.Fixpoint (_,funcs,att) -> funcs, att, height | _ ->prerr_endline "get_checked_(co)fix on a non (co)fix 2";assert false) | r -> prerr_endline ("get_checked_(co)fix on " ^ Ref.string_of_reference r); assert false ;; let get_relevance (Ref.Ref (_, infos) as r) = match infos with Ref.Def _ -> let res,_,_,_,_,_ = get_checked_def r in res | Ref.Decl -> let res,_,_,_,_ = get_checked_decl r in res | Ref.Ind _ -> let _,_,tl,_,n = get_checked_indtys r in let res,_,_,_ = List.nth tl n in res | Ref.Con (_,i,_) -> let _,_,tl,_,n = get_checked_indtys r in let _,_,_,cl = List.nth tl n in let res,_,_ = List.nth cl (i - 1) in res | Ref.Fix (fixno,_,_) | Ref.CoFix fixno -> let fl,_,_ = get_checked_fixes_or_cofixes r in let res,_,_,_,_ = List.nth fl fixno in res ;; let invalidate _ = assert (!frozen_list = []); NUri.UriHash.clear cache ;;