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