Skip to content

Commit b6e6f1c

Browse files
Overhaul ExtendAnti to support arbitrary prefixes
1 parent 646c3ee commit b6e6f1c

File tree

1 file changed

+31
-47
lines changed

1 file changed

+31
-47
lines changed

src/treefrog.rs

+31-47
Original file line numberDiff line numberDiff line change
@@ -297,17 +297,19 @@ impl<T: Ord + Copy> Relation<T> {
297297
{
298298
extend_with::ExtendWith::from(self, key_func)
299299
}
300-
}
301300

302-
impl<Key: Ord, Val: Ord> Relation<(Key, Val)> {
303301
/// Extend with `Val` using the complement of the relation.
304-
pub fn extend_anti<'leap, Tuple: Ord, Func: Fn(&Tuple) -> Key>(
305-
&'leap self,
306-
key_func: Func,
307-
) -> extend_anti::ExtendAnti<'leap, Key, Val, Tuple, Func>
308-
where
309-
Key: 'leap,
310-
Val: 'leap,
302+
///
303+
/// This leaper *removes* all proposed values that appear as a suffix in `self` for the prefix
304+
/// extracted from the source tuple via `key_func`.
305+
///
306+
///
307+
///
308+
/// ```prolog
309+
/// step_sibling(X, Y) :- parent(X, P), parent(Y, P), !biological_sibling(X, Y).
310+
/// ```
311+
pub fn extend_anti<P, F, S>(&self, key_func: F) -> extend_anti::ExtendAnti<'_, P, T, F>
312+
where F: Fn(&S) -> P
311313
{
312314
extend_anti::ExtendAnti::from(self, key_func)
313315
}
@@ -419,63 +421,45 @@ pub(crate) mod extend_anti {
419421

420422
use super::{binary_search, Leaper, Relation};
421423
use crate::join::gallop;
424+
use crate::Split;
422425

423426
/// Wraps a Relation<Tuple> as a leaper.
424-
pub struct ExtendAnti<'leap, Key, Val, Tuple, Func>
425-
where
426-
Key: Ord + 'leap,
427-
Val: Ord + 'leap,
428-
Tuple: Ord,
429-
Func: Fn(&Tuple) -> Key,
430-
{
431-
relation: &'leap Relation<(Key, Val)>,
432-
key_func: Func,
433-
old_key: Option<(Key, Range<usize>)>,
434-
phantom: ::std::marker::PhantomData<Tuple>,
427+
pub struct ExtendAnti<'a, P, T, F> {
428+
relation: &'a Relation<T>,
429+
key_func: F,
430+
old_key: Option<(P, Range<usize>)>,
435431
}
436432

437-
impl<'leap, Key, Val, Tuple, Func> ExtendAnti<'leap, Key, Val, Tuple, Func>
438-
where
439-
Key: Ord + 'leap,
440-
Val: Ord + 'leap,
441-
Tuple: Ord,
442-
Func: Fn(&Tuple) -> Key,
443-
{
433+
impl<'a, P, T, F> ExtendAnti<'a, P, T, F> {
444434
/// Constructs a ExtendAnti from a relation and key and value function.
445-
pub fn from(relation: &'leap Relation<(Key, Val)>, key_func: Func) -> Self {
446-
ExtendAnti {
447-
relation,
448-
key_func,
449-
old_key: None,
450-
phantom: ::std::marker::PhantomData,
451-
}
435+
pub fn from(relation: &'a Relation<T>, key_func: F) -> Self {
436+
ExtendAnti { relation, key_func, old_key: None }
452437
}
453438
}
454439

455-
impl<'leap, Key: Ord, Val: Ord + 'leap, Tuple: Ord, Func> Leaper<Tuple, Val>
456-
for ExtendAnti<'leap, Key, Val, Tuple, Func>
440+
impl<P, T, S, F> Leaper<S, T::Suffix> for ExtendAnti<'_, P, T, F>
457441
where
458-
Key: Ord + 'leap,
459-
Val: Ord + 'leap,
460-
Tuple: Ord,
461-
Func: Fn(&Tuple) -> Key,
442+
T: Copy + Split<P>,
443+
P: Ord,
444+
T::Suffix: Ord,
445+
F: Fn(&S) -> P,
462446
{
463-
fn count(&mut self, _prefix: &Tuple) -> usize {
447+
fn count(&mut self, _prefix: &S) -> usize {
464448
usize::max_value()
465449
}
466-
fn propose(&mut self, _prefix: &Tuple, _values: &mut Vec<Val>) {
450+
fn propose(&mut self, _prefix: &S, _values: &mut Vec<T::Suffix>) {
467451
panic!("ExtendAnti::propose(): variable apparently unbound.");
468452
}
469-
fn intersect(&mut self, prefix: &Tuple, values: &mut Vec<Val>) {
453+
fn intersect(&mut self, prefix: &S, values: &mut Vec<T::Suffix>) {
470454
let key = (self.key_func)(prefix);
471455

472456
let range = match self.old_key.as_ref() {
473457
Some((old, range)) if old == &key => range.clone(),
474458

475459
_ => {
476-
let start = binary_search(&self.relation.elements, |x| &x.0 < &key);
460+
let start = binary_search(&self.relation.elements, |x| &x.prefix() < &key);
477461
let slice1 = &self.relation[start..];
478-
let slice2 = gallop(slice1, |x| &x.0 <= &key);
462+
let slice2 = gallop(slice1, |x| &x.prefix() <= &key);
479463
let range = start..self.relation.len()-slice2.len();
480464

481465
self.old_key = Some((key, range.clone()));
@@ -487,8 +471,8 @@ pub(crate) mod extend_anti {
487471
let mut slice = &self.relation[range];
488472
if !slice.is_empty() {
489473
values.retain(|v| {
490-
slice = gallop(slice, |kv| &kv.1 < v);
491-
slice.get(0).map(|kv| &kv.1) != Some(v)
474+
slice = gallop(slice, |kv| &kv.suffix() < v);
475+
slice.get(0).map(|kv| kv.suffix()).as_ref() != Some(v)
492476
});
493477
}
494478
}

0 commit comments

Comments
 (0)