X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Fsoftware%2Fcomponents%2Fng_kernel%2FnCicEnvironment.ml;h=893e514b1fef9f642a212997aa92e54be2c0533c;hb=56d3455abc6bcffd9d0e2af3ed370bf0751057a0;hp=bd0587a43a53f3fd6afb5f8dda9954167c9716f1;hpb=f4d71b463ae8510e80a40cf4df475d19fab3df2c;p=helm.git diff --git a/helm/software/components/ng_kernel/nCicEnvironment.ml b/helm/software/components/ng_kernel/nCicEnvironment.ml index bd0587a43..893e514b1 100644 --- a/helm/software/components/ng_kernel/nCicEnvironment.ml +++ b/helm/software/components/ng_kernel/nCicEnvironment.ml @@ -16,44 +16,191 @@ module Ref = NReference exception CircularDependency of string Lazy.t;; exception ObjectNotFound of string Lazy.t;; -exception BadDependency of string Lazy.t;; +exception BadDependency of string Lazy.t * exn;; exception BadConstraint of string Lazy.t;; +exception AlreadyDefined of string Lazy.t;; -let type0 = [false, NUri.uri_of_string ("cic:/matita/pts/Type.univ")] +let cache = NUri.UriHash.create 313;; +let history = ref [];; +let frozen_list = ref [];; + +let get_obj = ref (fun _ -> assert false);; +let set_get_obj f = get_obj := f;; + +let type0 = [] + +module F = Format + +let rec ppsort f = function + | C.Prop -> F.fprintf f "Prop" + | (C.Type []) -> F.fprintf f "Type0" + | (C.Type [`Type, u]) -> F.fprintf f "%s" (NUri.name_of_uri u) + | (C.Type [`Succ, u]) -> F.fprintf f "S(%s)" (NUri.name_of_uri u) + | (C.Type [`CProp, u]) -> F.fprintf f "P(%s)" (NUri.name_of_uri u) + | (C.Type l) -> + F.fprintf f "Max("; + ppsort f ((C.Type [List.hd l])); + List.iter (fun x -> F.fprintf f ",";ppsort f ((C.Type [x]))) (List.tl l); + F.fprintf f ")" +;; + +let string_of_univ u = + let b = Buffer.create 100 in + let f = Format.formatter_of_buffer b in + ppsort f (NCic.Type u); + Format.fprintf f "@?"; + Buffer.contents b +;; + +let eq_univ (b1,u1) (b2,u2) = b1=b2 && NUri.eq u1 u2;; + +let max (l1:NCic.universe) (l2:NCic.universe) = + match l2 with + | x::tl -> + let rest = List.filter (fun y -> not (eq_univ x y)) (l1@tl) in + x :: HExtlib.list_uniq ~eq:eq_univ + (List.sort (fun (b1,u1) (b2,u2) -> + let res = compare b1 b2 in + if res = 0 then NUri.compare u1 u2 else res) + rest) + | [] -> + match l1 with + | [] -> [] + | ((`Type|`Succ), _)::_ -> l1 + | (`CProp, u)::tl -> (`Type, u)::tl +;; -let le_constraints = ref [] (* strict,a,b *) +let lt_constraints = ref [] (* a,b := a < b *) -let rec le_path_uri avoid strict a b = - (not strict && NUri.eq a b) || +let rec lt_path_uri avoid 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 + (fun (x,y) -> + NUri.eq y b && + (NUri.eq a x || + (not (List.exists (NUri.eq x) avoid) && + lt_path_uri (x::avoid) a x)) + ) !lt_constraints ;; -let leq_path a b = le_path_uri [b] (fst a) (snd a) b;; +let lt_path a b = lt_path_uri [b] a b;; + +let universe_eq a b = + match a,b with + | [(`Type|`CProp) as b1, u1], [(`Type|`CProp) as b2, u2] -> + b1 = b2 && NUri.eq u1 u2 + | _, [(`Type|`CProp),_] + | [(`Type|`CProp),_],_ -> false + | _ -> + raise (BadConstraint + (lazy "trying to check if two inferred universes are equal")) +;; 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")) + | (((`Type|`Succ),_)::_ | []) , [`CProp,_] -> false + | l, [((`Type|`CProp),b)] -> + List.for_all + (function + | `Succ,a -> lt_path a b + | _, a -> NUri.eq a b || lt_path a b) l + | _, ([] | [`Succ,_] | _::_::_) -> + raise (BadConstraint (lazy ( + "trying to check if "^string_of_univ a^ + " is leq than the inferred universe " ^ string_of_univ b))) +;; + +let are_sorts_convertible ~test_eq_only s1 s2 = + match s1,s2 with + | C.Type a, C.Type b when not test_eq_only -> universe_leq a b + | C.Type a, C.Type b -> universe_eq a b + | C.Prop,C.Type _ -> (not test_eq_only) + | C.Prop, C.Prop -> true + | _ -> false +;; + +let pp_constraint x y = + NUri.name_of_uri x ^ " < " ^ NUri.name_of_uri y +;; + +let pp_constraints () = + String.concat "\n" (List.map (fun (x,y) -> pp_constraint x y) !lt_constraints) +;; -let universe_eq a b = universe_leq b a && universe_leq a b +let universes = ref [];; -let add_constraint strict a b = +let get_universes () = + List.map (fun x -> [`Type,x]) !universes @ + List.map (fun x -> [`CProp,x]) !universes +;; + +let is_declared u = + match u with + | [(`CProp|`Type),x] -> List.exists (fun y -> NUri.eq x y) !universes + | _ -> assert false +;; + +exception UntypableSort of string Lazy.t +exception AssertFailure of string Lazy.t + +let typeof_sort = function + | C.Type ([(`Type|`CProp),u] as univ) -> + if is_declared univ then (C.Type [`Succ, u]) + else + raise (UntypableSort (lazy ("undeclared universe " ^ + NUri.string_of_uri u ^ "\ndeclared ones are: " ^ + String.concat ", " (List.map NUri.string_of_uri !universes) + ))) + | C.Type t -> + raise (AssertFailure (lazy ( + "Cannot type an inferred type: "^ string_of_univ t))) + | C.Prop -> (C.Type type0) +;; + +let add_lt_constraint 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) + | [`Type,a2],[`Type,b2] -> + if not (lt_path_uri [] a2 b2) then ( + if lt_path_uri [] b2 a2 || NUri.eq a2 b2 then + (raise(BadConstraint(lazy("universe inconsistency adding "^ + pp_constraint a2 b2 + ^ " to:\n" ^ pp_constraints ())))); + universes := a2 :: b2 :: + List.filter (fun x -> not (NUri.eq x a2 || NUri.eq x b2)) !universes; + lt_constraints := (a2,b2) :: !lt_constraints); + history := (`Constr (a,b))::!history; | _ -> raise (BadConstraint (lazy "trying to add a constraint on an inferred universe")) ;; +let sup l = + match l with + | [(`Type|`CProp),_] -> Some l + | l -> + let bigger_than acc (_s1,n1) = + List.filter (fun x -> lt_path_uri [] n1 x || NUri.eq n1 x) acc + in + let solutions = List.fold_left bigger_than !universes l in + let fam = match l with (`CProp,_)::_ -> `CProp | _ -> `Type in + let rec aux = function + | [] -> None + | u :: tl -> + if List.exists (fun x -> lt_path_uri [] x u) solutions then aux tl + else Some [fam,u] + in + aux solutions +;; + +let allowed_sort_elimination s1 s2 = + match s1, s2 with + | C.Type (((`Type|`Succ),_)::_ | []), C.Type (((`Type|`Succ),_)::_ | []) + | C.Type _, C.Type ((`CProp,_)::_) + | C.Type _, C.Prop + | C.Prop, C.Prop -> `Yes + + | C.Type ((`CProp,_)::_), C.Type (((`Type|`Succ),_)::_ | []) + | C.Prop, C.Type _ -> `UnitOnly +;; + let typecheck_obj,already_set = ref (fun _ -> assert false), ref false;; let set_typecheck_obj f = if !already_set then @@ -65,59 +212,93 @@ let set_typecheck_obj f = end ;; -let cache = NUri.UriHash.create 313;; -let frozen_list = ref [];; +let invalidate_item item = + let item_eq a b = + match a, b with + | `Obj (u1,_), `Obj (u2,_) -> NUri.eq u1 u2 + | `Constr _, `Constr _ -> a=b (* MAKE EFFICIENT *) + | _ -> false + in + let rec aux to_be_deleted = + function + [] -> assert false + | item'::tl when item_eq item item' -> item'::to_be_deleted,tl + | item'::tl -> aux (item'::to_be_deleted) tl + in + let to_be_deleted,h = aux [] !history in + history := h; + List.iter + (function + | `Obj (uri,_) -> NUri.UriHash.remove cache uri + | `Constr ([_,u1],[_,u2]) as c -> + let w = u1,u2 in + if not(List.mem c !history) then + lt_constraints := List.filter ((<>) w) !lt_constraints; + | `Constr _ -> assert false + ) to_be_deleted +;; exception Propagate of NUri.uri * exn;; +let to_exn f x = + match f x with + `WellTyped o -> o + | `Exn e -> raise e +;; + +let check_and_add_obj ((u,_,_,_,_) as obj) = + let saved_frozen_list = !frozen_list in + try + 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'; + history := (`Obj (u,obj))::!history; + obj' + with + Sys.Break as e -> + frozen_list := saved_frozen_list; + raise e + | Propagate (u',old_exn) 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"), + match old_exn with BadDependency (_,e) -> e | _ -> old_exn)) in + NUri.UriHash.add cache u exn; + history := (`Obj (u,obj))::!history; + 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; + history := (`Obj (u,obj))::!history; + if saved_frozen_list = [] then + exn + else + raise (Propagate (u,e)) +;; + 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 + try NUri.UriHash.find cache u + with Not_found -> check_and_add_obj (!get_obj u) +;; + +let get_checked_obj u = to_exn get_checked_obj u;; + +let check_and_add_obj ((u,_,_,_,_) as obj) = + if NUri.UriHash.mem cache u then + raise (AlreadyDefined (lazy (NUri.string_of_uri u))) + else + ignore (to_exn check_and_add_obj obj) ;; let get_checked_decl = function @@ -152,12 +333,12 @@ let get_checked_indtys = function ;; let get_checked_fixes_or_cofixes = function - | Ref.Ref (uri, (Ref.Fix (fixno,_,_)|Ref.CoFix fixno))-> + | Ref.Ref (uri, (Ref.Fix _|Ref.CoFix _))-> (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 + | _ -> prerr_endline "get_checked_(co)fix on a non (co)fix"; assert false ;; let get_relevance (Ref.Ref (_, infos) as r) =