Termination Checking
Why termination Checking?
By default, LH checks that functions terminate!
Most functions should terminate.
Example: Termination of fib
Q: Why is there an error?
Proving Termination ...
... is difficult (Halting Problem = NP-Complete).
Proving Termination
Two main ways to prove termnination:
Syntactic: Recursive calls only happen on smaller inputs.
Semantic: (Finite Chains) A value is descreasing at each resursive call.
This value (called well founded metric) cannot get negative!
Proving Termination
Liquid Haskell Checks:
Some well founded metric decreases at each recursive call.
Heuristic Metric:
The first Int parameter.
Example: Termination of fib
Automatically Proved Terminating
User Specified Termination Metrics
The first Int need not always be decreasing!
Specify metric as an expression over the inputs
User Specified Termination Metrics
The first Int need not always be decreasing!
Excercise: Fill in metric that proves range terminates.
Proving Termination
Liquid Haskell Checks:
Some well founded metric decreases at each recursive call.
Either first Int parameter (default)
or
User specified metric
Lexicographic Termination
Why does Ackermann Function terminate?
First argument m decreases or second argument n decreases.
Specify lexicographically ordered sequence of termination metrics [m, n]
How About Data Types?
Why does map terminate?
Recursive Calls on Smaller Lists.
Use first parameter with associated size
... as default metric.
User specified metrics on ADTs
What does merge terminate?
Q: The default is insufficient here; can you fill in a suitable metric?
Mutually Recursive Functions
Same idea generalizes to mutual recursion.
Q: Can you find the correct metric?
Liquid Haskell does not even attempt to guess it...
Diverging Functions
Some functions do not terminate!
lazy annotation deactivates termination checking.
Proving Termination
Liquid Haskell Checks
Some well founded metric decreases at each recursive call.
First Int or sized parameter (default), or
User specified lexicographic metric, or
The function is marked lazy.
Recap
| Refinements: | Types + Predicates |
| Specification: | Refined Input/Output Types |
| Verification: | SMT-based Predicate Subtyping |
| Measures: | Specify Properties of Data |
| Termination: | Well-founded Metrics |
Thank You!
https://github.com/ucsd-progsys/liquidhaskell
http://www.refinement-types.org
online demo @ http://goto.ucsd.edu/liquidhaskell