Skip to content

Commit

Permalink
Try write first test
Browse files Browse the repository at this point in the history
  • Loading branch information
AZWN committed Dec 1, 2023
1 parent c5f2077 commit fcf0a6d
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 45 deletions.
1 change: 1 addition & 0 deletions scopegraphs-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ scopegraphs-regular-expressions = {path = "../scopegraphs-regular-expressions"}

[dev-dependencies]
scopegraphs = {path = "../scopegraphs"}
scopegraphs-macros = {path = "../scopegraphs-macros"}
57 changes: 39 additions & 18 deletions scopegraphs-lib/src/resolve/topdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::iter;

use crate::{
label::Label,
scopegraph::{Completeness, Scope},
scopegraph::{completeness::Completeness, Scope},
};
use scopegraphs_regular_expressions::RegexMatcher;

Expand All @@ -20,18 +20,18 @@ pub trait DataOrder<DATA>: for<'sg> Fn(&'sg DATA, &'sg DATA) -> bool {}
impl<DATA, T> DataOrder<DATA> for T where for<'sg> T: Fn(&'sg DATA, &'sg DATA) -> bool {}

#[derive(Debug, Hash, PartialEq, Eq)]
pub enum EdgeOrData<'sg, LABEL> {
pub enum EdgeOrData<LABEL> {
Data,
Edge(&'sg LABEL),
Edge(LABEL),
}

// custom implementation not to impose LABEL: Copy
impl<LABEL> Clone for EdgeOrData<'_, LABEL> {
impl<LABEL: Copy> Clone for EdgeOrData<LABEL> {
fn clone(&self) -> Self {
*self
}
}
impl<LABEL> Copy for EdgeOrData<'_, LABEL> {}
impl<LABEL: Copy> Copy for EdgeOrData<LABEL> {}

pub fn resolve<'sg: 'query, 'query, LABEL, DATA, CMPL>(
sg: &'sg mut ScopeGraph<LABEL, DATA, CMPL>,
Expand All @@ -42,13 +42,13 @@ pub fn resolve<'sg: 'query, 'query, LABEL, DATA, CMPL>(
source: Scope,
) -> Env<'sg, LABEL, DATA>
where
LABEL: Label<'sg> + Copy + 'sg,
LABEL: Label + Copy,
CMPL: Completeness<LABEL, DATA>,
for<'a> CMPL::GetEdgesResult<'a>: Iterator<Item = Scope>,
ResolvedPath<'sg, LABEL, DATA>: Hash + Eq,
Path<LABEL>: Clone,
{
let all_edges: Vec<EdgeOrData<LABEL>> = LABEL::iter_ref()
let all_edges: Vec<EdgeOrData<LABEL>> = LABEL::iter()
.map(EdgeOrData::Edge)
.chain(iter::once(EdgeOrData::Data))
.collect();
Expand All @@ -65,7 +65,7 @@ where
}

struct ResolutionContext<'sg: 'query, 'query, LABEL, DATA, CMPL, DWF, LO, DO> {
all_edges: Vec<EdgeOrData<'query, LABEL>>,
all_edges: Vec<EdgeOrData<LABEL>>,
sg: &'sg ScopeGraph<LABEL, DATA, CMPL>,
data_wellformedness: &'query DWF,
label_order: &'query LO,
Expand Down Expand Up @@ -95,7 +95,7 @@ where
.copied()
.filter(|e| match *e {
EdgeOrData::Data => path_wellformedness.is_accepting(),
EdgeOrData::Edge(label) => path_wellformedness.accepts([label]),
EdgeOrData::Edge(label) => path_wellformedness.accepts([&label]),
})
.collect();

Expand All @@ -105,7 +105,7 @@ where
fn resolve_edges(
&self,
path_wellformedness: &mut impl for<'a> RegexMatcher<&'a LABEL>,
edges: &[EdgeOrData<'query, LABEL>],
edges: &[EdgeOrData<LABEL>],
path: &Path<LABEL>,
) -> Env<'sg, LABEL, DATA> {
let max = self.max(edges);
Expand All @@ -122,8 +122,8 @@ where
fn resolve_shadow(
&self,
path_wellformedness: &mut impl for<'a> RegexMatcher<&'a LABEL>,
edge: EdgeOrData<'query, LABEL>,
edges: &[EdgeOrData<'query, LABEL>],
edge: EdgeOrData<LABEL>,
edges: &[EdgeOrData<LABEL>],
path: &Path<LABEL>,
) -> Env<'sg, LABEL, DATA> {
let mut env = Env::new();
Expand All @@ -143,11 +143,11 @@ where
fn resolve_edge(
&self,
path_wellformedness: &mut impl for<'a> RegexMatcher<&'a LABEL>,
edge: EdgeOrData<'query, LABEL>,
edge: EdgeOrData<LABEL>,
path: &Path<LABEL>,
) -> Env<'sg, LABEL, DATA> {
match edge {
EdgeOrData::Edge(label) => self.resolve_label(path_wellformedness, *label, path),
EdgeOrData::Edge(label) => self.resolve_label(path_wellformedness, label, path),
EdgeOrData::Data => self.resolve_data(path),
}
}
Expand Down Expand Up @@ -180,7 +180,7 @@ where
}
}

fn max(&self, edges: &[EdgeOrData<'query, LABEL>]) -> Vec<EdgeOrData<'query, LABEL>> {
fn max(&self, edges: &[EdgeOrData<LABEL>]) -> Vec<EdgeOrData<LABEL>> {
edges
.iter()
.filter(|l| !edges.iter().any(|ll| (self.label_order)(l, ll)))
Expand All @@ -190,13 +190,34 @@ where

fn smaller(
&self,
edge: EdgeOrData<'query, LABEL>,
edges: &[EdgeOrData<'query, LABEL>],
) -> Vec<EdgeOrData<'query, LABEL>> {
edge: EdgeOrData<LABEL>,
edges: &[EdgeOrData<LABEL>],
) -> Vec<EdgeOrData<LABEL>> {
edges
.iter()
.filter(|l| (self.label_order)(l, &edge))
.copied()
.collect()
}
}

#[cfg(test)]
mod tests {
use scopegraphs_macros::Label;

use crate::scopegraph::{completeness::ImplicitClose, ScopeGraph};

#[test]
fn test_traverse_single() {
#[derive(Label, Hash, PartialEq, Eq)]
enum Lbl {
Lex,
Def,
}

let mut scope_graph: ScopeGraph<Lbl, usize, ImplicitClose<Lbl>> =
ScopeGraph::new(ImplicitClose::default());

let s1 = scope_graph.new_scope(42);
}
}
53 changes: 33 additions & 20 deletions scopegraphs-lib/src/scopegraph/completeness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ use private::Sealed;
/*** Completeness trait ***/

pub trait Completeness<LABEL, DATA>: Sealed {
fn new_scope(&mut self, inner_scope_graph: &InnerScopeGraph<LABEL, DATA>, scope: Scope); // FIXME `scope` needed?
fn cmpl_new_scope(&mut self, inner_scope_graph: &InnerScopeGraph<LABEL, DATA>, scope: Scope); // FIXME `scope` needed?

type NewEdgeResult;
fn new_edge(
fn cmpl_new_edge(
&mut self,
inner_scope_graph: &mut InnerScopeGraph<LABEL, DATA>,
src: Scope,
Expand All @@ -32,7 +32,7 @@ pub trait Completeness<LABEL, DATA>: Sealed {
Self: 'a,
DATA: 'a,
LABEL: 'a;
fn get_edges<'a, 'b: 'a>(
fn cmpl_get_edges<'a, 'b: 'a>(
&mut self,
inner_scope_graph: &'a InnerScopeGraph<LABEL, DATA>,
src: Scope,
Expand All @@ -46,11 +46,11 @@ struct UncheckedCompleteness {}
impl Sealed for UncheckedCompleteness {}

impl<LABEL: Hash + Eq, DATA> Completeness<LABEL, DATA> for UncheckedCompleteness {
fn new_scope(&mut self, inner_scope_graph: &InnerScopeGraph<LABEL, DATA>, scope: Scope) {}
fn cmpl_new_scope(&mut self, inner_scope_graph: &InnerScopeGraph<LABEL, DATA>, scope: Scope) {}

type NewEdgeResult = ();

fn new_edge<'a>(
fn cmpl_new_edge<'a>(
&mut self,
inner_scope_graph: &mut InnerScopeGraph<LABEL, DATA>,
src: Scope,
Expand All @@ -62,7 +62,7 @@ impl<LABEL: Hash + Eq, DATA> Completeness<LABEL, DATA> for UncheckedCompleteness

type GetEdgesResult<'a> = Box<dyn Iterator<Item = Scope> + 'a> where DATA: 'a, LABEL: 'a;

fn get_edges<'a, 'b: 'a>(
fn cmpl_get_edges<'a, 'b: 'a>(
&mut self,
inner_scope_graph: &'a InnerScopeGraph<LABEL, DATA>,
src: Scope,
Expand All @@ -78,6 +78,14 @@ struct CriticalEdgeSet<LABEL> {
open_edges: Vec<HashSet<LABEL>>,
}

impl<LABEL> Default for CriticalEdgeSet<LABEL> {
fn default() -> Self {
Self {
open_edges: Default::default(),
}
}
}

impl<LABEL> CriticalEdgeSet<LABEL> {
fn init_scope(&mut self, edges: HashSet<LABEL>) {
self.open_edges.push(edges)
Expand Down Expand Up @@ -105,23 +113,22 @@ pub enum EdgesOrDelay<'a, EDGES, LABEL> {

/*** Weakly-Critical-Edge Based Completeness Checking with Explicit Closing ***/

struct ExplicitClose<LABEL> {
#[derive(Default)]
pub struct ExplicitClose<LABEL> {
critical_edges: CriticalEdgeSet<LABEL>,
}

impl<LABEL> Sealed for ExplicitClose<LABEL> {}

impl<LABEL: Hash + Eq + for<'a> Label<'a>, DATA> Completeness<LABEL, DATA>
for ExplicitClose<LABEL>
{
fn new_scope(&mut self, inner_scope_graph: &InnerScopeGraph<LABEL, DATA>, scope: Scope) {
impl<LABEL: Hash + Eq + Label, DATA> Completeness<LABEL, DATA> for ExplicitClose<LABEL> {
fn cmpl_new_scope(&mut self, inner_scope_graph: &InnerScopeGraph<LABEL, DATA>, scope: Scope) {
self.critical_edges
.init_scope(HashSet::from_iter(LABEL::iter()))
}

type NewEdgeResult = Result<(), EdgeClosedError<LABEL>>;

fn new_edge(
fn cmpl_new_edge(
&mut self,
inner_scope_graph: &mut InnerScopeGraph<LABEL, DATA>,
src: Scope,
Expand All @@ -141,7 +148,7 @@ impl<LABEL: Hash + Eq + for<'a> Label<'a>, DATA> Completeness<LABEL, DATA>

type GetEdgesResult<'a> = EdgesOrDelay<'a, Box<dyn Iterator<Item = Scope> + 'a>, LABEL> where DATA: 'a, LABEL: 'a;

fn get_edges<'a, 'b: 'a>(
fn cmpl_get_edges<'a, 'b: 'a>(
&mut self,
inner_scope_graph: &'a InnerScopeGraph<LABEL, DATA>,
src: Scope,
Expand All @@ -162,24 +169,30 @@ impl<LABEL: Hash + Eq + for<'a> Label<'a>, DATA> Completeness<LABEL, DATA>

/*** Weakly-Critical-Edge Based Completeness Checking with Implicit Closing ***/

struct ImplicitClose<LABEL> {
pub struct ImplicitClose<LABEL> {
critical_edges: CriticalEdgeSet<LABEL>,
}

impl<LABEL> Default for ImplicitClose<LABEL> {
fn default() -> Self {
Self {
critical_edges: Default::default(),
}
}
}

impl<LABEL> Sealed for ImplicitClose<LABEL> {}

impl<LABEL: Hash + Eq + for<'a> Label<'a>, DATA> Completeness<LABEL, DATA>
for ImplicitClose<LABEL>
{
fn new_scope(&mut self, inner_scope_graph: &InnerScopeGraph<LABEL, DATA>, scope: Scope) {
impl<LABEL: Hash + Eq + Label, DATA> Completeness<LABEL, DATA> for ImplicitClose<LABEL> {
fn cmpl_new_scope(&mut self, inner_scope_graph: &InnerScopeGraph<LABEL, DATA>, scope: Scope) {
self.critical_edges
.init_scope(HashSet::from_iter(LABEL::iter()))
}

type NewEdgeResult = Result<(), EdgeClosedError<LABEL>>;

// FIXME: identical to `ExplicitClose` impl.
fn new_edge(
fn cmpl_new_edge(
&mut self,
inner_scope_graph: &mut InnerScopeGraph<LABEL, DATA>,
src: Scope,
Expand All @@ -200,7 +213,7 @@ impl<LABEL: Hash + Eq + for<'a> Label<'a>, DATA> Completeness<LABEL, DATA>

type GetEdgesResult<'a> = Box<dyn Iterator<Item = Scope> + 'a> where DATA: 'a, LABEL: 'a;

fn get_edges<'a, 'b: 'a>(
fn cmpl_get_edges<'a, 'b: 'a>(
&mut self,
inner_scope_graph: &'a InnerScopeGraph<LABEL, DATA>,
src: Scope,
Expand Down
23 changes: 16 additions & 7 deletions scopegraphs-lib/src/scopegraph/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![allow(unused)]

mod completeness;
pub mod completeness;

use std::{
cell::RefCell,
Expand All @@ -12,7 +12,7 @@ use std::{

use bumpalo::Bump;

pub use completeness::Completeness;
use completeness::Completeness;

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Scope(usize);
Expand Down Expand Up @@ -123,31 +123,40 @@ pub struct ScopeGraph<LABEL, DATA, CMPL> {
completeness: RefCell<CMPL>,
}

impl<'a, LABEL, DATA, CMPL> ScopeGraph<LABEL, DATA, CMPL>
impl<LABEL, DATA, CMPL> ScopeGraph<LABEL, DATA, CMPL> {
pub fn new(completeness: CMPL) -> Self {
ScopeGraph {
inner_scope_graph: InnerScopeGraph::new(),
completeness: RefCell::new(completeness),
}
}
}

impl<LABEL, DATA, CMPL> ScopeGraph<LABEL, DATA, CMPL>
where
CMPL: Completeness<LABEL, DATA>,
{
pub fn new_scope(&mut self, data: DATA) -> Scope {
let scope = self.inner_scope_graph.add_scope(data);
self.completeness
.borrow_mut()
.new_scope(&self.inner_scope_graph, scope);
.cmpl_new_scope(&self.inner_scope_graph, scope);
scope
}

pub fn new_edge(&mut self, src: Scope, lbl: LABEL, dst: Scope) -> CMPL::NewEdgeResult {
self.completeness
.borrow_mut()
.new_edge(&mut self.inner_scope_graph, src, lbl, dst)
.cmpl_new_edge(&mut self.inner_scope_graph, src, lbl, dst)
}

pub fn get_data(&self, scope: Scope) -> &DATA {
&self.inner_scope_graph.data[scope.0]
}

pub fn get_edges<'b: 'a>(&'a self, src: Scope, lbl: &'b LABEL) -> CMPL::GetEdgesResult<'a> {
pub fn get_edges<'a>(&'a self, src: Scope, lbl: &'a LABEL) -> CMPL::GetEdgesResult<'a> {
self.completeness
.borrow_mut()
.get_edges(&self.inner_scope_graph, src, lbl)
.cmpl_get_edges(&self.inner_scope_graph, src, lbl)
}
}

0 comments on commit fcf0a6d

Please sign in to comment.