Skip to content

Commit

Permalink
Factor out shared part about merging the environments
Browse files Browse the repository at this point in the history
  • Loading branch information
AZWN committed Oct 30, 2024
1 parent 677b3c4 commit 957e1f7
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 47 deletions.
67 changes: 27 additions & 40 deletions scopegraphs/src/containers/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,63 +165,58 @@ where
}
}

// Shadowable
// Filtering

/// Sub trait of [EnvContainer] that validates that shadowin operations can be applied on it.
pub trait Shadowable<'sg, 'rslv, LABEL: 'sg, DATA: 'sg, DEQO>:
/// Sub trait of [EnvContainer] that validates that filtering operations (for shadowing) can be applied on it.
pub trait Filterable<'sg, 'rslv, LABEL: 'sg, DATA: 'sg, DEQO>:
EnvContainer<'sg, 'rslv, LABEL, DATA>
where
ResolvedPath<'sg, LABEL, DATA>: Eq + Hash + Clone,
{
/// Implementation of the shadow operation on this container.
fn shadow(
base_env: Env<'sg, LABEL, DATA>,
fn filter(
base_env: &Env<'sg, LABEL, DATA>,
sub_env: &Env<'sg, LABEL, DATA>,
equiv: &'rslv impl DataEquivalence<'sg, DATA, Output = DEQO>,
) -> Self;
}

impl<'sg: 'rslv, 'rslv, LABEL: 'sg, DATA: 'sg, ENVC> Shadowable<'sg, 'rslv, LABEL, DATA, bool>
impl<'sg: 'rslv, 'rslv, LABEL: 'sg, DATA: 'sg, ENVC> Filterable<'sg, 'rslv, LABEL, DATA, bool>
for ENVC
where
ENVC: EnvContainer<'sg, 'rslv, LABEL, DATA>,
Env<'sg, LABEL, DATA>: Clone,
ResolvedPath<'sg, LABEL, DATA>: Eq + Hash + Clone,
{
fn shadow(
base_env: Env<'sg, LABEL, DATA>,
fn filter(
base_env: &Env<'sg, LABEL, DATA>,
sub_env: &Env<'sg, LABEL, DATA>,
equiv: &'rslv impl DataEquivalence<'sg, DATA, Output = bool>,
) -> Self {
let filtered_env = sub_env
sub_env
.iter()
.filter(|p1| !base_env.iter().any(|p2| equiv.data_equiv(p1.data, p2.data)))
.collect::<Vec<_>>();

// FIXME: factor out this part?
let mut new_env = base_env;
for path in filtered_env {
new_env.insert(path.clone())
}
new_env.into()
.cloned()
.collect::<Env<_, _>>()
.into()
}
}

impl<'sg: 'rslv, 'rslv, LABEL: Clone + Eq + 'sg, DATA: Eq + 'sg, E: Clone + 'rslv>
Shadowable<'sg, 'rslv, LABEL, DATA, Result<bool, E>> for Result<Env<'sg, LABEL, DATA>, E>
Filterable<'sg, 'rslv, LABEL, DATA, Result<bool, E>> for Result<Env<'sg, LABEL, DATA>, E>
where
Env<'sg, LABEL, DATA>: Clone,
ResolvedPath<'sg, LABEL, DATA>: Eq + Hash + Clone,
{
fn shadow(
base_env: Env<'sg, LABEL, DATA>,
fn filter(
base_env: &Env<'sg, LABEL, DATA>,
sub_env: &Env<'sg, LABEL, DATA>,
equiv: &'rslv impl DataEquivalence<'sg, DATA, Output = Result<bool, E>>,
) -> Self {
let sub_env = sub_env.clone();
let filtered_env = sub_env.into_iter().try_fold(
Vec::<ResolvedPath<'sg, LABEL, DATA>>::new(),
|mut filtered_env: Vec<ResolvedPath<'sg, LABEL, DATA>>,
sub_env.into_iter().try_fold(
Env::new(),
|mut filtered_env: Env<'sg, LABEL, DATA>,
p1: ResolvedPath<'sg, LABEL, DATA>| {
let shadowed = base_env.iter().try_fold(
/* initially, not shadowed */ false,
Expand All @@ -236,48 +231,40 @@ where
)?;
// p1 is not shadowed, so add it to accumulator
if !shadowed {
filtered_env.push(p1);
filtered_env.insert(p1);
}

Ok(filtered_env)
},
)?;
let mut new_env = base_env;
filtered_env
.into_iter()
.for_each(|path| new_env.insert(path));
new_env.into()
)
}
}

impl<'sg: 'rslv, 'rslv, LABEL: Clone + Eq + 'sg, DATA: Eq + 'sg>
Shadowable<'sg, 'rslv, LABEL, DATA, FutureWrapper<'rslv, bool>>
Filterable<'sg, 'rslv, LABEL, DATA, FutureWrapper<'rslv, bool>>
for FutureWrapper<'rslv, Env<'sg, LABEL, DATA>>
where
Env<'sg, LABEL, DATA>: Clone,
ResolvedPath<'sg, LABEL, DATA>: Eq + Hash + Clone,
{
fn shadow(
base_env: Env<'sg, LABEL, DATA>,
fn filter(
base_env: &Env<'sg, LABEL, DATA>,
sub_env: &Env<'sg, LABEL, DATA>,
equiv: &'rslv impl DataEquivalence<'sg, DATA, Output = FutureWrapper<'rslv, bool>>,
) -> Self {
let base_env = base_env.clone();
let sub_env = sub_env.clone();
FutureWrapper::new(async move {
let mut filtered_env: Vec<ResolvedPath<'sg, LABEL, DATA>> = Vec::new();
let mut filtered_env = Env::new();
'outer: for sub_path in sub_env {
for base_path in &base_env {
if equiv.data_equiv(sub_path.data, base_path.data).await {
continue 'outer;
}
}
filtered_env.push(sub_path.clone());
}
let mut new_env = base_env;
for path in filtered_env {
new_env.insert(path);
filtered_env.insert(sub_path.clone());
}
new_env
filtered_env
})
}
}
6 changes: 3 additions & 3 deletions scopegraphs/src/containers/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use futures::future::join_all;
use std::fmt::Debug;
use std::hash::Hash;

use super::{Injectable, Shadowable};
use super::{Injectable, Filterable};

/// Interface for path containers that support the operations required for query resolution.
pub trait PathContainer<'sg, 'rslv, LABEL: 'sg, DATA: 'sg>: Debug + 'rslv {
Expand All @@ -26,7 +26,7 @@ where
{
/// Witness that ```Self::EnvContainer``` is a valid environment container.
type EnvContainerWf: Injectable<'sg, 'rslv, LABEL, DATA, DWFO>
+ Shadowable<'sg, 'rslv, LABEL, DATA, DEQO>;
+ Filterable<'sg, 'rslv, LABEL, DATA, DEQO>;
}

impl<'sg, 'rslv, LABEL, DATA, DWFO, DEQO, T> PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO, DEQO>
Expand All @@ -36,7 +36,7 @@ where
DATA: 'sg,
T: PathContainer<'sg, 'rslv, LABEL, DATA>,
Self::EnvContainer:
Injectable<'sg, 'rslv, LABEL, DATA, DWFO> + Shadowable<'sg, 'rslv, LABEL, DATA, DEQO>,
Injectable<'sg, 'rslv, LABEL, DATA, DWFO> + Filterable<'sg, 'rslv, LABEL, DATA, DEQO>,
ResolvedPath<'sg, LABEL, DATA>: Eq + Hash + Clone,
{
type EnvContainerWf = Self::EnvContainer;
Expand Down
10 changes: 7 additions & 3 deletions scopegraphs/src/resolve/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::sync::Arc;
use crate::completeness::Completeness;
use crate::containers::{
EnvContainer, Injectable, PathContainer, PathContainerWf, ScopeContainer, ScopeContainerWf,
Shadowable,
Filterable,
};
use crate::resolve::{
DataEquivalence, DataWellformedness, EdgeOrData, LabelOrder, Path, Query, Resolve, ResolvedPath,
Expand Down Expand Up @@ -224,10 +224,14 @@ where
if !base_env.is_empty() && local_self.data_equiv.always_equivalent() {
base_env.clone().into()
} else {
let base_env = base_env.clone();
let mut base_env = base_env.clone();
let sub_env = local_self.resolve_edge(path_wellformedness.clone(), edge, path);
sub_env.flat_map(move |sub_env| {
Shadowable::shadow(base_env, sub_env, local_self.data_equiv)
let merged_env: EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output, DEq::Output> = Filterable::filter(&base_env, sub_env, local_self.data_equiv);
merged_env.flat_map(move |merged_env| {
base_env.merge(merged_env);
base_env.into()
})
})
}
}))
Expand Down
2 changes: 1 addition & 1 deletion scopegraphs/src/resolve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ where
}
}

impl<'sg, LABEL: 'sg, DATA: Hash> FromIterator<ResolvedPath<'sg, LABEL, DATA>>
impl<'sg, LABEL: 'sg, DATA> FromIterator<ResolvedPath<'sg, LABEL, DATA>>
for Env<'sg, LABEL, DATA>
where
ResolvedPath<'sg, LABEL, DATA>: Eq + Hash,
Expand Down

0 comments on commit 957e1f7

Please sign in to comment.