blob: 5d948a58184fb87ef3bfb5ac14e8467ae6746ef5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
// RUN: %dafny /print:"%t.print" "%s" > "%t"
// RUN: %diff "%s.expect" "%t"
function method Twice<A>(f : A -> A): A -> A
{
x requires f.requires(x) && f.requires(f(x))
reads f.reads(x) reads if f.requires(x) then f.reads(f(x)) else {}
=> f(f(x))
}
method Simple() {
assert Twice(x => x + 1)(0) == 2;
assert Twice(Twice(x => x + 1))(0) == 4;
// why does these fail? need requires/reads for literals?
// assert Twice(Twice)(x => x + 1)(0) == 4;
// assert Twice(Twice)(Twice)(x => x + 1)(0) == 16;
}
method WithReads() {
var a : array<int> := new int[1];
a[0] := 1;
var f := x reads a => x + a[0];
assert Twice(f)(0) == 2;
a[0] := 2;
assert Twice(f)(0) == 4;
assert Twice(f)(0) == 2; // should fail
assert false; // should fail
}
function method Twice_bad<A>(f : A -> A): A -> A
{
x requires f.requires(x) && f.requires(f(x))
reads f.reads(x) + f.reads(f(x))
=> f(f(x))
}
|