From 01b11656211ebe9255710feaaafb042d20eb2631 Mon Sep 17 00:00:00 2001 From: Joe Hellerstein Date: Thu, 22 Aug 2024 23:34:25 -0700 Subject: [PATCH] WIP on force testing --- lattices/src/ght.rs | 12 +++- lattices/src/ght_lazy.rs | 145 ++++++++++++++++++--------------------- lattices/src/ght_test.rs | 112 +++++++++++++++++++++++++++--- variadics/src/lib.rs | 56 --------------- 4 files changed, 179 insertions(+), 146 deletions(-) diff --git a/lattices/src/ght.rs b/lattices/src/ght.rs index 0951ecf254b4..30df5dc4b357 100644 --- a/lattices/src/ght.rs +++ b/lattices/src/ght.rs @@ -145,7 +145,7 @@ where fn height(&self) -> Option { if let Some((_k, v)) = self.children.iter().next() { - Some(v.height().unwrap() + 1) + v.height().map(|h| h + 1) } else { None } @@ -731,13 +731,21 @@ macro_rules! GhtNodeTypeWithSchema { (() => $y:ty, $( $z:ty ),* => $( $schema:ty ),+ ) => ( $crate::ght::GhtLeaf::<$( $schema ),*, ( $y, $crate::variadics::var_type!($( $z ),* )) > ); + // Singleton key, empty val base case. + ($a:ty => () => ( $schema:ty ),+ ) => ( + $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$( $schema ),*, $crate::variadics::var_type!( $z ) >> + ); // Singleton key, singleton val base case. ($a:ty => $z:ty => $( $schema:ty ),+ ) => ( $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$( $schema ),*, $crate::variadics::var_type!( $z ) >> ); // Singleton key, compound val base case. ($a:ty => $y:ty, $( $z:ty ),* => $( $schema:ty ),+ ) => ( - $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$( $schema ),*, $crate::variadics::var_type!($y, $( $z ),*) >> + $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$( $schema ),*, $crate::variadics::var_type!($y, $( $z ),*) >> + ); + // Compound key, singleton val base case. + ($a:ty, $( $b:ty ),* => $z:ty => $( $schema:ty ),+ ) => ( + $crate::ght::GhtInner::<$a, $crate::GhtNodeTypeWithSchema!($( $b ),* => $z => $( $schema ),*)> ); // Recursive case. ($a:ty, $( $b:ty ),* => $( $z:ty ),* => $( $schema:ty ),+ ) => ( diff --git a/lattices/src/ght_lazy.rs b/lattices/src/ght_lazy.rs index 476443b28059..a0845afc1500 100644 --- a/lattices/src/ght_lazy.rs +++ b/lattices/src/ght_lazy.rs @@ -1,10 +1,8 @@ use std::hash::Hash; +use std::marker::PhantomData; -use ref_cast::RefCast; use sealed::sealed; -use variadics::{ - var_expr, var_type, PartialEqVariadic, RefVariadic, Split, SplitBySuffix, VariadicExt, -}; +use variadics::{var_expr, var_type, PartialEqVariadic, Split, SplitBySuffix, VariadicExt}; use crate::ght::{GeneralizedHashTrieNode, GhtHasChildren, GhtInner, GhtLeaf, GhtTakeLeaf}; @@ -103,13 +101,13 @@ where /// one for each height from 1 to length of the schema macro_rules! GhtForestType { ($a:tt, $( $b:tt ),* => ()) => { - () + GhtType!($a, $( $b ),* => ()) }; ($a:tt => $c:tt, $( $d:tt ),* ) => { (GhtType!($a => $c, $( $d ),*), GhtForestType!($a, $c => $( $d ),*)) }; ($a:tt, $( $b:tt ),* => $c:tt) => { - (GhtType!($a, $( $b ),* => $c), ()) + (GhtType!($a, $( $b ),* => $c), GhtForestType!($a, $( $b ),*, $c => ())) }; ($a:tt, $( $b:tt ),* => $c:tt, $( $d:tt ),* ) => { @@ -119,10 +117,6 @@ macro_rules! GhtForestType { ($a:tt, $( $b:tt ),* ) => { GhtForestType!($a => $( $b ),*) }; - - // ($head:tt, ($rest:tt)) => { - // GhtForestType!($head => $rest ) - // }; } /// Make a GhtForest trait with a force method that does the forcing+merging logic @@ -139,50 +133,28 @@ where fn force(&mut self, search_key: SearchKey) -> bool; } -/// GhtForestStruct is a metadata node pointing to a variadic list of GHTs -#[derive(RefCast)] -#[repr(transparent)] -pub struct GhtForestStruct -where - T: VariadicExt, -{ - pub(crate) forest: T, -} - -// prefix_iter(): -// given: Forest F, first tree T of height h(T), search key k of length |k| -// if |k| > h(T): -// if the prefix of k is found in a leaf L of T: -// force L and merge result into next tree -// else: -// recurse to next tree -// else: // |k| <= h(T) -// if |k| == |schema|: -// find_containing_leaf(k).iter() -// else: -// T.prefix_iter(k).chain(...) // iterator that recurses down the forest - -// force(): -// given: Forest F, first tree T of height h(T), search key k of length |k| -// if |k| > h(T): -// if the prefix of k is found in a leaf L of T: -// force L and merge result into next tree -// recurse to next tree -// else: // |k| <= h(T) -// return +// /// GhtForestStruct is a metadata node pointing to a variadic list of GHTs +// #[derive(RefCast)] +// #[repr(transparent)] +// pub struct GhtForestStruct +// where +// T: VariadicExt, +// { +// pub(crate) forest: T, +// } #[sealed] -impl GhtForest - for GhtForestStruct +impl GhtForest for var_type!(TrieFirst, TrieSecond, ...TrieRest) where TrieFirst: GeneralizedHashTrieNode + GhtTakeLeaf, - TrieSecond: GeneralizedHashTrieNode - + GhtTakeLeaf, + TrieSecond: GeneralizedHashTrieNode + GhtTakeLeaf, SearchKey: Split, var_type!(TrieSecond, ...TrieRest): VariadicExt + GhtForest, SearchKey: VariadicExt + Clone, - GhtForestStruct: GhtForest, + // GhtForestStruct: GhtForest, + var_type!(TrieSecond, ...TrieRest): GhtForest, TrieFirst::Schema: PartialEqVariadic + SplitBySuffix + Eq + Hash + Clone, + TrieSecond::Schema: PartialEqVariadic + SplitBySuffix + Eq + Hash + Clone, Self: ForestFindLeaf, <::Reverse as VariadicExt>::Reverse: Eq + Hash + Clone, GhtLeaf< @@ -191,8 +163,8 @@ where >: ColumnLazyTrieNode, { fn force<'a>(&mut self, search_key: SearchKey) -> bool { - let var_expr!(first, ...rest) = &mut self.forest; - if first.height().unwrap() < SearchKey::LEN { + let var_expr!(first, ...rest) = self; //.forest; + if let Some(_h) = first.height().filter(|&h| h < SearchKey::LEN) { let (row, _): ( TrieFirst::Schema, ::Schema>>::Suffix, @@ -200,6 +172,13 @@ where // try to force first if let Some(leaf) = first.take_containing_leaf(row.as_ref_var()) { let var_expr!(rest_first, ..._rr) = rest; + // TrieFirst::ValType IS NOT the same as TrieSecond::ValType, + // but the elements in the leaf are the same. + // So we just need a new GhtLeaf with the right ValType. + let leaf = GhtLeaf:: { + elements: leaf.elements, + _suffix_schema: PhantomData, + }; rest_first.merge_leaf(row.as_ref_var(), leaf); // drop through and recurse: we may have to force again in the neighbor } @@ -211,10 +190,22 @@ where } } +/// If we're on the last trie in the forest, there's nowhere to force right to #[sealed] -impl GhtForest for GhtForestStruct +impl GhtForest for var_type!(TrieFirst) where - SearchKey: VariadicExt + RefVariadic, + SearchKey: VariadicExt, + TrieFirst: GeneralizedHashTrieNode, +{ + fn force<'a>(&mut self, _search_key: SearchKey) -> bool { + false + } +} + +#[sealed] +impl GhtForest for var_type!() +where + SearchKey: VariadicExt, { fn force<'a>(&mut self, _search_key: SearchKey) -> bool { false @@ -277,32 +268,32 @@ where } } -impl Default for GhtForestStruct -where - // T: VariadicExt, - TrieFirst: Default + GeneralizedHashTrieNode, - TrieRest: VariadicExt, - GhtForestStruct: Default, - // for<'a> ::AsRefVar<'a>: PartialEq, - // ::Node: Eq + Hash, - // GhtLeaf: GeneralizedHashTrieNode, - // need something like TrieFirst::Schema = TrieRest.0::Schema? -{ - fn default() -> Self { - let first_trie = TrieFirst::default(); - let rest = GhtForestStruct::::default(); - let rest_forest: TrieRest = rest.forest; +// impl Default for GhtForestStruct +// where +// // T: VariadicExt, +// TrieFirst: Default + GeneralizedHashTrieNode, +// TrieRest: VariadicExt, +// GhtForestStruct: Default, +// // for<'a> ::AsRefVar<'a>: PartialEq, +// // ::Node: Eq + Hash, +// // GhtLeaf: GeneralizedHashTrieNode, +// // need something like TrieFirst::Schema = TrieRest.0::Schema? +// { +// fn default() -> Self { +// let first_trie = TrieFirst::default(); +// let rest = GhtForestStruct::::default(); +// let rest_forest: TrieRest = rest.forest; - Self { - forest: var_expr!(first_trie, ...rest_forest), - } - } -} +// Self { +// forest: var_expr!(first_trie, ...rest_forest), +// } +// } +// } -impl Default for GhtForestStruct { - fn default() -> Self { - Self { - forest: var_expr!(), - } - } -} +// impl Default for GhtForestStruct { +// fn default() -> Self { +// Self { +// forest: var_expr!(), +// } +// } +// } diff --git a/lattices/src/ght_test.rs b/lattices/src/ght_test.rs index 3e74d81f1e11..3f02253e41da 100644 --- a/lattices/src/ght_test.rs +++ b/lattices/src/ght_test.rs @@ -7,10 +7,11 @@ mod test { use crate::ght::{GeneralizedHashTrieNode, GhtInner, GhtLeaf, GhtPrefixIter}; use crate::ght_lattice::{ - DeepJoinLatticeBimorphism, GhtBimorphism, GhtCartesianProductBimorphism, - GhtNodeKeyedBimorphism, GhtValTypeProductBimorphism, + // DeepJoinLatticeBimorphism, GhtBimorphism, + GhtCartesianProductBimorphism, + // GhtNodeKeyedBimorphism, GhtValTypeProductBimorphism, }; - use crate::ght_lazy::{ColumnLazyTrieNode, ForestFindLeaf, GhtForest, GhtForestStruct}; + use crate::ght_lazy::{ColumnLazyTrieNode, ForestFindLeaf, GhtForest}; // GhtForestStruct}; use crate::{GhtForestType, GhtType, LatticeBimorphism, Merge, NaiveLatticeOrd}; #[test] @@ -940,18 +941,54 @@ mod test { #[test] fn test_build_forest() { - type MyForest = GhtForestStruct; + // type MyForest = GhtForestStruct; + // let mut forest = MyForest::default(); + // forest.forest.0.insert(var_expr!(1, 1, 1, 1)); + // forest.forest.1 .0.insert(var_expr!(2, 2, 2, 2)); + // forest.forest.1 .1 .0.insert(var_expr!(3, 3, 3, 3)); + + type MyForest = ( + GhtInner>, + ( + GhtInner< + u8, + GhtInner>, + >, + ( + GhtInner< + u8, + GhtInner< + u16, + GhtInner>, + >, + >, + ( + GhtInner< + u8, + GhtInner< + u16, + GhtInner< + u32, + GhtInner>, + >, + >, + >, + (), + ), + ), + ), + ); let mut forest = MyForest::default(); - forest.forest.0.insert(var_expr!(1, 1, 1, 1)); - forest.forest.1 .0.insert(var_expr!(2, 2, 2, 2)); - forest.forest.1 .1 .0.insert(var_expr!(3, 3, 3, 3)); + forest.0.insert(var_expr!(1, 1, 1, 1)); + forest.1 .0.insert(var_expr!(2, 2, 2, 2)); + forest.1 .1 .0.insert(var_expr!(3, 3, 3, 3)); // let i = ::AsRefVar<'_>>>::find_matching_trie(&forest, var_expr!(1, 1, 1, 1).as_ref_var(), 0); assert_eq!( // println!( // "found in trie {}", ForestFindLeaf::::find_containing_leaf( - &forest.forest, + &forest, var_expr!(1_u8, 1_u16, 1_u32, 1_u64).as_ref_var() ) .unwrap() @@ -964,7 +1001,7 @@ mod test { // println!( // "found in trie {}", ForestFindLeaf::::find_containing_leaf( - &forest.forest, + &forest, var_expr!(2, 2, 2, 2).as_ref_var() ) .unwrap() @@ -977,7 +1014,7 @@ mod test { // println!( // "found in trie {}", ForestFindLeaf::::find_containing_leaf( - &forest.forest, + &forest, var_expr!(3, 3, 3, 3).as_ref_var() ) .unwrap() @@ -990,11 +1027,64 @@ mod test { // println!( // "found in trie {}", ForestFindLeaf::::find_containing_leaf( - &forest.forest, + &forest, var_expr!(4, 4, 4, 4).as_ref_var() ) .is_none() ); // println!("{:?}", forest.forest); } + + #[test] + fn test_force_forest() { + // type MyForest = GhtForestStruct; + // let mut forest = MyForest::default(); + // forest.forest.0.insert(var_expr!(1, 1, 1, 1)); + // forest.forest.0.insert(var_expr!(2, 2, 2, 2)); + // forest.forest.0.insert(var_expr!(3, 3, 3, 3)); + type MyForest = ( + GhtInner>, + ( + GhtInner< + u8, + GhtInner>, + >, + ( + GhtInner< + u8, + GhtInner< + u16, + GhtInner>, + >, + >, + ( + GhtInner< + u8, + GhtInner< + u16, + GhtInner< + u32, + GhtInner>, + >, + >, + >, + (), + ), + ), + ), + ); // GhtForestType!(u8, u16, u32, u64); + let mut forest = MyForest::default(); + forest.0.insert(var_expr!(1, 1, 1, 1)); + forest.0.insert(var_expr!(2, 2, 2, 2)); + forest.0.insert(var_expr!(3, 3, 3, 3)); + + GhtForest::::force(&mut forest, var_expr!(1, 1, 1, 1)); + GhtForest::::force(&mut forest, var_expr!(2, 1, 1, 1)); + GhtForest::::force(&mut forest, var_expr!(3, 3, 3, 3)); + println!("{:?}", forest); + println!( + "leaf: {:?}", + forest.find_containing_leaf(var_expr!(1, 1, 1, 1).as_ref_var()) + ); + } } diff --git a/variadics/src/lib.rs b/variadics/src/lib.rs index f2b25d58c66c..d2333c78a319 100644 --- a/variadics/src/lib.rs +++ b/variadics/src/lib.rs @@ -776,62 +776,6 @@ where } } -// #[sealed] -// impl SplitBySuffix for (Item, Rest) -// where -// Rest: SplitBySuffix, -// Suffix: VariadicExt, -// { -// type Prefix = var_type!(Item, ...Rest::Prefix); -// fn split_by_suffix(self) -> (Self::Prefix, Suffix) { -// let (item, rest) = self; -// let (prefix, suffix) = rest.split_by_suffix(); -// ((item, prefix), suffix) -// } -// fn split_by_suffix_ref( -// this: Self::AsRefVar<'_>, -// ) -> ( -// ::AsRefVar<'_>, -// Suffix::AsRefVar<'_>, -// ) { -// let (item, rest) = this; -// let (prefix, suffix) = Rest::split_by_suffix_ref(rest); -// ((item, prefix), suffix) -// } -// } -// #[sealed] -// impl SplitBySuffix for (Item, Suffix) -// where -// Suffix: VariadicExt, -// { -// type Prefix = var_type!(Item); -// fn split_by_suffix(self) -> (Self::Prefix, Suffix) { -// let (item, suffix) = self; -// (var_expr!(item), suffix) -// } -// fn split_by_suffix_ref( -// this: Self::AsRefVar<'_>, -// ) -> ( -// ::AsRefVar<'_>, -// Suffix::AsRefVar<'_>, -// ) { -// let (item, suffix) = this; -// (var_expr!(item), suffix) -// } -// } -// #[sealed] -// impl SplitBySuffix<()> for () { -// type Prefix = (); -// fn split_by_suffix(self) -> (Self::Prefix, ()) { -// ((), ()) -// } -// fn split_by_suffix_ref( -// _this: Self::AsRefVar<'_>, -// ) -> (::AsRefVar<'_>, ()) { -// ((), ()) -// } -// } - #[cfg(test)] mod test { use super::*;