@@ -1005,18 +1005,33 @@ mod program_three {
10051005
10061006 assert( next_step( c, s4, s5, Step :: UnmapEnd , RLbl :: UnmapEnd { thread_id: 0 , vaddr: pte1_vaddr, result: Ok ( ( ) ) } ) ) ;
10071007
1008- let s6 = s5;
10091008
1010- let s5s6op = MemOp :: Store { new_value: seq![ 10 , 0 , 0 , 0 ] , result: StoreResult :: Pagefault } ;
1011- assert( s5s6op. op_size( ) == 4 ) ;
1009+ { // Proof 1: A pagefault is a possible result of a store in this state
1010+ let s6 = s5;
1011+ let s5s6op = MemOp :: Store { new_value: seq![ 10 , 0 , 0 , 0 ] , result: StoreResult :: Pagefault } ;
1012+ assert( s5s6op. op_size( ) == 4 ) ;
10121013
1013- assert( next_step( c, s5, s6, Step :: MemOp { pte: None } ,
1014- RLbl :: MemOp {
1015- thread_id: 0 ,
1016- vaddr: pte1_vaddr,
1017- op: s5s6op,
1018- } ,
1019- ) ) ;
1014+ assert( next_step( c, s5, s6, Step :: MemOp { pte: None } ,
1015+ RLbl :: MemOp {
1016+ thread_id: 0 ,
1017+ vaddr: pte1_vaddr,
1018+ op: s5s6op,
1019+ } ,
1020+ ) ) ;
1021+ }
1022+
1023+ { // Proof 2: If thread 0 does a store to address pte1_vaddr, it must result in a pagefault
1024+ assume( exists|s6, step, rlbl| // Assuming we do a store ...
1025+ next_step( c, s5, s6, step, rlbl) &&
1026+ ( rlbl matches RLbl :: MemOp { thread_id, vaddr, op: MemOp :: Store { new_value, result } }
1027+ && thread_id == 0 && vaddr == pte1_vaddr) ) ;
1028+ let ( s6, step, rlbl) = choose|s6: State , step: Step , rlbl: RLbl |
1029+ next_step( c, s5, s6, step, rlbl) &&
1030+ ( rlbl matches RLbl :: MemOp { thread_id, vaddr, op: MemOp :: Store { new_value, result } }
1031+ && thread_id == 0 && vaddr == pte1_vaddr) ;
1032+ assert( rlbl is MemOp ) ;
1033+ assert( rlbl->op->Store_result is Pagefault ) ; // ... then it must cause a page fault
1034+ }
10201035 }
10211036}
10221037
@@ -1078,18 +1093,33 @@ mod program_four {
10781093 assert( next_step( c, s4, s5, Step :: ProtectEnd , s4s5rlbl) ) ;
10791094
10801095
1081- let s6 = State { mem: update_range( s5. mem, pte1_vaddr as int, seq![ 42 , 0 , 0 , 0 ] ) , ..s5 } ;
1096+ { // Proof 1: We *can* successfully write to pte1_vaddr
1097+ let s6 = State { mem: update_range( s5. mem, pte1_vaddr as int, seq![ 42 , 0 , 0 , 0 ] ) , ..s5 } ;
10821098
1083- let s5s6op = MemOp :: Store { new_value: seq![ 42 , 0 , 0 , 0 ] , result: StoreResult :: Ok } ;
1084- assert( s5s6op. op_size( ) == 4 ) ;
1099+ let s5s6op = MemOp :: Store { new_value: seq![ 42 , 0 , 0 , 0 ] , result: StoreResult :: Ok } ;
1100+ assert( s5s6op. op_size( ) == 4 ) ;
10851101
1086- assert( next_step(
1087- c,
1088- s5,
1089- s6,
1090- Step :: MemOp { pte: Some ( ( pte1_vaddr, pte1) ) } ,
1091- RLbl :: MemOp { thread_id: 0 , vaddr: pte1_vaddr, op: s5s6op } ,
1092- ) ) ;
1102+ assert( next_step(
1103+ c,
1104+ s5,
1105+ s6,
1106+ Step :: MemOp { pte: Some ( ( pte1_vaddr, pte1) ) } ,
1107+ RLbl :: MemOp { thread_id: 0 , vaddr: pte1_vaddr, op: s5s6op } ,
1108+ ) ) ;
1109+ }
1110+
1111+ { // Proof 2: Any write to pte1_vaddr is successful
1112+ assume( exists|s6, step, rlbl| // Assuming we do a store ...
1113+ next_step( c, s5, s6, step, rlbl) &&
1114+ ( rlbl matches RLbl :: MemOp { thread_id, vaddr, op: MemOp :: Store { new_value, result } }
1115+ && thread_id == 0 && vaddr == pte1_vaddr) ) ;
1116+ let ( s6, step, rlbl) = choose|s6: State , step: Step , rlbl: RLbl |
1117+ next_step( c, s5, s6, step, rlbl) &&
1118+ ( rlbl matches RLbl :: MemOp { thread_id, vaddr, op: MemOp :: Store { new_value, result } }
1119+ && thread_id == 0 && vaddr == pte1_vaddr) ;
1120+ assert( rlbl is MemOp ) ;
1121+ assert( rlbl->op->Store_result is Ok ) ; // ... then its result must be Ok
1122+ }
10931123 }
10941124}
10951125
0 commit comments