Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Why3
why3
Commits
1128d7bb
Commit
1128d7bb
authored
Apr 13, 2015
by
Jean-Christophe Filliâtre
Browse files
VerifyThis @ ETAPS 2015: solution to challenge 1
parent
66605993
Changes
3
Hide whitespace changes
Inline
Side-by-side
examples/verifythis_2015_relaxed_prefix.mlw
0 → 100644
View file @
1128d7bb
(**
{1 VerifyThis @ ETAPS 2015 competition, Challenge 1: Relaxed Prefix}
{h
The following is the original description of the verification task,
reproduced verbatim from
<a href="http://etaps2015.verifythis.org/challenges">the competition web site</a>.
<pre>
RELAXED PREFIX (60 minutes)
===========================
Description
-----------
Verify a function isRelaxedPrefix determining if a list _pat_ (for
pattern) is a relaxed prefix of another list _a_.
The relaxed prefix property holds iff _pat_ is a prefix of _a_ after
removing at most one element from _pat_.
Examples
--------
pat = {1,3} is a relaxed prefix of a = {1,3,2,3} (standard prefix)
pat = {1,2,3} is a relaxed prefix of a = {1,3,2,3} (remove 2 from pat)
pat = {1,2,4} is not a relaxed prefix of a = {1,3,2,3}.
Implementation notes
--------------------
You can implement lists as arrays, e.g., of integers. A reference
implementation is given below. It may or may not contain errors.
public class Relaxed {
public static boolean isRelaxedPrefix(int[] pat, int[] a) {
int shift = 0;
for(int i=0; i<pat.length; i++) {
if (pat[i]!=a[i-shift])
if (shift==0) shift=1;
else return false;
}
return true;
}
public static void main(String[] argv) {
int[] pat = {1,2,3};
int[] a1 = {1,3,2,3};
System.out.println(isRelaxedPrefix(pat, a1));
}
}
Advanced verification task (if you get bored)
---------------------------------------------
Implement and verify a function relaxedContains(pat, a) returning
whether _a_ contains _pat_ in the above relaxed sense, i.e., whether
_pat_ is a relaxed prefix of any suffix of _a_.
</pre>}
The following is the solution by Jean-Christophe Filliâtre (CNRS)
and Guillaume Melquiond (Inria) who entered the competition as "team Why3".
*)
module RelaxedPrefix
use import int.Int
use import ref.Ref
use import array.Array
type char
(** [a1[ofs1..ofs1+len]] and [a2[ofs2..ofs2+len]] are valid sub-arrays
and they are equal *)
predicate eq_array (a1: array char) (ofs1: int)
(a2: array char) (ofs2: int) (len: int) =
0 <= len /\ 0 <= ofs1 /\ 0 <= ofs2 /\
ofs1 + len <= length a1 /\ ofs2 + len <= length a2 /\
forall i: int. 0 <= i < len -> a1[ofs1 + i] = a2[ofs2 + i]
(** The target property. Note that this definition imposes the
index of the character which is ignored (index [i] in the existential
quantifier). It simplifies our proof, but a looser definition would
be possible (see the comment at the end of this file). *)
predicate is_relaxed_prefix (pat a: array char) =
let n = length pat in
eq_array pat 0 a 0 n
\/ exists i: int. 0 <= i < n /\
eq_array pat 0 a 0 i /\
(i = length a \/ pat[i] <> a[i]) /\
eq_array pat (i+1) a i (n - i - 1)
(** This exception is used to exit the loop as soon as the target
property is no more possible. *)
exception NoPrefix
(** Note regarding the code: the suggested pseudo-code is buggy, as it
may access [a] out of bounds. We fix it by strengthening the
test in the conditional. *)
let is_relaxed_prefix (pat a: array char) : bool
ensures { result <-> is_relaxed_prefix pat a }
=
let n = length pat in
let m = length a in
try
let shift = ref 0 in
let ghost ignored = ref 0 in
for i = 0 to n - 1 do
invariant { 0 <= !shift <= 1 }
invariant { i = 0 -> !shift = 0 }
invariant { !shift = 1 -> 0 <= !ignored < i }
invariant { m + !shift >= i }
invariant {
if !shift = 0 then eq_array pat 0 a 0 i
else eq_array pat 0 a 0 !ignored /\
eq_array pat (!ignored + 1) a !ignored (i - !ignored - 1) /\
not (eq_array pat 0 a 0 i) /\
(!ignored < m -> pat[!ignored] <> a[!ignored]) }
if i - !shift >= m || pat[i] <> a[i - !shift] then begin
if !shift = 1 then raise NoPrefix;
ignored := i;
shift := 1;
end
done;
True
with NoPrefix ->
False
end
(** a simpler definition of [is_relaxed_prefix] would be the following: *)
predicate simple_is_relaxed_prefix (pat a: array char) =
let n = length pat in
eq_array pat 0 a 0 n
\/ exists i: int. 0 <= i < n /\
eq_array pat 0 a 0 i /\
eq_array pat (i+1) a i (n - i - 1)
(* TODO: prove the equivalence
lemma equivalence:
forall pat a: array char.
is_relaxed_prefix pat a <-> simple_is_relaxed_prefix pat a
*)
end
examples/verifythis_2015_relaxed_prefix/why3session.xml
0 → 100644
View file @
1128d7bb
<?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=
"Alt-Ergo"
version=
"0.95.2"
timelimit=
"6"
memlimit=
"1000"
/>
<prover
id=
"1"
name=
"CVC4"
version=
"1.4"
timelimit=
"6"
memlimit=
"1000"
/>
<prover
id=
"2"
name=
"Z3"
version=
"4.3.1"
timelimit=
"6"
memlimit=
"1000"
/>
<file
name=
"../verifythis_2015_relaxed_prefix.mlw"
expanded=
"true"
>
<theory
name=
"RelaxedPrefix"
sum=
"1aec45f1cb638f259a0aa093f19178a1"
expanded=
"true"
>
<goal
name=
"WP_parameter is_relaxed_prefix"
expl=
"VC for is_relaxed_prefix"
expanded=
"true"
>
<transf
name=
"split_goal_wp"
expanded=
"true"
>
<goal
name=
"WP_parameter is_relaxed_prefix.1"
expl=
"1. postcondition"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.01"
steps=
"6"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.2"
expl=
"2. loop invariant init"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.01"
steps=
"3"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.3"
expl=
"3. loop invariant init"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.02"
steps=
"3"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.4"
expl=
"4. loop invariant init"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.02"
steps=
"3"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.5"
expl=
"5. loop invariant init"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.02"
steps=
"5"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.6"
expl=
"6. postcondition"
>
<transf
name=
"inline_goal"
>
<goal
name=
"WP_parameter is_relaxed_prefix.6.1"
expl=
"1. postcondition"
>
<transf
name=
"split_goal_wp"
>
<goal
name=
"WP_parameter is_relaxed_prefix.6.1.1"
expl=
"1. postcondition"
>
<proof
prover=
"0"
timelimit=
"30"
><result
status=
"valid"
time=
"0.02"
steps=
"11"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.6.1.2"
expl=
"2. postcondition"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.03"
steps=
"14"
/></proof>
</goal>
</transf>
</goal>
</transf>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.7"
expl=
"7. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.01"
steps=
"12"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.8"
expl=
"8. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.02"
steps=
"12"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.9"
expl=
"9. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.02"
steps=
"12"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.10"
expl=
"10. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.01"
steps=
"12"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.11"
expl=
"11. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.15"
steps=
"43"
/></proof>
<proof
prover=
"1"
obsolete=
"true"
><result
status=
"timeout"
time=
"6.04"
/></proof>
<proof
prover=
"2"
obsolete=
"true"
><result
status=
"timeout"
time=
"5.98"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.12"
expl=
"12. index in array bounds"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.02"
steps=
"10"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.13"
expl=
"13. index in array bounds"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.01"
steps=
"11"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.14"
expl=
"14. postcondition"
>
<transf
name=
"inline_goal"
>
<goal
name=
"WP_parameter is_relaxed_prefix.14.1"
expl=
"1. postcondition"
>
<transf
name=
"split_goal_wp"
>
<goal
name=
"WP_parameter is_relaxed_prefix.14.1.1"
expl=
"1. postcondition"
>
<proof
prover=
"0"
timelimit=
"30"
><result
status=
"valid"
time=
"0.03"
steps=
"34"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.14.1.2"
expl=
"2. postcondition"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.31"
steps=
"353"
/></proof>
</goal>
</transf>
</goal>
</transf>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.15"
expl=
"15. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.02"
steps=
"15"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.16"
expl=
"16. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.01"
steps=
"15"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.17"
expl=
"17. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.02"
steps=
"15"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.18"
expl=
"18. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.01"
steps=
"15"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.19"
expl=
"19. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.10"
steps=
"77"
/></proof>
<proof
prover=
"2"
><result
status=
"valid"
time=
"0.01"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.20"
expl=
"20. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.02"
steps=
"12"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.21"
expl=
"21. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.02"
steps=
"12"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.22"
expl=
"22. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.01"
steps=
"16"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.23"
expl=
"23. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.01"
steps=
"12"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.24"
expl=
"24. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.08"
steps=
"157"
/></proof>
</goal>
<goal
name=
"WP_parameter is_relaxed_prefix.25"
expl=
"25. postcondition"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.00"
steps=
"38"
/></proof>
</goal>
</transf>
</goal>
</theory>
</file>
</why3session>
examples/verifythis_2015_relaxed_prefix/why3shapes.gz
0 → 100644
View file @
1128d7bb
File added
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment