From 0abb0671d424b328afa991ef2240ba8c3e7b2dc7 Mon Sep 17 00:00:00 2001 From: Aria Shrimpton Date: Thu, 7 Mar 2024 20:51:54 +0000 Subject: rename eager vecs and change uniquevec to be actually useful --- src/crates/library/src/eager_sorted_vector.rs | 353 ------------------------ src/crates/library/src/eager_unique_vector.rs | 360 ------------------------ src/crates/library/src/lib.rs | 8 +- src/crates/library/src/sorted_unique_vector.rs | 361 +++++++++++++++++++++++++ src/crates/library/src/sorted_vector.rs | 353 ++++++++++++++++++++++++ 5 files changed, 718 insertions(+), 717 deletions(-) delete mode 100644 src/crates/library/src/eager_sorted_vector.rs delete mode 100644 src/crates/library/src/eager_unique_vector.rs create mode 100644 src/crates/library/src/sorted_unique_vector.rs create mode 100644 src/crates/library/src/sorted_vector.rs (limited to 'src') diff --git a/src/crates/library/src/eager_sorted_vector.rs b/src/crates/library/src/eager_sorted_vector.rs deleted file mode 100644 index 27d454b..0000000 --- a/src/crates/library/src/eager_sorted_vector.rs +++ /dev/null @@ -1,353 +0,0 @@ -/*LIBSPEC-NAME* -rust-eager-sorted-vec-spec primrose_library::EagerSortedVec -*ENDLIBSPEC-NAME*/ - -use crate::traits::{Container, Indexable}; - -use std::vec::Vec; - -/// A Sorted Vector -#[derive(Debug, Clone)] -pub struct EagerSortedVec { - v: Vec, -} - -impl EagerSortedVec { - pub fn from_vec(mut v: Vec) -> EagerSortedVec { - v.sort(); - EagerSortedVec { v } - } - - pub fn new() -> EagerSortedVec { - EagerSortedVec { v: Vec::new() } - } - - pub fn len(&self) -> usize { - self.v.len() - } - - pub fn contains(&self, x: &T) -> bool { - self.v.binary_search(x).is_ok() - } - - pub fn is_empty(&self) -> bool { - self.len() == 0 - } - - pub fn push(&mut self, value: T) { - let index = self.v.binary_search(&value).unwrap_or_else(|i| i); - self.v.insert(index, value); - } - - pub fn pop(&mut self) -> Option { - self.v.pop() - } - - pub fn remove(&mut self, index: usize) -> T { - self.v.remove(index) - } - - pub fn clear(&mut self) { - self.v.clear() - } - - pub fn first(&self) -> Option<&T> { - self.v.first() - } - - pub fn last(&self) -> Option<&T> { - self.v.last() - } - - pub fn to_vec(self) -> Vec { - self.v - } -} - -/*IMPL* -Container -*ENDIMPL*/ -impl Container for EagerSortedVec { - /*LIBSPEC* - /*OPNAME* - len op-len pre-len post-len - *ENDOPNAME*/ - (define (op-len xs) (cons xs (length xs))) - (define (pre-len xs) (equal? xs (sort xs <))) - (define (post-len xs r) (equal? r (op-len xs))) - *ENDLIBSPEC*/ - fn len(&self) -> usize { - EagerSortedVec::len(self) - } - - /*LIBSPEC* - /*OPNAME* - contains op-contains pre-contains post-contains - *ENDOPNAME*/ - (define (op-contains xs x) - (cond - [(list? (member x xs)) (cons xs #t)] - [else (cons xs #f)])) - (define (pre-contains xs) (equal? xs (sort xs <))) - (define (post-contains xs x r) (equal? r (op-contains xs x))) - *ENDLIBSPEC*/ - fn contains(&self, x: &T) -> bool { - EagerSortedVec::contains(self, x) - } - - /*LIBSPEC* - /*OPNAME* - is-empty op-is-empty pre-is-empty post-is-empty - *ENDOPNAME*/ - (define (op-is-empty xs) (cons xs (null? xs))) - (define (pre-is-empty xs) (equal? xs (sort xs <))) - (define (post-is-empty xs r) (equal? r (op-is-empty xs))) - *ENDLIBSPEC*/ - fn is_empty(&self) -> bool { - EagerSortedVec::is_empty(self) - } - - /*LIBSPEC* - /*OPNAME* - clear op-clear pre-clear post-clear - *ENDOPNAME*/ - (define (op-clear xs) null) - (define (pre-clear xs) (equal? xs (sort xs <))) - (define (post-clear xs r) (equal? r (op-clear xs))) - *ENDLIBSPEC*/ - fn clear(&mut self) { - EagerSortedVec::clear(self); - } - - /*LIBSPEC* - /*OPNAME* - insert op-insert pre-insert post-insert - *ENDOPNAME*/ - (define (op-insert xs x) (sort (append xs (list x)) <)) - (define (pre-insert xs) (equal? xs (sort xs <))) - (define (post-insert xs x ys) (equal? ys (op-insert xs x))) - *ENDLIBSPEC*/ - fn insert(&mut self, elt: T) { - EagerSortedVec::push(self, elt); - } - - /*LIBSPEC* - /*OPNAME* - remove op-remove pre-remove post-remove - *ENDOPNAME*/ - (define (op-remove xs x) - (cond - [(list? (member x xs)) (cons (remove x xs) x)] - [else (cons xs null)])) - (define (pre-remove xs) (equal? xs (sort xs <))) - (define (post-remove xs r) (equal? r (op-remove xs))) - *ENDLIBSPEC*/ - fn remove(&mut self, elt: T) -> Option { - let idx = self.v.binary_search(&elt).ok()?; - Some(self.v.remove(idx)) - } - - fn iter<'a>(&'a self) -> impl Iterator - where - T: 'a, - { - self.v.iter() - } -} - -/*IMPL* -Indexable -*ENDIMPL*/ -impl Indexable for EagerSortedVec { - /*LIBSPEC* - /*OPNAME* - first op-first pre-first post-first - *ENDOPNAME*/ - (define (op-first xs) - (cond - [(null? xs) (cons xs null)] - [else (cons xs (first xs))])) - (define (pre-first xs) #t) - (define (post-first xs r) (equal? r (op-first xs))) - *ENDLIBSPEC*/ - fn first(&self) -> Option<&T> { - EagerSortedVec::first(self) - } - - /*LIBSPEC* - /*OPNAME* - last op-last pre-last post-last - *ENDOPNAME*/ - (define (op-last xs) - (cond - [(null? xs) (cons xs null)] - [else (cons xs (last xs))])) - (define (pre-last xs) #t) - (define (post-last xs r) (equal? r (op-last xs))) - *ENDLIBSPEC*/ - fn last(&self) -> Option<&T> { - EagerSortedVec::last(self) - } - - /*LIBSPEC* - /*OPNAME* - nth op-nth pre-nth post-nth - *ENDOPNAME*/ - (define (op-nth xs n) - (cond - [(>= n (length xs)) (cons xs null)] - [(< n 0) (cons xs null)] - [else (cons xs (list-ref xs n))])) - (define (pre-nth xs) #t) - (define (post-nth xs n r) (equal? r (op-nth xs n))) - *ENDLIBSPEC*/ - fn nth(&self, n: usize) -> Option<&T> { - EagerSortedVec::iter(self).nth(n) - } -} - -impl Default for EagerSortedVec { - fn default() -> Self { - Self::new() - } -} - -impl IntoIterator for EagerSortedVec { - type Item = T; - type IntoIter = std::vec::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.v.into_iter() - } -} - -impl FromIterator for EagerSortedVec { - fn from_iter>(iter: T) -> Self { - let mut v = Vec::from_iter(iter); - v.sort(); - Self { v } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::proptest::{strategies::eager_sorted_vec, *}; - - use im::conslist::ConsList; - use proptest::prelude::*; - - fn abstraction(v: EagerSortedVec) -> ConsList - where - T: Ord, - { - let list: ConsList = ConsList::from(v.to_vec()); - list - } - - proptest! { - #![proptest_config(ProptestConfig { - cases: 100, .. ProptestConfig::default() - })] - - #[test] - fn test_eager_sorted_vec_len(ref mut v in eager_sorted_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - assert_eq!(Container::::len(v), abs_list.len()); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_eager_sorted_vec_contains(ref mut v in eager_sorted_vec(".*", 0..100), a in ".*") { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - assert_eq!(Container::::contains(v, &a), contains(&abs_list, &a)); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_eager_sorted_vec_is_empty(ref mut v in eager_sorted_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - assert_eq!(Container::::is_empty(v), abs_list.is_empty()); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_eager_sorted_vec_insert(ref mut v in eager_sorted_vec(".*", 0..100), a in ".*") { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - let after_list = abs_list.append(conslist![a.clone()]).sort(); - Container::::insert(v, a.clone()); - assert_eq!(abstraction(v.clone()), after_list); - } - - #[test] - fn test_eager_sorted_vec_clear(ref mut v in eager_sorted_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - let after_list = clear(&abs_list); - Container::::clear(v); - assert_eq!(abstraction(v.clone()), after_list); - } - - #[test] - fn test_eager_sorted_vec_remove(ref mut v in eager_sorted_vec(".*", 0..100), a in ".*") { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - let (after_list, abs_elem) = remove(&abs_list, a.clone()); - let elem = Container::::remove(v, a.clone()); - assert_eq!(abstraction(v.clone()), after_list); - assert_eq!(elem, abs_elem); - } - - #[test] - fn test_eager_sorted_vec_first(ref mut v in eager_sorted_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - let elem = Indexable::::first(v); - let abs_first = first(&abs_list); - assert_eq!(elem, abs_first); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_eager_sorted_vec_last(ref mut v in eager_sorted_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - let elem = Indexable::::last(v); - let abs_last = last(&abs_list); - assert_eq!(elem, abs_last); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_eager_sorted_vec_nth(ref mut v in eager_sorted_vec(".*", 0..100), n in 0usize..100) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - let elem = Indexable::::nth(v, n); - let abs_nth = nth(&abs_list, n); - assert_eq!(elem, abs_nth); - assert_eq!(abstraction(v.clone()), abs_list); - } - } -} diff --git a/src/crates/library/src/eager_unique_vector.rs b/src/crates/library/src/eager_unique_vector.rs deleted file mode 100644 index da98421..0000000 --- a/src/crates/library/src/eager_unique_vector.rs +++ /dev/null @@ -1,360 +0,0 @@ -/*LIBSPEC-NAME* -rust-eager-unique-vec-spec primrose_library::EagerUniqueVec -*ENDLIBSPEC-NAME*/ - -use crate::traits::{Container, Indexable}; - -use std::vec::Vec; - -/// A Unique Vector -#[derive(Debug, Clone)] -pub struct EagerUniqueVec { - v: Vec, -} - -impl EagerUniqueVec { - pub fn from_vec(v: Vec) -> EagerUniqueVec { - let mut vec = Vec::::new(); - for i in v { - if !vec.contains(&i) { - vec.push(i); - } - } - EagerUniqueVec { v: vec } - } - - pub fn new() -> EagerUniqueVec { - EagerUniqueVec { v: Vec::new() } - } - - pub fn len(&self) -> usize { - self.v.len() - } - - pub fn contains(&self, x: &T) -> bool { - self.v.contains(x) - } - - pub fn is_empty(&self) -> bool { - self.len() == 0 - } - - // Duplicated elements will be discarded - pub fn push(&mut self, value: T) { - if !self.contains(&value) { - self.v.push(value); - } - } - - pub fn pop(&mut self) -> Option { - self.v.pop() - } - - pub fn remove(&mut self, index: usize) -> T { - self.v.remove(index) - } - - pub fn clear(&mut self) { - self.v.clear() - } - - pub fn first(&self) -> Option<&T> { - self.v.first() - } - - pub fn last(&self) -> Option<&T> { - self.v.last() - } - - pub fn to_vec(self) -> Vec { - self.v - } -} - -/*IMPL* -Container -*ENDIMPL*/ -impl Container for EagerUniqueVec { - /*LIBSPEC* - /*OPNAME* - len op-len pre-len post-len - *ENDOPNAME*/ - (define (op-len xs) (cons xs (length xs))) - (define (pre-len xs) (equal? xs (remove-duplicates xs))) - (define (post-len xs r) (equal? r (op-len xs))) - *ENDLIBSPEC*/ - fn len(&self) -> usize { - EagerUniqueVec::len(self) - } - - /*LIBSPEC* - /*OPNAME* - contains op-contains pre-contains post-contains - *ENDOPNAME*/ - (define (op-contains xs x) - (cond - [(list? (member x xs)) (cons xs #t)] - [else (cons xs #f)])) - (define (pre-contains xs) (equal? xs (remove-duplicates xs))) - (define (post-contains xs x r) (equal? r (op-contains xs x))) - *ENDLIBSPEC*/ - fn contains(&self, x: &T) -> bool { - EagerUniqueVec::contains(self, x) // use fully qualified syntax to avoid function name collision - } - - /*LIBSPEC* - /*OPNAME* - is-empty op-is-empty pre-is-empty post-is-empty - *ENDOPNAME*/ - (define (op-is-empty xs) (cons xs (null? xs))) - (define (pre-is-empty xs) (equal? xs (remove-duplicates xs))) - (define (post-is-empty xs r) (equal? r (op-is-empty xs))) - *ENDLIBSPEC*/ - fn is_empty(&self) -> bool { - EagerUniqueVec::is_empty(self) - } - - /*LIBSPEC* - /*OPNAME* - clear op-clear pre-clear post-clear - *ENDOPNAME*/ - (define (op-clear xs) null) - (define (pre-clear xs) (equal? xs (remove-duplicates xs))) - (define (post-clear xs r) (equal? r (op-clear xs))) - *ENDLIBSPEC*/ - fn clear(&mut self) { - EagerUniqueVec::clear(self); - } - - /*LIBSPEC* - /*OPNAME* - insert op-insert pre-insert post-insert - *ENDOPNAME*/ - (define (op-insert xs x) (remove-duplicates (append xs (list x)))) - (define (pre-insert xs) (equal? xs (remove-duplicates xs))) - (define (post-insert xs x ys) (equal? ys (op-insert xs x))) - *ENDLIBSPEC*/ - fn insert(&mut self, elt: T) { - EagerUniqueVec::push(self, elt); - } - - /*LIBSPEC* - /*OPNAME* - remove op-remove pre-remove post-remove - *ENDOPNAME*/ - (define (op-remove xs x) - (cond - [(list? (member x xs)) (cons (remove x xs) x)] - [else (cons xs null)])) - (define (pre-remove xs) (equal? xs (remove-duplicates xs))) - (define (post-remove xs r) (equal? r (op-remove xs))) - *ENDLIBSPEC*/ - fn remove(&mut self, elt: T) -> Option { - let idx = self.iter().position(|x| *x == elt)?; - Some(self.v.remove(idx)) - } - - fn iter<'a>(&'a self) -> impl Iterator - where - T: 'a, - { - self.v.iter() - } -} - -/*IMPL* -Indexable -*ENDIMPL*/ -impl Indexable for EagerUniqueVec { - /*LIBSPEC* - /*OPNAME* - first op-first pre-first post-first - *ENDOPNAME*/ - (define (op-first xs) - (cond - [(null? xs) (cons xs null)] - [else (cons xs (first xs))])) - (define (pre-first xs) #t) - (define (post-first xs r) (equal? r (op-first xs))) - *ENDLIBSPEC*/ - fn first(&self) -> Option<&T> { - EagerUniqueVec::first(self) - } - - /*LIBSPEC* - /*OPNAME* - last op-last pre-last post-last - *ENDOPNAME*/ - (define (op-last xs) - (cond - [(null? xs) (cons xs null)] - [else (cons xs (last xs))])) - (define (pre-last xs) #t) - (define (post-last xs r) (equal? r (op-last xs))) - *ENDLIBSPEC*/ - fn last(&self) -> Option<&T> { - EagerUniqueVec::last(self) - } - - /*LIBSPEC* - /*OPNAME* - nth op-nth pre-nth post-nth - *ENDOPNAME*/ - (define (op-nth xs n) - (cond - [(>= n (length xs)) (cons xs null)] - [(< n 0) (cons xs null)] - [else (cons xs (list-ref xs n))])) - (define (pre-nth xs) #t) - (define (post-nth xs n r) (equal? r (op-nth xs n))) - *ENDLIBSPEC*/ - fn nth(&self, n: usize) -> Option<&T> { - self.v.get(n) - } -} - -impl Default for EagerUniqueVec { - fn default() -> Self { - Self::new() - } -} - -impl IntoIterator for EagerUniqueVec { - type Item = T; - type IntoIter = std::vec::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.v.into_iter() - } -} - -impl FromIterator for EagerUniqueVec { - fn from_iter>(iter: T) -> Self { - let mut v = Vec::from_iter(iter); - v.sort(); - v.dedup(); - Self { v } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::proptest::{strategies::eager_unique_vec, *}; - use im::conslist::ConsList; - use proptest::prelude::*; - - fn abstraction(v: EagerUniqueVec) -> ConsList - where - T: PartialEq, - { - let list: ConsList = ConsList::from(v.to_vec()); - list - } - - proptest! { - #![proptest_config(ProptestConfig { - cases: 100, .. ProptestConfig::default() - })] - - #[test] - fn test_eager_unique_vec_len(ref mut v in eager_unique_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list)); - //post - assert_eq!(Container::::len(v), abs_list.len()); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_eager_unique_vec_contains(ref mut v in eager_unique_vec(".*", 0..100), a in ".*") { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list)); - //post - assert_eq!(Container::::contains(v, &a), contains(&abs_list, &a)); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_eager_unique_vec_is_empty(ref mut v in eager_unique_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list)); - //post - assert_eq!(Container::::is_empty(v), abs_list.is_empty()); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_eager_unique_vec_insert(ref mut v in eager_unique_vec(".*", 0..100), a in ".*") { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list)); - //post - let after_list = unique(&abs_list.append(conslist![a.clone()])); - Container::::insert(v, a.clone()); - assert_eq!(abstraction(v.clone()), after_list); - } - - #[test] - fn test_eager_unique_vec_clear(ref mut v in eager_unique_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list)); - //post - let after_list = clear(&abs_list); - Container::::clear(v); - assert_eq!(abstraction(v.clone()), after_list); - } - - #[test] - fn test_eager_unique_vec_remove(ref mut v in eager_unique_vec(".*", 0..100), a in ".*") { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list)); - //post - let (after_list, abs_elem) = remove(&abs_list, a.clone()); - let elem = Container::::remove(v, a.clone()); - assert_eq!(abstraction(v.clone()), after_list); - assert_eq!(elem, abs_elem); - } - - #[test] - fn test_eager_unique_vec_first(ref mut v in eager_unique_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list)); - //post - let elem = Indexable::::first(v); - let abs_first = first(&abs_list); - assert_eq!(elem, abs_first); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_eager_unique_vec_last(ref mut v in eager_unique_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list)); - //post - let elem = Indexable::::last(v); - let abs_last = last(&abs_list); - assert_eq!(elem, abs_last); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_eager_unique_vec_nth(ref mut v in eager_unique_vec(".*", 0..100), n in 0usize..100) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list)); - //post - let elem = Indexable::::nth(v, n); - let abs_nth = nth(&abs_list, n); - assert_eq!(elem, abs_nth); - assert_eq!(abstraction(v.clone()), abs_list); - } - } -} diff --git a/src/crates/library/src/lib.rs b/src/crates/library/src/lib.rs index 825ffad..44df8db 100644 --- a/src/crates/library/src/lib.rs +++ b/src/crates/library/src/lib.rs @@ -10,8 +10,8 @@ pub use profiler::{MappingProfilerWrapper, ProfilerWrapper}; mod adaptive; pub use adaptive::AdaptiveContainer; -mod eager_sorted_vector; -mod eager_unique_vector; +mod sorted_unique_vector; +mod sorted_vector; mod btreemap; mod hashmap; @@ -20,8 +20,8 @@ mod list; mod treeset; mod vector; -pub use eager_sorted_vector::EagerSortedVec; -pub use eager_unique_vector::EagerUniqueVec; +pub use sorted_unique_vector::SortedUniqueVec; +pub use sorted_vector::SortedVec; #[cfg(test)] pub mod proptest; diff --git a/src/crates/library/src/sorted_unique_vector.rs b/src/crates/library/src/sorted_unique_vector.rs new file mode 100644 index 0000000..c5a36d8 --- /dev/null +++ b/src/crates/library/src/sorted_unique_vector.rs @@ -0,0 +1,361 @@ +/*LIBSPEC-NAME* +rust-eager-unique-vec-spec primrose_library::SortedUniqueVec +*ENDLIBSPEC-NAME*/ + +use crate::traits::{Container, Indexable}; + +use std::vec::Vec; + +/// A Unique Vector +#[derive(Debug, Clone)] +pub struct SortedUniqueVec { + v: Vec, +} + +impl SortedUniqueVec { + pub fn from_vec(v: Vec) -> SortedUniqueVec { + let mut vec = Vec::::new(); + for i in v { + if !vec.contains(&i) { + vec.push(i); + } + } + SortedUniqueVec { v: vec } + } + + pub fn new() -> SortedUniqueVec { + SortedUniqueVec { v: Vec::new() } + } + + pub fn len(&self) -> usize { + self.v.len() + } + + pub fn contains(&self, x: &T) -> bool { + self.v.contains(x) + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + // Duplicated elements will be discarded + pub fn push(&mut self, value: T) { + // Ok indicates already in list + if let Err(idx) = self.v.binary_search(&value) { + self.v.insert(idx, value); + } + } + + pub fn pop(&mut self) -> Option { + self.v.pop() + } + + pub fn remove(&mut self, index: usize) -> T { + self.v.remove(index) + } + + pub fn clear(&mut self) { + self.v.clear() + } + + pub fn first(&self) -> Option<&T> { + self.v.first() + } + + pub fn last(&self) -> Option<&T> { + self.v.last() + } + + pub fn to_vec(self) -> Vec { + self.v + } +} + +/*IMPL* +Container +*ENDIMPL*/ +impl Container for SortedUniqueVec { + /*LIBSPEC* + /*OPNAME* + len op-len pre-len post-len + *ENDOPNAME*/ + (define (op-len xs) (cons xs (length xs))) + (define (pre-len xs) (equal? xs (remove-duplicates xs))) + (define (post-len xs r) (equal? r (op-len xs))) + *ENDLIBSPEC*/ + fn len(&self) -> usize { + SortedUniqueVec::len(self) + } + + /*LIBSPEC* + /*OPNAME* + contains op-contains pre-contains post-contains + *ENDOPNAME*/ + (define (op-contains xs x) + (cond + [(list? (member x xs)) (cons xs #t)] + [else (cons xs #f)])) + (define (pre-contains xs) (equal? xs (remove-duplicates xs))) + (define (post-contains xs x r) (equal? r (op-contains xs x))) + *ENDLIBSPEC*/ + fn contains(&self, x: &T) -> bool { + SortedUniqueVec::contains(self, x) // use fully qualified syntax to avoid function name collision + } + + /*LIBSPEC* + /*OPNAME* + is-empty op-is-empty pre-is-empty post-is-empty + *ENDOPNAME*/ + (define (op-is-empty xs) (cons xs (null? xs))) + (define (pre-is-empty xs) (equal? xs (remove-duplicates xs))) + (define (post-is-empty xs r) (equal? r (op-is-empty xs))) + *ENDLIBSPEC*/ + fn is_empty(&self) -> bool { + SortedUniqueVec::is_empty(self) + } + + /*LIBSPEC* + /*OPNAME* + clear op-clear pre-clear post-clear + *ENDOPNAME*/ + (define (op-clear xs) null) + (define (pre-clear xs) (equal? xs (remove-duplicates xs))) + (define (post-clear xs r) (equal? r (op-clear xs))) + *ENDLIBSPEC*/ + fn clear(&mut self) { + SortedUniqueVec::clear(self); + } + + /*LIBSPEC* + /*OPNAME* + insert op-insert pre-insert post-insert + *ENDOPNAME*/ + (define (op-insert xs x) (remove-duplicates (append xs (list x)))) + (define (pre-insert xs) (equal? xs (remove-duplicates xs))) + (define (post-insert xs x ys) (equal? ys (op-insert xs x))) + *ENDLIBSPEC*/ + fn insert(&mut self, elt: T) { + SortedUniqueVec::push(self, elt); + } + + /*LIBSPEC* + /*OPNAME* + remove op-remove pre-remove post-remove + *ENDOPNAME*/ + (define (op-remove xs x) + (cond + [(list? (member x xs)) (cons (remove x xs) x)] + [else (cons xs null)])) + (define (pre-remove xs) (equal? xs (remove-duplicates xs))) + (define (post-remove xs r) (equal? r (op-remove xs))) + *ENDLIBSPEC*/ + fn remove(&mut self, elt: T) -> Option { + let idx = self.iter().position(|x| *x == elt)?; + Some(self.v.remove(idx)) + } + + fn iter<'a>(&'a self) -> impl Iterator + where + T: 'a, + { + self.v.iter() + } +} + +/*IMPL* +Indexable +*ENDIMPL*/ +impl Indexable for SortedUniqueVec { + /*LIBSPEC* + /*OPNAME* + first op-first pre-first post-first + *ENDOPNAME*/ + (define (op-first xs) + (cond + [(null? xs) (cons xs null)] + [else (cons xs (first xs))])) + (define (pre-first xs) #t) + (define (post-first xs r) (equal? r (op-first xs))) + *ENDLIBSPEC*/ + fn first(&self) -> Option<&T> { + SortedUniqueVec::first(self) + } + + /*LIBSPEC* + /*OPNAME* + last op-last pre-last post-last + *ENDOPNAME*/ + (define (op-last xs) + (cond + [(null? xs) (cons xs null)] + [else (cons xs (last xs))])) + (define (pre-last xs) #t) + (define (post-last xs r) (equal? r (op-last xs))) + *ENDLIBSPEC*/ + fn last(&self) -> Option<&T> { + SortedUniqueVec::last(self) + } + + /*LIBSPEC* + /*OPNAME* + nth op-nth pre-nth post-nth + *ENDOPNAME*/ + (define (op-nth xs n) + (cond + [(>= n (length xs)) (cons xs null)] + [(< n 0) (cons xs null)] + [else (cons xs (list-ref xs n))])) + (define (pre-nth xs) #t) + (define (post-nth xs n r) (equal? r (op-nth xs n))) + *ENDLIBSPEC*/ + fn nth(&self, n: usize) -> Option<&T> { + self.v.get(n) + } +} + +impl Default for SortedUniqueVec { + fn default() -> Self { + Self::new() + } +} + +impl IntoIterator for SortedUniqueVec { + type Item = T; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.v.into_iter() + } +} + +impl FromIterator for SortedUniqueVec { + fn from_iter>(iter: T) -> Self { + let mut v = Vec::from_iter(iter); + v.sort(); + v.dedup(); + Self { v } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::proptest::{strategies::eager_unique_vec, *}; + use im::conslist::ConsList; + use proptest::prelude::*; + + fn abstraction(v: SortedUniqueVec) -> ConsList + where + T: PartialEq, + { + let list: ConsList = ConsList::from(v.to_vec()); + list + } + + proptest! { + #![proptest_config(ProptestConfig { + cases: 100, .. ProptestConfig::default() + })] + + #[test] + fn test_eager_unique_vec_len(ref mut v in eager_unique_vec(".*", 0..100)) { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, unique(&abs_list)); + //post + assert_eq!(Container::::len(v), abs_list.len()); + assert_eq!(abstraction(v.clone()), abs_list); + } + + #[test] + fn test_eager_unique_vec_contains(ref mut v in eager_unique_vec(".*", 0..100), a in ".*") { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, unique(&abs_list)); + //post + assert_eq!(Container::::contains(v, &a), contains(&abs_list, &a)); + assert_eq!(abstraction(v.clone()), abs_list); + } + + #[test] + fn test_eager_unique_vec_is_empty(ref mut v in eager_unique_vec(".*", 0..100)) { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, unique(&abs_list)); + //post + assert_eq!(Container::::is_empty(v), abs_list.is_empty()); + assert_eq!(abstraction(v.clone()), abs_list); + } + + #[test] + fn test_eager_unique_vec_insert(ref mut v in eager_unique_vec(".*", 0..100), a in ".*") { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, unique(&abs_list)); + //post + let after_list = unique(&abs_list.append(conslist![a.clone()])); + Container::::insert(v, a.clone()); + assert_eq!(abstraction(v.clone()), after_list); + } + + #[test] + fn test_eager_unique_vec_clear(ref mut v in eager_unique_vec(".*", 0..100)) { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, unique(&abs_list)); + //post + let after_list = clear(&abs_list); + Container::::clear(v); + assert_eq!(abstraction(v.clone()), after_list); + } + + #[test] + fn test_eager_unique_vec_remove(ref mut v in eager_unique_vec(".*", 0..100), a in ".*") { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, unique(&abs_list)); + //post + let (after_list, abs_elem) = remove(&abs_list, a.clone()); + let elem = Container::::remove(v, a.clone()); + assert_eq!(abstraction(v.clone()), after_list); + assert_eq!(elem, abs_elem); + } + + #[test] + fn test_eager_unique_vec_first(ref mut v in eager_unique_vec(".*", 0..100)) { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, unique(&abs_list)); + //post + let elem = Indexable::::first(v); + let abs_first = first(&abs_list); + assert_eq!(elem, abs_first); + assert_eq!(abstraction(v.clone()), abs_list); + } + + #[test] + fn test_eager_unique_vec_last(ref mut v in eager_unique_vec(".*", 0..100)) { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, unique(&abs_list)); + //post + let elem = Indexable::::last(v); + let abs_last = last(&abs_list); + assert_eq!(elem, abs_last); + assert_eq!(abstraction(v.clone()), abs_list); + } + + #[test] + fn test_eager_unique_vec_nth(ref mut v in eager_unique_vec(".*", 0..100), n in 0usize..100) { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, unique(&abs_list)); + //post + let elem = Indexable::::nth(v, n); + let abs_nth = nth(&abs_list, n); + assert_eq!(elem, abs_nth); + assert_eq!(abstraction(v.clone()), abs_list); + } + } +} diff --git a/src/crates/library/src/sorted_vector.rs b/src/crates/library/src/sorted_vector.rs new file mode 100644 index 0000000..3d4ae1f --- /dev/null +++ b/src/crates/library/src/sorted_vector.rs @@ -0,0 +1,353 @@ +/*LIBSPEC-NAME* +rust-eager-sorted-vec-spec primrose_library::SortedVec +*ENDLIBSPEC-NAME*/ + +use crate::traits::{Container, Indexable}; + +use std::vec::Vec; + +/// A Sorted Vector +#[derive(Debug, Clone)] +pub struct SortedVec { + v: Vec, +} + +impl SortedVec { + pub fn from_vec(mut v: Vec) -> SortedVec { + v.sort(); + SortedVec { v } + } + + pub fn new() -> SortedVec { + SortedVec { v: Vec::new() } + } + + pub fn len(&self) -> usize { + self.v.len() + } + + pub fn contains(&self, x: &T) -> bool { + self.v.binary_search(x).is_ok() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub fn push(&mut self, value: T) { + let index = self.v.binary_search(&value).unwrap_or_else(|i| i); + self.v.insert(index, value); + } + + pub fn pop(&mut self) -> Option { + self.v.pop() + } + + pub fn remove(&mut self, index: usize) -> T { + self.v.remove(index) + } + + pub fn clear(&mut self) { + self.v.clear() + } + + pub fn first(&self) -> Option<&T> { + self.v.first() + } + + pub fn last(&self) -> Option<&T> { + self.v.last() + } + + pub fn to_vec(self) -> Vec { + self.v + } +} + +/*IMPL* +Container +*ENDIMPL*/ +impl Container for SortedVec { + /*LIBSPEC* + /*OPNAME* + len op-len pre-len post-len + *ENDOPNAME*/ + (define (op-len xs) (cons xs (length xs))) + (define (pre-len xs) (equal? xs (sort xs <))) + (define (post-len xs r) (equal? r (op-len xs))) + *ENDLIBSPEC*/ + fn len(&self) -> usize { + SortedVec::len(self) + } + + /*LIBSPEC* + /*OPNAME* + contains op-contains pre-contains post-contains + *ENDOPNAME*/ + (define (op-contains xs x) + (cond + [(list? (member x xs)) (cons xs #t)] + [else (cons xs #f)])) + (define (pre-contains xs) (equal? xs (sort xs <))) + (define (post-contains xs x r) (equal? r (op-contains xs x))) + *ENDLIBSPEC*/ + fn contains(&self, x: &T) -> bool { + SortedVec::contains(self, x) + } + + /*LIBSPEC* + /*OPNAME* + is-empty op-is-empty pre-is-empty post-is-empty + *ENDOPNAME*/ + (define (op-is-empty xs) (cons xs (null? xs))) + (define (pre-is-empty xs) (equal? xs (sort xs <))) + (define (post-is-empty xs r) (equal? r (op-is-empty xs))) + *ENDLIBSPEC*/ + fn is_empty(&self) -> bool { + SortedVec::is_empty(self) + } + + /*LIBSPEC* + /*OPNAME* + clear op-clear pre-clear post-clear + *ENDOPNAME*/ + (define (op-clear xs) null) + (define (pre-clear xs) (equal? xs (sort xs <))) + (define (post-clear xs r) (equal? r (op-clear xs))) + *ENDLIBSPEC*/ + fn clear(&mut self) { + SortedVec::clear(self); + } + + /*LIBSPEC* + /*OPNAME* + insert op-insert pre-insert post-insert + *ENDOPNAME*/ + (define (op-insert xs x) (sort (append xs (list x)) <)) + (define (pre-insert xs) (equal? xs (sort xs <))) + (define (post-insert xs x ys) (equal? ys (op-insert xs x))) + *ENDLIBSPEC*/ + fn insert(&mut self, elt: T) { + SortedVec::push(self, elt); + } + + /*LIBSPEC* + /*OPNAME* + remove op-remove pre-remove post-remove + *ENDOPNAME*/ + (define (op-remove xs x) + (cond + [(list? (member x xs)) (cons (remove x xs) x)] + [else (cons xs null)])) + (define (pre-remove xs) (equal? xs (sort xs <))) + (define (post-remove xs r) (equal? r (op-remove xs))) + *ENDLIBSPEC*/ + fn remove(&mut self, elt: T) -> Option { + let idx = self.v.binary_search(&elt).ok()?; + Some(self.v.remove(idx)) + } + + fn iter<'a>(&'a self) -> impl Iterator + where + T: 'a, + { + self.v.iter() + } +} + +/*IMPL* +Indexable +*ENDIMPL*/ +impl Indexable for SortedVec { + /*LIBSPEC* + /*OPNAME* + first op-first pre-first post-first + *ENDOPNAME*/ + (define (op-first xs) + (cond + [(null? xs) (cons xs null)] + [else (cons xs (first xs))])) + (define (pre-first xs) #t) + (define (post-first xs r) (equal? r (op-first xs))) + *ENDLIBSPEC*/ + fn first(&self) -> Option<&T> { + SortedVec::first(self) + } + + /*LIBSPEC* + /*OPNAME* + last op-last pre-last post-last + *ENDOPNAME*/ + (define (op-last xs) + (cond + [(null? xs) (cons xs null)] + [else (cons xs (last xs))])) + (define (pre-last xs) #t) + (define (post-last xs r) (equal? r (op-last xs))) + *ENDLIBSPEC*/ + fn last(&self) -> Option<&T> { + SortedVec::last(self) + } + + /*LIBSPEC* + /*OPNAME* + nth op-nth pre-nth post-nth + *ENDOPNAME*/ + (define (op-nth xs n) + (cond + [(>= n (length xs)) (cons xs null)] + [(< n 0) (cons xs null)] + [else (cons xs (list-ref xs n))])) + (define (pre-nth xs) #t) + (define (post-nth xs n r) (equal? r (op-nth xs n))) + *ENDLIBSPEC*/ + fn nth(&self, n: usize) -> Option<&T> { + SortedVec::iter(self).nth(n) + } +} + +impl Default for SortedVec { + fn default() -> Self { + Self::new() + } +} + +impl IntoIterator for SortedVec { + type Item = T; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.v.into_iter() + } +} + +impl FromIterator for SortedVec { + fn from_iter>(iter: T) -> Self { + let mut v = Vec::from_iter(iter); + v.sort(); + Self { v } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::proptest::{strategies::eager_sorted_vec, *}; + + use im::conslist::ConsList; + use proptest::prelude::*; + + fn abstraction(v: SortedVec) -> ConsList + where + T: Ord, + { + let list: ConsList = ConsList::from(v.to_vec()); + list + } + + proptest! { + #![proptest_config(ProptestConfig { + cases: 100, .. ProptestConfig::default() + })] + + #[test] + fn test_eager_sorted_vec_len(ref mut v in eager_sorted_vec(".*", 0..100)) { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, abs_list.sort()); + //post + assert_eq!(Container::::len(v), abs_list.len()); + assert_eq!(abstraction(v.clone()), abs_list); + } + + #[test] + fn test_eager_sorted_vec_contains(ref mut v in eager_sorted_vec(".*", 0..100), a in ".*") { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, abs_list.sort()); + //post + assert_eq!(Container::::contains(v, &a), contains(&abs_list, &a)); + assert_eq!(abstraction(v.clone()), abs_list); + } + + #[test] + fn test_eager_sorted_vec_is_empty(ref mut v in eager_sorted_vec(".*", 0..100)) { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, abs_list.sort()); + //post + assert_eq!(Container::::is_empty(v), abs_list.is_empty()); + assert_eq!(abstraction(v.clone()), abs_list); + } + + #[test] + fn test_eager_sorted_vec_insert(ref mut v in eager_sorted_vec(".*", 0..100), a in ".*") { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, abs_list.sort()); + //post + let after_list = abs_list.append(conslist![a.clone()]).sort(); + Container::::insert(v, a.clone()); + assert_eq!(abstraction(v.clone()), after_list); + } + + #[test] + fn test_eager_sorted_vec_clear(ref mut v in eager_sorted_vec(".*", 0..100)) { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, abs_list.sort()); + //post + let after_list = clear(&abs_list); + Container::::clear(v); + assert_eq!(abstraction(v.clone()), after_list); + } + + #[test] + fn test_eager_sorted_vec_remove(ref mut v in eager_sorted_vec(".*", 0..100), a in ".*") { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, abs_list.sort()); + //post + let (after_list, abs_elem) = remove(&abs_list, a.clone()); + let elem = Container::::remove(v, a.clone()); + assert_eq!(abstraction(v.clone()), after_list); + assert_eq!(elem, abs_elem); + } + + #[test] + fn test_eager_sorted_vec_first(ref mut v in eager_sorted_vec(".*", 0..100)) { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, abs_list.sort()); + //post + let elem = Indexable::::first(v); + let abs_first = first(&abs_list); + assert_eq!(elem, abs_first); + assert_eq!(abstraction(v.clone()), abs_list); + } + + #[test] + fn test_eager_sorted_vec_last(ref mut v in eager_sorted_vec(".*", 0..100)) { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, abs_list.sort()); + //post + let elem = Indexable::::last(v); + let abs_last = last(&abs_list); + assert_eq!(elem, abs_last); + assert_eq!(abstraction(v.clone()), abs_list); + } + + #[test] + fn test_eager_sorted_vec_nth(ref mut v in eager_sorted_vec(".*", 0..100), n in 0usize..100) { + let abs_list = abstraction(v.clone()); + //pre + assert_eq!(abs_list, abs_list.sort()); + //post + let elem = Indexable::::nth(v, n); + let abs_nth = nth(&abs_list, n); + assert_eq!(elem, abs_nth); + assert_eq!(abstraction(v.clone()), abs_list); + } + } +} -- cgit v1.2.3