Prove two functions are equal by extensionality
josedusol opened this issue · comments
Im reading test T1577.hs, which ilustrates the use of the --extensionality
flag. For example:
{-@ reflect plus1 @-}
{-@ reflect plus1' @-}
plus1, plus1' :: Int -> Int
plus1 x = x + 1
plus1' x = 1 + x
{-@ thm1 :: () -> { plus1' == plus1 } @-}
thm1 :: () -> ()
thm1 _ = ()
In this case it seems the proof is discharged automatically by the SMT. However, could it be possible to explicitly write the proof in detail?
I imagine in this simple example the proof could be something like:
==. plus1' x
==. 1 + x
==. x + 1
==. plus1 x
*** QED
But obviously this is not matching the goal { plus1' == plus1 }.
You could, but you would need an extensionality axiom to conclude function equality.
The problem is that function equality is not an easy topic and to encode function extensionality correctly you need a type-based axiom.... https://dl.acm.org/doi/pdf/10.1145/3546189.3549919
Ah, interesting. Will take a look. Thanks
So, im playing with the extensionality axiom as is presented in the paper:
{-@ assume funext :: forall a b. f:(a -> b) -> g:(a -> b) -> (x:a -> {f x = g x}) -> {f = g} @-}
funext _f _g _pf = ()
However, LH doesn't like it:
src\Test.hs:6:22: error:
* Specified type does not refine Haskell type forTest.funext
(Plugged Init types new)
The Liquid type
.
forall a b . (a -> b) -> (a -> b) -> (a -> _) -> _
.
is inconsistent with the Haskell type
.
forall p1 p2 p3 -> p1 -> p2 -> p3 -> ()
.
defined at src\Test.hs:7:1-6
.
Specifically, the Liquid component
.
lq_tmp$db##0:a -> b
.
is inconsistent with the Haskell component
.
p
.HINT: Use the hole '_' instead of the mismatched component (in the Liquid specification)
*
|
6 | {-@ assume funext :: forall a b. f:(a -> b) -> g:(a -> b) -> (x:a -> {f x = g x}) -> {f = g} @-}
Not sure if this is just a version problem (using liquidhaskell-0.9.0.2) or im missing a directive. Besides, what is the purpose of prefixing variable names with underscores (e.g. "_f" or "_g") in proofs ?
Can you add the Haskell type of funext
?
Can you add the Haskell type of
funext
?
Yeah, that and adding --higherorder
solved the issue. Thanks