Positive Almost-Sure Termination
Positive almost-sure termination (PAST for short) means that a program terminates almost-surely and the expected runtime to termination is finite.
In terms of the expected runtime calculus, this means that ert[C](0) < ∞ holds for a program C.
In Caesar, there are several ways to prove PAST:
Upper Bounds on ert
The simplest way to prove positive almost-sure termination is by proving a finite upper bound on the expected runtime of a program using the expected runtime calculus, i.e. . The upper bound must be finite: for every state , must hold.
Upper bounds on the expected runtime can be shown with Park induction.
The ranking-superinvariant rule below can be viewed as a derived way of constructing such an ert-superinvariant.
PAST from Ranking Superinvariants
Caesar supports proofs of PAST using ranking superinvariants, also called ranking supermartingales.
We use the wp-based formulation of Theorem 6.3 in Benjamin Kaminski's PhD thesis.
Closely related statements also appear as:
- Theorem 4 of „Probabilistic Program Analysis with Martingales“ by Chakarov and Sankaranarayanan (CAV 2013).
- Theorem 5.6 of „Probabilistic Termination: Soundness, Completeness, and Compositionality“ by Fioriti and Hermanns (POPL 2015).
Ranking superinvariants are supported via Caesar's built-in @past annotation on while loops.
Formal Theorem
Consider a loop while G { Body } whose Body is exact.1
The loop's used and modified variables, except the ones declared within the loop, are referred to as vars.
Let
- , a function assigning a value to every state,
- ,
- ,
such that all the following conditions are fulfilled:
-
is bounded on terminating states: ,
HeyVL Encoding
proc I_bounded_on_exit(vars: ...) -> ()
{
assert ?(([!G(vars)] * I(vars)) <= K)
} -
is small enough on states where the loop continues: ,
HeyVL Encoding
proc K_bounded_by_I(vars: ...) -> ()
{
assert ?(([G(vars)] * K) <= (([G(vars)] * I(vars)) + [!G(vars)]))
} -
decreases in expectation by at least in each loop iteration: ,2
HeyVL Encoding
proc I_decreases(init_vars: ...) -> (vars: ...)
pre [G(init_vars)] * (I(init_vars) - epsilon)
post 0
{
vars = init_vars // set current state to input values
if G {
Body
assert I(vars)
assume 0
} else {}
}
Then while G { Body } is universally positively almost-surely terminating, i.e. ert[while G { Body }](0) < ∞.
Usage
Consider the following example, where we have a loop that decrements a variable x with probability 0.5 in each iteration.
The loop terminates with probability 1 and the expected number of iterations is finite.
We show this by using the @past annotation on the loop.
proc main(init_x: UInt) -> (x: UInt)
{
var prob_choice: Bool
x = init_x
@past(
/* invariant: */ x + 1,
/* epsilon: */ 0.5,
/* K: */ 1)
while 0 < x {
prob_choice = flip(0.5)
if prob_choice {
x = x - 1
} else {}
}
}
Inputs:
invariant: The ranking superinvariant.epsilon: The expected decrease of the ranking superinvariant in one loop iteration.K: The constant from Conditions 1 and 2.
Mathematically, the rule requires .
Currently, Caesar requires epsilon and K to be literal UReal expressions and checks .
PAST via ert Superinvariants
Every use of @past can be replaced by a proof via an ert-superinvariant.
Let L = while G { Body }.
Assume that and that the decrease premise of @past holds for some and some , i.e. .
Then the following expectation is an ert-superinvariant of with respect to postexpectation :
Hence, by Park induction, . In particular, is PAST since is finite.
Generalization and Proof
More generally, assume that holds for some constant . Then
is an ert-superinvariant of .
The theorem above is the special case .
Write for the ert loop-characteristic function of with postexpectation .
Then
So is an ert-superinvariant of , and Park induction yields .