Advertisement
Guest User

Untitled

a guest
Nov 22nd, 2019
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 12.84 KB | None | 0 0
  1. //  Time to verify: 0m37.716s (note that this is almost 5 minutes via SSH)
  2. //  Corresponds to the packet pile in PacketPile.java
  3. //  Abstractions:
  4. //      In practice, packet pile would store a buffer of blood packets
  5. //      This version of the proof will abstract each blood packet to
  6. //      just the expiry date, since the functions we prove in this file
  7. //      will only see blood packets as expiry date integers.
  8.  
  9. class PacketPile
  10. {
  11.     var buf: array<int>; // int represents expiry date of blood packet
  12.     var count: int;
  13.     var low: int;
  14.     // bloodStatuses
  15.    
  16.  
  17.     predicate Valid()
  18.     reads this, this.buf;
  19.     {
  20.         buf != null &&
  21.         0 <= count <= buf.Length &&
  22.         0 <= low <= buf.Length &&
  23.         Sorted(buf, 0, count) // Sorted by expiry date
  24.     }
  25.  
  26.     method Init(size: int, low1: int)
  27.     modifies this;
  28.     requires 0 <= low1 <= size;
  29.     ensures Valid();
  30.     ensures fresh(buf);
  31.     ensures count == 0;
  32.     ensures low == low1;
  33.     {
  34.         buf := new int[size];
  35.         count := 0; // initially 0 packets
  36.         low := low1;
  37.     }
  38.  
  39.     method popAtIndex(index: int) returns (el: int)
  40.     modifies this.buf, this`count;
  41.     requires Valid(); ensures Valid();
  42.     requires 0 <= index < count;
  43.     ensures count == old(count) - 1;
  44.     ensures el == old(buf[index]);
  45.     ensures buf[..count] == old(buf[..index]) + old(buf[index+1..old(count)]); // Putting RHS into predicate fails(?)
  46.  
  47.     // Excluding String dest since we aren't dealing with actual bloodpacket objects
  48.     method doRequest(nPackets: int, useBy: int) returns (result: array<int>)
  49.     modifies this.buf, this`count;
  50.     requires Valid();
  51.     requires nPackets > 0;
  52.     ensures Valid();
  53.     ensures result != null;
  54.     ensures forall i :: 0 <= i < result.Length ==> result[i] >= useBy;
  55.     ensures 0 <= result.Length <= old(count);
  56.     ensures CountGE(old(buf)[..old(count)],useBy) < nPackets ==> result.Length == 0; // If not enough, return nothinf
  57.     ensures CountGE(old(buf)[..old(count)],useBy) >= nPackets ==> count == old(count) - nPackets;
  58.     ensures CountGE(old(buf)[..old(count)],useBy) >= nPackets ==> result.Length == nPackets; // If enough, then returns some amount
  59.     // ensures CountGE(buf[..],useBy) >= nPackets ==> result[0]// If enough, return the oldest possible
  60.     // Oldest <==> Just before result it too early // what if result[0]
  61.         // Everything before is too early
  62.         // THere exists an index such hat everything befor eis tpoo early
  63.     // ensures CountGE(old(buf)[..old(count)]),useBy) >= nPackets ==>
  64.     //     exists lo :: 0 <= lo <= i+nPackets <= old(count) && (
  65.     //         (forall j :: 0 <= j < lo ==> buf[j] == old(buf[j]) < useBy) &&
  66.     //         (forall j :: 0 <= j < nPackets ==> result[j] == old(buf[j+lo]))
  67.     //     );
  68.     {
  69.         result := new int[nPackets];
  70.         var lo := 0;
  71.         while (lo < count && buf[lo] < useBy)
  72.         decreases count - lo;
  73.         invariant old(buf) == buf;
  74.         invariant forall i :: 0 <= i < count ==> buf[i] == old(buf[i]);
  75.         invariant old(count) == count;
  76.         invariant 0 <= lo <= count;
  77.         invariant forall j :: 0 <= j < lo ==> buf[j] == old(buf[j]);
  78.         invariant forall j :: 0 <= j < lo ==> buf[j] < useBy;
  79.         invariant Valid();
  80.         invariant Sorted(buf,0,count);
  81.         invariant CountGE(buf[..lo],useBy) == 0;
  82.         invariant count <= buf.Length;
  83.         {
  84.             // assert CountGE(buf[..i],useBy) == 0;
  85.             // assert buf[i] < useBy;
  86.             // assert count > 0;
  87.             // assert CountGE(buf[..i+1],useBy) == if |buf[..i+1]| == 0 then 0 else
  88.             //                                 (if buf[..i+1][|buf[..i+1]|-1] >= useBy then 1 else 0) + CountGE(buf[..i+1][..|buf[..i+1]|-1], useBy);
  89.  
  90.             // assert |buf[..i+1]| == i+1 != 0;
  91.             // assert CountGE(buf[..i+1],useBy) == (if buf[..i+1][|buf[..i+1]|-1] >= useBy then 1 else 0) + CountGE(buf[..i+1][..|buf[..i+1]|-1], useBy);
  92.             // assert |buf[..i+1]|-1 == i;
  93.             // assert buf[..i+1][|buf[..i+1]|-1] == buf[i] < useBy;
  94.             // assert (if buf[..i+1][|buf[..i+1]|-1] >= useBy then 1 else 0) == 0;
  95.  
  96.             // assert CountGE(buf[..i+1],useBy) == 0 + CountGE(buf[..i+1][..i], useBy);
  97.             assert buf[..lo+1][..lo] == buf[..lo];
  98.             // assert CountGE(buf[..i+1],useBy) == 0 + CountGE(buf[..i], useBy);
  99.             // assert CountGE(buf[..i+1],useBy) == CountGE(buf[..i],useBy);
  100.             lo := lo + 1;
  101.         }
  102.         assert CountGE(buf[..lo],useBy) == 0;
  103.         assert forall j :: 0 <= j < lo ==> buf[j] == old(buf[j]);
  104.         assert forall j :: 0 <= j < lo ==> buf[j] < useBy;
  105.  
  106.         // if (count - i < nPackets)
  107.         if (lo == count) {
  108.             assert CountGE(buf[..count],useBy) == 0 < nPackets;
  109.             result := new int [0];
  110.         } else {
  111.             assert (lo < count);
  112.             assert (buf[lo] >= useBy);
  113.             assert (useBy <= buf[lo]);
  114.             assert Sorted(buf,0,count);
  115.             assert forall j :: lo <= j < count ==> buf[j] >= useBy;
  116.             assert CountGE(buf[..lo],useBy) == 0;
  117.             var found := 0;
  118.  
  119.             while (lo + found < count && found < nPackets)
  120.             decreases count - (lo + found);
  121.             invariant Valid();
  122.             invariant useBy <= buf[lo];
  123.             invariant old(buf) == buf;
  124.             invariant forall i :: 0 <= i < count ==> buf[i] == old(buf[i]);
  125.             invariant old(count) == count;
  126.             invariant 0 <= lo <= count;
  127.             invariant lo <= lo + found <= count <= buf.Length;
  128.             invariant 0 <= found <= nPackets;
  129.  
  130.             invariant forall j :: 0 <= j < lo ==> buf[j] == old(buf[j]);
  131.             invariant forall j :: 0 <= j < lo ==> buf[j] < useBy;
  132.            
  133.             invariant Sorted(buf,0,count);
  134.             invariant allGE(buf,lo,lo+found,useBy);
  135.  
  136.  
  137.             // Now you've found how many that are possible
  138.             if (found >= nPackets) {
  139.                
  140.                 // Good
  141.                 // We formalise this as 'good', that there are enough packets
  142.                 assert 0 <= count <= buf.Length;
  143.  
  144.                 assert allGE(buf,lo,lo+found,useBy);
  145.  
  146.                 assert buf[..lo+found] == buf[..lo] + buf[lo..lo+found];
  147.                 assert CountGE(buf[lo..lo+found],useBy) == nPackets;
  148.                 assert CountGE(buf[..lo],useBy) == 0;
  149.                 distCountGE(buf[..lo],buf[lo..lo+found],useBy);
  150.                 assert CountGE(buf[..lo+found],useBy) == nPackets;
  151.  
  152.                 assert buf[..count] == buf[..lo+found] + buf[lo+found..count];
  153.                 assert CountGE(buf[lo+found..count],useBy) >= 0;
  154.                 distCountGE(buf[..lo+found],buf[lo+found..count],useBy);
  155.                 assert CountGE(buf[..count],useBy) >= nPackets;
  156.  
  157.                 result := new int[nPackets];
  158.                 assert old(buf) == buf;
  159.                 assert allGE(buf,lo,lo+found,useBy);
  160.                 assert CountGE(buf[..count],useBy) >= nPackets;
  161.  
  162.                 assert !(CountGE(old(buf)[..old(count)],useBy) < nPackets);
  163.  
  164.                 var i := 0;
  165.                 while (i < nPackets)
  166.                 decreases nPackets - i;
  167.                 invariant Valid();
  168.                 invariant buf == old(buf);
  169.                 invariant forall i :: 0 <= i < count ==> buf[i] == old(buf[i]);
  170.                 invariant useBy <= buf[lo];
  171.                 invariant allGE(buf,lo,lo+found,useBy);
  172.                 invariant 0 <= count <= buf.Length && CountGE(buf[..count],useBy) >= nPackets;
  173.                 invariant 0 <= i <= nPackets;
  174.                 invariant lo <= lo + i <= lo + nPackets <= count;
  175.                 invariant Sorted(buf,0,count);
  176.                 invariant forall j :: 0 <= j < lo ==> buf[j] == old(buf[j]);
  177.                 invariant forall j :: 0 <= j < lo ==> buf[j] < useBy;
  178.                 invariant forall j :: 0 <= j < i ==> result[j] >= useBy;
  179.                 invariant forall j :: 0 <= j < i ==> result[j] == buf[lo+j];
  180.                 invariant count == old(count);
  181.                 {
  182.                     assert useBy <= buf[lo] <= buf[lo+i];
  183.                     assert forall j :: 0 <= j < i ==> result[j] == buf[lo+j];
  184.                     result[i] := buf[lo+i];
  185.                     assert forall j :: 0 <= j <= i ==> result[j] == buf[lo+j];
  186.                     i := i + 1;
  187.                 }
  188.                 assert CountGE(buf[..count],useBy) >= nPackets ==> result.Length == nPackets;
  189.                 assert count <= buf.Length;
  190.  
  191.                 assert 0 <= lo <= old(count);
  192.                 assert forall j :: 0 <= j < lo ==> buf[j] < useBy;
  193.                 assert forall j :: 0 <= j < lo ==> buf[j] == old(buf[j]);
  194.                 assert forall j :: 0 <= j < nPackets ==> result[j] == old(buf[lo+j]);
  195.  
  196.                 assert lo + nPackets <= old(count);
  197.  
  198.                 // Now that you have the correct ones we assert that this came from a continuous subset:
  199.                
  200.  
  201.                 assert lo + nPackets <= old(count);
  202.                 assert 0 <= lo <= old(count);
  203.                 assert forall j :: 0 <= j < nPackets ==> result[j] == old(buf[lo+j]);
  204.                 assert forall j :: 0 <= j < lo ==> buf[j] == old(buf[j]);
  205.                 assert forall j :: 0 <= j < lo ==> buf[j] < useBy;
  206.  
  207.                 i := 0;
  208.                 while (i < nPackets)
  209.                 invariant Valid();
  210.                 invariant count == old(count) - i;
  211.                 invariant 0 <= lo <= old(count) - nPackets <= count;
  212.                 invariant buf.Length != 0;
  213.                 invariant forall j :: 0 <= j < nPackets ==> result[j] == old(buf[lo+j]);
  214.                 invariant forall j :: 0 <= j < lo ==> buf[j] == old(buf[j]);
  215.                 invariant forall j :: 0 <= j < lo ==> buf[j] < useBy;
  216.                 {
  217.                     var p := popAtIndex(lo);
  218.                     i := i + 1;
  219.                 }
  220.                 assert CountGE(buf[..old(count)],useBy) >= nPackets ==> count == old(count) - nPackets;
  221.                 assert CountGE(buf[..old(count)],useBy) >= nPackets ==> (forall j :: 0 <= j < nPackets ==> result[j] == old(buf[lo+j]));
  222.                 assert CountGE(buf[..old(count)],useBy) >= nPackets ==> (forall j :: 0 <= j < lo ==> buf[j] == old(buf[j]));
  223.                 assert CountGE(buf[..old(count)],useBy) >= nPackets ==> (forall j :: 0 <= j < lo ==> buf[j] < useBy);
  224.             } else {
  225.                 assert found < nPackets;
  226.                 assert lo + found == count;
  227.                 assert buf[..count] == buf[..lo] + buf[lo..count];
  228.                 assert CountGE(buf[lo..count],useBy) == found;
  229.                 assert CountGE(buf[..lo],useBy) == 0;
  230.                 distCountGE(buf[..lo],buf[lo..count],useBy);
  231.                 assert CountGE(buf[..count],useBy) == found < nPackets;
  232.                 result := new int[0];
  233.             }
  234.         }
  235.     }
  236. }
  237.  
  238. predicate Sorted(a: array<int>, low: int, high: int)
  239. reads a;
  240. requires a != null;
  241. requires 0 <= low <= high <= a.Length;  
  242. {
  243.     forall i, j :: low <= i < j < high ==> a[i] <= a[j]
  244. }
  245.  
  246. // Counts greater than or equal to key
  247. function CountGE(a: seq<int>, key: int): nat
  248. decreases |a|;
  249. ensures 0 <= CountGE(a, key) <= |a|;
  250. {
  251.     if |a| == 0 then 0 else
  252.     (if a[|a|-1] >= key then 1 else 0) + CountGE(a[..|a|-1], key)
  253. }
  254.  
  255. lemma distCountGE(a: seq<int>, b: seq<int>, key: int)
  256. decreases |b|;
  257. ensures CountGE(a,key) + CountGE(b,key) == CountGE(a+b,key);
  258. {
  259.     if (|b| == 0) {
  260.         assert a + b == a;
  261.     } else {
  262.         distCountGE(a,b[0..|b|-1],key);
  263.         // assert CountGE(a,key) + CountGE(b[..|b|-1],key) == CountGE(a+b[..|b|-1],key);
  264.         // assert b[..|b|-1] + [b[|b|-1]] == b;
  265.         // assert CountGE(b,key) == CountGE(b[..|b|-1],key) + (if b[|b|-1] >= key then 1 else 0);
  266.         assert a + b[..|b|-1] + [b[|b|-1]] == a + b;
  267.     }
  268. }
  269.  
  270. lemma inclusiveGE(a: array<int>, lo: int, hi: int, key: int)
  271. requires a != null;
  272. requires 0 <= lo <= hi < a.Length;
  273. requires forall i:: lo <= i < hi ==> a[i] >= key;
  274. requires a[hi] >= key;
  275. ensures forall i:: lo <= i <= hi ==> a[i] >= key;
  276. {
  277.  
  278. }
  279.  
  280. predicate allGE(a: array<int>, lo: int, hi: int, key: int)
  281. requires a != null;
  282. reads a;
  283. requires 0 <= lo <= hi <= a.Length;
  284. {
  285.     forall i:: lo <= i < hi ==> a[i] >= key
  286. }
  287.  
  288. predicate oldestPossible(a: seq<int>, b: seq<int>, a': seq<int>, needed: int, size: int, key: int)
  289. requires 0 <= needed;
  290. requires |a| == |a'|;
  291. requires |b| == needed;
  292. {
  293.     exists k :: 0 <= k <= |a| &&
  294.         k + needed <= |a| &&
  295.         forall j :: 0 <= j < needed ==> b[j] == a[k+j] &&
  296.         forall j :: 0 <= j < k ==> a[j] == a'[j] &&
  297.        forall j :: 0 <= j < k ==> a[j] < key
  298. }
  299.  
  300. function DualRange(a: array<int>, low: int, mid1: int, mid2: int, high: int): seq<int>
  301. reads a;
  302. requires a != null;
  303. requires 0 <= low <= mid1 <= mid2 <= high <= a.Length;
  304. {
  305.    a[low..mid1] + a[mid2..high]
  306. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement