class C { var n: set; method M(v: Stack) requires v != null; { var o: object := v; assert o !in n; // should be known from the types involved } method N(v: Stack) /* this time without the precondition */ { var o: object := v; assert o !in n; // error: v may be null } method A0(a: CP, b: CP) { var x: object := a; var y: object := b; assert x == y ==> x == null; } method A1(a: CP) { var x: object := a; assert (forall b: CP :: x == b ==> b == null); // error (we don't add a type antecedent to // quantifiers; is that what we want?) } var a2x: set>; method A2(b: set>) requires null !in b; { var x: set := a2x; var y: set := b; assert x * y == {}; } method A3(b: set>) /* this time without the precondition */ { var x: set := a2x; var y: set := b; assert x * y <= {null}; } method A4(b: set>) /* again, without the precondition */ { var x: set := a2x; var y: set := b; assert x * y == {}; // error } method A5() { var a := new CP; var b := new CP; while (a != null) decreases *; // omit loop termination check (in fact, the loop does not terminate) { var x: object := a; var y: object := b; assert x == y ==> x == null; a := a; // make 'a' a loop target } } } class Stack { } class Node { } class CP { }