diff options
-rw-r--r-- | src/crates/library/src/lazy_sorted_vector.rs | 363 | ||||
-rw-r--r-- | src/crates/library/src/lazy_unique_vector.rs | 360 | ||||
-rw-r--r-- | src/crates/library/src/lib.rs | 4 | ||||
-rw-r--r-- | thesis/parts/implementation.tex | 2 |
4 files changed, 2 insertions, 727 deletions
diff --git a/src/crates/library/src/lazy_sorted_vector.rs b/src/crates/library/src/lazy_sorted_vector.rs deleted file mode 100644 index 17cb7f6..0000000 --- a/src/crates/library/src/lazy_sorted_vector.rs +++ /dev/null @@ -1,363 +0,0 @@ -/*LIBSPEC-NAME* -rust-lazy-sorted-vec-spec primrose_library::LazySortedVec -*ENDLIBSPEC-NAME*/ - -use crate::traits::{Container, Indexable}; - -use std::slice::Iter; -pub use std::vec::Vec; - -/// A Sorted Vector -#[derive(Debug, Clone)] -pub struct LazySortedVec<T> { - v: Vec<T>, - modified: bool, -} - -impl<T: Ord> LazySortedVec<T> { - pub fn from_vec(mut v: Vec<T>) -> LazySortedVec<T> { - v.sort(); - LazySortedVec { v, modified: false } - } - - pub fn new() -> LazySortedVec<T> { - LazySortedVec { - v: Vec::new(), - modified: false, - } - } - - pub fn len(&self) -> usize { - self.v.len() - } - - pub fn contains(&mut self, x: &T) -> bool { - if self.modified { - self.v.sort(); - self.modified = false; - } - self.v.binary_search(x).is_ok() - } - - pub fn is_empty(&self) -> bool { - self.len() == 0 - } - - pub fn push(&mut self, value: T) { - self.v.push(value); - self.modified = true; - } - - pub fn pop(&mut self) -> Option<T> { - if self.modified { - self.v.sort(); - self.modified = false; - } - self.v.pop() - } - - pub fn remove(&mut self, index: usize) -> T { - if self.modified { - self.v.sort(); - self.modified = false; - } - self.v.remove(index) - } - - pub fn clear(&mut self) { - self.v.clear() - } - - pub fn first(&mut self) -> Option<&T> { - if self.modified { - self.v.sort(); - self.modified = false; - } - self.v.first() - } - - pub fn last(&mut self) -> Option<&T> { - if self.modified { - self.v.sort(); - self.modified = false; - } - self.v.last() - } - - pub fn get(&mut self, index: usize) -> Option<&T> { - self.v.get(index) - } - - pub fn iter(&mut self) -> Iter<T> { - self.v.iter() - } - - pub fn to_vec(self) -> Vec<T> { - self.v - } -} - -/*IMPL* -Container -*ENDIMPL*/ -impl<T: Ord> Container<T> for LazySortedVec<T> { - /*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 { - LazySortedVec::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(&mut self, x: &T) -> bool { - LazySortedVec::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 { - LazySortedVec::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) { - LazySortedVec::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) { - LazySortedVec::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<T> { - self.iter() - .position(|x| *x == elt) - .map(|index| self.remove(index)) - } -} - -/*IMPL* -Indexable -*ENDIMPL*/ -impl<T: Ord> Indexable<T> for LazySortedVec<T> { - /*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) (equal? xs (sort xs <))) - (define (post-first xs r) (equal? r (op-first xs))) - *ENDLIBSPEC*/ - fn first(&mut self) -> Option<&T> { - LazySortedVec::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) (equal? xs (sort xs <))) - (define (post-last xs r) (equal? r (op-last xs))) - *ENDLIBSPEC*/ - fn last(&mut self) -> Option<&T> { - LazySortedVec::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) (equal? xs (sort xs <))) - (define (post-nth xs n r) (equal? r (op-nth xs n))) - *ENDLIBSPEC*/ - fn nth(&mut self, n: usize) -> Option<&T> { - LazySortedVec::iter(self).nth(n) - } -} - -impl<T: Ord> Default for LazySortedVec<T> { - fn default() -> Self { - Self::new() - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::proptest::{strategies::lazy_sorted_vec, *}; - use proptest::prelude::*; - - use im::conslist::ConsList; - - fn abstraction<T>(v: LazySortedVec<T>) -> ConsList<T> - where - T: Ord, - { - let list: ConsList<T> = ConsList::from(v.to_vec()); - list.sort() - } - - proptest! { - #![proptest_config(ProptestConfig { - cases: 100, .. ProptestConfig::default() - })] - - #[test] - fn test_lazy_sorted_vec_len(ref mut v in lazy_sorted_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - assert_eq!(Container::<String>::len(v), abs_list.len()); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_lazy_sorted_vec_contains(ref mut v in lazy_sorted_vec(".*", 0..100), a in ".*") { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - assert_eq!(Container::<String>::contains(v, &a), contains(&abs_list, &a)); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_lazy_sorted_vec_is_empty(ref mut v in lazy_sorted_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - assert_eq!(Container::<String>::is_empty(v), abs_list.is_empty()); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_lazy_sorted_vec_insert(ref mut v in lazy_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::<String>::insert(v, a.clone()); - assert_eq!(abstraction(v.clone()), after_list); - } - - #[test] - fn test_lazy_sorted_vec_clear(ref mut v in lazy_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::<String>::clear(v); - assert_eq!(abstraction(v.clone()), after_list); - } - - #[test] - fn test_lazy_sorted_vec_remove(ref mut v in lazy_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::<String>::remove(v, a.clone()); - assert_eq!(abstraction(v.clone()), after_list); - assert_eq!(elem, abs_elem); - } - - #[test] - fn test_lazy_sorted_vec_first(ref mut v in lazy_sorted_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - let elem = Indexable::<String>::first(v); - let abs_first = first(&abs_list); - assert_eq!(elem, abs_first); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_lazy_sorted_vec_last(ref mut v in lazy_sorted_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, abs_list.sort()); - //post - let elem = Indexable::<String>::last(v); - let abs_last = last(&abs_list); - assert_eq!(elem, abs_last); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_lazy_sorted_vec_nth(ref mut v in lazy_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::<String>::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/lazy_unique_vector.rs b/src/crates/library/src/lazy_unique_vector.rs deleted file mode 100644 index e9c24dc..0000000 --- a/src/crates/library/src/lazy_unique_vector.rs +++ /dev/null @@ -1,360 +0,0 @@ -/*LIBSPEC-NAME* -rust-lazy-unique-vec-spec primrose_library::LazyUniqueVec -*ENDLIBSPEC-NAME*/ - -use crate::traits::{Container, Indexable}; - -use std::slice::Iter; -use std::vec::Vec; - -/// A Unique and Ascending Vector -#[derive(Debug, Clone)] -pub struct LazyUniqueVec<T> { - v: Vec<T>, - modified: bool, -} - -impl<T: Ord> LazyUniqueVec<T> { - pub fn new() -> LazyUniqueVec<T> { - LazyUniqueVec { - v: Vec::new(), - modified: false, - } - } - - pub fn from_vec(mut v: Vec<T>) -> LazyUniqueVec<T> { - v.sort(); - v.dedup(); - LazyUniqueVec { v, modified: false } - } - - pub fn len(&self) -> usize { - self.v.len() - } - - pub fn contains(&mut self, x: &T) -> bool { - if self.modified { - self.v.sort(); - self.v.dedup(); - self.modified = false; - } - self.v.binary_search(x).is_ok() - } - - pub fn is_empty(&self) -> bool { - self.len() == 0 - } - - // Duplicated elements will be discarded - pub fn push(&mut self, value: T) { - self.v.push(value); - self.modified = true; - } - - pub fn pop(&mut self) -> Option<T> { - if self.modified { - self.v.sort(); - self.v.dedup(); - self.modified = false; - } - self.v.pop() - } - - pub fn remove(&mut self, index: usize) -> T { - if self.modified { - self.v.sort(); - self.v.dedup(); - self.modified = false; - } - self.v.remove(index) - } - - pub fn clear(&mut self) { - self.v.clear() - } - - pub fn first(&mut self) -> Option<&T> { - if self.modified { - self.v.sort(); - self.v.dedup(); - self.modified = false; - } - self.v.first() - } - - pub fn last(&mut self) -> Option<&T> { - if self.modified { - self.v.sort(); - self.v.dedup(); - self.modified = false; - } - self.v.last() - } - - pub fn iter(&mut self) -> Iter<'_, T> { - if self.modified { - self.v.sort(); - self.v.dedup(); - self.modified = false; - } - self.v.iter() - } - - pub fn to_vec(self) -> Vec<T> { - self.v - } -} - -/*IMPL* -Container -*ENDIMPL*/ -impl<T: Ord> Container<T> for LazyUniqueVec<T> { - /*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 (sort xs <)))) - (define (post-len xs r) (equal? r (op-len xs))) - *ENDLIBSPEC*/ - fn len(&self) -> usize { - LazyUniqueVec::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 (sort xs <)))) - (define (post-contains xs x r) (equal? r (op-contains xs x))) - *ENDLIBSPEC*/ - fn contains(&mut self, x: &T) -> bool { - LazyUniqueVec::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 (sort xs <)))) - (define (post-is-empty xs r) (equal? r (op-is-empty xs))) - *ENDLIBSPEC*/ - fn is_empty(&self) -> bool { - LazyUniqueVec::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 (sort xs <)))) - (define (post-clear xs r) (equal? r (op-clear xs))) - *ENDLIBSPEC*/ - fn clear(&mut self) { - LazyUniqueVec::clear(self); - } - - /*LIBSPEC* - /*OPNAME* - insert op-insert pre-insert post-insert - *ENDOPNAME*/ - (define (op-insert xs x) (remove-duplicates (sort (append xs (list x)) <))) - (define (pre-insert xs) (equal? xs (remove-duplicates (sort xs <)))) - (define (post-insert xs x ys) (equal? ys (op-insert xs x))) - *ENDLIBSPEC*/ - fn insert(&mut self, elt: T) { - LazyUniqueVec::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 (sort xs <)))) - (define (post-remove xs r) (equal? r (op-remove xs))) - *ENDLIBSPEC*/ - fn remove(&mut self, elt: T) -> Option<T> { - self.iter() - .position(|x| *x == elt) - .map(|index| self.remove(index)) - } -} - -/*IMPL* -Indexable -*ENDIMPL*/ -impl<T: Ord> Indexable<T> for LazyUniqueVec<T> { - /*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) (equal? xs (remove-duplicates (sort xs <)))) - (define (post-first xs r) (equal? r (op-first xs))) - *ENDLIBSPEC*/ - fn first(&mut self) -> Option<&T> { - LazyUniqueVec::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) (equal? xs (remove-duplicates (sort xs <)))) - (define (post-last xs r) (equal? r (op-last xs))) - *ENDLIBSPEC*/ - fn last(&mut self) -> Option<&T> { - LazyUniqueVec::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) (equal? xs (remove-duplicates (sort xs <)))) - (define (post-nth n xs r) (equal? r (op-nth xs n))) - *ENDLIBSPEC*/ - fn nth(&mut self, n: usize) -> Option<&T> { - LazyUniqueVec::iter(self).nth(n) - } -} - -impl<T: Ord> Default for LazyUniqueVec<T> { - fn default() -> Self { - Self::new() - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::proptest::{strategies::lazy_unique_vec, *}; - use proptest::prelude::*; - - use im::conslist::ConsList; - - fn abstraction<T>(v: LazyUniqueVec<T>) -> ConsList<T> - where - T: Ord, - { - let list: ConsList<T> = ConsList::from(v.to_vec()); - unique(&list.sort()) - } - - proptest! { - #![proptest_config(ProptestConfig { - cases: 100, .. ProptestConfig::default() - })] - - #[test] - fn test_lazy_unique_vec_len(ref mut v in lazy_unique_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list.sort())); - //post - assert_eq!(Container::<String>::len(v), abs_list.len()); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_lazy_unique_vec_contains(ref mut v in lazy_unique_vec(".*", 0..100), a in ".*") { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list.sort())); - //post - assert_eq!(Container::<String>::contains(v, &a), contains(&abs_list, &a)); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_lazy_unique_vec_insert(ref mut v in lazy_unique_vec(".*", 0..100), a in ".*") { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list.sort())); - //post - let after_list = unique(&abs_list.append(conslist![a.clone()]).sort()); - Container::<String>::insert(v, a.clone()); - assert_eq!(abstraction(v.clone()), after_list); - } - - #[test] - fn test_lazy_vec_is_empty(ref mut v in lazy_unique_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list.sort())); - //post - assert_eq!(Container::<String>::is_empty(v), abs_list.is_empty()); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_lazy_unique_vec_remove(ref mut v in lazy_unique_vec(".*", 0..100), a in ".*") { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list.sort())); - //post - let (after_list, abs_elem) = remove(&abs_list, a.clone()); - let elem = Container::<String>::remove(v, a.clone()); - assert_eq!(abstraction(v.clone()), after_list); - assert_eq!(elem, abs_elem); - } - - #[test] - fn test_lazy_unique_vec_first(ref mut v in lazy_unique_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list.sort())); - //post - let elem = Indexable::<String>::first(v); - let abs_first = first(&abs_list); - assert_eq!(elem, abs_first); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_lazy_unique_vec_last(ref mut v in lazy_unique_vec(".*", 0..100)) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list.sort())); - //post - let elem = Indexable::<String>::last(v); - let abs_last = last(&abs_list); - assert_eq!(elem, abs_last); - assert_eq!(abstraction(v.clone()), abs_list); - } - - #[test] - fn test_lazy_unique_vec_nth(ref mut v in lazy_unique_vec(".*", 0..100), n in 0usize..100) { - let abs_list = abstraction(v.clone()); - //pre - assert_eq!(abs_list, unique(&abs_list.sort())); - //post - let elem = Indexable::<String>::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 219ccb3..f1ff34d 100644 --- a/src/crates/library/src/lib.rs +++ b/src/crates/library/src/lib.rs @@ -9,8 +9,6 @@ pub use profiler::ProfilerWrapper; mod eager_sorted_vector; mod eager_unique_vector; -mod lazy_sorted_vector; -mod lazy_unique_vector; mod btreemap; mod hashmap; @@ -21,8 +19,6 @@ mod vector; pub use eager_sorted_vector::EagerSortedVec; pub use eager_unique_vector::EagerUniqueVec; -pub use lazy_sorted_vector::LazySortedVec; -pub use lazy_unique_vector::LazyUniqueVec; #[cfg(test)] pub mod proptest; diff --git a/thesis/parts/implementation.tex b/thesis/parts/implementation.tex index d175d63..4faa8a8 100644 --- a/thesis/parts/implementation.tex +++ b/thesis/parts/implementation.tex @@ -39,6 +39,8 @@ each drop generates a file, so we get details of every individual collection all estimate a cost for each candidate: op(avg_n) * op_times for each op pick the smallest one +\todo{update for nsplit stuff} +\todo{mention difficulties with lazy vecs} \todo{Caching} \todo{Other implementation details?} |