summaryrefslogtreecommitdiff
path: root/Test/dafny0/EqualityTypes.dfy
blob: 251b2e2fbfb65fac1483315be7e580013bd8ab8c (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
module A {
  datatype Explicit<T(==)> = Nil | Cons(set<T>, Explicit<T>);
  datatype Inferred<T> = Nil | Cons(set<T>, Inferred<T>);

  class C {
    method M<T>(x: Explicit<T>)
    method N<T>(x: Inferred<T>)
  }
}

module B refines A {
  class C {
    method M<T>(x: Explicit<T>)
    method N<T(==)>(x: Inferred<T>)
  }
}

// ----------------------------

module C {
  type X(==);
  type Y(==);
}

module D refines C {
  class X { }
  datatype Y = Red | Green | Blue;
}

module E refines C {
  codatatype X = Next(int, X);  // error: X requires equality and codatatypes don't got it
  datatype Y = Nil | Something(Z) | More(Y, Y);  // error: Y does not support equality
  codatatype Z = Red | Green(X) | Blue;
}

module F refines C {
  datatype X<T> = Nil | Cons(T, X<T>);  // error: not allowed to add a type parameter to type X
  class Y<T> { }  // error: not allowed to add a type parameter to type Y
}

module G refines C {
  datatype X = Nil | Next(Z, X);  // error: X does not support equality
  datatype Y = Nil | Something(Z) | More(Y, Y);  // error: Y does not support equality
  codatatype Z = Red | Green | Blue;
}

// ----------------------------

module H {
  datatype Dt<T> = Nil | Cons(T, Dt);

  datatype BulkyList<T> = Nothing | Wrapper(T, BulkyListAux);
  datatype BulkyListAux<T> = Kons(set<T>, BulkyListAuxAux);
  datatype BulkyListAuxAux<T> = GoBack(BulkyList);

  codatatype Stream<T> = Next(head: T, tail: Stream<T>);

  method M<T(==)>(x: T)
  { }
  function method F<T>(x: BulkyList<T>, y: BulkyList<T>): int
  { if x == y then 5 else 7 }  // this equality is allowed
  function method G<T>(x: Dt<T>, y: Dt<T>): int
  { if x == y then 5 else 7 }  // error: the equality is not allowed, because Dt<T> may not support equality
  function method G'<T(==)>(x: Dt<T>, y: Dt<T>): int
  { if x == y then 5 else 7 }  // fine

  method Caller0(b: BulkyList, y: int) {
    match (b) {
      case Nothing =>
      case Wrapper(t, bla) =>
        var u;
        if (y < 100) { u := t; }
        // The following call is allowed, because it will be inferred that
        // 'u' is of a type that supports equality
        M(u);
    }
  }
  method Caller1(d: Dt) {
    match (d) {
      case Nil =>
      case Cons(t, rest) =>
        M(t);  // error: t may be of a type that does not support equality
    }
  }
  method Caller2(co: Stream) {
    var d := Cons(co, Nil);
     Caller1(d);  // case in point for the error in Caller1
  }
}