Commit 72e24dba authored by Jean-Christophe Filliâtre's avatar Jean-Christophe Filliâtre
Browse files

new example: random access lists

features polymorphic recursion, both in the logic and in programs
parent ac0cd54a
(** Random Access Lists.
The code below uses polymorphic recursion (both in the logic
and in the programs).
- induction_ty_lex has no effect on a goal involving polymorphic recursion
- a lemma function is not allowed to perform polymorphic recursion?
module RandomAccessList
use import int.Int
use import int.ComputerDivision
use import list.List
use import list.Length
use import list.Nth
use import option.Option
type ral 'a =
| Empty
| Zero (ral ('a, 'a))
| One 'a (ral ('a, 'a))
function flatten (l: list ('a , 'a)) : list 'a
= match l with
| Nil -> Nil
| Cons (x, y) l1 -> Cons x (Cons y (flatten l1))
lemma length_flatten:
forall l: list ('a, 'a). length (flatten l) = 2 * length l
function elements (l: ral 'a) : list 'a
= match l with
| Empty -> Nil
| Zero l1 -> flatten (elements l1)
| One x l1 -> Cons x (flatten (elements l1))
let rec size (l: ral 'a) : int
variant { l }
ensures { result = length (elements l) }
match l with
| Empty -> 0
| Zero l1 -> 2 * size l1
| One _ l1 -> 1 + 2 * size l1
let rec add (x: 'a) (l: ral 'a) : ral 'a
variant { l }
ensures { elements result = Cons x (elements l) }
= match l with
| Empty -> One x Empty
| Zero l1 -> One x l1
| One y l1 -> Zero (add (x, y) l1)
let rec lemma nth_flatten (i: int) (l: list ('a, 'a))
requires { 0 <= i < length l }
variant { l }
ensures { match nth i l with
| None -> false
| Some (x0, x1) -> Some x0 = nth (2 * i) (flatten l) /\
Some x1 = nth (2 * i + 1) (flatten l) end }
= match l with
| Nil -> ()
| Cons _ r -> if i > 0 then nth_flatten (i-1) r
let rec get (i: int) (l: ral 'a) : 'a
requires { 0 <= i < length (elements l) }
variant { i, l }
ensures { nth i (elements l) = Some result }
= match l with
| Empty -> absurd
| One x l1 -> if i = 0 then x else get (i-1) (Zero l1)
| Zero l1 -> let (x0, x1) = get (div i 2) l1 in
if mod i 2 = 0 then x0 else x1
(* This file is generated by Why3's Coq driver *)
(* Beware! Only edit allowed sections below *)
Require Import BuiltIn.
Require BuiltIn.
Require int.Int.
Require int.Abs.
Require int.ComputerDivision.
Require list.List.
Require list.Length.
Require list.Nth.
Require option.Option.
(* Why3 assumption *)
Definition unit := unit.
Axiom qtmark : Type.
Parameter qtmark_WhyType : WhyType qtmark.
Existing Instance qtmark_WhyType.
(* Why3 assumption *)
Inductive ral
(a:Type) :=
| Empty : ral a
| Zero : (ral (a* a)%type) -> ral a
| One : a -> (ral (a* a)%type) -> ral a.
Axiom ral_WhyType : forall (a:Type) {a_WT:WhyType a}, WhyType (ral a).
Existing Instance ral_WhyType.
Implicit Arguments Empty [[a]].
Implicit Arguments Zero [[a]].
Implicit Arguments One [[a]].
(* Why3 assumption *)
Fixpoint flatten {a:Type} {a_WT:WhyType a} (l:(list (a*
a)%type)) {struct l}: (list a) :=
match l with
| Init.Datatypes.nil => Init.Datatypes.nil
| (Init.Datatypes.cons (x, y) l1) =>
(Init.Datatypes.cons x (Init.Datatypes.cons y (flatten l1)))
(* Why3 goal *)
Theorem length_flatten : forall {a:Type} {a_WT:WhyType a},
forall (l:(list (a* a)%type)),
((list.Length.length (flatten l)) = (2%Z * (list.Length.length l))%Z).
intros a a_WT l.
induction l.
simpl (flatten (a0::l)).
destruct a0.
replace (Length.length ((a0,a1)::l))
with (1 + (Length.length l))%Z by auto.
unfold Length.length at 1; fold Length.length.
rewrite IHl.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE why3session PUBLIC "-//Why3//proof session v5//EN"
<why3session shape_version="4">
<prover id="0" name="Alt-Ergo" version="0.99.1" timelimit="6" memlimit="1000"/>
<prover id="1" name="CVC4" version="1.4" timelimit="6" memlimit="1000"/>
<prover id="5" name="Coq" version="8.4pl2" timelimit="6" memlimit="1000"/>
<prover id="6" name="CVC4" version="1.3" timelimit="1" memlimit="1000"/>
<file name="../random_access_list.mlw" expanded="true">
<theory name="RandomAccessList" sum="d4e729fc281cff0f1f6b9c21461a02b6" expanded="true">
<goal name="length_flatten" expanded="true">
<proof prover="5" edited="random_access_list_RandomAccessList_length_flatten_1.v"><result status="valid" time="0.83"/></proof>
<goal name="WP_parameter size" expl="VC for size">
<proof prover="0"><result status="valid" time="0.02" steps="68"/></proof>
<goal name="WP_parameter add" expl="VC for add">
<proof prover="0"><result status="valid" time="0.02" steps="70"/></proof>
<goal name="WP_parameter nth_flatten" expl="VC for nth_flatten">
<transf name="split_goal_wp">
<goal name="WP_parameter nth_flatten.1" expl="1. postcondition">
<proof prover="0"><result status="valid" time="0.02" steps="11"/></proof>
<goal name="WP_parameter nth_flatten.2" expl="2. variant decrease">
<proof prover="0"><result status="valid" time="0.02" steps="21"/></proof>
<goal name="WP_parameter nth_flatten.3" expl="3. precondition">
<proof prover="0"><result status="valid" time="0.02" steps="12"/></proof>
<goal name="WP_parameter nth_flatten.4" expl="4. postcondition">
<proof prover="6"><result status="valid" time="0.24"/></proof>
<goal name="WP_parameter nth_flatten.5" expl="5. postcondition">
<proof prover="0"><result status="unknown" time="0.04"/></proof>
<proof prover="1"><result status="valid" time="0.07"/></proof>
<goal name="WP_parameter get" expl="VC for get" expanded="true">
<proof prover="0"><result status="valid" time="0.34" steps="410"/></proof>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment