aboutsummaryrefslogtreecommitdiffhomepage
path: root/kernel/univ.ml
diff options
context:
space:
mode:
authorGravatar letouzey <letouzey@85f007b7-540e-0410-9357-904b9bb8a0f7>2012-02-27 18:28:05 +0000
committerGravatar letouzey <letouzey@85f007b7-540e-0410-9357-904b9bb8a0f7>2012-02-27 18:28:05 +0000
commitd3935d5fb70db8755b7bb96fdb75ba126d0cfad6 (patch)
treee7cb680697b8bb5700744ba00691630292dbeffa /kernel/univ.ml
parente0da5c0227680becfc9bf87046b26afb290c55a3 (diff)
Univ: correct compare_neq (fix #2703)
The earlier version was a bit too quick to answer <= while strict constraints could still appear from remaining universes to explore. Typical situation: compare u v when u <= v and u <= w < v. Encountering u <= v isn't enough to conclude yet... This means that kernels from r13719 to now in trunk, and from r13735 to now in 8.3 (including 8.3pl{1,2,3}) couldn't accurately detect universe inconsistencies, leading to potential proofs of False! Oups, sorry... git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@14993 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'kernel/univ.ml')
-rw-r--r--kernel/univ.ml38
1 files changed, 22 insertions, 16 deletions
diff --git a/kernel/univ.ml b/kernel/univ.ml
index a89345440..345bc3e07 100644
--- a/kernel/univ.ml
+++ b/kernel/univ.ml
@@ -260,12 +260,15 @@ type order = EQ | LT | LE | NLE
(** [compare_neq] : is [arcv] in the transitive upward closure of [arcu] ?
- We try to avoid visiting unneeded parts of this transitive closure,
- by stopping as soon as [arcv] is encountered. During the recursive
- traversal, [lt_done] and [le_done] are universes we have already
- visited, they do not contain [arcv]. The 3rd arg is
- [(lt_todo,le_todo)], two lists of universes not yet considered,
- known to be above [arcu], strictly or not.
+ If [arcv] is encountered in a LT part, we could directly answer
+ without visiting unneeded parts of this transitive closure.
+ If [arcv] is encountered in a LE part, we could only change the
+ default answer (1st arg [c]) from NLE to LE, since a strict
+ constraint may appear later. During the recursive traversal,
+ [lt_done] and [le_done] are universes we have already visited,
+ they do not contain [arcv]. The 4rd arg is [(lt_todo,le_todo)],
+ two lists of universes not yet considered, known to be above [arcu],
+ strictly or not.
We use depth-first search, but the presence of [arcv] in [new_lt]
is checked as soon as possible : this seems to be slightly faster
@@ -273,30 +276,33 @@ type order = EQ | LT | LE | NLE
*)
let compare_neq g arcu arcv =
- let rec cmp lt_done le_done = function
- | [],[] -> NLE
+ let rec cmp c lt_done le_done = function
+ | [],[] -> c
| arc::lt_todo, le_todo ->
if List.memq arc lt_done then
- cmp lt_done le_done (lt_todo,le_todo)
+ cmp c lt_done le_done (lt_todo,le_todo)
else
let lt_new = can g (arc.lt@arc.le) in
if List.memq arcv lt_new then LT
- else cmp (arc::lt_done) le_done (lt_new@lt_todo,le_todo)
+ else cmp c (arc::lt_done) le_done (lt_new@lt_todo,le_todo)
| [], arc::le_todo ->
- if arc == arcv then LE
- (* No need to continue inspecting universes above arc:
- if arcv is strictly above arc, then we would have a cycle *)
+ if arc == arcv then
+ (* No need to continue inspecting universes above arc:
+ if arcv is strictly above arc, then we would have a cycle.
+ But we cannot answer LE yet, a stronger constraint may
+ come later from [le_todo]. *)
+ cmp LE lt_done le_done ([],le_todo)
else
if (List.memq arc lt_done) || (List.memq arc le_done) then
- cmp lt_done le_done ([],le_todo)
+ cmp c lt_done le_done ([],le_todo)
else
let lt_new = can g arc.lt in
if List.memq arcv lt_new then LT
else
let le_new = can g arc.le in
- cmp lt_done (arc::le_done) (lt_new, le_new@le_todo)
+ cmp c lt_done (arc::le_done) (lt_new, le_new@le_todo)
in
- cmp [] [] ([],[arcu])
+ cmp NLE [] [] ([],[arcu])
let compare g arcu arcv =
if arcu == arcv then EQ else compare_neq g arcu arcv