Skip to content

Commit

Permalink
Missing docs
Browse files Browse the repository at this point in the history
  • Loading branch information
AZWN committed Oct 28, 2024
1 parent 2caae92 commit 4f0a919
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 89 deletions.
37 changes: 18 additions & 19 deletions scopegraphs/src/containers/path.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use crate::future_wrapper::FutureWrapper;
use crate::resolve::{DataEquivalence, Env, Path, ResolvedPath};
use crate::resolve::{Env, Path, ResolvedPath};
use futures::future::join_all;
use std::hash::Hash;
use std::fmt::Debug;
use std::hash::Hash;

use super::EnvContainer;

/// Interface for path containers that support the operations required for query resolution.
pub trait PathContainer<'sg, 'rslv, LABEL: 'sg, DATA: 'sg>: Debug + 'rslv
{
pub trait PathContainer<'sg, 'rslv, LABEL: 'sg, DATA: 'sg>: Debug + 'rslv {
/// Type returned by resolving a path to its sub-environment.
type EnvContainer;

Expand All @@ -19,26 +18,26 @@ pub trait PathContainer<'sg, 'rslv, LABEL: 'sg, DATA: 'sg>: Debug + 'rslv
) -> Self::EnvContainer;
}

pub trait PathContainerWf<'sg, 'rslv, LABEL: 'sg, DATA: 'sg, DWFO>: PathContainer<'sg, 'rslv, LABEL, DATA, EnvContainer = Self::EnvContainerWf> {

/// Trait that is auto-implemented for any [PathContainer] implementation that yields a valid [EnvContainer].
pub trait PathContainerWf<'sg, 'rslv, LABEL: 'sg, DATA: 'sg, DWFO>:
PathContainer<'sg, 'rslv, LABEL, DATA, EnvContainer = Self::EnvContainerWf>
{
/// Witness that ```Self::EnvContainer``` is a valid environment container.
type EnvContainerWf: EnvContainer<'sg, 'rslv, LABEL, DATA, DWFO>;

}


impl<'sg, 'rslv, LABEL, DATA, DWFO, T> PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO> for T
where
LABEL: Debug + 'sg,
DATA: 'sg,
T: PathContainer<'sg, 'rslv, LABEL, DATA>,
Self::EnvContainer: EnvContainer<'sg, 'rslv, LABEL, DATA, DWFO>
impl<'sg, 'rslv, LABEL, DATA, DWFO, T> PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO> for T
where
LABEL: Debug + 'sg,
DATA: 'sg,
T: PathContainer<'sg, 'rslv, LABEL, DATA>,
Self::EnvContainer: EnvContainer<'sg, 'rslv, LABEL, DATA, DWFO>,
{
type EnvContainerWf = Self::EnvContainer;
}



impl<'rslv, 'sg, LABEL: Debug + 'sg, DATA: 'sg> PathContainer<'sg, 'rslv, LABEL, DATA> for Vec<Path<LABEL>>
impl<'rslv, 'sg, LABEL: Debug + 'sg, DATA: 'sg> PathContainer<'sg, 'rslv, LABEL, DATA>
for Vec<Path<LABEL>>
where
Self: 'rslv,
LABEL: Clone + Hash + Eq,
Expand All @@ -53,8 +52,8 @@ where

// TODO: can this be generalized to arbitrary results of PathContainers?
// (challenge is converting between the different `::EnvContainer`s.)
impl<'rslv, 'sg, LABEL: Debug + 'sg, DATA: 'sg, E: Debug + 'rslv> PathContainer<'sg, 'rslv, LABEL, DATA>
for Result<Vec<Path<LABEL>>, E>
impl<'rslv, 'sg, LABEL: Debug + 'sg, DATA: 'sg, E: Debug + 'rslv>
PathContainer<'sg, 'rslv, LABEL, DATA> for Result<Vec<Path<LABEL>>, E>
where
Self: 'rslv,
LABEL: Clone + Hash,
Expand Down
88 changes: 51 additions & 37 deletions scopegraphs/src/containers/scope.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::hash::Hash;
use std::fmt::Debug;
use std::hash::Hash;

use crate::future_wrapper::FutureWrapper;
use crate::resolve::Path;
Expand All @@ -20,7 +20,7 @@ pub trait ScopeContainer<'sg, 'rslv, LABEL: Debug + 'sg, DATA: 'sg>: Debug {
}

/// Trait that is auto-implemented for any [ScopeContainer] implementation that yields a valid [PathContainer].
///
///
/// This trait is implemented for:
/// - `Vec<Scope>`,
/// - [Result] of scope containers, and
Expand All @@ -31,80 +31,82 @@ pub trait ScopeContainer<'sg, 'rslv, LABEL: Debug + 'sg, DATA: 'sg>: Debug {
/// # use scopegraphs::Scope;
/// # use std::fmt::Debug;
/// # use std::hash::Hash;
///
///
/// # trait LBound<'sg>: Copy + Hash + Eq + Debug + 'sg {}
/// # trait DBound<'sg>: Hash + Eq + 'sg {}
///
///
/// fn test<'sg, 'rslv, LABEL: LBound<'sg>, DATA: DBound<'sg>, DWFO>(
/// cont: impl ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>
/// ) { }
///
///
/// # fn scope_vec<'sg, 'rslv, LABEL: LBound<'sg>, DATA: DBound<'sg>>() {
/// let vec: Vec<Scope> = todo!();
/// test::<'_, '_, LABEL, DATA, bool>(vec);
/// # }
///
///
/// # fn result<'sg, 'rslv, LABEL: LBound<'sg>, DATA: DBound<'sg>, E: Debug + Clone>() {
/// let result: Result<Vec<Scope>, E> = todo!();
/// test::<'_, '_, LABEL, DATA, bool>(result);
/// test::<'_, '_, LABEL, DATA, Result<bool, E>>(result);
/// # }
///
///
/// # fn future<'sg, 'rslv, LABEL: LBound<'sg>, DATA: DBound<'sg>>() {
/// let future: FutureWrapper<Vec<Scope>> = todo!();
/// test::<'_, '_, LABEL, DATA, bool>(future);
/// test::<'_, '_, LABEL, DATA, FutureWrapper<'_, bool>>(result);
/// test::<'_, '_, LABEL, DATA, FutureWrapper<'_, bool>>(future);
/// # }
/// ```
///
///
/// ```no_run
/// # use scopegraphs::containers::ScopeContainerWf;
/// # use scopegraphs::Scope;
/// # use std::fmt::Debug;
/// # use std::hash::Hash;
///
///
///
///
/// fn test<'sg, 'rslv, LABEL: Hash + Eq + Debug + 'sg, DATA: Hash + Eq + 'sg, DWFO>(cont: impl ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>) {
///
///
/// }
/// ```
///
///
/// ```no_run
/// # use scopegraphs::containers::ScopeContainerWf;
/// # use scopegraphs::Scope;
/// # use std::fmt::Debug;
/// # use std::hash::Hash;
///
///
/// test::<'_, '_, (), (), bool>(Result::<_, ()>::Ok(Vec::<Scope>::new()));
/// test::<'_, '_, (), (), Result<bool, ()>>(Result::<_, ()>::Ok(Vec::<Scope>::new()));
///
///
/// fn test<'sg, 'rslv, LABEL: Hash + Eq + Debug + 'sg, DATA: Hash + Eq + 'sg, DWFO>(cont: impl ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>) {
///
///
/// }
/// ```
///
pub trait ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>: ScopeContainer<'sg, 'rslv, LABEL, DATA, PathContainer = Self::PathContainerWf>
where
LABEL: Debug + 'sg,
DATA: 'sg
///
pub trait ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>:
ScopeContainer<'sg, 'rslv, LABEL, DATA, PathContainer = Self::PathContainerWf>
where
LABEL: Debug + 'sg,
DATA: 'sg,
{
/// Refinement of `Self::PathContainer`, carrying proof that this scope container resolves to valid path containers.
type PathContainerWf: PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>;
}

impl<'sg, 'rslv, LABEL, DATA, DWFO, T> ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO> for T
where
LABEL: Debug + 'sg,
DATA: 'sg,
T: ScopeContainer<'sg, 'rslv, LABEL, DATA>,
Self::PathContainer: PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>
impl<'sg, 'rslv, LABEL, DATA, DWFO, T> ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO> for T
where
LABEL: Debug + 'sg,
DATA: 'sg,
T: ScopeContainer<'sg, 'rslv, LABEL, DATA>,
Self::PathContainer: PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>,
{
type PathContainerWf = Self::PathContainer;
}


impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash + 'sg> ScopeContainer<'sg, 'rslv, LABEL, DATA> for Vec<Scope>
where
Vec<Path<LABEL>>: PathContainer<'sg, 'rslv, LABEL, DATA>
impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash + 'sg>
ScopeContainer<'sg, 'rslv, LABEL, DATA> for Vec<Scope>
where
Vec<Path<LABEL>>: PathContainer<'sg, 'rslv, LABEL, DATA>,
{
type PathContainer = Vec<Path<LABEL>>;

Expand All @@ -115,9 +117,16 @@ impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash +
}
}

impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash + 'sg, SC: ScopeContainer<'sg, 'rslv, LABEL, DATA>, E: Debug> ScopeContainer<'sg, 'rslv, LABEL, DATA> for Result<SC, E>
where
Result<SC::PathContainer, E>: PathContainer<'sg, 'rslv, LABEL, DATA>
impl<
'sg: 'rslv,
'rslv,
LABEL: Debug + Copy + Eq + Hash + 'sg,
DATA: Eq + Hash + 'sg,
SC: ScopeContainer<'sg, 'rslv, LABEL, DATA>,
E: Debug,
> ScopeContainer<'sg, 'rslv, LABEL, DATA> for Result<SC, E>
where
Result<SC::PathContainer, E>: PathContainer<'sg, 'rslv, LABEL, DATA>,
{
type PathContainer = Result<SC::PathContainer, E>;

Expand All @@ -126,13 +135,18 @@ impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash +
}
}

impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash + 'sg, SC: ScopeContainer<'sg, 'rslv, LABEL, DATA> + Clone> ScopeContainer<'sg, 'rslv, LABEL, DATA>
for FutureWrapper<'rslv, SC>
impl<
'sg: 'rslv,
'rslv,
LABEL: Debug + Copy + Eq + Hash + 'sg,
DATA: Eq + Hash + 'sg,
SC: ScopeContainer<'sg, 'rslv, LABEL, DATA> + Clone,
> ScopeContainer<'sg, 'rslv, LABEL, DATA> for FutureWrapper<'rslv, SC>
where
LABEL: Copy,
Self: 'rslv,
LABEL: 'rslv,
SC::PathContainer: Clone
SC::PathContainer: Clone,
{
type PathContainer = FutureWrapper<'rslv, SC::PathContainer>;

Expand Down
7 changes: 5 additions & 2 deletions scopegraphs/src/future_wrapper.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Defines a cloneable pointer to a future.

use futures::future::Shared;
use futures::FutureExt;
use std::fmt::{Debug, Formatter};
Expand All @@ -7,8 +9,8 @@ use std::{
task::{Context, Poll},
};

// TODO: fork futures and create our own shared future that can have a
// ?Sized inner type (this should be possible)
// FIXME: only expose futures on tests
/// Shared pointer to a future, useful to make functions parametric over the type of future they are invoked with.
pub struct FutureWrapper<'fut, T>(pub Shared<Pin<Box<dyn Future<Output = T> + 'fut>>>);

impl<T> Clone for FutureWrapper<'_, T> {
Expand All @@ -18,6 +20,7 @@ impl<T> Clone for FutureWrapper<'_, T> {
}

impl<'fut, T: Clone> FutureWrapper<'fut, T> {
/// Creates shared pointer to `f`.
pub fn new(f: impl Future<Output = T> + 'fut) -> Self {
let f: Pin<Box<dyn Future<Output = T> + 'fut>> = Box::pin(f);
Self(f.shared())
Expand Down
65 changes: 34 additions & 31 deletions scopegraphs/src/resolve/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ use std::rc::Rc;
use std::sync::Arc;

use crate::completeness::Completeness;
use crate::containers::{EnvContainer, PathContainer, PathContainerWf, ScopeContainer, ScopeContainerWf};
use crate::containers::{
EnvContainer, PathContainer, PathContainerWf, ScopeContainer, ScopeContainerWf,
};
use crate::resolve::{
DataEquivalence, DataWellformedness, EdgeOrData, Env, LabelOrder, Path, Query, Resolve,
ResolvedPath,
Expand All @@ -28,7 +30,7 @@ where
LABEL: Label + Copy + Debug + Hash,
DATA: Debug,
CMPL: Completeness<LABEL, DATA>,
CMPL::GetEdgesResult<'rslv> : ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWF::Output>,
CMPL::GetEdgesResult<'rslv>: ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWF::Output>,
PWF: for<'a> RegexMatcher<&'a LABEL> + 'rslv,
DWF: DataWellformedness<'sg, DATA> + 'rslv,

Expand Down Expand Up @@ -95,9 +97,14 @@ struct ResolutionContext<'storage, 'sg: 'rslv, 'rslv, LABEL: Label, DATA, CMPL,
data_equiv: &'rslv DEq,
}

type EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWFO> = <<<CMPL as Completeness<LABEL, DATA>>::GetEdgesResult<
'rslv,
> as ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>>::PathContainerWf as PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>>::EnvContainerWf;
type EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWFO> =
<<<CMPL as Completeness<LABEL, DATA>>::GetEdgesResult<'rslv> as ScopeContainerWf<
'sg,
'rslv,
LABEL,
DATA,
DWFO,
>>::PathContainerWf as PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>>::EnvContainerWf;

type EnvCache<LABEL, ENVC> = RefCell<HashMap<EdgeOrData<LABEL>, Rc<ENVC>>>;

Expand All @@ -108,7 +115,7 @@ where
DATA: Debug,
ResolvedPath<'sg, LABEL, DATA>: Hash + Eq,
CMPL: Completeness<LABEL, DATA>,
CMPL::GetEdgesResult<'rslv> : ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWF::Output>,
CMPL::GetEdgesResult<'rslv>: ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWF::Output>,
DEq: DataEquivalence<DATA>,
DWF: DataWellformedness<'sg, DATA>,
LO: LabelOrder<LABEL>,
Expand Down Expand Up @@ -183,9 +190,9 @@ where
let mut merged_env = agg_env.clone();
env2.flat_map(move |new_env| {
merged_env.merge(new_env);
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> as From<Env<'sg, LABEL, DATA>>>::from(
merged_env,
)
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> as From<
Env<'sg, LABEL, DATA>,
>>::from(merged_env)
})
})
})
Expand All @@ -211,9 +218,9 @@ where
// environment of current (max) label, which might be shadowed by the base environment
Rc::new(base_env.flat_map(move |base_env| {
if !base_env.is_empty() && local_self.data_equiv.always_equivalent() {
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> as From<Env<'sg, LABEL, DATA>>>::from(
base_env.clone(),
)
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> as From<
Env<'sg, LABEL, DATA>,
>>::from(base_env.clone())
} else {
let sub_env = local_self.resolve_edge(path_wellformedness.clone(), edge, path);
let local_self = Arc::clone(&local_self);
Expand Down Expand Up @@ -245,9 +252,9 @@ where
for path in filtered_env {
new_env.insert(path.clone())
}
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> as From<Env<'sg, LABEL, DATA>>>::from(
new_env,
)
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> as From<
Env<'sg, LABEL, DATA>,
>>::from(new_env)
})
}
}))
Expand Down Expand Up @@ -284,9 +291,10 @@ where
let targets = self.sg.get_edges(source, label);
let path_set = targets.lift_step(label, path.clone());
let local_ctx = Arc::clone(self);
let env: EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> = path_set.map_into_env::<_>(move |p| {
local_ctx.resolve_all(path_wellformedness.clone(), p.clone())
});
let env: EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> =
path_set.map_into_env::<_>(move |p| {
local_ctx.resolve_all(path_wellformedness.clone(), p.clone())
});
env
}

Expand Down Expand Up @@ -460,19 +468,14 @@ mod tests {
.with_path_wellformedness(query_regex!(Lbl: Lex* Imp? Def))
.with_data_wellformedness(TData::matcher_fut("x"))
.with_label_order(label_order!(Lbl: Def < Imp < Lex));
type DWF = impl for<'sg> DataWellformedness<'sg, TData<'sg>, Output = FutureWrapper<'sg, bool>>;
let env = crate::resolve::Query::<
'_,
'_,
'_,
_,
_,
_,
_,
DWF,
_,
_
>::resolve(&query, s_let).await;
type DWF = impl for<'sg> DataWellformedness<
'sg,
TData<'sg>,
Output = FutureWrapper<'sg, bool>,
>;
let env =
crate::resolve::Query::<'_, '_, '_, _, _, _, _, DWF, _, _>::resolve(&query, s_let)
.await;

let env_vec = env.into_iter().collect::<Vec<_>>();
assert_eq!(1, env_vec.len());
Expand Down

0 comments on commit 4f0a919

Please sign in to comment.