Hey Jeff, I get the following error when I tried your code
resources/custom/liquidhaskell/sandbox/1458413579_6077.hs:5:1: Error: GHC Error
parse error (possibly incorrect indentation or mismatched brackets)
It is definitely possible to combine Abstract and Bounded Refinements to model what you have in mind, but it will indeed require some (a lot of) effort.
I am positive, because I believe (without any formal proof yet) that you can use
Bounded Refinement Types to encode _any_ ghost variable. As an example see
this code:
{-@ T :: forall <p :: x:Symbol -> [a] -> Prop, q :: s:Symbol -> x -> Prop>.
{x::Symbol |- ([a])<p> <: {v:[a] | len v == len x}}
{x::Symbol |- x<q> <: {v:x | v == x}}
([a])<p> -> T x a @-}
You can refine the data constructor `T` using two abstract refinements `p` on lists and `q` on the type variable `x` , so that
- bound 1: p implies your desired length constraint
- bound 2: q relates somehow the symbol x and the type variable x
So, in theory you can use AR to encode what you want. In practice
- We have never tried this kind of encoding before, so you will most probably hit many LH bugs.
- I do not know how proofs on `T` will work, as to use `T` the specification requires the existence of a Symbol `x` that will not exist in your code.
- Note that I am just refining the type constructor `T` because currently the refined data definition does not support any bounds.
Will be happy to help of you have more concrete questions!
Good luck:)
Niki