Skip to content
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

smart constructors for booleans / integers #70

Closed
niedjoh opened this issue Aug 16, 2024 · 4 comments · Fixed by #72
Closed

smart constructors for booleans / integers #70

niedjoh opened this issue Aug 16, 2024 · 4 comments · Fixed by #72
Labels
enhancement New feature or request

Comments

@niedjoh
Copy link

niedjoh commented Aug 16, 2024

It would be convenient to have smart constructors for things like (&&) and (+) which directly handle constants. For example, in Language.Hasmtlib.Internal.Expr.Num you could write:

instance Num (Expr IntSort) where
   fromInteger = Constant . IntValue
   {-# INLINE fromInteger #-}
   (Constant (IntValue 0)) + y = y
   x + (Constant (IntValue 0)) = x
   x + y = Plus x y
   {-# INLINE (+) #-}
   x - (Constant (IntValue 0)) = x
   x - y = Plus x (Neg y)
   {-# INLINE (-) #-}
   (Constant (IntValue 0)) * _ = 0
   _ * (Constant (IntValue 0)) = 0
   (Constant (IntValue 1)) * y = y
   x * (Constant (IntValue 1)) = x
   x * y = Mul x y
   {-# INLINE (*) #-}
   negate      = Neg
   {-# INLINE negate #-}
   abs         = Abs
   {-# INLINE abs #-}
   signum x    = ite (x === 0) 0 $ ite (x <? 0) (-1) 1
   {-# INLINE signum #-}

and Language.Hasmtlib.Internal.Expr could look as follows:

instance Boolean (Expr BoolSort) where
  bool = Constant . BoolValue
  {-# INLINE bool #-}
  (Constant (BoolValue x)) && y = if x then y else false
  x && (Constant (BoolValue y)) = if y then x else false
  x && y = And x y
  {-# INLINE (&&) #-}
  (Constant (BoolValue x)) || y = if x then true else y
  x || (Constant (BoolValue y)) = if y then true else x
  x || y = Or x y
  {-# INLINE (||) #-}
  not (Constant (BoolValue x)) = bool . Prelude.not $ x
  not x = Not x
  {-# INLINE not #-}
  xor (Constant (BoolValue x)) y  = if x then Language.Hasmtlib.Boolean.not y else y
  xor x (Constant (BoolValue y)) = if y then Language.Hasmtlib.Boolean.not x else x
  xor x y = Xor x y
  {-# INLINE xor #-}

I saw that as of version 2.3 the constructors of Expr are exported, so I can now just write wrappers which implement this functionality, but I think it's still a useful enhancement of the library :)

@bruderj15 bruderj15 added the enhancement New feature or request label Aug 16, 2024
@bruderj15
Copy link
Owner

It certainly is!
You may drop a PR if you want. Otherwise i will add it very soon.
This may actually decrease formula size by quite a lot in some use cases.
Thank you!

@bruderj15
Copy link
Owner

Any specific reason why not for Real and BitVec?
I will add them otherwise and publish to hackage.

@niedjoh
Copy link
Author

niedjoh commented Aug 16, 2024

no specific reason - these are just the cases which I need at the moment ^^
It also just occured to me that I forgot to add proper constant folding for the Num instance, e.g.

(Constant (IntValue x))  + (Constant (IntValue y)) = Constant (IntValue (x + y))

and also for the other functions. thanks for your quick reply!

@bruderj15 bruderj15 linked a pull request Aug 16, 2024 that will close this issue
@bruderj15
Copy link
Owner

Has been published with v2.3.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants