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

Chapter 8 exercise "reverse" #111

Open
jllang opened this issue Jul 14, 2021 · 8 comments
Open

Chapter 8 exercise "reverse" #111

jllang opened this issue Jul 14, 2021 · 8 comments

Comments

@jllang
Copy link

jllang commented Jul 14, 2021

For reference, here's the template given in the material:

{-@ assume reverse    :: xs:UList a -> UList a    @-}
reverse :: [a] -> [a]
reverse         = go []
  where
    {-@ go     :: acc:[a] -> xs:[a] -> [a] @-}
    go acc []     = acc
    go acc (x:xs) = go (x:acc) xs

The empty list given to go has (vacuously) only unique values, hasn't it? I tried to bind it in a variable and declare it as unique as follows:

reverse :: [a] -> [a]
reverse         = go seed
  where
    {-@ seed :: UList a @-}
    seed          = []
    go acc []     = acc
    go acc (x:xs) = go (x:acc) xs

This led into a weird error:

[ 9 of 13] Compiling Tutorial_08_Measure_Set
ghc: panic! (the 'impossible' happened)
  (GHC version 8.10.1:
	Uh oh.
    Predicate in lhs of constraint:forall <p :: a a -> Bool>.
{lq_tmp$x##7006 : [a]<\lq_tmp$x##7007 VV -> {lq_tmp$x##7005 : a<p lq_tmp$x##7007> | true}> | Tutorial_08_Measure_Set.elts lq_tmp$x##7006 == Set_empty 0
                                                                                             && (Tutorial_08_Measure_Set.unique lq_tmp$x##7006 <=> true)
                                                                                             && len lq_tmp$x##7006 == 0
                                                                                             && Set_emp (listElts lq_tmp$x##7006)}
<:
{VV##0 : [a] | Tutorial_08_Measure_Set.unique VV##0}

Please report this as a GHC bug:  https://www.haskell.org/ghc/reportabug

I wonder what's the issue here.

@jllang jllang changed the title Chapter 8 reverse exercise Chapter 8 exercise "reverse" Jul 14, 2021
@ranjitjhala
Copy link
Member

Wow that’s odd! What happens if you also add a plain GHC signature

seed :: [a]

@jllang
Copy link
Author

jllang commented Jul 14, 2021

It seems that I get the same error even if I add that Haskell type signature.

@ranjitjhala
Copy link
Member

Hmm definitely something odd going on -- I believe it works if you make seed a top-level definition though?

@jllang
Copy link
Author

jllang commented Jul 14, 2021

Yes, I can confirm that defining seed on top-level works.

@yanhasu
Copy link

yanhasu commented Jul 15, 2021

Adding seed :: [a] does make the error go away for me, provided that I also:

  • Add {-# LANGUAGE ScopedTypeVariables #-} at the top of the file
  • Add an explicit forall to the type signature of reverse (to turn lexical scoping of type variables on).

Patched demo

@yanhasu
Copy link

yanhasu commented Jul 15, 2021

I also noticed that you don't even need to use abstract refinements to get the bug.

i.e. if I remove all references to UList and just use plain [a], the bug still arises.

However, if I remove the owl braces {-@ @-} (so that the signature is no longer liquid), the bug goes away (although seed :: [a] is quite misleading, since it re-binds a)

@yanhasu
Copy link

yanhasu commented Jul 15, 2021

I suspect that the bug comes from the built-in refinement of [a].

If I port Blank3 to a custom list type (which doesn't bind an abstract refinement), the bug goes away, even when the type annotation is liquid.

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

3 participants