Commit 8a6f9e75 authored by Jean-Christophe Filliâtre's avatar Jean-Christophe Filliâtre
Browse files

tortoise and hare example totally revamped

this is much closer now to TAOCP, vol 2, exercise 6 page 7
parent 626ca4d8
......@@ -3,88 +3,162 @@
See The Art of Computer Programming, vol 2, exercise 6 page 7. *)
module TortoiseAndHare
module TortoiseAndHareAlgorithm
use import int.Int
use int.Iter
use import int.EuclideanDivision
use import int.Iter
use import seq.Seq
use import seq.Distinct
use import ref.Refint
use import pigeon.Pigeonhole
type t
val predicate eq (x y : t)
ensures { result <-> x = y }
val function f int : int
(* let f be a function from t to t *)
val function f t : t
(* f maps 0..m-1 to 0..m-1 *)
constant m: int
axiom m_positive: m > 0
axiom f_range: forall x. 0 <= x < m -> 0 <= f x < m
(* given some initial value x0 *)
val constant x0: t
val constant x0: int
ensures { 0 <= result < m }
(* we can build the infinite sequence defined by x{i+1} = f(xi) *)
function x (i: int): t = Iter.iter f i x0
(* let use assume now that the sequence (x_i) has finitely many distinct
values (e.g. f is an integer function with values in 0..m)
it means that there exists values lambda and mu such that
(1) x0, x1, ... x{mu+lambda-1} are all distinct,
and
(2) x{n+lambda} = x_n when n >= mu. *)
(* lambda and mu are skomlemized *)
constant mu : int
constant lambda : int
(* they are axiomatized as follows *)
axiom mu_range: 0 <= mu
axiom lambda_range: 1 <= lambda
axiom distinct:
forall i j: int. 0 <= i < mu+lambda -> 0 <= j < mu+lambda ->
i <> j -> x i <> x j
axiom cycle: forall n: int. mu <= n -> x (n + lambda) = x n
lemma cycle_induction:
forall n: int. mu <= n -> forall k: int. 0 <= k -> x (n + lambda * k) = x n
(* Now comes the code.
Two references, tortoise and hare, traverses the sequence (xi)
at speed 1 and 2 respectively. We stop whenever they are equal.
The challenge is to prove termination.
Actually, we even prove that the code runs in time O(lambda + mu). *)
use import ref.Ref
use import relations.WellFounded
(* the minimal distance between x i and x j *)
function dist int int : int
(* it is defined as soon as i,j >= mu *)
axiom dist_def: forall i j: int. mu <= i -> mu <= j ->
dist i j >= 0 /\
x (i + dist i j) = x j /\
forall k: int. 0 <= k -> x (i + k) = x j -> dist i j <= k
predicate rel (t2 t1: t) =
exists i: int. t1 = x i /\ t2 = x (i+1) /\ 1 <= i <= mu + lambda /\
(i >= mu -> dist (2*i+2) (i+1) < dist (2*i) i)
axiom wfrel: well_founded rel
let tortoise_hare () =
function x (i: int): int = iter f i x0
let rec lemma x_in_range (n: int)
requires { 0 <= n } ensures { 0 <= x n < m }
variant { n }
= if n > 0 then x_in_range (n - 1)
(* First, we prove the existence of mu and lambda, with a ghost program.
Starting with x0, we repeteadly apply f, storing the elements in
a sequence, until we find a repetition. *)
let ghost periodicity () : (int, int)
returns { mu, lambda ->
0 <= mu < m /\ 1 <= lambda <= m /\ mu + lambda <= m /\
x (mu + lambda) = x mu /\
forall i j. 0 <= i < j < mu + lambda -> x i <> x j
}
= let s = ref (singleton x0) in
let cur = ref x0 in
for k = 1 to m do
invariant { 1 <= length !s = k <= m /\ !cur = !s[length !s - 1] }
invariant { forall i. 0 <= i < length !s -> !s[i] = x i }
invariant { distinct !s }
cur := f !cur;
(* look for a repetition *)
for mu = 0 to length !s - 1 do
invariant { forall i. 0 <= i < mu -> !s[i] <> !cur }
if !cur = !s[mu] then return (mu, length !s - mu)
done;
s := snoc !s !cur;
if k = m then pigeonhole (m+1) m (pure { fun i -> !s[i] })
done;
absurd
(* Then we can state the condition for two elements to be equal. *)
let lemma equality (mu lambda: int)
requires { 0 <= mu < m /\ 1 <= lambda <= m /\ mu + lambda <= m /\
x (mu + lambda) = x mu }
requires { forall i j. 0 <= i < j < mu + lambda -> x i <> x j }
ensures { forall r n. r > n >= 0 ->
x r = x n <-> n >= mu /\ exists k. k >= 1 /\ r-n = k*lambda }
= let rec lemma plus_lambda (n: int) variant { n }
requires { mu <= n }
ensures { x (n + lambda) = x n } =
if n > mu then plus_lambda (n - 1) in
let rec lemma plus_lambdas (n k: int) variant { k }
requires { mu <= n } requires { 0 <= k }
ensures { x (n + k * lambda) = x n } =
if k > 0 then begin
plus_lambdas n (k - 1); plus_lambda (n + (k - 1) * lambda) end in
let decomp (i: int) : (int, int)
requires { i >= mu }
returns { qi,mi -> i = mu + qi * lambda + mi && qi >= 0 &&
0 <= mi < lambda && x i = x (mu + mi) } =
let qi = div (i - mu) lambda in
let mi = mod (i - mu) lambda in
plus_lambdas (mu + mi) qi;
qi, mi in
let lemma equ (r n: int)
requires { r > n >= 0 } requires { x r = x n }
ensures { n >= mu /\ exists k. k >= 1 /\ r-n = k*lambda } =
if n < mu then (if r >= mu then let _ = decomp r in absurd)
else begin
let qr,mr = decomp r in let qn, mn = decomp n in
assert { mr = mn };
assert { r-n = (qr-qn) * lambda }
end in
()
(* Finally, we implement the tortoise and hare algorithm that computes
the values of mu and lambda in linear time and constant space *)
let tortoise_and_hare () : (int, int)
returns { mu, lambda ->
0 <= mu < m /\ 1 <= lambda <= m /\ mu + lambda <= m /\
x (mu + lambda) = x mu /\
forall i j. 0 <= i < j < mu + lambda -> x i <> x j
}
= let mu, lambda = periodicity () in
equality mu lambda;
(* the first loop implements the tortoise and hare,
and finds the smallest n >= 1 such that x n = x (2n) *)
let tortoise = ref (f x0) in
let hare = ref (f (f x0)) in
while not (eq !tortoise !hare) do
let n = ref 1 in
while !tortoise <> !hare do
invariant {
exists t: int.
1 <= t <= mu+lambda /\ !tortoise = x t /\ !hare = x (2 * t) /\
forall i: int. 1 <= i < t -> x i <> x (2*i) }
variant { !tortoise with rel }
1 <= !n <= mu+lambda /\ !tortoise = x !n /\ !hare = x (2 * !n) /\
forall i. 1 <= i < !n -> x i <> x (2*i) }
variant { mu + lambda - !n }
tortoise := f !tortoise;
hare := f (f !hare)
done
(* TODO: code to find out lambda and mu. See wikipedia. *)
hare := f (f !hare);
incr n;
if !n > mu + lambda then begin
let m = lambda - mod mu lambda in
let i = mu + m in
assert { 2*i - i = (div mu lambda + 1) * lambda };
absurd
end
done;
let n = !n in
assert { n >= mu };
assert { exists k. k >= 1 /\ n = k * lambda >= 1 };
assert { forall j. j >= mu -> x j = x (j + n) };
let xn = !tortoise in
(* a first loop to find mu *)
let i = ref 0 in
let xi = ref x0 in (* = x i *)
let xni = ref xn in (* = x (n+i) *)
while !xi <> !xni do
invariant { 0 <= !i <= mu }
invariant { !xi = x !i /\ !xni = x (n + !i) }
invariant { forall j. 0 <= j < !i -> x j <> x (n + j) }
variant { mu - !i }
xi := f !xi;
xni := f !xni;
incr i;
done;
let m = !i in
assert { m = mu };
(* and a second loop to find lambda
(this is slightly less efficient than the argument in TAOCP,
but since the first loop is already O(mu+lambda), using two loops
respectively O(mu) and O(lambda) is not a problem). *)
i := 1;
xni := f xn;
while !xni <> xn do
invariant { !xni = x (n + !i) }
invariant { forall j. 1 <= j < !i -> x (n + j) <> x n }
invariant { 1 <= !i <= lambda }
variant { lambda - !i }
xni := f !xni;
incr i
done;
assert { !i = lambda };
m, !i
end
......@@ -2,30 +2,370 @@
<!DOCTYPE why3session PUBLIC "-//Why3//proof session v5//EN"
"http://why3.lri.fr/why3session.dtd">
<why3session shape_version="4">
<prover id="0" name="Coq" version="8.7.1" timelimit="5" steplimit="0" memlimit="1000"/>
<prover id="1" name="Coq" version="8.7.2" timelimit="5" steplimit="0" memlimit="0"/>
<prover id="3" name="Alt-Ergo" version="1.30" timelimit="5" steplimit="0" memlimit="1000"/>
<prover id="4" name="Z3" version="4.5.0" timelimit="5" steplimit="0" memlimit="1000"/>
<prover id="2" name="Alt-Ergo" version="2.0.0" timelimit="1" steplimit="0" memlimit="1000"/>
<prover id="5" name="Z3" version="4.4.0" timelimit="1" steplimit="0" memlimit="1000"/>
<prover id="6" name="CVC4" version="1.5" timelimit="1" steplimit="0" memlimit="1000"/>
<prover id="7" name="Eprover" version="1.8-001" timelimit="16" steplimit="0" memlimit="1000"/>
<file name="../tortoise_and_hare.mlw" proved="true">
<theory name="TortoiseAndHare" proved="true">
<theory name="TortoiseAndHareAlgorithm" proved="true">
<goal name="VC x0" expl="VC for x0" proved="true">
<transf name="split_goal_right" proved="true" >
<proof prover="6"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="VC x_in_range" expl="VC for x_in_range" proved="true">
<proof prover="2"><result status="valid" time="0.36" steps="311"/></proof>
</goal>
<goal name="VC periodicity" expl="VC for periodicity" proved="true">
<transf name="split_vc" proved="true" >
<goal name="VC periodicity.0" expl="loop invariant init" proved="true">
<proof prover="6"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="VC periodicity.1" expl="loop invariant init" proved="true">
<proof prover="6"><result status="valid" time="0.18"/></proof>
</goal>
<goal name="VC periodicity.2" expl="loop invariant init" proved="true">
<proof prover="6"><result status="valid" time="0.06"/></proof>
</goal>
<goal name="VC periodicity.3" expl="loop invariant init" proved="true">
<proof prover="2"><result status="valid" time="0.01" steps="16"/></proof>
</goal>
<goal name="VC periodicity.4" expl="VC for periodicity" proved="true">
<proof prover="6"><result status="valid" time="0.19"/></proof>
</goal>
<goal name="VC periodicity.5" expl="loop invariant preservation" proved="true">
<proof prover="6"><result status="valid" time="0.07"/></proof>
</goal>
<goal name="VC periodicity.6" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.03"/></proof>
</goal>
<goal name="VC periodicity.7" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.19"/></proof>
</goal>
<goal name="VC periodicity.8" expl="loop invariant preservation" proved="true">
<proof prover="6"><result status="valid" time="1.24"/></proof>
</goal>
<goal name="VC periodicity.9" expl="loop invariant preservation" proved="true">
<proof prover="2"><result status="valid" time="0.92" steps="823"/></proof>
</goal>
<goal name="VC periodicity.10" expl="loop invariant preservation" proved="true">
<proof prover="6"><result status="valid" time="0.16"/></proof>
</goal>
<goal name="VC periodicity.11" expl="VC for periodicity" proved="true">
<proof prover="6"><result status="valid" time="0.05"/></proof>
</goal>
<goal name="VC periodicity.12" expl="unreachable point" proved="true">
<proof prover="6"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="VC periodicity.13" expl="unreachable point" proved="true">
<proof prover="6"><result status="valid" time="0.06"/></proof>
</goal>
</transf>
</goal>
<goal name="cycle_induction" proved="true">
<proof prover="0" edited="tortoise_and_hare_WP_TortoiseAndHare_cycle_induction_1.v"><result status="valid" time="0.36"/></proof>
<goal name="VC equality" expl="VC for equality" proved="true">
<transf name="split_vc" proved="true" >
<goal name="VC equality.0" expl="variant decrease" proved="true">
<proof prover="6"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="VC equality.1" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.03"/></proof>
</goal>
<goal name="VC equality.2" expl="postcondition" proved="true">
<proof prover="6"><result status="valid" time="0.03"/></proof>
</goal>
<goal name="VC equality.3" expl="variant decrease" proved="true">
<proof prover="6"><result status="valid" time="0.07"/></proof>
</goal>
<goal name="VC equality.4" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.05"/></proof>
</goal>
<goal name="VC equality.5" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.05"/></proof>
</goal>
<goal name="VC equality.6" expl="precondition" proved="true">
<transf name="assert" proved="true" arg1="((k-1)*lambda &gt;= 0)">
<goal name="VC equality.6.0" proved="true">
<proof prover="7"><result status="valid" time="2.45"/></proof>
</goal>
<goal name="VC equality.6.1" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.03"/></proof>
</goal>
</transf>
</goal>
<goal name="VC equality.7" expl="postcondition" proved="true">
<proof prover="6"><result status="valid" time="0.06"/></proof>
</goal>
<goal name="VC equality.8" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="VC equality.9" expl="precondition" proved="true">
<transf name="split_all_full" proved="true" >
<goal name="VC equality.9.0" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.09"/></proof>
</goal>
</transf>
</goal>
<goal name="VC equality.10" expl="precondition" proved="true">
<transf name="split_vc" proved="true" >
<goal name="VC equality.10.0" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.05"/></proof>
</goal>
</transf>
</goal>
<goal name="VC equality.11" expl="precondition" proved="true">
<proof prover="5"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="VC equality.12" expl="postcondition" proved="true">
<proof prover="5"><result status="valid" time="0.18"/></proof>
</goal>
<goal name="VC equality.13" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.04"/></proof>
</goal>
<goal name="VC equality.14" expl="unreachable point" proved="true">
<transf name="split_all_full" proved="true" >
<goal name="VC equality.14.0" expl="unreachable point" proved="true">
<proof prover="6"><result status="valid" time="0.04"/></proof>
</goal>
</transf>
</goal>
<goal name="VC equality.15" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.03"/></proof>
</goal>
<goal name="VC equality.16" expl="precondition" proved="true">
<transf name="split_vc" proved="true" >
<goal name="VC equality.16.0" expl="precondition" proved="true">
<proof prover="7"><result status="valid" time="0.03"/></proof>
</goal>
</transf>
</goal>
<goal name="VC equality.17" expl="assertion" proved="true">
<proof prover="6"><result status="valid" time="0.03"/></proof>
</goal>
<goal name="VC equality.18" expl="assertion" proved="true">
<proof prover="5"><result status="valid" time="0.21"/></proof>
</goal>
<goal name="VC equality.19" expl="postcondition" proved="true">
<proof prover="2"><result status="valid" time="0.03" steps="73"/></proof>
</goal>
<goal name="VC equality.20" expl="postcondition" proved="true">
<transf name="split_vc" proved="true" >
<goal name="VC equality.20.0" expl="VC for equality" proved="true">
<proof prover="6"><result status="valid" time="0.08"/></proof>
</goal>
<goal name="VC equality.20.1" expl="VC for equality" proved="true">
<proof prover="2"><result status="valid" time="0.01" steps="15"/></proof>
</goal>
<goal name="VC equality.20.2" expl="VC for equality" proved="true">
<transf name="assert" proved="true" arg1="((k-1) * lambda &gt;= 0)">
<goal name="VC equality.20.2.0" proved="true">
<proof prover="7"><result status="valid" time="5.90"/></proof>
</goal>
<goal name="VC equality.20.2.1" expl="VC for equality" proved="true">
<proof prover="7"><result status="valid" time="0.22"/></proof>
</goal>
</transf>
</goal>
</transf>
</goal>
</transf>
</goal>
<goal name="VC tortoise_hare" expl="VC for tortoise_hare" proved="true">
<transf name="split_goal_right" proved="true" >
<goal name="VC tortoise_hare.0" expl="loop invariant init" proved="true">
<proof prover="3"><result status="valid" time="0.02" steps="77"/></proof>
<proof prover="4" obsolete="true"><result status="valid" time="0.02"/></proof>
<goal name="VC tortoise_and_hare" expl="VC for tortoise_and_hare" proved="true">
<transf name="split_vc" proved="true" >
<goal name="VC tortoise_and_hare.0" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="VC tortoise_and_hare.1" expl="precondition" proved="true">
<transf name="split_vc" proved="true" >
<goal name="VC tortoise_and_hare.1.0" expl="precondition" proved="true">
<transf name="split_all_full" proved="true" >
<goal name="VC tortoise_and_hare.1.0.0" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.05"/></proof>
</goal>
</transf>
</goal>
</transf>
</goal>
<goal name="VC tortoise_and_hare.2" expl="loop invariant init" proved="true">
<proof prover="6"><result status="valid" time="0.07"/></proof>
</goal>
<goal name="VC tortoise_and_hare.3" expl="precondition" proved="true">
<proof prover="6"><result status="valid" time="0.04"/></proof>
</goal>
<goal name="VC tortoise_and_hare.4" expl="assertion" proved="true">
<proof prover="2"><result status="valid" time="0.02" steps="20"/></proof>
</goal>
<goal name="VC tortoise_and_hare.5" expl="unreachable point" proved="true">
<proof prover="2"><result status="valid" time="0.63" steps="396"/></proof>
</goal>
<goal name="VC tortoise_and_hare.6" expl="loop variant decrease" proved="true">
<proof prover="6"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="VC tortoise_and_hare.7" expl="loop invariant preservation" proved="true">
<transf name="split_vc" proved="true" >
<goal name="VC tortoise_and_hare.7.0" expl="VC for tortoise_and_hare" proved="true">
<proof prover="6"><result status="valid" time="0.04"/></proof>
</goal>
<goal name="VC tortoise_and_hare.7.1" expl="VC for tortoise_and_hare" proved="true">
<proof prover="6"><result status="valid" time="0.03"/></proof>
</goal>
<goal name="VC tortoise_and_hare.7.2" expl="VC for tortoise_and_hare" proved="true">
<proof prover="6"><result status="valid" time="0.29"/></proof>
</goal>
<goal name="VC tortoise_and_hare.7.3" expl="VC for tortoise_and_hare" proved="true">
<proof prover="6"><result status="valid" time="0.12"/></proof>
</goal>
<goal name="VC tortoise_and_hare.7.4" expl="VC for tortoise_and_hare" proved="true">
<proof prover="6"><result status="valid" time="0.10"/></proof>
</goal>
</transf>
</goal>
<goal name="VC tortoise_and_hare.8" expl="assertion" proved="true">
<proof prover="5"><result status="valid" time="0.04"/></proof>
</goal>
<goal name="VC tortoise_and_hare.9" expl="assertion" proved="true">
<transf name="instantiate" proved="true" arg1="H7" arg2="(n+n),n">
<goal name="VC tortoise_and_hare.9.0" expl="assertion" proved="true">
<proof prover="2"><result status="valid" time="0.01" steps="33"/></proof>
</goal>
</transf>
</goal>
<goal name="VC tortoise_and_hare.10" expl="assertion" proved="true">
<transf name="destruct" proved="true" arg1="H1">
<goal name="VC tortoise_and_hare.10.0" expl="assertion" proved="true">
<transf name="replace" proved="true" arg1="n" arg2="(k*lambda)">
<goal name="VC tortoise_and_hare.10.0.0" expl="assertion" proved="true">
<transf name="instantiate" proved="true" arg1="H10" arg2="(j+n),j">
<goal name="VC tortoise_and_hare.10.0.0.0" expl="assertion" proved="true">
<proof prover="6"><result status="valid" time="0.12"/></proof>
</goal>
</transf>
</goal>
<goal name="VC tortoise_and_hare.10.0.1" proved="true">
<proof prover="6"><result status="valid" time="0.04"/></proof>
</goal>
</transf>
</goal>
</transf>
</goal>
<goal name="VC tortoise_and_hare.11" expl="loop invariant init" proved="true">
<transf name="split_all_full" proved="true" >
<goal name="VC tortoise_and_hare.11.0" expl="VC for tortoise_and_hare" proved="true">
<proof prover="2"><result status="valid" time="0.01" steps="19"/></proof>
</goal>
<goal name="VC tortoise_and_hare.11.1" expl="VC for tortoise_and_hare" proved="true">
<proof prover="6"><result status="valid" time="0.05"/></proof>
</goal>
</transf>
</goal>
<goal name="VC tortoise_and_hare.12" expl="loop invariant init" proved="true">
<proof prover="6"><result status="valid" time="0.25"/></proof>
</goal>
<goal name="VC tortoise_and_hare.13" expl="loop invariant init" proved="true">
<proof prover="5"><result status="valid" time="0.01"/></proof>
</goal>
<goal name="VC tortoise_and_hare.14" expl="loop variant decrease" proved="true">
<transf name="case" proved="true" arg1="(i = mu+1)">
<goal name="VC tortoise_and_hare.14.0" expl="true case (loop variant decrease)" proved="true">
<transf name="assert" proved="true" arg1="(x mu = x (mu + n))">
<goal name="VC tortoise_and_hare.14.0.0" proved="true">
<proof prover="6"><result status="valid" time="0.05"/></proof>
</goal>
<goal name="VC tortoise_and_hare.14.0.1" expl="true case (loop variant decrease)" proved="true">
<proof prover="6"><result status="valid" time="0.12"/></proof>
</goal>
</transf>
</goal>
<goal name="VC tortoise_and_hare.14.1" expl="false case (loop variant decrease)" proved="true">
<proof prover="5"><result status="valid" time="0.03"/></proof>
</goal>
</transf>
</goal>
<goal name="VC tortoise_and_hare.15" expl="loop invariant preservation" proved="true">
<transf name="replace" proved="true" arg1="n" arg2="(2*n - n)">
<goal name="VC tortoise_and_hare.15.0" expl="loop invariant preservation" proved="true">
<proof prover="2"><result status="valid" time="0.01" steps="36"/></proof>
</goal>
<goal name="VC tortoise_and_hare.15.1" proved="true">
<proof prover="6"><result status="valid" time="0.02"/></proof>
</goal>
</transf>
</goal>
<goal name="VC tortoise_and_hare.16" expl="loop invariant preservation" proved="true">
<proof prover="6"><result status="valid" time="0.27"/></proof>
</goal>
<goal name="VC tortoise_and_hare.17" expl="loop invariant preservation" proved="true">
<proof prover="6"><result status="valid" time="0.07"/></proof>
</goal>
<goal name="VC tortoise_and_hare.18" expl="assertion" proved="true">
<proof prover="6"><result status="valid" time="0.60"/></proof>
</goal>
<goal name="VC tortoise_and_hare.19" expl="loop invariant init" proved="true">
<proof prover="6"><result status="valid" time="0.09"/></proof>
</goal>
<goal name="VC tortoise_and_hare.20" expl="loop invariant init" proved="true">
<proof prover="6"><result status="valid" time="0.03"/></proof>
</goal>
<goal name="VC tortoise_and_hare.21" expl="loop invariant init" proved="true">
<proof prover="6"><result status="valid" time="0.05"/></proof>
</goal>
<goal name="VC tortoise_and_hare.22" expl="loop variant decrease" proved="true">
<proof prover="6"><result status="valid" time="0.04"/></proof>
</goal>
<goal name="VC tortoise_and_hare.23" expl="loop invariant preservation" proved="true">
<proof prover="6"><result status="valid" time="0.06"/></proof>
</goal>
<goal name="VC tortoise_and_hare.24" expl="loop invariant preservation" proved="true">
<proof prover="2"><result status="valid" time="0.02" steps="41"/></proof>
</goal>
<goal name="VC tortoise_and_hare.25" expl="loop invariant preservation" proved="true">
<transf name="split_vc" proved="true" >
<goal name="VC tortoise_and_hare.25.0" expl="VC for tortoise_and_hare" proved="true">
<proof prover="6"><result status="valid" time="0.03"/></proof>
</goal>
<goal name="VC tortoise_and_hare.25.1" expl="VC for tortoise_and_hare" proved="true">
<transf name="assert" proved="true" arg1="(x (n+lambda) = x n)">
<goal name="VC tortoise_and_hare.25.1.0" proved="true">
<proof prover="6"><result status="valid" time="0.39"/></proof>
</goal>
<goal name="VC tortoise_and_hare.25.1.1" expl="VC for tortoise_and_hare" proved="true">
<proof prover="5"><result status="valid" time="0.02"/></proof>
</goal>
</transf>
</goal>
</transf>
</goal>
<goal name="VC tortoise_hare.1" expl="loop variant decrease" proved="true">
<proof prover="1" memlimit="1000" edited="tortoise_and_hare_WP_TortoiseAndHare_WP_parameter_tortoise_hare_1.v"><result status="valid" time="0.43"/></proof>
<goal name="VC tortoise_and_hare.26" expl="assertion" proved="true">
<transf name="instantiate" proved="true" arg1="H23" arg2="(n+i),n">
<goal name="VC tortoise_and_hare.26.0" expl="assertion" proved="true">
<transf name="assert" proved="true" arg1="(exists k. k &gt;= 1 /\ i = k * lambda)">
<goal name="VC tortoise_and_hare.26.0.0" proved="true">
<proof prover="6"><result status="valid" time="0.04"/></proof>
</goal>
<goal name="VC tortoise_and_hare.26.0.1" expl="assertion" proved="true">
<transf name="destruct" proved="true" arg1="h">
<goal name="VC tortoise_and_hare.26.0.1.0" expl="assertion" proved="true">
<transf name="case" proved="true" arg1="(k=1)">
<goal name="VC tortoise_and_hare.26.0.1.0.0" expl="true case (assertion)" proved="true">
<proof prover="6"><result status="valid" time="0.04"/></proof>
</goal>
<goal name="VC tortoise_and_hare.26.0.1.0.1" expl="false case (assertion)" proved="true">
<transf name="assert" proved="true" arg1="(x (n + (k-1) * lambda) = x n)">
<goal name="VC tortoise_and_hare.26.0.1.0.1.0" proved="true">
<proof prover="6"><result status="valid" time="0.52"/></proof>
</goal>
<goal name="VC tortoise_and_hare.26.0.1.0.1.1" expl="false case (assertion)" proved="true">
<proof prover="6"><result status="valid" time="0.60"/></proof>
</goal>