-
Notifications
You must be signed in to change notification settings - Fork 76
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
Improve trigonometric abstractions #1272
Conversation
This yields 4 more successful tasks, I'll start it on the server. |
src/cdomains/floatDomain.ml
Outdated
@@ -907,8 +929,16 @@ module FloatIntervalImplLifted = struct | |||
let acos = lift (F1.acos, F2.acos) | |||
let asin = lift (F1.asin, F2.asin) | |||
let atan = lift (F1.atan, F2.atan) | |||
let cos = lift (F1.cos, F2.cos) | |||
let sin = lift (F1.sin, F2.sin) | |||
let cos ?(asPreciseAsConcrete=BoolDomain.MustBool.top ()) ?(notInf_notNaN=BoolDomain.MustBool.top ()) = function |
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.
let cos ?(asPreciseAsConcrete=BoolDomain.MustBool.top ()) ?(notInf_notNaN=BoolDomain.MustBool.top ()) = function | |
let cos ?(asPreciseAsConcrete=false) ?(notInf_notNaN=false) = function |
BoolDomain.MustBool.top ()
is false
.
src/cdomains/floatDomain.ml
Outdated
| F64 a -> F64 (F2.cos ~asPreciseAsConcrete:true ~notInf_notNaN a) | ||
| FLong a -> FLong (F2.cos ~notInf_notNaN a) | ||
| FFloat128 a -> FFloat128 (F2.cos ~notInf_notNaN a) | ||
let sin ?(asPreciseAsConcrete=BoolDomain.MustBool.top ()) ?(notInf_notNaN=BoolDomain.MustBool.top ()) = function |
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.
let sin ?(asPreciseAsConcrete=BoolDomain.MustBool.top ()) ?(notInf_notNaN=BoolDomain.MustBool.top ()) = function | |
let sin ?(asPreciseAsConcrete=false) ?(notInf_notNaN=false) = function |
src/cdomains/floatDomain.ml
Outdated
map { f1= (fun (type a) (module F : FloatDomain with type t = a) -> F.cos); } | ||
let sin = | ||
map { f1= (fun (type a) (module F : FloatDomain with type t = a) -> F.sin); } | ||
let cos ?(asPreciseAsConcrete=BoolDomain.MustBool.top ()) ?(notInf_notNaN=BoolDomain.MustBool.top ()) = |
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.
let cos ?(asPreciseAsConcrete=BoolDomain.MustBool.top ()) ?(notInf_notNaN=BoolDomain.MustBool.top ()) = | |
let cos ?(asPreciseAsConcrete=false) ?(notInf_notNaN=false) = |
src/cdomains/floatDomain.ml
Outdated
map { f1= (fun (type a) (module F : FloatDomain with type t = a) -> F.sin); } | ||
let cos ?(asPreciseAsConcrete=BoolDomain.MustBool.top ()) ?(notInf_notNaN=BoolDomain.MustBool.top ()) = | ||
map { f1= (fun (type a) (module F : FloatDomain with type t = a) -> F.cos ~asPreciseAsConcrete ~notInf_notNaN); } | ||
let sin ?(asPreciseAsConcrete=BoolDomain.MustBool.top ()) ?(notInf_notNaN=BoolDomain.MustBool.top ()) = |
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.
let sin ?(asPreciseAsConcrete=BoolDomain.MustBool.top ()) ?(notInf_notNaN=BoolDomain.MustBool.top ()) = | |
let sin ?(asPreciseAsConcrete=false) ?(notInf_notNaN=false) = |
src/cdomains/floatDomain.ml
Outdated
@@ -791,8 +791,30 @@ module FloatIntervalImpl(Float_t : CFloatType) = struct | |||
let acos = eval_unop eval_acos | |||
let asin = eval_unop eval_asin | |||
let atan = eval_unop eval_atan | |||
let cos = eval_unop eval_cos | |||
let sin = eval_unop eval_sin | |||
let cos ?(asPreciseAsConcrete=false) ?(notInf_notNaN=false) op = |
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.
Seems like we should be able to get some reuse here for sin
and cos
.
let isNotNan = Q.MLInv.exists (fun (y, ml) -> matchnan ml && isFalse y) s in | ||
let isNotInf = Q.MLInv.exists (fun (y, ml) -> matchinf ml && isFalse y) s in | ||
isNotInf && isNotNan) |
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.
Might make sense to restructure so the lookup for isNotInf
doesn't always happen.
match Queries.ID.to_bool v with | ||
| Some b -> not b | ||
| None -> false) |
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.
match Queries.ID.to_bool v with | |
| Some b -> not b | |
| None -> false) | |
Queries.ID.to_bool v = Some false) |
@@ -2355,6 +2355,40 @@ struct | |||
| _ -> failwith ("non-integer argument in call to function "^f.vname) | |||
end | |||
in | |||
let apply_better_trig fk (float_fun : ?asPreciseAsConcrete:bool -> ?notInf_notNaN:bool -> FD.t -> FD.t) x = |
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.
Is the type annotation needed, it looks a bit clunky.
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.
Possibly, because the type inference of optional arguments is not principal: https://dev.realworldocaml.org/variables-and-functions.html#inference-of-labeled-and-optional-arguments.
D.add (v, Offset.Exp.of_cil offs) ((ML.lift fun_args, Deps.of_list ((Lval lv)::arglist))) d | ||
else ( | ||
if M.tracing then M.trace "tmpSpecialInv" "build tmpSpecial Entry for Lval %s\n" v.vname; | ||
let d1 = MM.add (v, Offset.Exp.of_cil offs) ((ML.lift fun_args, Deps.of_list ((Lval lv)::arglist))) (fst d) in |
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.
I think some parens are unneeded here...
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.
Also Deps.of_list ((Lval lv)::arglist))
is constructed twice here.
let mlv = MInvEntrySet.fold (fun (v, ml, deps) acc -> Queries.MLInv.add (v,ml) acc) es (Queries.MLInv.empty ()) | ||
|> Queries.MLInv.filter (fun (v,ml) -> | ||
match ml, v with | ||
| `Bot, _ -> false | ||
| _, `Lifted exp -> true | ||
| _ -> false) in |
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.
This way of doing looks as if it may be in a figure of speech potentially trying to achieve the goal in a way that might be described as roundabout. You might want to do the filtering right in place. 😉
|
||
(* arg maps to (x, mathf(arg), deps) if x = mathf(arg) *) | ||
module ExpFlat = Lattice.Flat (CilType.Exp) (Printable.DefaultNames) | ||
module MInvEntry = Lattice.Prod3 (ExpFlat) (ML) (Deps) |
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.
Have you tried this type:
module MInvEntry = Printable.Prod3 (CilType.Exp) (LibraryDesc.MathPrintable) (SetDomain.Make(CilType.Exp))
Might make it easier on the inside to give up on the lattice structure that is unused anyway.
Since this is still in need of refactoring/cleanup, it's too late to include for SV-COMP 2024. Four additional tasks out of ~32000 is not worth the risk for a possible regression. |
There is no regression, we ran it overnight on all tasks with full timeouts. |
It's not just about SV-COMP though. It will be the representative version of Goblint for the entire year to come. If something doesn't yet meet our own standards, then it's not ready for such release. This is just too last minute, considering the freezing deadline we set for ourselves. |
Ok. I think it would've been nice for Sarah's work this past week to be reflected in that version, but I won't push too hard. |
Why is the |
let matchinf = function | ||
| `Lifted LibraryDesc.Isnan _ -> true |
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.
let matchinf = function | |
| `Lifted LibraryDesc.Isnan _ -> true | |
let matchinf = function | |
| `Lifted LibraryDesc.Isinf _ -> true |
As this PR only shows improvements on four SV-Comp tasks but introduces quite some additional code, we will close this PR. |
This PR improves the abstraction of the
cos
function if the argument is neither nan nor inf bytmpSpecial
analysiscos(x)
in case one can assure that variables representingisInf(x)
andisNaN
are definitely false