-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix distinct unsoundness #890
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -239,9 +239,13 @@ and make_form up_qv name_base ~toplevel f loc ~decl_kind : E.t = | |
let res = make_term up_qv name_base t in | ||
if negated then E.neg res else res | ||
|
||
| TAneq lt | TAdistinct lt -> | ||
| TAneq lt -> | ||
let lt = List.map (make_term up_qv name_base) lt in | ||
E.mk_distinct ~iff:true lt | ||
|
||
| TAdistinct lt -> | ||
E.mk_distinct ~iff:true (List.map (make_term up_qv name_base) lt) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we avoid these changes? They don't seem useful, and keeping the patch as tiny as possible makes it easier to cherry-pick and move around if needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. Besides, we should use a different constructor for TAneq? It's not documented and I'm not sure what is the expected semantic for this constructor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| TAle [t1;t2] -> | ||
E.mk_builtin ~is_pos:true Sy.LE | ||
[make_term up_qv name_base t1; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1337,7 +1337,7 @@ let rec mk_expr | |
end | ||
|
||
| B.Distinct, _ -> | ||
E.mk_distinct ~iff:true (List.map (fun t -> aux_mk_expr t) args) | ||
E.mk_distinct ~iff:true (List.map aux_mk_expr args) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, can we undo this? There shouldn't be this sort of unrelated cleanup in a hotfix. |
||
|
||
| B.Constructor _, _ -> | ||
let name = get_basename path in | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1210,10 +1210,20 @@ let mk_nary_eq l = | |
with Exit -> | ||
vrai | ||
|
||
let mk_distinct ~iff tl = | ||
match tl with | ||
| [a; b] -> neg (mk_eq ~iff a b) | ||
| _ -> neg (mk_nary_eq tl) | ||
let mk_distinct ~iff args = | ||
(* This fix makes sure that the smart constructor agrees with | ||
the SMT-LIB specification when used with at least 3 arguments. | ||
To prevent a soundness bug, we translate the expected expression into a | ||
conjonction of binary disequations. *) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: this is not specifically related to the SMT-LIB specification but to the usual definition of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also the comment should point to #889 which will track the fix in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually I didn't plan to apply this patch on next but I can. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok :) |
||
let args = Array.of_list args in | ||
let acc = ref vrai in | ||
for i = 0 to Array.length args - 1 do | ||
for j = i + 1 to Array.length args - 1 do | ||
acc := | ||
mk_and (neg (mk_eq ~iff args.(i) args.(j))) !acc false | ||
done; | ||
done; | ||
!acc | ||
Comment on lines
+1219
to
+1227
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: it doesn't really matter here as this is a hotfix but conversion to an array is not needed: let distinct_from x acc ys =
List.fold_left (fun acc y -> mk_and (neg (mk_eq ~iff x y)) acc) acc ys
in let rec distinct_aux acc = function
| [] -> acc
| x :: ys -> distinct_aux (distinct_from x acc ys) ys
in distinct_aux acc args There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know but I think the imperative version is the easier to read and a bit less error-prone. It's a matter of taste. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is not only a matter of taste (I also find the imperative version easier to read in this specific case); the imperative version is slower and uses more memory because of the call to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure ;) |
||
|
||
let mk_builtin ~is_pos n l = | ||
let pos = | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
unknown |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
(set-logic ALL) | ||
(declare-const a Int) | ||
(declare-const b Int) | ||
(declare-const c Int) | ||
(assert (not (distinct a b c))) | ||
(assert (distinct a b)) | ||
(check-sat) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you undo this whitespace change? Thanks.