22//@compile-flags: -C debug-assertions=off
33//@rustc-env: THRUST_SOLVER=tests/thrust-pcsat-wrapper THRUST_SOLVER_TIMEOUT_SECS=60
44
5- // A loop invariant in a *trait default method* may refer to `Self`, the trait's
6- // associated types (`Self::Item`) and its predicates (`Self::step`). The
7- // invariant is rewritten into a free `formula_fn` in which `Self` becomes a
8- // synthetic generic, so that generic must inherit the host `Self: Foo` bound for
9- // the associated type / predicate to remain resolvable.
10-
115#[ thrust_macros:: requires( true ) ]
126#[ thrust_macros:: ensures( true ) ]
137#[ thrust:: trusted]
@@ -16,53 +10,50 @@ fn rand() -> i64 {
1610}
1711
1812#[ thrust_macros:: context]
19- trait Foo {
20- type Item ;
21-
13+ trait Gauge {
2214 #[ thrust_macros:: predicate]
23- fn step ( self , item : Self :: Item , dist : Self ) -> bool ;
15+ fn invariant ( x : i32 ) -> bool ;
16+
17+ fn update ( & mut self ) -> i32 ;
2418
2519 #[ thrust_macros:: invariant_context]
26- fn run ( self , item : Self :: Item )
27- where
28- Self : Sized ,
29- {
30- let c = self ;
31- let it = item;
20+ fn run ( & mut self ) -> i32 {
21+ let mut state = 0 ;
3222 while rand ( ) == 0 {
33- thrust_macros:: invariant!( |c: Self , it: Self :: Item | Self :: step( c, it, c) || true ) ;
23+ state = self . update ( ) ;
24+ thrust_macros:: invariant!( |state: i32 | Self :: invariant( state) ) ;
3425 }
35- let _last = c;
36- let _last_item = it;
26+ state
3727 }
3828}
3929
4030#[ derive( PartialEq ) ]
41- struct Range {
42- start : i64 ,
43- end : i64 ,
31+ struct Counter {
32+ value : i32 ,
4433}
4534
46- impl thrust_models:: Model for Range {
47- type Ty = Range ;
35+ impl thrust_models:: Model for Counter {
36+ type Ty = Counter ;
4837}
4938
5039#[ thrust_macros:: context]
51- impl Foo for Range {
52- type Item = i64 ;
53-
40+ impl Gauge for Counter {
5441 #[ thrust_macros:: predicate]
55- fn step ( self , item : Self :: Item , dist : Self ) -> bool {
56- // self.end == dist.end && self.start == item && self.start + 1 == dist.start
57- "(and
58- (= (tuple_proj<Int-Int>.1 self_) (tuple_proj<Int-Int>.1 dist))
59- (= (tuple_proj<Int-Int>.0 self_) item)
60- (= (+ (tuple_proj<Int-Int>.0 self_) 1) (tuple_proj<Int-Int>.0 dist))
61- )" ;
62- true
42+ fn invariant ( x : i32 ) -> bool {
43+ "(>= x 0)" ; true
44+ }
45+
46+ fn update ( & mut self ) -> i32 {
47+ if self . value < 0 {
48+ self . value *= -1 ;
49+ } else {
50+ self . value += 1 ;
51+ }
52+ self . value
6353 }
6454}
6555
6656fn main ( ) {
67- Range { start : 0 , end : 5 } . run ( 0 ) ;
57+ let mut c = Counter { value : 0 } ;
58+ assert ! ( c. run( ) >= 0 ) ;
6859}
0 commit comments