Advertisement
Guest User

Untitled

a guest
Apr 20th, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.39 KB | None | 0 0
  1. #![allow(dead_code)]
  2.  
  3. extern crate prusti_contracts;
  4.  
  5. pub struct VecWrapperI32{
  6. v: Vec<i32>
  7. }
  8.  
  9. impl VecWrapperI32 {
  10.  
  11. #[trusted]
  12. #[pure]
  13. #[ensures="result >= 0"]
  14.  
  15. pub fn len(&self) -> usize {
  16. self.v.len()
  17. }
  18.  
  19. #[trusted]
  20. #[pure]
  21. #[requires="0 <= index && index < self.len()"]
  22.  
  23. pub fn lookup(&self, index: usize) -> i32 {
  24. self.v[index]
  25. }
  26.  
  27. #[trusted]
  28. #[requires="0 <= index && index < self.len()"]
  29. #[ensures="self.lookup(index) == *result"]
  30.  
  31. pub fn index(&self, index: usize) -> &i32 {
  32. &self.v[index]
  33. }
  34. }
  35.  
  36. pub enum UsizeOption {
  37. Some(usize),
  38. None,
  39. }
  40.  
  41. impl UsizeOption {
  42. #[pure]
  43.  
  44. pub fn is_some(&self) -> bool {
  45. match self {
  46. UsizeOption::Some(_) => true,
  47. UsizeOption::None => false,
  48. }
  49. }
  50.  
  51. #[pure]
  52.  
  53. pub fn is_none(&self) -> bool {
  54. match self {
  55. UsizeOption::Some(_) => false,
  56. UsizeOption::None => true,
  57. }
  58. }
  59. }
  60.  
  61. pub enum Ordering {
  62. Less,
  63. Equal,
  64. Greater,
  65. }
  66. use self::Ordering::*;
  67.  
  68. #[ensures="(match result {
  69. Equal => *a == *b,
  70. Less => *a < *b,
  71. Greater => *a > *b,
  72. })"]
  73.  
  74. fn cmp(a: &i32, b: &i32) -> Ordering {
  75. if *a == *b { Equal }
  76. else if *a < *b { Less }
  77. else { Greater }
  78. }
  79.  
  80. #[requires="forall k1: usize, k2: usize :: (0 <= k1 && k1 < k2 && k2 < arr.len()) ==>
  81. arr.lookup(k1) <= arr.lookup(k2)"]
  82. #[ensures="result.is_none() ==>
  83. (forall k: usize :: (0 <= k && k < arr.len()) ==> *elem != arr.lookup(k))"]
  84. #[ensures="match result {
  85. UsizeOption::Some(index) => (
  86. 0 <= index && index < arr.len() &&
  87. arr.lookup(index) == *elem
  88. ),
  89. UsizeOption::None => true,
  90. }"]
  91.  
  92. fn binary_search(arr: &VecWrapperI32, elem: &i32) -> UsizeOption {
  93. let mut size = arr.len();
  94. let mut base = 0;
  95. let mut result = UsizeOption::None;
  96. let mut continue_loop = size > 0;
  97.  
  98. #[invariant="0 <= base"]
  99. #[invariant="0 <= size"]
  100. #[invariant="continue_loop == (size > 0 && result.is_none())"]
  101. #[invariant="base + size <= arr.len()"]
  102. #[invariant="forall k1: usize, k2: usize :: (0 <= k1 && k1 < k2 && k2 < arr.len()) ==>
  103. arr.lookup(k1) <= arr.lookup(k2)"]
  104. #[invariant="forall k: usize:: (0 <= k && k < base) ==> arr.lookup(k) < *elem"]
  105. #[invariant="result.is_none() ==>
  106. (forall k: usize :: (base + size <= k && k < arr.len()) ==> *elem != arr.lookup(k))"]
  107. #[invariant="match result {
  108. UsizeOption::Some(index) => (
  109. 0 <= index && index < arr.len() &&
  110. arr.lookup(index) == *elem
  111. ),
  112. UsizeOption::None => true,
  113. }"]
  114.  
  115. while continue_loop {
  116. let half = size / 2;
  117. let mid = base + half;
  118. let mid_element = arr.index(mid);
  119. let cmp_result = cmp(mid_element, elem);
  120. base = match cmp_result {
  121. Less => {
  122. mid
  123. },
  124. Greater => {
  125. base
  126. },
  127. Equal => {
  128. result = UsizeOption::Some(mid);
  129. base // Just return anything because we are finished.
  130. }
  131. };
  132. size -= half;
  133. continue_loop = size > 0 && result.is_none();
  134. }
  135. result
  136. }
  137.  
  138. fn main() {}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement