diff --git a/examples/fenwick.mlw b/examples/fenwick.mlw
new file mode 100644
index 0000000000000000000000000000000000000000..f2dda2a9a19df81fda7fe743507e0554853c7d64
--- /dev/null
+++ b/examples/fenwick.mlw
@@ -0,0 +1,120 @@
+
+(* Fenwick trees (or binary indexed tree) for prefix/interval sums.
+   Represent an integer array over interval [0;n[ such that the following
+   operations are both efficient:
+   . incrementation of individual cell (O(log(n)))
+   . Query sum of elements over interval [a;b[ (O(log(b-a)))
+
+   Author: Martin Clochard (Université Paris Sud) *)
+
+(* Array-based implementation with i->(2i+1,2i+2) node encoding:
+   . Integer represent nodes
+   . 0 is the root
+   . childs of node n are 2n+1 and 2n+2
+   . Leaves represent the model array cells. For n > 0 elements in the model,
+     they are represented by the cells over the range [n-1;2n-1[
+   The structure manage queries by keeping for each node the sum of the
+   values of all descendant leaves, which we call here 'node summary' *)
+module Fenwick
+
+  use import int.Int
+  use import int.ComputerDivision
+  use import ref.Ref
+  use import int.Sum
+  use import array.Array as A
+
+  (* Encode fenwick trees within an array. The leaves field represent
+     the actual number of element within the model. *)
+  type fenwick = {
+    t : array int;
+    ghost leaves : int;
+  }
+
+  (* Invariant *)
+  predicate valid (f:fenwick) =
+    f.leaves >= 0 /\
+    f.t.length = (if f.leaves = 0 then 0 else 2 * f.leaves - 1) /\
+    forall i. 0 <= i /\ i < f.leaves - 1 ->
+      f.t[i] = f.t[2*i+1] + f.t[2*i+2]
+
+  (* Get the i-th elements of the model. *)
+  function get (f:fenwick) (i:int) : int = f.t[i+f.leaves-1]
+  (* Get the sum of elements over range [a;b[ *)
+  function rget (f:fenwick) (a b:int) : int = sum a b (get f)
+
+  (* Create a Fenwick tree initialized at 0 *)
+  let make (lv:int) : fenwick
+    requires { lv >= 0 }
+    ensures { valid result }
+    ensures { forall i. 0 <= i < lv -> get result i = 0 }
+    ensures { result.leaves = lv }
+  = { t = if lv = 0 then make 0 0 else make (2*lv-1) 0;
+      leaves = lv }
+
+  (* Add x to the l-th cell *)
+  let add (f:fenwick) (l:int) (x:int) : unit
+    requires { 0 <= l < f.leaves /\ valid f }
+    ensures { valid f }
+    ensures { forall i. 0 <= i < f.leaves /\ i <> l ->
+      get f i = get (old f) i }
+    ensures { get f l = get (old f) l + x }
+  = let lc = ref (div f.t.length 2 + l) in
+    f.t[!lc] <- f.t[!lc] + x;
+    (* Update node summaries for all elements on the path
+       from the updated leaf to the root. *)
+    'I:
+    while !lc <> 0 do
+      invariant { 0 <= !lc < f.t.length }
+      invariant { forall i. 0 <= i /\ i < f.leaves - 1 ->
+        f.t[i] = f.t[2*i+1] + f.t[2*i+2] -
+          if 2*i+1 <= !lc <= 2*i+2 then x else 0 }
+      invariant { forall i. f.leaves - 1 <= i < f.t.length ->
+        f.t[i] = (at f 'I).t[i] }
+      variant { !lc }
+      lc := div (!lc - 1) 2;
+      f.t[!lc] <- f.t[!lc] + x
+    done
+
+  (* Lemma to shift dum indices. *)
+  let rec ghost sum_dec (a b c:int) : unit
+    requires { a <= b }
+    ensures { forall f g. (forall i. a <= i < b -> f i = g (i+c)) ->
+      sum a b f = sum (a+c) (b+c) g }
+    variant { b - a }
+  = if a < b then sum_dec (a+1) b c
+
+  (* Crucial lemma for the query routine: Summing the node summaries
+     over range [2a+1;2b+1[ is equivalent to summing node summaries
+     over range [a;b[. This is because the elements of range [2a+1;2b+1[
+     are exactly the childs of elements of range [a;b[. *)
+  let rec ghost fen_compact (f:fenwick) (a b:int) : unit
+    requires { 0 <= a <= b /\ 2 * b < f.t.length /\ valid f }
+    ensures { sum a b (A.get f.t) = sum (2*a+1) (2*b+1) (A.get f.t) }
+    variant { b - a }
+  = if a < b then fen_compact f (a+1) b
+
+  (* Query sum of elements over interval [a,b[. *)
+  let query (f:fenwick) (a b:int) : int
+    requires { 0 <= a <= b <= f.leaves /\ valid f }
+    ensures { result = rget f a b }
+  = let lv = div f.t.length 2 in
+    let ra = ref (a + lv) in let rb = ref (b + lv) in
+    let acc = ref 0 in
+    ghost sum_dec a b lv;
+    (* If ra = rb, the sum is 0.
+       Otherwise, adjust the range to odd boundaries in constant time
+       and use compaction lemma to halve interval size. *)
+    while !ra <> !rb do
+      invariant { 0 <= !ra <= !rb <= f.t.length }
+      invariant { !acc + sum !ra !rb (A.get f.t) = rget f a b }
+      variant { !rb - !ra }
+      if mod !ra 2 = 0 then acc := !acc + f.t[!ra];
+      ra := div !ra 2;
+      rb := !rb - 1;
+      if mod !rb 2 <> 0 then acc := !acc + f.t[!rb];
+      rb := div !rb 2;
+      ghost fen_compact f !ra !rb
+    done;
+    !acc
+
+end
diff --git a/examples/fenwick/why3session.xml b/examples/fenwick/why3session.xml
new file mode 100644
index 0000000000000000000000000000000000000000..165a482d639c8fb125dc283de7715284077a76dd
--- /dev/null
+++ b/examples/fenwick/why3session.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE why3session PUBLIC "-//Why3//proof session v5//EN"
+"http://why3.lri.fr/why3session.dtd">
+<why3session shape_version="4">
+<prover id="0" name="CVC4" version="1.4" timelimit="5" steplimit="0" memlimit="1000"/>
+<prover id="1" name="Alt-Ergo" version="1.30" timelimit="5" steplimit="0" memlimit="1000"/>
+<file name="../fenwick.mlw">
+<theory name="Fenwick" sum="2acffcabae53480cd6db25628871c757">
+ <goal name="WP_parameter make" expl="VC for make">
+ <proof prover="1"><result status="valid" time="0.03" steps="29"/></proof>
+ </goal>
+ <goal name="WP_parameter add" expl="VC for add">
+ <proof prover="1"><result status="valid" time="0.74" steps="353"/></proof>
+ </goal>
+ <goal name="WP_parameter sum_dec" expl="VC for sum_dec">
+ <proof prover="1"><result status="valid" time="0.06" steps="67"/></proof>
+ </goal>
+ <goal name="WP_parameter fen_compact" expl="VC for fen_compact">
+ <proof prover="0"><result status="valid" time="1.36"/></proof>
+ </goal>
+ <goal name="WP_parameter query" expl="VC for query">
+ <transf name="split_goal_wp">
+  <goal name="WP_parameter query.1" expl="1. precondition">
+  <proof prover="1"><result status="valid" time="0.01" steps="6"/></proof>
+  </goal>
+  <goal name="WP_parameter query.2" expl="2. loop invariant init">
+  <proof prover="1"><result status="valid" time="0.02" steps="16"/></proof>
+  </goal>
+  <goal name="WP_parameter query.3" expl="3. loop invariant init">
+  <proof prover="1"><result status="valid" time="0.19" steps="154"/></proof>
+  </goal>
+  <goal name="WP_parameter query.4" expl="4. index in array bounds">
+  <proof prover="1"><result status="valid" time="0.01" steps="12"/></proof>
+  </goal>
+  <goal name="WP_parameter query.5" expl="5. index in array bounds">
+  <proof prover="1"><result status="valid" time="0.01" steps="17"/></proof>
+  </goal>
+  <goal name="WP_parameter query.6" expl="6. precondition">
+  <proof prover="1"><result status="valid" time="0.13" steps="95"/></proof>
+  </goal>
+  <goal name="WP_parameter query.7" expl="7. loop invariant preservation">
+  <proof prover="1"><result status="valid" time="0.01" steps="25"/></proof>
+  </goal>
+  <goal name="WP_parameter query.8" expl="8. loop invariant preservation">
+  <proof prover="1"><result status="valid" time="0.78" steps="434"/></proof>
+  </goal>
+  <goal name="WP_parameter query.9" expl="9. loop variant decrease">
+  <proof prover="1"><result status="valid" time="0.11" steps="74"/></proof>
+  </goal>
+  <goal name="WP_parameter query.10" expl="10. precondition">
+  <proof prover="1"><result status="valid" time="0.08" steps="69"/></proof>
+  </goal>
+  <goal name="WP_parameter query.11" expl="11. loop invariant preservation">
+  <proof prover="1"><result status="valid" time="0.01" steps="22"/></proof>
+  </goal>
+  <goal name="WP_parameter query.12" expl="12. loop invariant preservation">
+  <proof prover="1"><result status="valid" time="1.57" steps="646"/></proof>
+  </goal>
+  <goal name="WP_parameter query.13" expl="13. loop variant decrease">
+  <proof prover="1"><result status="valid" time="0.02" steps="32"/></proof>
+  </goal>
+  <goal name="WP_parameter query.14" expl="14. index in array bounds">
+  <proof prover="1"><result status="valid" time="0.00" steps="15"/></proof>
+  </goal>
+  <goal name="WP_parameter query.15" expl="15. precondition">
+  <proof prover="1"><result status="valid" time="0.14" steps="97"/></proof>
+  </goal>
+  <goal name="WP_parameter query.16" expl="16. loop invariant preservation">
+  <proof prover="1"><result status="valid" time="0.01" steps="23"/></proof>
+  </goal>
+  <goal name="WP_parameter query.17" expl="17. loop invariant preservation">
+  <proof prover="1"><result status="valid" time="0.88" steps="427"/></proof>
+  </goal>
+  <goal name="WP_parameter query.18" expl="18. loop variant decrease">
+  <proof prover="1"><result status="valid" time="0.14" steps="70"/></proof>
+  </goal>
+  <goal name="WP_parameter query.19" expl="19. precondition">
+  <proof prover="1"><result status="valid" time="0.09" steps="73"/></proof>
+  </goal>
+  <goal name="WP_parameter query.20" expl="20. loop invariant preservation">
+  <proof prover="1"><result status="valid" time="0.01" steps="20"/></proof>
+  </goal>
+  <goal name="WP_parameter query.21" expl="21. loop invariant preservation">
+  <proof prover="1"><result status="valid" time="1.00" steps="546"/></proof>
+  </goal>
+  <goal name="WP_parameter query.22" expl="22. loop variant decrease">
+  <proof prover="1"><result status="valid" time="0.05" steps="55"/></proof>
+  </goal>
+  <goal name="WP_parameter query.23" expl="23. postcondition">
+  <proof prover="1"><result status="valid" time="0.01" steps="17"/></proof>
+  </goal>
+ </transf>
+ </goal>
+</theory>
+</file>
+</why3session>
diff --git a/examples/fenwick/why3shapes.gz b/examples/fenwick/why3shapes.gz
new file mode 100644
index 0000000000000000000000000000000000000000..5bd7d100e60fe7a83660d239a6e0ad792732da3e
Binary files /dev/null and b/examples/fenwick/why3shapes.gz differ