| C.Sort (C.Type u1), C.Sort (C.Type u2) -> C.Sort (C.Type (max u1 u2))
| C.Sort _,C.Sort (C.Type _) -> t2
| C.Sort (C.Type _) , C.Sort C.CProp -> t1
- | C.Sort _, C.Sort C.CProp -> t2
- | C.Meta _, C.Sort _
- | C.Meta _, C.Meta _
- | C.Sort _, C.Meta _ when U.is_closed t2 -> t2
+ | C.Sort _, C.Sort C.CProp
+ | C.Meta (_,(_,(C.Irl 0 | C.Ctx []))), C.Sort _
+ | C.Meta (_,(_,(C.Irl 0 | C.Ctx []))), C.Meta (_,(_,(C.Irl 0 | C.Ctx [])))
+ | C.Sort _, C.Meta (_,(_,(C.Irl 0 | C.Ctx []))) -> t2
| _ ->
raise (TypeCheckerFailure (lazy (Printf.sprintf
"Prod: expected two sorts, found = %s, %s"
exception DoesOccur;;
let does_not_occur ~subst context n nn t =
- let rec aux (context,n,nn as k) _ = function
- | C.Rel m when m > n && m <= nn -> raise DoesOccur
+ let rec aux k _ = function
+ | C.Rel m when m > n+k && m <= nn+k -> raise DoesOccur
+ | C.Rel m when m > nn+k -> ()
| C.Rel m ->
- (try (match List.nth context (m-1) with
- | _,C.Def (bo,_) -> aux k () (S.lift m bo)
- | _ -> ())
+ (try match List.nth context (m-1-k) with
+ | _,C.Def (bo,_) -> aux (n-m) () bo
+ | _ -> ()
with Failure _ -> assert false)
| C.Meta (_,(_,(C.Irl 0 | C.Ctx []))) -> (* closed meta *) ()
| C.Meta (mno,(s,l)) ->
(try
- let _,_,term,_ = U.lookup_subst mno subst in
- aux (context,n+s,nn+s) () (S.subst_meta (0,l) term)
- with CicUtil.Subst_not_found _ -> match l with
- | C.Irl len -> if not (n >= s+len || s > nn) then raise DoesOccur
- | C.Ctx lc -> List.iter (aux (context,n+s,nn+s) ()) lc)
- | t -> U.fold (fun e (ctx,n,nn) -> (e::ctx,n+1,nn+1)) k aux () t
+ (* possible optimization here: try does_not_occur on l and
+ perform substitution only if DoesOccur is raised *)
+ let _,_,term,_ = U.lookup_subst mno subst in
+ aux (k-s) () (S.subst_meta (0,l) term)
+ with U.Subst_not_found _ -> match l with
+ | C.Irl len -> if not (n+k >= s+len || s > nn+k) then raise DoesOccur
+ | C.Ctx lc -> List.iter (aux (k-s) ()) lc)
+ | t -> U.fold (fun _ k -> k + 1) k aux () t
in
- try aux (context,n,nn) () t; true
+ try aux 0 () t; true
with DoesOccur -> false
;;