diff options
author | Matthieu Sozeau <matthieu.sozeau@inria.fr> | 2014-07-03 23:45:01 +0200 |
---|---|---|
committer | Matthieu Sozeau <matthieu.sozeau@inria.fr> | 2014-07-03 23:45:01 +0200 |
commit | 23d30ddc2a7cdfa3f71e99f57d36818b16ad40b7 (patch) | |
tree | bdd895f74d2764e4e57a1c4aab65ba4408442190 /library | |
parent | 7e4925b78162226331c65ef77f2da681a0b8ee48 (diff) |
Cleanup code related to the constraint solving, which sits now outside the
kernel in library/universes.ml.
Diffstat (limited to 'library')
-rw-r--r-- | library/universes.ml | 70 | ||||
-rw-r--r-- | library/universes.mli | 5 |
2 files changed, 75 insertions, 0 deletions
diff --git a/library/universes.ml b/library/universes.ml index e84f1f975..1c704bc22 100644 --- a/library/universes.ml +++ b/library/universes.ml @@ -930,3 +930,73 @@ let refresh_constraints univs (ctx, cstrs) = else (Univ.Constraint.add c cstrs', Univ.enforce_constraint c univs)) cstrs (Univ.Constraint.empty, univs) in ((ctx, cstrs'), univs') + + +(**********************************************************************) +(* Tools for sort-polymorphic inductive types *) + +(* Miscellaneous functions to remove or test local univ assumed to + occur only in the le constraints *) + +(* + Solve a system of universe constraint of the form + + u_s11, ..., u_s1p1, w1 <= u1 + ... + u_sn1, ..., u_snpn, wn <= un + +where + + - the ui (1 <= i <= n) are universe variables, + - the sjk select subsets of the ui for each equations, + - the wi are arbitrary complex universes that do not mention the ui. +*) + +let is_direct_sort_constraint s v = match s with + | Some u -> univ_level_mem u v + | None -> false + +let solve_constraints_system levels level_bounds level_min = + let open Univ in + let levels = + Array.map (Option.map + (fun u -> match Universe.level u with + | Some u -> u + | _ -> Errors.anomaly (Pp.str"expects Atom"))) + levels in + let v = Array.copy level_bounds in + let nind = Array.length v in + let clos = Array.map (fun _ -> Int.Set.empty) levels in + (* First compute the transitive closure of the levels dependencies *) + for i=0 to nind-1 do + for j=0 to nind-1 do + if not (Int.equal i j) && is_direct_sort_constraint levels.(j) v.(i) then + clos.(i) <- Int.Set.add j clos.(i); + done; + done; + let rec closure () = + let continue = ref false in + Array.iteri (fun i deps -> + let deps' = + Int.Set.fold (fun j acc -> Int.Set.union acc clos.(j)) deps deps + in + if Int.Set.equal deps deps' then () + else (clos.(i) <- deps'; continue := true)) + clos; + if !continue then closure () + else () + in + closure (); + for i=0 to nind-1 do + for j=0 to nind-1 do + if not (Int.equal i j) && Int.Set.mem j clos.(i) then + (v.(i) <- Universe.sup v.(i) level_bounds.(j); + level_min.(i) <- Universe.sup level_min.(i) level_min.(j)) + done; + for j=0 to nind-1 do + match levels.(j) with + | Some u -> v.(i) <- univ_level_rem u v.(i) level_min.(i) + | None -> () + done + done; + v diff --git a/library/universes.mli b/library/universes.mli index 5b0951928..2fc476732 100644 --- a/library/universes.mli +++ b/library/universes.mli @@ -243,3 +243,8 @@ val minimize_univ_variables : Univ.LSet.t * Univ.universe option Univ.LMap.t * Univ.LSet.t * (bool * bool * Univ.universe) Univ.LMap.t * Univ.constraints + +(** {6 Support for old-style sort-polymorphism } *) + +val solve_constraints_system : universe option array -> universe array -> universe array -> + universe array |