Skip to content

Commit ae87ec5

Browse files
committed
Fix soudness bug in Enum
The PR OCamlPro#1078 introduces a soundness bug in `assume_distinct`. We have to propagate explanations of singleton domains, otherwise we may raise Inconsistency with an empty explanation. Add a test that caught the bug.
1 parent 7e1fdbf commit ae87ec5

4 files changed

Lines changed: 319 additions & 8 deletions

File tree

src/lib/reasoners/enum_rel.ml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ module Domain = struct
5151

5252
let[@inline always] choose { constrs; _ } = HSS.choose constrs
5353

54-
let[@inline always] as_singleton { constrs; _ } =
54+
let[@inline always] as_singleton { constrs; ex } =
5555
if HSS.cardinal constrs = 1 then
56-
Some (HSS.choose constrs)
56+
Some (HSS.choose constrs, ex)
5757
else
5858
None
5959

@@ -128,10 +128,10 @@ module Domains = struct
128128

129129
let get r t =
130130
match Th.embed r with
131-
| Cons (r, _) ->
131+
| Cons (c, _) ->
132132
(* For sake of efficiency, we don't look in the map if the
133133
semantic value is a constructor. *)
134-
Domain.singleton ~ex:Explanation.empty r
134+
Domain.singleton ~ex:Explanation.empty c
135135
| _ ->
136136
try MX.find r t.domains
137137
with Not_found ->
@@ -297,14 +297,16 @@ let assume_distinct ~ex r1 r2 env =
297297
let d2 = Domains.get r2 env.domains in
298298
let env =
299299
match Domain.as_singleton d1 with
300-
| Some c ->
300+
| Some (c, ex1) ->
301+
let ex = Ex.union ex1 ex in
301302
let nd = Domain.remove ~ex c d2 in
302303
tighten_domain r2 nd env
303304
| None ->
304305
env
305306
in
306307
match Domain.as_singleton d2 with
307-
| Some c ->
308+
| Some (c, ex2) ->
309+
let ex = Ex.union ex2 ex in
308310
let nd = Domain.remove ~ex c d1 in
309311
tighten_domain r1 nd env
310312
| None ->
@@ -364,9 +366,9 @@ let propagate_domains env =
364366
Domains.propagate
365367
(fun eqs rr d ->
366368
match Domain.as_singleton d with
367-
| Some c ->
369+
| Some (c, ex) ->
368370
let nr = Th.is_mine (Cons (c, X.type_info rr)) in
369-
let eq = Literal.LSem (LR.mkv_eq rr nr), d.ex, Th_util.Other in
371+
let eq = Literal.LSem (LR.mkv_eq rr nr), ex, Th_util.Other in
370372
eq :: eqs
371373
| None ->
372374
eqs

tests/dune.inc

Lines changed: 292 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/sum/testfile-sum019.ae

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
type house = H1 | H2 | H3 | H4
2+
3+
logic h1, h2 : house
4+
5+
predicate leftof(h1: house, h2: house) =
6+
(h2 = H2 -> h1 <> H2 and h1 <> H3 and h1 <> H4) (* h1 = H1 *)
7+
and
8+
(h2 = H3 -> h1 <> H1 and h1 <> H3 and h1 <> H4) (* h1 = H2 *)
9+
and
10+
(h2 = H4 -> h1 <> H1 and h1 <> H2 and h1 <> H4) (* h1 = H3 *)
11+
and
12+
(h2 = H1 -> h1 <> H1 and h1 <> H2 and h1 <> H3) (* h1 = H4 *)
13+
14+
axiom clue : leftof(h1, h2)
15+
goal g : false

tests/sum/testfile-sum019.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
unknown

0 commit comments

Comments
 (0)