MAJ terminée. Nous sommes passés en version 14.6.2 . Pour consulter les "releases notes" associées c'est ici :

https://about.gitlab.com/releases/2022/01/11/security-release-gitlab-14-6-2-released/
https://about.gitlab.com/releases/2022/01/04/gitlab-14-6-1-released/

Commit 9c6979c1 authored by Jean-Christophe Filliâtre's avatar Jean-Christophe Filliâtre
Browse files

random access lists (new example in progress)

parent 44aa9329
(*
Purely Functional Random-Access Lists
Chris Okasaki, FPCA, 1995.
(thanks to Simon Cruanes for suggesting this example)
*)
module RandomAccessList
use import int.Int
use import int.ComputerDivision
use import list.Append
use import list.HdTl
use import list.Nth
type tree 'a =
| Leaf 'a
| Node (tree 'a) 'a (tree 'a)
function preorder (t: tree 'a) : list 'a = match t with
| Leaf x -> Cons x Nil
| Node l x r -> Cons x (preorder l ++ preorder r)
end
function flatten (l: list (int, tree 'a)) : list 'a = match l with
| Nil -> Nil
| Cons (_, t) r -> preorder t ++ flatten r
end
function size (t: tree 'a) : int = match t with
| Leaf _ -> 1
| Node l _ r -> size l + 1 + size r
end
lemma size_pos: forall t: tree 'a. size t >= 1
(* perfect binary tree of size s *)
inductive perfect (s: int) (t: tree 'a) =
| perfect_leaf:
forall x: 'a. perfect 1 (Leaf x)
| perfect_node:
forall x: 'a, l r: tree 'a, s: int.
perfect s l -> perfect s r -> perfect (1 + 2*s) (Node l x r)
lemma perfect_size: forall s: int, t: tree 'a. perfect s t -> s = size t
predicate well_formed (l: list (int, tree 'a)) = match l with
| Nil -> true
| Cons (s, t) Nil -> perfect s t
| Cons (s1, t1) ((Cons (s2, t2) _) as rest) ->
perfect s1 t1 && s1 < s2 && well_formed rest
end
predicate well_formed0 (l: list (int, tree 'a)) = match l with
| Nil -> true
| Cons (s, t) Nil -> perfect s t
| Cons (s1, t1) ((Cons (s2, t2) _) as rest) ->
perfect s1 t1 && s1 <= s2 && well_formed rest
end
type t 'a =
{ trees: list (int, tree 'a);
ghost contents: list 'a; }
invariant { well_formed0 self.trees }
invariant { self.contents = flatten self.trees }
let empty () : t 'a =
{ trees = Nil : list (int, tree 'a); contents = Nil }
let is_empty (t: t 'a) : bool
ensures { result = True <-> t.contents = Nil }
= t.trees = Nil
let cons (x: 'a) (t: t 'a) : t 'a
ensures { result.contents = Cons x t.contents }
= match t.trees with
| Cons (s1, t1) (Cons (s2, t2) rest) ->
if s1 = s2 then
{ trees = Cons (1+s1+s2, Node t1 x t2) rest;
contents = Cons x t.contents }
else
{ trees = Cons (1, Leaf x) t.trees; contents = Cons x t.contents }
| _ ->
{ trees = Cons (1, Leaf x) t.trees; contents = Cons x t.contents }
end
let head (t: t 'a) : option 'a
ensures { result = hd t.contents }
= match t.trees with
| Nil -> None
| Cons (_, Leaf x) _ -> Some x
| Cons (_, Node _ x _) _ -> Some x
end
let safe_hd (l: list 'a) : list 'a
requires { l <> Nil } ensures { Some result = tl l }
= match l with Nil -> absurd | Cons _ rest -> rest end
let tail (t: t 'a) : option (t 'a)
ensures
{ match result with None -> tl t.contents = None
| Some t' -> tl t.contents = Some t'.contents end }
= match t.trees with
| Nil ->
None
| Cons (_, Leaf _) trees' ->
Some { trees = trees'; contents = safe_hd t.contents }
| Cons (size, Node l x r) rest ->
let size' = div size 2 in
Some { trees = Cons (size', l) (Cons (size', r) rest);
contents = safe_hd t.contents }
end
end
(* This file is generated by Why3's Coq 8.4 driver *)
(* Beware! Only edit allowed sections below *)
Require Import BuiltIn.
Require Import ZOdiv.
Require BuiltIn.
Require int.Int.
Require int.Abs.
Require int.ComputerDivision.
Require list.List.
Require list.Length.
Require list.Mem.
Require list.Nth.
Require option.Option.
Require list.HdTl.
Require list.Append.
(* Why3 assumption *)
Definition unit := unit.
(* Why3 assumption *)
Inductive tree
(a:Type) {a_WT:WhyType a} :=
| Leaf : a -> tree a
| Node : (@tree a a_WT) -> a -> (@tree a a_WT) -> tree a.
Axiom tree_WhyType : forall (a:Type) {a_WT:WhyType a}, WhyType (tree a).
Existing Instance tree_WhyType.
Implicit Arguments Leaf [[a] [a_WT]].
Implicit Arguments Node [[a] [a_WT]].
(* Why3 assumption *)
Fixpoint preorder {a:Type} {a_WT:WhyType a} (t:(@tree
a a_WT)) {struct t}: (list a) :=
match t with
| (Leaf x) => (cons x nil)
| (Node l x r) => (cons x (List.app (preorder l) (preorder r)))
end.
(* Why3 assumption *)
Fixpoint flatten {a:Type} {a_WT:WhyType a} (l:(list (Z* (@tree
a a_WT))%type)) {struct l}: (list a) :=
match l with
| nil => nil
| (cons (_, t) r) => (List.app (preorder t) (flatten r))
end.
(* Why3 assumption *)
Fixpoint size {a:Type} {a_WT:WhyType a} (t:(@tree a a_WT)) {struct t}: Z :=
match t with
| (Leaf _) => 1%Z
| (Node l _ r) => (((size l) + 1%Z)%Z + (size r))%Z
end.
Axiom size_pos : forall {a:Type} {a_WT:WhyType a}, forall (t:(@tree a a_WT)),
(1%Z <= (size t))%Z.
(* Why3 assumption *)
Inductive perfect {a:Type} {a_WT:WhyType a} : Z -> (@tree a a_WT) -> Prop :=
| perfect_leaf : forall (x:a), ((@perfect _ _) 1%Z (Leaf x))
| perfect_node : forall (x:a) (l:(@tree a a_WT)) (r:(@tree a a_WT)) (s:Z),
((@perfect _ _) s l) -> (((@perfect _ _) s r) -> ((@perfect _ _)
(1%Z + (2%Z * s)%Z)%Z (Node l x r))).
Axiom perfect_size : forall {a:Type} {a_WT:WhyType a}, forall (s:Z) (t:(@tree
a a_WT)), (perfect s t) -> (s = (size t)).
(* Why3 assumption *)
Fixpoint well_formed {a:Type} {a_WT:WhyType a} (l:(list (Z* (@tree
a a_WT))%type)) {struct l}: Prop :=
match l with
| nil => True
| (cons (s, t) nil) => (perfect s t)
| (cons (s1, t1) ((cons (s2, t2) _) as rest)) => (perfect s1 t1) /\
((s1 < s2)%Z /\ (well_formed rest))
end.
(* Why3 assumption *)
Definition well_formed0 {a:Type} {a_WT:WhyType a} (l:(list (Z* (@tree
a a_WT))%type)): Prop :=
match l with
| nil => True
| (cons (s, t) nil) => (perfect s t)
| (cons (s1, t1) ((cons (s2, t2) _) as rest)) => (perfect s1 t1) /\
((s1 <= s2)%Z /\ (well_formed rest))
end.
(* Why3 assumption *)
Inductive t
(a:Type) {a_WT:WhyType a} :=
| mk_t : (list (Z* (@tree a a_WT))%type) -> (list a) -> t a.
Axiom t_WhyType : forall (a:Type) {a_WT:WhyType a}, WhyType (t a).
Existing Instance t_WhyType.
Implicit Arguments mk_t [[a] [a_WT]].
(* Why3 assumption *)
Definition contents {a:Type} {a_WT:WhyType a} (v:(@t a a_WT)): (list a) :=
match v with
| (mk_t x x1) => x1
end.
(* Why3 assumption *)
Definition trees {a:Type} {a_WT:WhyType a} (v:(@t a a_WT)): (list (Z* (@tree
a a_WT))%type) := match v with
| (mk_t x x1) => x
end.
(* Why3 goal *)
Theorem WP_parameter_is_empty : forall {a:Type} {a_WT:WhyType a},
forall (t1:(list (Z* (@tree a a_WT))%type)) (t2:(list a)), ((well_formed0
t1) /\ (t2 = (flatten t1))) -> ((t1 = nil) <-> (t2 = nil)).
intros a a_WT t1 t2 (h1,h2).
destruct t1; simpl in h2.
intuition.
simpl in h1.
destruct p; simpl in *.
intuition.
discriminate H.
destruct t1; simpl in h1.
inversion h1; intuition.
subst t0; simpl in h2.
subst t2.
discriminate h2.
subst t0; simpl in h2.
subst t2.
discriminate h2.
destruct t0; simpl in h2.
subst t2.
discriminate H.
subst t2.
discriminate H.
Qed.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE why3session PUBLIC "-//Why3//proof session v2//EN" "http://why3.lri.fr/why3session.dtd">
<why3session shape_version="3">
<prover
id="0"
name="Alt-Ergo"
version="0.95.1"/>
<prover
id="1"
name="CVC4"
version="1.0"/>
<prover
id="2"
name="Coq"
version="8.4pl1"/>
<prover
id="3"
name="Z3"
version="3.2"/>
<file
name="../random_access_list.mlw"
verified="false"
expanded="true">
<theory
name="RandomAccessList"
locfile="../random_access_list.mlw"
loclnum="8" loccnumb="7" loccnume="23"
verified="false"
expanded="true">
<goal
name="size_pos"
locfile="../random_access_list.mlw"
loclnum="35" loccnumb="8" loccnume="16"
sum="44b56b2619d430b0f583ace095da7b97"
proved="false"
expanded="true"
shape="ainfix &gt;=asizeV0c1F">
</goal>
<goal
name="perfect_size"
locfile="../random_access_list.mlw"
loclnum="45" loccnumb="8" loccnume="20"
sum="fbc39b3768e51792fc7dbc1764803247"
proved="false"
expanded="true"
shape="ainfix =V0asizeV1IaperfectV0V1F">
</goal>
<goal
name="WP_parameter empty"
locfile="../random_access_list.mlw"
loclnum="67" loccnumb="6" loccnume="11"
expl="VC for empty"
sum="cf4f7b1cdc89cbf4db027823c9d4cfd0"
proved="true"
expanded="true"
shape="ainfix =aNilaflattenaNilAawell_formed0aNil">
<label
name="expl:VC for empty"/>
<proof
prover="0"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="valid" time="0.02"/>
</proof>
</goal>
<goal
name="WP_parameter is_empty"
locfile="../random_access_list.mlw"
loclnum="70" loccnumb="6" loccnume="14"
expl="VC for is_empty"
sum="63ff9dc171f048f61bb585efadb2eef6"
proved="true"
expanded="true"
shape="ainfix =V1aNilqainfix =V0aNilIainfix =V1aflattenV0Aawell_formed0V0F">
<label
name="expl:VC for is_empty"/>
<proof
prover="2"
timelimit="10"
memlimit="1000"
edited="random_access_list_RandomAccessList_WP_parameter_is_empty_2.v"
obsolete="false"
archived="false">
<result status="valid" time="1.56"/>
</proof>
</goal>
<goal
name="WP_parameter cons"
locfile="../random_access_list.mlw"
loclnum="74" loccnumb="6" loccnume="10"
expl="VC for cons"
sum="053083618c434083510c846e4047ca98"
proved="false"
expanded="true"
shape="Cainfix =V2V2Aainfix =aConsV0V2aflatteniaConsaTuple2c1aLeafV0V1aConsaTuple2ainfix +ainfix +c1V3V5aNodeV4V0V6V7ainfix =V3V5Aawell_formed0iaConsaTuple2c1aLeafV0V1aConsaTuple2ainfix +ainfix +c1V3V5aNodeV4V0V6V7ainfix =V3V5aConsaTuple2VVaConsaTuple2VVVainfix =V2V2Aainfix =aConsV0V2aflattenaConsaTuple2c1aLeafV0V1Aawell_formed0aConsaTuple2c1aLeafV0V1wV1Iainfix =V2aflattenV1Aawell_formed0V1F">
<label
name="expl:VC for cons"/>
<transf
name="split_goal_wp"
proved="false"
expanded="true">
<goal
name="WP_parameter cons.1"
locfile="../random_access_list.mlw"
loclnum="74" loccnumb="6" loccnume="10"
expl="1. type invariant"
sum="ce232bf998a18b924deb6d93b303a543"
proved="false"
expanded="true"
shape="type invariantCawell_formed0iaConsaTuple2c1aLeafV0V1aConsaTuple2ainfix +ainfix +c1V3V5aNodeV4V0V6V7ainfix =V3V5aConsaTuple2VVaConsaTuple2VVVtwV1Iainfix =V2aflattenV1Aawell_formed0V1F">
<label
name="expl:VC for cons"/>
<proof
prover="0"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="timeout" time="9.99"/>
</proof>
<proof
prover="1"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="timeout" time="10.00"/>
</proof>
<proof
prover="3"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="timeout" time="9.89"/>
</proof>
</goal>
<goal
name="WP_parameter cons.2"
locfile="../random_access_list.mlw"
loclnum="74" loccnumb="6" loccnume="10"
expl="2. type invariant"
sum="5187ed06891625bec0564d7383aea765"
proved="true"
expanded="false"
shape="type invariantCainfix =aConsV0V2aflatteniaConsaTuple2c1aLeafV0V1aConsaTuple2ainfix +ainfix +c1V3V5aNodeV4V0V6V7ainfix =V3V5aConsaTuple2VVaConsaTuple2VVVtwV1Iainfix =V2aflattenV1Aawell_formed0V1F">
<label
name="expl:VC for cons"/>
<proof
prover="0"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="valid" time="1.10"/>
</proof>
</goal>
<goal
name="WP_parameter cons.3"
locfile="../random_access_list.mlw"
loclnum="74" loccnumb="6" loccnume="10"
expl="3. postcondition"
sum="8a0a59a318a2e81ae51e889c715e35a9"
proved="true"
expanded="false"
shape="postconditionCainfix =V2V2Iainfix =aConsV0V2aflatteniaConsaTuple2c1aLeafV0V1aConsaTuple2ainfix +ainfix +c1V3V5aNodeV4V0V6V7ainfix =V3V5Aawell_formed0iaConsaTuple2c1aLeafV0V1aConsaTuple2ainfix +ainfix +c1V3V5aNodeV4V0V6V7ainfix =V3V5aConsaTuple2VVaConsaTuple2VVVtwV1Iainfix =V2aflattenV1Aawell_formed0V1F">
<label
name="expl:VC for cons"/>
<proof
prover="0"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="valid" time="0.02"/>
</proof>
</goal>
<goal
name="WP_parameter cons.4"
locfile="../random_access_list.mlw"
loclnum="74" loccnumb="6" loccnume="10"
expl="4. type invariant"
sum="b6abdb2978fb578aac653e94c325c4df"
proved="false"
expanded="true"
shape="type invariantCtaConsaTuple2VVaConsaTuple2VVVawell_formed0aConsaTuple2c1aLeafV0V1wV1Iainfix =V2aflattenV1Aawell_formed0V1F">
<label
name="expl:VC for cons"/>
<proof
prover="0"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="timeout" time="10.00"/>
</proof>
<proof
prover="1"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="timeout" time="9.91"/>
</proof>
<proof
prover="3"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="timeout" time="9.99"/>
</proof>
</goal>
<goal
name="WP_parameter cons.5"
locfile="../random_access_list.mlw"
loclnum="74" loccnumb="6" loccnume="10"
expl="5. type invariant"
sum="2e9b778de431cb8373619a8d2ceeecf5"
proved="true"
expanded="false"
shape="type invariantCtaConsaTuple2VVaConsaTuple2VVVainfix =aConsV0V2aflattenaConsaTuple2c1aLeafV0V1wV1Iainfix =V2aflattenV1Aawell_formed0V1F">
<label
name="expl:VC for cons"/>
<proof
prover="0"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="valid" time="0.13"/>
</proof>
</goal>
<goal
name="WP_parameter cons.6"
locfile="../random_access_list.mlw"
loclnum="74" loccnumb="6" loccnume="10"
expl="6. postcondition"
sum="aabfc798d39711c3bd7349e4d821bc3b"
proved="true"
expanded="false"
shape="postconditionCtaConsaTuple2VVaConsaTuple2VVVainfix =V2V2Iainfix =aConsV0V2aflattenaConsaTuple2c1aLeafV0V1Aawell_formed0aConsaTuple2c1aLeafV0V1wV1Iainfix =V2aflattenV1Aawell_formed0V1F">
<label
name="expl:VC for cons"/>
<proof
prover="0"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="valid" time="0.02"/>
</proof>
</goal>
</transf>
</goal>
<goal
name="WP_parameter head"
locfile="../random_access_list.mlw"
loclnum="87" loccnumb="6" loccnume="10"
expl="VC for head"
sum="ad03130d4d27dc4f1c9372ea7a99fb26"
proved="true"
expanded="true"
shape="CCtaNilfaConsVwV1aNilCfaNilainfix =V3V4aConsVwV1aConsaTuple2waLeafVwCfaNilainfix =V5V6aConsVwV1aConsaTuple2waNodewVwwV0Iainfix =V1aflattenV0Aawell_formed0V0F">
<label
name="expl:VC for head"/>
<proof
prover="0"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="valid" time="0.11"/>
</proof>
</goal>
<goal
name="WP_parameter safe_hd"
locfile="../random_access_list.mlw"
loclnum="95" loccnumb="6" loccnume="13"
expl="unreachable point"
sum="f0698b9c88344bdce42fd1c49d4ab6af"
proved="true"
expanded="true"
shape="unreachable pointCfaNilCfaNilainfix =V1V2aConswVV0aConswVV0INainfix =V0aNilF">
<label
name="expl:VC for safe_hd"/>
<proof
prover="0"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="valid" time="0.02"/>
</proof>
</goal>
<goal
name="WP_parameter tail"
locfile="../random_access_list.mlw"
loclnum="99" loccnumb="6" loccnume="10"
expl="VC for tail"
sum="68bf3f55495d2365d4152a0416afde78"
proved="false"
expanded="true"
shape="CCtaNilfaConswVV1aNilCfaNilainfix =V4V5aConswVV1Aainfix =V4aflattenV3Aawell_formed0V3ICfaNilainfix =V4V6aConswVV1FANainfix =V1aNilaConsaTuple2waLeafwVCfaNilainfix =V13V14aConswVV1Aainfix =V13aflattenaConsaTuple2V12V8aConsaTuple2V12V10V11Aawell_formed0aConsaTuple2V12V8aConsaTuple2V12V10V11ICfaNilainfix =V13V15aConswVV1FANainfix =V1aNilLadivV7c2aConsaTuple2VaNodeVVVVV0Iainfix =V1aflattenV0Aawell_formed0V0F">
<label
name="expl:VC for tail"/>
<transf
name="split_goal_wp"
proved="false"
expanded="true">
<goal
name="WP_parameter tail.1"
locfile="../random_access_list.mlw"
loclnum="99" loccnumb="6" loccnume="10"
expl="1. postcondition"
sum="0bdf1433fb4384ce5c31905623c7ae7b"
proved="true"
expanded="false"
shape="postconditionCCtaNilfaConswVV1aNiltaConsaTuple2waLeafwVtaConsaTuple2VaNodeVVVVV0Iainfix =V1aflattenV0Aawell_formed0V0F">
<label
name="expl:VC for tail"/>
<proof
prover="0"
timelimit="10"
memlimit="1000"
obsolete="false"
archived="false">
<result status="valid" time="0.02"/>
</proof>
</goal>
<goal
name="WP_parameter tail.2"
locfile="../random_access_list.mlw"
loclnum="99" loccnumb="6" loccnume="10"
expl="2. precondition"
sum="56b00bcb9728e9b43e9f7c5b4011dafe"
proved="true"
expanded="false"
shape="preconditionCtaNilNainfix =V1aNilaConsaTuple2waLeafwVtaConsaTuple2VaNodeVVVVV0Iainfix =V1aflattenV0Aawell_formed0V0F">
<label
name="expl:VC for tail"/>
<proof
prover="0"
timelimit="10"
memlimit="1000"
obsolete="false"