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

Add proper support for units #5

Open
snowleopard opened this issue Feb 9, 2018 · 4 comments
Open

Add proper support for units #5

snowleopard opened this issue Feb 9, 2018 · 4 comments

Comments

@snowleopard
Copy link
Member

snowleopard commented Feb 9, 2018

For example, Variable Milli Watt. To be able to use Num instance, we should probably allow arbitrary addition and multiplication, but still reflect meaningless results in the type:

  • 1 :: Variable Milli Watt + 2 :: Variable Milli Watt == 3 :: Variable Milli Watt.
  • 1 :: Variable Milli Watt + 2 :: Variable Micro Watt == 3 :: Variable Error Watt.
  • 1 :: Variable Milli Watt + 2 :: Variable Milli Seconds == 3 :: Variable Milli Error.
@geo2a
Copy link
Member

geo2a commented Feb 18, 2018

I implemented a limited support for units of measurement via units package, please see Redfin.Language.Units and changes to Redfin.Examples.Energy.

For now, units are only used in the verification constraints (as we do in the paper). To be used as an underlying representation for units, a numeric type must be an instance of Fractional, therefore I'm not sure if the high-level language can be easily enriched with units considering the current design. We can do it for fixed-point numbers, but I'm not sure if the full power of the units package may be used for integer values.

At this moment, we have everything we claimed to have in the paper, and the syntax closely resembles our examples, but the proper support for units in the high-level language is still to be implemented.

@snowleopard
Copy link
Member Author

@geo2a Thank you, looks promising!

Can't GHC infer Time here: (30 % Year :: Time) # Second? Presumably, Second implies Time? I think it would be a bit cleaner if we could write (30 % Year) # Second in the example.

At this moment, we have everything we claimed to have in the paper

But we can't do integers, can we? So the example from the paper doesn't really work.

@geo2a
Copy link
Member

geo2a commented Feb 19, 2018

Can't GHC infer Time here: (30 % Year :: Time) # Second? Presumably, Second implies Time? I think it would be a bit cleaner if we could write (30 % Year) # Second in the example.

No, it can't, since the Time type, declared in Redfin.Language.Units, resolves the internal representation of units (Fixed in this case). In the units package, units of measurement are not tied to a concrete numeric type, therefore the abstract Second unit doesn't imply the concrete Time dimension.

I made the examples more ad-hoc, and now they resemble the paper ones as closely as possible

constrain $ t1 .>= 0 &&& t1 .<= toMilliSeconds (30 % Year)

toMilliSeconds :: Time -> Value
toMilliSeconds t = unsafeFixedToValue (t # milli Second)

But we can't do integers, can we? So the example from the paper doesn't really work.

We can, and we do, but with a limitation. The current implementation of fixed-point numbers (see Redfin.Data.Fixed has 8 out of 64 bits devoted to the fractional part. Therefore, we can cook up 56-bit values as Fixed and then convert the result to integral Value type. This is of suboptimal since we must make sure to use only integer literals to avoid rounding and also tracking the overflow by ourselves.

@snowleopard
Copy link
Member Author

snowleopard commented Feb 19, 2018

constrain $ t1 .>= 0 &&& t1 .<= toMilliSeconds (30 % Year)

Looks good!

The current implementation of fixed-point numbers (see Redfin.Data.Fixed has 8 out of 64 bits devoted to the fractional part.

What about switching from newtype Fixed = Fixed { getFixed :: Value } to something like this?

data Fixed = Fixed { getFixed :: Value, fixedToValue :: Value }

unsafeValueToFixed :: Value -> Fixed
unsafeValueToFixed x = Fixed (sShiftLeft x $ literal fracBits) x

Or something similar. Perhaps, we could also split integer and fractional parts into separate fields.

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

No branches or pull requests

2 participants