summaryrefslogtreecommitdiff
path: root/Test/test2/LambdaExt.bpl
blob: be0d84ee7be4437ae739c32d42312cb124c5f48a (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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// RUN: %boogie -noinfer "%s" > "%t"
// RUN: %diff "%s.expect" "%t"

procedure Simplest() {
  var id1, id2 : [int]int;
  id1 := (lambda x: int :: x);
  id2 := (lambda x: int :: x);
  assert id1 == id2;
  id2 := (lambda x: int :: 0);
  assert id1 == id2; // fail
}

procedure Const() {
  var v, w : [int][int]int;
  var f, g : [int, int]int;

  v := (lambda x : int :: (lambda y : int :: x));

  w := (lambda x : int :: (lambda i : int :: x));
  assert v == w;

  w := (lambda i : int :: (lambda y : int :: i));
  assert v == w;

  w := (lambda a : int :: (lambda b : int :: b));
  assert v == w; // should fail, now two different functions

  f := (lambda x : int, y : int :: x);
  assert f == (lambda p : int, q : int :: p);
  assert f == (lambda p : int, q : int :: q); // should fail, different functions
}

procedure PolyConst() {
  assert (lambda<A> x: A :: x) == (lambda<A>x: A :: x); // fails because of type parameters. this could be fixed.
  /* // more tests, when it is fixed
  var k1 : <A1>[A1]<B1>[B1]A1;
  var k2 : <A2>[A2]<B2>[B2]A2;
  k1 := (lambda<A> x: A :: (lambda<B> y: B :: x));
  k2 := (lambda<A> x: A :: (lambda<C> z: C :: x));
  assert k1 == k2;
  k2 := (lambda<X> u: X :: (lambda<Y> v: Y :: u));
  assert k1 == k2;  */
}

procedure FreeVarP() {
  var k : real;
  var m : [int]real;
  m := (lambda x:int :: k);
  assert m[0] == k;
}

procedure FreeVarQ() {
  var k : int;
  var m : [int]int;
  m := (lambda x:int :: k); // should be a different lambda from in FreeVarP, because they have different types
  assert m[0] == k;
}

procedure Quantifiers() {
  var k1 : [int]bool;
  var k2 : [int]bool;
  k1 := (lambda x: int :: (exists y: int :: x > y));
  k2 := (lambda x: int :: (exists y: int :: x > y));
  assert k1 == k2;
  k2 := (lambda x: int :: (exists z: int :: x > z));
  assert k1 == k2;
}

procedure FreeVariables() {
  var m : [bool,bool,bool]bool;
  var k : [bool,bool]bool;

  var f : [bool]bool;
  var g : [bool]bool;

  var a : bool;
  var b : bool;

  f := (lambda r: bool :: a);
  g := (lambda s: bool :: b);
  if (a == b) {
    assert f == g; // should be OK
  } else {
    assert f == g; // should fail
  }

  f := (lambda r: bool :: k[a,b]);
  g := (lambda s: bool :: k[b,a]);
  if (a == b) {
    assert f == g; // should be OK
  } else {
    assert f == g; // should fail
  }

  f := (lambda r: bool :: m[a,a,b]);
  g := (lambda s: bool :: m[a,b,b]);
  if (a == b) {
    assert f == g; // should fail because they are different lambda
  } else {
    assert f == g; // should fail because they are different lambda
  }
}

function f(int) : int;

procedure Triggers() {
  var a,b : [int]bool;
  a := (lambda x:int :: (forall u:int :: { f(u) } x == f(u)));
  b := (lambda y:int :: (forall v:int :: { f(v) } y == f(v)));
  assert a == b;
  b := (lambda y:int :: (forall v:int :: y == f(v)));
  assert a == b; // should fail because triggers are different
}

procedure Attributes() {
  var a,b : [int]bool;
  a := (lambda x:int :: (forall u:int :: {:attrib f(u) } x == f(u)));
  b := (lambda y:int :: (forall v:int :: {:attrib f(v) } y == f(v)));
  assert a == b;
  b := (lambda y:int :: (forall v:int :: {:battrib f(v) } y == f(v)));
  assert a == b; // should fail since attributes are different
  a := (lambda x:int :: (forall u:int :: {:battrib f(x) } x == f(u)));
  assert a == b; // should fail since attributes are different
}

procedure Old() {
  var u,v : [int]int;
  var a,b : int;
  u := (lambda x:int :: old(x+a));
  v := (lambda y:int :: old(y+b));
  if (a == b) {
    assert u == v; // ok
  } else {
    assert u == v; // fails
  }
}

type Box;
function $Box<T>(T) : Box;
function $Unbox<T>(Box) : T;

procedure Coercion() {
  assert (lambda x: Box :: $Box($Unbox(x): int))
      == (lambda y: Box :: $Box($Unbox(y): int));
}