@@ -5,11 +5,190 @@ HumanEval/34
55/* 
66### VERUS BEGIN 
77*/ 
8+ use  vstd:: calc; 
89use  vstd:: prelude:: * ; 
10+ use  vstd:: seq_lib:: lemma_multiset_commutative; 
11+ use  vstd:: seq_lib:: lemma_seq_contains_after_push; 
912
1013verus !  { 
1114
12- // TODO: Put your solution (the specification, implementation, and proof) to the task here 
15+ proof fn  swap_preserves_multiset_helper( s:  Seq <i32 >,  i:  int,  j:  int) 
16+     requires
17+         0  <= i < j < s. len( ) , 
18+     ensures
19+         ( s. take( j + 1 ) ) . to_multiset( )  =~= s. take( i) . to_multiset( ) . add( 
20+             s. subrange( i + 1 ,  j) . to_multiset( ) , 
21+         ) . insert( s. index( j) ) . insert( s. index( i) ) , 
22+ { 
23+     let  fst = s. take( i) ; 
24+     let  snd = s. subrange( i + 1 ,  j) ; 
25+ 
26+     assert( ( s. take( j + 1 ) ) . to_multiset( )  =~= fst. to_multiset( ) . insert( s. index( i) ) . add( 
27+         snd. to_multiset( ) . insert( s. index( j) ) , 
28+     ) )  by { 
29+         assert( s. take( i + 1 ) . to_multiset( )  =~= fst. to_multiset( ) . insert( s. index( i) ) )  by { 
30+             fst. to_multiset_ensures( ) ; 
31+             assert( fst. push( s. index( i) )  =~= s. take( i + 1 ) ) ; 
32+         } 
33+         assert( s. subrange( i + 1 ,  j + 1 ) . to_multiset( )  =~= snd. to_multiset( ) . insert( s. index( j) ) )  by { 
34+             snd. to_multiset_ensures( ) ; 
35+             assert( snd. push( s. index( j) )  =~= s. subrange( i + 1 ,  j + 1 ) ) ; 
36+         } 
37+         lemma_multiset_commutative( s. take( i + 1 ) ,  s. subrange( i + 1 ,  j + 1 ) ) ; 
38+         assert( s. take( i + 1 )  + s. subrange( i + 1 ,  j + 1 )  =~= s. take( j + 1 ) ) ; 
39+     } 
40+ } 
41+ 
42+ // Helper lemma to prove that swapping two elements doesn't change the multiset 
43+ proof fn  swap_preserves_multiset( s1:  Seq <i32 >,  s2:  Seq <i32 >,  i:  int,  j:  int) 
44+     requires
45+         0  <= i < j < s1. len( )  == s2. len( ) , 
46+         forall|x:  int| 0  <= x < s1. len( )  && x != i && x != j ==> s1. index( x)  == s2. index( x) , 
47+         s1. index( i)  == s2. index( j) , 
48+         s1. index( j)  == s2. index( i) , 
49+     ensures
50+         s1. to_multiset( )  == s2. to_multiset( ) , 
51+ { 
52+     calc! { 
53+         ( ==) 
54+         s1. to_multiset( ) ;  { 
55+             lemma_multiset_commutative( s1. take( j + 1 ) ,  s1. skip( j + 1 ) ) ; 
56+             assert( s1 =~= s1. take( j + 1 )  + s1. skip( j + 1 ) ) ; 
57+         } 
58+         s1. take( j + 1 ) . to_multiset( ) . add( s1. skip( j + 1 ) . to_multiset( ) ) ;  { 
59+             assert( s1. take( j + 1 ) . to_multiset( )  =~= s2. take( j + 1 ) . to_multiset( ) )  by { 
60+                 assert( s1. take( i)  == s2. take( i) ) ; 
61+                 assert( s1. subrange( i + 1 ,  j)  =~= ( s2. subrange( i + 1 ,  j) ) ) ; 
62+                 swap_preserves_multiset_helper( s1,  i,  j) ; 
63+                 swap_preserves_multiset_helper( s2,  i,  j) ; 
64+             } 
65+             assert( s1. skip( j + 1 ) . to_multiset( )  =~= s2. skip( j + 1 ) . to_multiset( ) )  by { 
66+                 assert( s1. skip( j + 1 )  =~= s2. skip( j + 1 ) ) ; 
67+             } 
68+         } 
69+         s2. take( j + 1 ) . to_multiset( ) . add( s2. skip( j + 1 ) . to_multiset( ) ) ;  { 
70+             lemma_multiset_commutative( s2. take( j + 1 ) ,  s2. skip( j + 1 ) ) ; 
71+             assert( s2 =~= s2. take( j + 1 )  + s2. skip( j + 1 ) ) ; 
72+         } 
73+         s2. to_multiset( ) ; 
74+     } 
75+ } 
76+ 
77+ fn  sort_seq( s:  & Vec <i32 >)  -> ( ret:  Vec <i32 >) 
78+     ensures
79+         forall|i:  int,  j:  int| 0  <= i < j < ret@. len( )  ==> ret@. index( i)  <= ret@. index( j) , 
80+         ret@. len( )  == s@. len( ) , 
81+         s@. to_multiset( )  == ret@. to_multiset( ) , 
82+ { 
83+     let  mut  sorted = s. clone( ) ; 
84+     let  mut  i:  usize  = 0 ; 
85+     while  i < sorted. len( ) 
86+         invariant
87+             i <= sorted. len( ) , 
88+             forall|j:  int,  k:  int| 0  <= j < k < i ==> sorted@. index( j)  <= sorted@. index( k) , 
89+             s@. to_multiset( )  == sorted@. to_multiset( ) , 
90+             forall|j:  int,  k:  int|
91+                 0  <= j < i <= k < sorted@. len( )  ==> sorted@. index( j)  <= sorted@. index( k) , 
92+             sorted@. len( )  == s@. len( ) , 
93+         decreases ( sorted. len( )  - i) , 
94+     { 
95+         let  mut  min_index:  usize  = i; 
96+         let  mut  j:  usize  = i + 1 ; 
97+         while  j < sorted. len( ) 
98+             invariant
99+                 i <= min_index < j <= sorted. len( ) , 
100+                 forall|k:  int| i <= k < j ==> sorted@. index( min_index as  int)  <= sorted@. index( k) , 
101+             decreases ( sorted. len( )  - j) , 
102+         { 
103+             if  sorted[ j]  < sorted[ min_index]  { 
104+                 min_index = j; 
105+             } 
106+             j += 1 ; 
107+         } 
108+         if  min_index != i { 
109+             let  ghost old_sorted = sorted@; 
110+             let  curr_val = sorted[ i] ; 
111+             let  min_val = sorted[ min_index] ; 
112+             sorted. set( i,  min_val) ; 
113+ 
114+             sorted. set( min_index,  curr_val) ; 
115+ 
116+             proof { 
117+                 swap_preserves_multiset( old_sorted,  sorted@,  i as  int,  min_index as  int) ; 
118+                 assert( old_sorted. to_multiset( )  =~= sorted@. to_multiset( ) ) ; 
119+             } 
120+         } 
121+         i += 1 ; 
122+     } 
123+     sorted
124+ } 
125+ 
126+ fn  unique_sorted( s:  Vec <i32 >)  -> ( result:  Vec <i32 >) 
127+     requires
128+         forall|i:  int,  j:  int| 0  <= i < j < s. len( )  ==> s[ i]  <= s[ j] , 
129+     ensures
130+         forall|i:  int,  j:  int| 0  <= i < j < result. len( )  ==> result[ i]  < result[ j] , 
131+         forall|i:  int| #![ auto]  0  <= i < result. len( )  ==> s@. contains( result[ i] ) , 
132+         forall|i:  int| #![ trigger s[ i] ]  0  <= i < s. len( )  ==> result@. contains( s[ i] ) , 
133+ { 
134+     let  mut  result:  Vec <i32 > = vec![ ] ; 
135+     for  i in 0 ..s. len( ) 
136+         invariant
137+             forall|i:  int,  j:  int| 0  <= i < j < s. len( )  ==> s[ i]  <= s[ j] , 
138+             forall|k:  int,  l:  int| 0  <= k < l < result. len( )  ==> result[ k]  < result[ l] , 
139+             forall|k:  int|
140+                 #![ trigger result[ k] ] 
141+                 0  <= k < result. len( )  ==> ( exists|m:  int| 0  <= m < i && result[ k]  == s[ m] ) , 
142+             forall|m:  int| #![ trigger s[ m] ]  0  <= m < i ==> result@. contains( s[ m] ) , 
143+     { 
144+         let  ghost pre = result; 
145+         if  result. len( )  == 0  || result[ result. len( )  - 1 ]  != s[ i]  { 
146+             assert( result. len( )  == 0  || result[ result. len( )  - 1 ]  < s[ i as  int] ) ; 
147+             result. push( s[ i] ) ; 
148+             assert forall|m:  int| #![ trigger s[ m] ]  0  <= m < i implies result@. contains( s[ m] )  by { 
149+                 assert( pre@. contains( s@[ m] ) ) ; 
150+                 lemma_seq_contains_after_push( pre@,  s@[ i as  int] ,  s@[ m] ) ; 
151+             } ; 
152+         } 
153+         assert( forall|m:  int|
154+             #![ trigger result@[ m] ,  pre@[ m] ] 
155+             0  <= m < pre. len( )  ==> pre@. contains( result@[ m] )  ==> result@. contains( pre@[ m] ) )  by { 
156+             assert( forall|m:  int| 0  <= m < pre. len( )  ==> result@[ m]  == pre@[ m] ) ; 
157+         } 
158+         assert( result@. contains( s[ i as  int] ) )  by { 
159+             assert( result[ result. len( )  - 1 ]  == s[ i as  int] ) ; 
160+         } 
161+     } 
162+     result
163+ } 
164+ 
165+ fn  unique( s:  Vec <i32 >)  -> ( result:  Vec <i32 >) 
166+     ensures
167+         forall|i:  int,  j:  int| 0  <= i < j < result. len( )  ==> result[ i]  < result[ j] , 
168+         forall|i:  int| #![ auto]  0  <= i < result. len( )  ==> s@. contains( result[ i] ) , 
169+         forall|i:  int| #![ trigger s[ i] ]  0  <= i < s. len( )  ==> result@. contains( s[ i] ) , 
170+ { 
171+     let  sorted = sort_seq( & s) ; 
172+     assert( forall|i:  int| #![ auto]  0  <= i < sorted. len( )  ==> s@. contains( sorted[ i] ) )  by { 
173+         assert( forall|i:  int|
174+             #![ auto] 
175+             0  <= i < sorted. len( )  ==> sorted@. to_multiset( ) . contains( sorted[ i] ) )  by { 
176+             sorted@. to_multiset_ensures( ) ; 
177+         } 
178+         assert( forall|i:  int|
179+             #![ auto] 
180+             0  <= i < sorted. len( )  ==> s@. to_multiset( ) . contains( sorted[ i] ) ) ; 
181+         s@. to_multiset_ensures( ) ; 
182+     } 
183+     assert( forall|i:  int| #![ trigger s[ i] ]  0  <= i < s. len( )  ==> sorted@. contains( s[ i] ) )  by { 
184+         assert( forall|i:  int| #![ auto]  0  <= i < s. len( )  ==> s@. to_multiset( ) . contains( s[ i] ) )  by { 
185+             s@. to_multiset_ensures( ) ; 
186+         } 
187+         assert( forall|i:  int| #![ auto]  0  <= i < s. len( )  ==> sorted@. to_multiset( ) . contains( s[ i] ) ) ; 
188+         sorted@. to_multiset_ensures( ) ; 
189+     } 
190+     unique_sorted( sorted) 
191+ } 
13192
14193}  // verus! 
15194fn  main ( )  { } 
0 commit comments