diff --git a/opam b/opam
index f221a563d28604d800206a45629726462bb97aff..3e99c4d8e557f9f68b9b50f8ffb89125f3521478 100644
--- a/opam
+++ b/opam
@@ -40,6 +40,7 @@ authors: [
   "Philippe Herrmann"
   "Maxime Jacquemin"
   "Florent Kirchner"
+  "Alexander Kogtenkov"
   "Tristan Le Gall"
   "Jean-Christophe Léchenet"
   "Matthieu Lemerre"
diff --git a/src/plugins/gui/help_manager.ml b/src/plugins/gui/help_manager.ml
index 5a9f2a5d04cae97f1fb2b0a96af33e62b3c49efe..9d08557f5be500e6d7a3bfb2bd634388664e8b5f 100644
--- a/src/plugins/gui/help_manager.ml
+++ b/src/plugins/gui/help_manager.ml
@@ -43,6 +43,7 @@ let show main_ui =
     "Philippe Herrmann";
     "Maxime Jacquemin";
     "Florent Kirchner";
+    "Alexander Kogtenkov";
     "Tristan Le Gall";
     "Jean-Christophe Léchenet";
     "Matthieu Lemerre";
diff --git a/src/plugins/wp/share/why3/frama_c_wp/vlist.mlw b/src/plugins/wp/share/why3/frama_c_wp/vlist.mlw
index 838aa45061449c66db8dd2d6ec2a567ee2ce883b..90dd0399e3cdf498d95a0e8fc2d56d4f8ae02fcb 100644
--- a/src/plugins/wp/share/why3/frama_c_wp/vlist.mlw
+++ b/src/plugins/wp/share/why3/frama_c_wp/vlist.mlw
@@ -28,61 +28,132 @@ theory Vlist
 
   use int.Int
   use int.ComputerDivision
+  use list.Append
+  use list.HdTl
+  use list.Nth
+  use option.Option
+
+  use export list.List
+  use export list.Length
 
   (* -------------------------------------------------------------------- *)
   (* --- Classical Lists for Alt-Ergo                                 --- *)
   (* -------------------------------------------------------------------- *)
 
-  type list 'a
+  function nil : list 'a = Nil
+
+  function cons (x: 'a) (xs: list 'a) : list 'a = Cons x xs
+
+  let function head (l: list 'a) : 'a
+    requires { l <> Nil }
+    ensures  { hd l = Some result }
+  = match l with Nil -> absurd | Cons h _ -> h end
+
+  let function tail (l: list 'a) : list 'a
+    requires { l <> Nil }
+    ensures  { tl l = Some result }
+  = match l with Nil -> absurd | Cons _ t -> t end
 
-  function nil : list 'a
-  function cons 'a (list 'a) : list 'a
-  function concat (list 'a) (list 'a) : list 'a
-  function repeat (list 'a) int : list 'a
-  function length (list 'a) : int
-  function nth (list 'a) int : 'a
+  function concat (xs: list 'a) (ys: list 'a) : list 'a = xs ++ ys
 
   function elt (x:'a) : list 'a  = cons x nil
 
+  (* repeat *)
+  (* Here we are forced to use axiomatic definition to conform to ACSL *)
+
+  function repeat (xs: list 'a) (n: int) : list 'a
+
+  axiom repeat_empty:
+    forall xs : list 'a.
+      repeat xs 0 = Nil
+
+  axiom repeat_pos:
+    forall xs : list 'a, n. n > 0 ->
+      repeat xs n = xs ++ repeat xs (n - 1)
+
+  (* nth *)
+  (* Here we are forced to use axiomatic definition to conform to ACSL *)
+
+  function nth (l: list 'a) (n: int): 'a
+
+  axiom nth_zero:
+    forall l : list 'a, x.
+      nth (Cons x l) 0 = x
+
+  axiom nth_pos:
+    forall l : list 'a, n.
+      l <> Nil -> 0 < n < length l -> nth l n = nth (tail l) (n-1)
+
+  (* -------------------------------------------------------------------- *)
+  (* --- concat                                                       --- *)
+  (* -------------------------------------------------------------------- *)
+
+  lemma concat_cons: forall u v: list 'a, x: 'a.
+    concat (cons x u) v = cons x (concat u v)
+
+  let lemma head_concat (u v: list 'a)
+    requires { u <> Nil }
+    ensures  { head (concat u v) = head u }
+  = match u with Nil -> absurd | Cons _ _ -> () end
+
+  lemma concat_tail:
+    forall u v: list 'a. u <> Nil -> concat (tail u) v = tail (concat u v)
+
   (* -------------------------------------------------------------------- *)
   (* --- length                                                       --- *)
   (* -------------------------------------------------------------------- *)
 
-  axiom length_pos : forall w:list 'a. (Int.(<=) 0 (length w))
+  lemma length_pos : forall w:list 'a. (Int.(<=) 0 (length w))
+
+  lemma length_nil : length (nil: list 'a) = 0
 
-  axiom length_nil : length (nil: list 'a) = 0
+  lemma length_nil_bis : forall w:list 'a. length w = 0 -> w = nil
 
-  axiom length_nil_bis : forall w:list 'a. length w = 0 -> w = nil
+  lemma length_not_nil : forall w:list 'a. w <> Nil -> 0 < length w
 
-  axiom length_cons :
+  lemma length_cons :
     forall x:'a, w:list 'a [length (cons x w)].
       length (cons x w) = (Int.(+) 1 (length w))
 
-  axiom length_concat :
+  lemma length_tail:
+    forall w: list 'a.
+      w <> Nil -> length (tail w) = length w - 1
+
+  lemma singleton_tail: forall w: list 'a. length w = 1 -> tail w = Nil
+
+  lemma length_concat :
     forall u,v:list 'a [length (concat u v)].
       length (concat u v) = (Int.(+) (length u) (length v))
 
-  axiom length_repeat : 
-    forall w:list 'a, n:int [length (repeat w n)].
-      (Int.(<=) 0 n) -> length (repeat w n) = (Int.( * ) n (length w))
+  let rec lemma length_repeat (w: list 'a) (n: int)
+    requires { 0 <= n }
+    ensures  { length (repeat w n) = (Int.( * ) n (length w)) }
+    variant  { n }
+  = if 0 < n then length_repeat w (n - 1)
 
   (* -------------------------------------------------------------------- *)
   (* --- nth                                                          --- *)
   (* -------------------------------------------------------------------- *)
 
-  axiom nth_cons: 
+  lemma nth_cons:
     forall k:int, x:'a, w:list 'a [nth (cons x w) k].
-      nth (cons x w) k = if k = 0 then x else nth w (k-1)
+      0 <= k <= length w -> nth (cons x w) k = if k = 0 then x else nth w (k-1)
+
+  let lemma nth_head (w: list 'a)
+    requires { w <> Nil }
+    ensures  { nth w 0 = head w }
+  = match w with Nil -> absurd | Cons _ _ -> () end
 
-  axiom nth_concat: 
-    forall u,v:list 'a, k:int [nth (concat u v) k].
-      nth (concat u v) k = if k < length u then nth u k 
-                                           else nth v (Int.(-) k (length u))
+  lemma nth_tail:
+    forall k: int, w: list 'a.
+      0 < k < length w - 1 -> nth (tail w) (k - 1) = nth w k
 
-  axiom nth_repeat: 
-    forall n,k:int, w:list 'a [nth (repeat w n) k].
-      0 <= k < (Int.( * ) n (length w)) -> (Int.(<) 0 (length w)) ->
-      nth (repeat w n) k = nth w (mod k (length w))
+  let rec lemma nth_concat (u v: list 'a) (k: int)
+    requires { 0 <= k < length u + length v }
+    ensures  { nth (concat u v) k =
+                 if k < length u then nth u k else nth v (k - length u) }
+    variant  { k }
+  = if 0 < k && 0 < length u then nth_concat (tail u) v (k - 1)
 
   (* -------------------------------------------------------------------- *)
   (* --- equality of Lists                                            --- *)
@@ -92,8 +163,13 @@ theory Vlist
     length u = length v &&
     forall i:int. 0 <= i < length u -> nth u i = nth v i
 
-  axiom extensionality:
-    forall u,v:list 'a. vlist_eq u v -> u = v
+  let rec lemma extensionality (u v: list 'a)
+    requires { vlist_eq u v }
+    ensures  { u = v }
+    variant  { length u }
+  = assert { forall x: 'a, r: list 'a. head (cons x r) = x } ;
+    assert { forall x: 'a, r: list 'a. tail (cons x r) = r } ;
+    match u, v with Cons _ x, Cons _ y -> extensionality x y | _ -> () end
 
   (* -------------------------------------------------------------------- *)
   (* --- neutral elements                                             --- *)
@@ -101,7 +177,6 @@ theory Vlist
 
   lemma eq_nil_concat:
     forall w:list 'a. vlist_eq (concat nil w) w /\ vlist_eq (concat w nil) w
-  meta "remove_for_" lemma eq_nil_concat
 
   lemma rw_nil_concat_left:
     forall w:list 'a [concat nil w]. concat nil w = w
@@ -114,28 +189,24 @@ theory Vlist
   (* -------------------------------------------------------------------- *)
 
   lemma eq_cons_concat:
-    forall x:'a, v,w:list 'a [concat (cons x v) w]. 
+    forall x:'a, v,w:list 'a [concat (cons x v) w].
       vlist_eq (concat (cons x v) w) (cons x (concat v w))
-  meta "remove_for_" lemma eq_cons_concat
 
   lemma rw_cons_concat:
     forall x:'a, v,w:list 'a [concat (cons x v) w].
       (concat (cons x v) w) = (cons x (concat v w))
-  meta "remove_for_" lemma rw_cons_concat
 
   lemma rw_nil_cons_concat:
     forall x:'a, w:list 'a [concat (cons x nil) w].
       (concat (cons x nil) w) = (cons x w)
-  meta "remove_for_" lemma rw_nil_cons_concat
 
   (* -------------------------------------------------------------------- *)
   (* --- associativity                                                --- *)
   (* -------------------------------------------------------------------- *)
 
-  lemma eq_assoc_concat: 
+  lemma eq_assoc_concat:
     forall u,v,w:list 'a.
       vlist_eq (concat (concat u v) w) (concat u (concat v w))
-  meta "remove_for_" lemma eq_assoc_concat
 
   (* -------------------------------------------------------------------- *)
   (* --- repeat                                                       --- *)
@@ -149,53 +220,76 @@ theory Vlist
     forall w:list 'a [repeat w 0].
       repeat w 0 = nil
 
-  lemma eq_repeat_one:
-    forall w:list 'a. vlist_eq (repeat w 1) w
-  meta "remove_for_" lemma eq_repeat_one
+  let lemma eq_repeat_one (w: list 'a)
+    ensures { vlist_eq (repeat w 1) w }
+  = assert { repeat w 1 = repeat w 0 ++ w }
 
   lemma rw_repeat_one:
     forall w:list 'a [repeat w 1]. repeat w 1 = w
 
+  let rec lemma repeat_more (w: list 'a) (n: int)
+    requires { 0 <= n }
+    ensures  { repeat w (n + 1) = concat (repeat w n) w }
+    variant  { n }
+  = if 0 < n then repeat_more w (n - 1)
+
+  let rec lemma rw_repeat_concat (p q: int) (w: list 'a)
+    requires { 0 <= p }
+    requires { 0 <= q }
+    ensures  { repeat w (Int.(+) p q) = concat (repeat w p) (repeat w q) }
+    variant  { p }
+  = if 0 < p then rw_repeat_concat (p - 1) q w
+
   lemma eq_repeat_concat:
     forall p,q:int, w:list 'a.
       0 <= p -> 0 <= q ->
       vlist_eq (repeat w (Int.(+) p q)) (concat (repeat w p) (repeat w q))
-  meta "remove_for_" lemma eq_repeat_concat
-
-  lemma rw_repeat_concat:
-    forall p,q:int, w:list 'a.
-      0 <= p -> 0 <= q ->
-      repeat w (Int.(+) p q) = concat (repeat w p) (repeat w q)
-  meta "remove_for_" lemma rw_repeat_concat
 
   lemma rw_repeat_after:
     forall p:int, w:list 'a.
        0 <= p -> concat (repeat w p) w = repeat w (Int.(+) p 1)
-  meta "remove_for_" lemma rw_repeat_after
 
   lemma rw_repeat_before:
     forall p:int, w:list 'a.
       0 <= p -> concat w (repeat w p) = repeat w (Int.(+) p 1)
-  meta "remove_for_" lemma rw_repeat_before
+
+  let rec lemma nth_repeat (w: list 'a) (n k: int)
+    requires { 0 <= k < n * length w }
+    ensures  { nth (repeat w n) k = nth w (mod k (length w)) }
+    variant  { n }
+  =
+    if n <= 0 then absurd
+    else if n = 1 then ()
+    else
+      if k < length w
+      then begin
+        assert { (n - 1) * length w >= 1 * length w };
+        nth_repeat w (n - 1) k
+      end
+      else begin
+        let lw = length w in
+          nth_repeat w (n - 1) (k - lw);
+          assert { mod (lw * 1 + (k - lw)) lw = mod (k - lw) lw };
+      end
 
 (*--- To avoid exponential blowup of use of repeat_after by alt-ergo ---*)
 
-function repeat_box (list 'a) int : (list 'a) (* repeat *)
+  function repeat_box (list 'a) int : (list 'a) (* repeat *)
 
-axiom rw_repeat_box_unfold: 
-  forall w:list 'a, n:int [ repeat_box w n ].
-    repeat_box w n = repeat w n
+  axiom rw_repeat_box_unfold:
+    forall w:list 'a, n:int [ repeat_box w n ].
+      repeat_box w n = repeat w n
 
-axiom rw_repeat_plus_box_unfold: 
-  forall w:list 'a, a,b: int [ repeat_box w (Int.(+) a b) ].
-    (Int.(<=) 0 a)
- -> (Int.(<=) 0 b)
- -> repeat_box w (Int.(+) a b) = concat (repeat w a)
+  axiom rw_repeat_plus_box_unfold:
+    forall w:list 'a, a,b: int [ repeat_box w (Int.(+) a b) ].
+      (Int.(<=) 0 a)
+  -> (Int.(<=) 0 b)
+  -> repeat_box w (Int.(+) a b) = concat (repeat w a)
                                                 (repeat w b)
-axiom rw_repeat_plus_one_box_unfold: 
-  forall w:list 'a, n:int [ repeat_box w n ].
-    (Int.(<) 0 n)
- -> (repeat_box w n = (concat (repeat w (Int.(-) n 1)) w)
- && (repeat_box w (Int.(+) n 1) = concat (repeat w n) w))
+  axiom rw_repeat_plus_one_box_unfold:
+    forall w:list 'a, n:int [ repeat_box w n ].
+      (Int.(<) 0 n)
+  -> (repeat_box w n = (concat (repeat w (Int.(-) n 1)) w)
+  && (repeat_box w (Int.(+) n 1) = concat (repeat w n) w))
 
 end
diff --git a/src/plugins/wp/tests/wp_plugin/nth.i b/src/plugins/wp/tests/wp_plugin/nth.i
index 33236ef838299d9fff8a9616d03b62b76f261b9c..88491366a5ba6dc6e2092f577d26e26635d20578 100644
--- a/src/plugins/wp/tests/wp_plugin/nth.i
+++ b/src/plugins/wp/tests/wp_plugin/nth.i
@@ -83,14 +83,16 @@
   check lemma nth_repeat_3: ok: \nth ( ([| f(0), f(1), f(2), f(3) |] *^ 3) ^ [| f(12) |] , 12 ) ==  f(12);
   check lemma nth_repeat_4: ok: \nth ( ([| f(0), f(1), f(2), f(3) |] *^ 3) ^ [| f(12),f(13),f(14)|] ^ S, 13 ) ==  f(13);
 
-  lemma access_16_16: ok:
-  \forall integer k ; 0 <= k < 16 ==>
-    f(k)==\nth([| f(0), f(1), f(2),  f(3),  f(4),  f(5),  f(6),  f(7),
-                  f(8), f(9), f(10), f(11), f(12), f(13), f(14), f(15) |], k);
 
   lemma access_4_4: ok:
   \forall integer k ; 0 <= k < 4 ==>
-    f(k)==\nth([| f(0), f(1), f(2),  f(3) |], k);
+    f(k)==\nth([| f(0), f(1), f(2), f(3) |], k);
+
+  // Performance problem with Alt-Ergo, cvc4 & z3 are ok.
+  lemma access_8_8: ko:
+  \forall integer k ; 0 <= k < 6 ==>
+    f(k)==\nth([| f(0), f(1), f(2), f(3),
+                  f(4), f(5), f(6), f(7) |], k);
 
   lemma eq_repeat_concat_3: ok: (S *^ 3) == (S ^ S ^ S) ;
 
diff --git a/src/plugins/wp/tests/wp_plugin/oracle/nth.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/nth.res.oracle
index c93629cbb62d4b5fa92e4144cc23d6e0c1089cf1..3042f600a4b71ccf48ac6ebb5e178b17fd97c225 100644
--- a/src/plugins/wp/tests/wp_plugin/oracle/nth.res.oracle
+++ b/src/plugins/wp/tests/wp_plugin/oracle/nth.res.oracle
@@ -96,35 +96,33 @@ Prove: true
   Axiomatic 'Nth'
 ------------------------------------------------------------
 
-Lemma access_16_16:
-Prove: (0<=k_0) -> (k_0<=15)
+Lemma access_4_4:
+Prove: (0<=k_0) -> (k_0<=3)
        -> ((nth
-             (concat (elt (L_f 0)) (elt (L_f 1)) (elt (L_f 2)) (elt (L_f 3))
-               (elt (L_f 4)) (elt (L_f 5)) (elt (L_f 6)) (elt (L_f 7))
-               (elt (L_f 8)) (elt (L_f 9)) (elt (L_f 10)) (elt (L_f 11))
-               (elt (L_f 12)) (elt (L_f 13)) (elt (L_f 14)) (elt (L_f 15)))
+             (concat (elt (L_f 0)) (elt (L_f 1)) (elt (L_f 2)) (elt (L_f 3)))
              k_0)=(L_f k_0))
 
 ------------------------------------------------------------
 
-Lemma access_4_4:
-Assume: 'access_16_16'
-Prove: (0<=k_0) -> (k_0<=3)
+Lemma access_8_8:
+Assume: 'access_4_4'
+Prove: (0<=k_0) -> (k_0<=5)
        -> ((nth
-             (concat (elt (L_f 0)) (elt (L_f 1)) (elt (L_f 2)) (elt (L_f 3)))
-             k_0)=(L_f k_0))
+             (concat (elt (L_f 0)) (elt (L_f 1)) (elt (L_f 2)) (elt (L_f 3))
+               (elt (L_f 4)) (elt (L_f 5)) (elt (L_f 6)) (elt (L_f 7))) k_0)=
+           (L_f k_0))
 
 ------------------------------------------------------------
 
 Lemma access_repeat_concat_3:
-Assume: 'eq_repeat_concat_3' 'access_4_4' 'access_16_16'
+Assume: 'eq_repeat_concat_3' 'access_8_8' 'access_4_4'
 Prove: (0<=k_0) -> (k_0<(3*(length L_S)))
        -> ((nth (concat L_S L_S L_S) k_0)=(nth (repeat L_S 3) k_0))
 
 ------------------------------------------------------------
 
 Lemma eq_repeat_concat_3:
-Assume: 'access_4_4' 'access_16_16'
+Assume: 'access_8_8' 'access_4_4'
 Prove: true
 
 ------------------------------------------------------------
diff --git a/src/plugins/wp/tests/wp_plugin/oracle_qualif/nth.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle_qualif/nth.res.oracle
index 1aeb2e63b01db6747367dd9c88cba0399224c93d..edb9844f6a4b1a158e205f172e3bd85ea2241b20 100644
--- a/src/plugins/wp/tests/wp_plugin/oracle_qualif/nth.res.oracle
+++ b/src/plugins/wp/tests/wp_plugin/oracle_qualif/nth.res.oracle
@@ -2,8 +2,8 @@
 [kernel] Parsing nth.i (no preprocessing)
 [wp] Running WP plugin...
 [wp] 26 goals scheduled
-[wp] [Valid] typed_lemma_access_16_16_ok (Alt-Ergo) (Cached)
 [wp] [Valid] typed_lemma_access_4_4_ok (Alt-Ergo) (Cached)
+[wp] [Unsuccess] typed_lemma_access_8_8_ko (Alt-Ergo) (Cached)
 [wp] [Valid] typed_lemma_access_repeat_concat_3_ok_lack (Alt-Ergo) (Cached)
 [wp] [Valid] typed_check_lemma_constructor_elt_ok (Qed)
 [wp] [Valid] typed_lemma_eq_repeat_concat_3_ok (Qed)
@@ -28,13 +28,13 @@
 [wp] [Valid] typed_check_lemma_right_unfold_repeat1_ok (Qed)
 [wp] [Valid] typed_check_lemma_right_unfold_repeat2_ok (Qed)
 [wp] [Valid] typed_check_lemma_subsequence1_ok (Qed)
-[wp] Proved goals:   25 / 26
+[wp] Proved goals:   24 / 26
   Qed:            22
-  Alt-Ergo:        3
-  Unsuccess:       1
+  Alt-Ergo:        2
+  Unsuccess:       2
 ------------------------------------------------------------
  Axiomatics                WP     Alt-Ergo  Total   Success
   Axiomatic Equality       13        -       13       100%
   Axiomatic MkRepeat        4        -        4       100%
-  Axiomatic Nth             5        3        9      88.9%
+  Axiomatic Nth             5        2        9      77.8%
 ------------------------------------------------------------