// RUN: %dafny /compile:0 /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t" // RUN: %diff "%s.expect" "%t" module A { method M(p: int) returns (y: int) requires p <= 30; { assume p < 100; var x; assume x == p + 20; x := x + 1; while (*) invariant x <= 120; decreases 120 - x; { if (x == 120) { break; } x := x + 1; } y := x; } } module B refines A { method M ... { assert p < 50; assert ...; var x := p + 20; assert ...; var k := x + 1; ...; while ... invariant k == x; { k := k + 1; } assert k == x || k == x + 1; // there are two exits from the loop } } module C0 refines B { method M ... ensures y == 120; // error: this holds only if the loop does not end early { } } module C1 refines B { method M ... ensures y <= 120; { } } module C2 refines B { method M ... ensures y == 120; { ...; while (true) ... assert k == x + 1; // only one loop exit remains ...; } }