True
is a bad argument10
is a good argument0
average
take
fib
fib
is an uninterpreted function
LiquidHaskell checks by default that all your functions terminate!
Why?
fib
Q: Why is there an error?
Liquid Haskell checks a well founded metric decreases at each recursive call.
Well founded metrics:
The first integer is not always decreasing!
Q: Replace 0
with the decreasing metric!
Liquid Haskell checks a well founded metric decreases at each recursive call.
Well founded metrics:
Why does Ackermann Function terminate?
Q: Replace 0
with the decreasing metrics!
Map ADTs to integers using measures!
But Liquid Haskell knows that!
It will use len
as the default metric to check x:[a]
decreasing.
Does merge
terminate?
Liquid Haskell cannot know that!
Same idea generalizes to mutual recursion.
Can you find the correct metric?
Liquid Haskell does not even attempt to guess it...
lazy
annotation deactivates termination checking.
For non Lazy
specified functions,
Liquid Haskell checks a well founded metric decreases at each recursive call.
Well founded metrics:
What properties can be expressed in the logic?
Linear Arithmetic, Booleans, Uninterpreted Functions, ... (SMT logic)
Terminating Haskell functions.
Next: Refinement Reflection