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

Extracting numerators/denominators of Rational values #1738

Open
RyanGlScott opened this issue Aug 22, 2024 · 1 comment
Open

Extracting numerators/denominators of Rational values #1738

RyanGlScott opened this issue Aug 22, 2024 · 1 comment
Labels
design needed We need to specify precisely what we want feature request Asking for new or improved functionality

Comments

@RyanGlScott
Copy link
Contributor

Currently, Cryptol offers a way to construct a Rational value from a numerator and a denominator:

primitive ratio : Integer -> Integer -> Rational

It does not offer convenient ways to extract the numerator or the denominator from an existing Rational value, however. That is, there are no functions of these types:

primitive numerator : Rational -> Integer
primitive denominator : Rational -> Integer

This issue tracks whether we should add such functions or not.

What's the risk?

At first glance, it seems like it should be straightforward to implement these. Before we return the numerator or denominator, we need to ensure that they are normalized so that, e.g., numerator (ratio 6 10) == 3 and denominator (ratio 6 10) == 5. To do so, we can compute the greatest common divisor (gcd) of both Integers and divide them by the gcd. For instance, the gcd of 6 and 10 is 2, and indeed we have that 6/2 == 3 and 10/2 == 5.

This plan will work well for concrete Rational values, but what about symbolic Rational values? (Recall that these can arise when :prove-ing properties about Rationals.) It is unclear to me how to implement gcd in a way such that SMT solvers can efficiently reason about it. The usual, recursive definition of gcd is:

gcd x y = gcd' (abs x) (abs y)
  where
    gcd' a b =
      if b == 0
      then a
      else gcd' b (a % b)

This is recursive in the gcd's second argument, but the termination criteria is not very obvious. As such, I suspect that most SMT solvers would infinitely loop if it had to reason about any properties involving gcd.

Accept the risk?

If we can't make numerator/denominator work efficiently for symbolic Rationals, then perhaps we could still add these operations, but prominently advertise that they are not designed to work well with :prove. Would that be an unusual thing to do? I'm not aware of any other Cryptol primitives that are anti–SMT reasoning to quite the same extent, but perhaps I'm just not aware of them.

Don't risk it?

If we decide that adding numerator/denominator is a bad idea, then at the very least, we should document this choice somewhere, as the topic of deconstructing Rational values comes up quite frequently. Perhaps the documentation for Rational would be a good place for this.

@RyanGlScott RyanGlScott added the feature request Asking for new or improved functionality label Aug 22, 2024
@weaversa
Copy link
Collaborator

@auricratio once made a symbolically terminating gcd in Cryptol...

@yav yav added the design needed We need to specify precisely what we want label Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design needed We need to specify precisely what we want feature request Asking for new or improved functionality
Projects
None yet
Development

No branches or pull requests

3 participants