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

Incomplete reasoning about exponentiation with respect to exhaustiveness checking #1796

Open
RyanGlScott opened this issue Feb 7, 2025 · 0 comments · May be fixed by #1819
Open

Incomplete reasoning about exponentiation with respect to exhaustiveness checking #1796

RyanGlScott opened this issue Feb 7, 2025 · 0 comments · May be fixed by #1819
Assignees
Labels
bug Something not working correctly type-guards typechecker Issues related to type-checking Cryptol code.

Comments

@RyanGlScott
Copy link
Contributor

In certain cases, Cryptol's exhaustiveness checker for numeric constraint guards incorrectly deems sets of guards to be inexhaustive when they involve exponentiation. Here is a program with some relevant examples:

module Bug where

exhaustive1 : {w} [2 ^^ (2 ^^ w)] -> [2 ^^ (2 ^^ w)]
exhaustive1 x
  | (2 ^^ (2 ^^ w)) < 2 => x
  | (2 ^^ (2 ^^ w)) == 2 => ~ x
  | (2 ^^ (2 ^^ w)) > 2 => x

// This should be exhaustive, as it simply reorders the guards found in the
// `exhaustive1` function, but Cryptol deems it non-exhaustive.
nonExhaustive1 : {w} [2 ^^ (2 ^^ w)] -> [2 ^^ (2 ^^ w)]
nonExhaustive1 x
  | (2 ^^ (2 ^^ w)) == 2 => ~ x
  | (2 ^^ (2 ^^ w)) < 2 => x
  | (2 ^^ (2 ^^ w)) > 2 => x

// This should be exhaustive, as it simply reorders the guards found in the
// `exhaustive1` function, but Cryptol deems it non-exhaustive.
nonExhaustive2 : {w} [2 ^^ (2 ^^ w)] -> [2 ^^ (2 ^^ w)]
nonExhaustive2 x
  | (2 ^^ (2 ^^ w)) == 2 => ~ x
  | (2 ^^ (2 ^^ w)) > 2 => x
  | (2 ^^ (2 ^^ w)) < 2 => x

// Note that `(2 ^^ w) >= 1`, which means that there is no need for a
// `(2 ^^ w) < 1` guard below.
exhaustive2 : {w} [2 ^^ w] -> [2 ^^ w]
exhaustive2 x
  | (2 ^^ w) == 1 => ~ x
  | (2 ^^ w) > 1 => x

// This should be exhaustive, as it is a slight variation on the same idea used
// in `exhaustive2`—namely, that `(2 ^^ (2 ^^ w)) >= 2`. Despite this, Cryptol
// deems this function non-exhaustive.
nonExhaustive3 : {w} [2 ^^ (2 ^^ w)] -> [2 ^^ (2 ^^ w)]
nonExhaustive3 x
  | (2 ^^ (2 ^^ w)) == 2 => ~ x
  | (2 ^^ (2 ^^ w)) > 2 => x

I would expect all of the functions above to be marked as exhaustive, but Cryptol does not do so for the functions prefixed with nonExhaustive*:

[warning] at Bug.cry:36:1--36:15:
  Could not prove that the constraint guards used in defining Bug::nonExhaustive3 were exhaustive.
[warning] at Bug.cry:20:1--20:15:
  Could not prove that the constraint guards used in defining Bug::nonExhaustive2 were exhaustive.
[warning] at Bug.cry:12:1--12:15:
  Could not prove that the constraint guards used in defining Bug::nonExhaustive1 were exhaustive.

My understanding is that the typechecker's reasoning about the behavior of exponentiation is necessarily incomplete, but it does feel like we could do better in these specific examples.

@RyanGlScott RyanGlScott added bug Something not working correctly type-guards typechecker Issues related to type-checking Cryptol code. labels Feb 7, 2025
@danmatichuk danmatichuk self-assigned this Feb 28, 2025
danmatichuk added a commit that referenced this issue Feb 28, 2025
this comes at the cost of increasing the time to
fail if the guards are truly non-exhaustive

fixes #1796
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something not working correctly type-guards typechecker Issues related to type-checking Cryptol code.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants