Skip to content

Commit 2f29bdc

Browse files
committed
Move utilities to module defining their bound
1 parent 93744ee commit 2f29bdc

File tree

3 files changed

+134
-136
lines changed

3 files changed

+134
-136
lines changed

Diff for: scopegraphs-lib/src/completeness/critical_edge.rs

+46-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{completeness::Completeness, Scope};
1+
use crate::{completeness::Completeness, Scope, ScopeGraph};
22
use std::{collections::HashSet, hash::Hash};
33

44
pub(super) struct CriticalEdgeSet<LABEL> {
@@ -53,3 +53,48 @@ pub struct Delay<LABEL> {
5353
}
5454

5555
pub(crate) type EdgesOrDelay<EDGES, LABEL> = Result<EDGES, Delay<LABEL>>;
56+
57+
impl<LABEL: Hash + Eq, DATA, CMPL> ScopeGraph<LABEL, DATA, CMPL>
58+
where
59+
CMPL: CriticalEdgeBasedCompleteness<LABEL, DATA>,
60+
{
61+
/// Adds a new scope with some open edges.
62+
pub fn add_scope_with<I>(&mut self, data: DATA, open_edges: I) -> Scope
63+
where
64+
I: IntoIterator<Item = LABEL>,
65+
{
66+
let scope = self.inner_scope_graph.add_scope(data);
67+
self.completeness
68+
.borrow_mut()
69+
.init_scope_with(HashSet::from_iter(open_edges.into_iter()));
70+
scope
71+
}
72+
73+
/// Adds a new scope with no open edges.
74+
pub fn add_scope_closed(&mut self, data: DATA) -> Scope {
75+
let scope = self.inner_scope_graph.add_scope(data);
76+
self.completeness
77+
.borrow_mut()
78+
.init_scope_with(HashSet::new());
79+
scope
80+
}
81+
}
82+
83+
impl<LABEL: Hash + Eq, DATA, CMPL> ScopeGraph<LABEL, DATA, CMPL>
84+
where
85+
DATA: Default,
86+
CMPL: CriticalEdgeBasedCompleteness<LABEL, DATA>,
87+
{
88+
/// Adds a new scope with some open edges and default data.
89+
pub fn add_scope_default_with<I>(&mut self, open_edges: I) -> Scope
90+
where
91+
I: IntoIterator<Item = LABEL>,
92+
{
93+
self.add_scope_with(DATA::default(), open_edges)
94+
}
95+
96+
/// Adds a new scope with no open edges and default data.
97+
pub fn add_scope_default_closed(&mut self) -> Scope {
98+
self.add_scope_with(DATA::default(), HashSet::new())
99+
}
100+
}

Diff for: scopegraphs-lib/src/completeness/explicit.rs

+84-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
EdgesOrDelay,
66
},
77
label::Label,
8-
InnerScopeGraph, Scope,
8+
InnerScopeGraph, Scope, ScopeGraph,
99
};
1010
use std::{collections::HashSet, hash::Hash};
1111

@@ -97,7 +97,89 @@ impl<LABEL: Hash + Eq + Label, DATA> CriticalEdgeBasedCompleteness<LABEL, DATA>
9797
}
9898

9999
impl<LABEL: Hash + Eq> ExplicitClose<LABEL> {
100-
pub(crate) fn close(&mut self, scope: Scope, label: &LABEL) {
100+
fn close(&mut self, scope: Scope, label: &LABEL) {
101101
self.critical_edges.close(scope, label);
102102
}
103103
}
104+
105+
impl<LABEL: Hash + Eq, DATA> ScopeGraph<LABEL, DATA, ExplicitClose<LABEL>> {
106+
/// Closes an edge, (i.e., prohibit future new
107+
///
108+
/// For example, the following program will return an error.
109+
/// ```
110+
/// # use scopegraphs_lib::completeness::ExplicitClose;
111+
/// # use scopegraphs_lib::ScopeGraph;
112+
/// # use scopegraphs_macros::Label;
113+
/// # #[derive(Eq, Hash, PartialEq, Label)] enum Lbl { Def }
114+
/// # use Lbl::*;
115+
/// let mut sg = ScopeGraph::<Lbl, usize, _>::new(ExplicitClose::default());
116+
///
117+
/// let s1 = sg.add_scope_with(0, [Def]);
118+
/// let s2 = sg.add_scope_closed(42);
119+
///
120+
/// sg.close(s1, &Def);
121+
/// sg.add_edge(s1, Def, s2).expect_err("cannot add edge after closing edge");
122+
/// ```
123+
///
124+
/// Closing is required to permit queries to traverse these edges:
125+
/// ```
126+
///
127+
/// # use scopegraphs_lib::completeness::ExplicitClose;
128+
/// # use scopegraphs_lib::ScopeGraph;
129+
/// # use scopegraphs_lib::resolve::{DefaultDataEquiv, DefaultLabelOrder, EdgeOrData, Resolve};
130+
/// # use scopegraphs_macros::{compile_regex, Label};
131+
/// #
132+
/// # #[derive(Eq, Hash, PartialEq, Label, Debug, Copy, Clone)]
133+
/// # enum Lbl { Def }
134+
/// # use Lbl::*;
135+
/// # type LblD = EdgeOrData<Lbl>;
136+
/// #
137+
/// # compile_regex!(type Regex<Lbl> = Def);
138+
/// let mut sg = ScopeGraph::<Lbl, usize, _>::new(ExplicitClose::default());
139+
///
140+
/// let s1 = sg.add_scope_with(0, [Def]);
141+
/// let s2 = sg.add_scope_closed(42);
142+
///
143+
/// // Note: not calling `sg.close(s1, &Def)`
144+
///
145+
/// let query_result = sg.query()
146+
/// .with_path_wellformedness(Regex::new()) // regex: `Def`
147+
/// .with_data_wellformedness(|x: &usize| *x == 42) // match `42`
148+
/// .resolve(s1);
149+
///
150+
/// query_result.expect_err("require s1/Def to be closed");
151+
/// ```
152+
///
153+
/// Closing allows queries to resolve:
154+
/// ```
155+
///
156+
/// # use scopegraphs_lib::completeness::ExplicitClose;
157+
/// # use scopegraphs_lib::ScopeGraph;
158+
/// # use scopegraphs_lib::resolve::{DefaultDataEquiv, DefaultLabelOrder, EdgeOrData, Resolve};
159+
/// # use scopegraphs_macros::{compile_regex, Label};
160+
/// #
161+
/// # #[derive(Eq, Hash, PartialEq, Label, Debug, Copy, Clone)]
162+
/// # enum Lbl { Def }
163+
/// # use Lbl::*;
164+
/// # type LblD = EdgeOrData<Lbl>;
165+
/// #
166+
/// # compile_regex!(type Regex<Lbl> = Def);
167+
/// let mut sg = ScopeGraph::<Lbl, usize, _>::new(ExplicitClose::default());
168+
///
169+
/// let s1 = sg.add_scope_with(0, [Def]);
170+
/// let s2 = sg.add_scope_closed(42);
171+
///
172+
/// // Note: closing the edge *after* creating all edges, *before* doing the query
173+
/// sg.close(s1, &Def);
174+
///
175+
/// let query_result = sg.query()
176+
/// .with_path_wellformedness(Regex::new()) // regex: `Def`
177+
/// .with_data_wellformedness(|x: &usize| *x == 42) // match `42`
178+
/// .resolve(s1);
179+
///
180+
/// query_result.expect("query should return result");
181+
/// ```
182+
pub fn close(&self, scope: Scope, label: &LABEL) {
183+
self.completeness.borrow_mut().close(scope, label)
184+
}
185+
}

Diff for: scopegraphs-lib/src/scopegraph.rs

+4-133
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ use std::{
55
hash::Hash,
66
};
77

8-
use crate::completeness::{
9-
Completeness, CriticalEdgeBasedCompleteness, ExplicitClose, UncheckedCompleteness,
10-
};
8+
use crate::completeness::{Completeness, UncheckedCompleteness};
119

1210
/// Representation of scopes (nodes in the scope graph).
1311
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -37,7 +35,7 @@ impl<LABEL, DATA> InnerScopeGraph<LABEL, DATA> {
3735

3836
/// Adds a new scope to the graph, with `data` as its associated data.
3937
/// After this operation, all future calls to [`InnerScopeGraph::get_data`] on this scope will return the associated data.
40-
fn add_scope(&mut self, data: DATA) -> Scope {
38+
pub(super) fn add_scope(&mut self, data: DATA) -> Scope {
4139
let id = self.data.len();
4240
self.data.push(data);
4341
self.edges.push(HashMap::with_capacity(0));
@@ -91,8 +89,8 @@ impl<'a, LABEL: Hash + Eq, DATA> InnerScopeGraph<LABEL, DATA> {
9189
/// In addition, there is no data type for edges, as edges should only be traversed, but never leak outside the scope graph structure.
9290
/// Finally, although not made explicit, [`LABEL`] should be a finite, iterable set.
9391
pub struct ScopeGraph<LABEL, DATA, CMPL> {
94-
inner_scope_graph: InnerScopeGraph<LABEL, DATA>,
95-
completeness: RefCell<CMPL>,
92+
pub(super) inner_scope_graph: InnerScopeGraph<LABEL, DATA>,
93+
pub(super) completeness: RefCell<CMPL>,
9694
}
9795

9896
impl<LABEL, DATA, CMPL> ScopeGraph<LABEL, DATA, CMPL> {
@@ -181,130 +179,3 @@ where
181179
self.add_scope(DATA::default())
182180
}
183181
}
184-
185-
impl<LABEL: Hash + Eq, DATA, CMPL> ScopeGraph<LABEL, DATA, CMPL>
186-
where
187-
CMPL: CriticalEdgeBasedCompleteness<LABEL, DATA>,
188-
{
189-
/// Adds a new scope with some open edges.
190-
pub fn add_scope_with<I>(&mut self, data: DATA, open_edges: I) -> Scope
191-
where
192-
I: IntoIterator<Item = LABEL>,
193-
{
194-
let scope = self.inner_scope_graph.add_scope(data);
195-
self.completeness
196-
.borrow_mut()
197-
.init_scope_with(HashSet::from_iter(open_edges.into_iter()));
198-
scope
199-
}
200-
201-
/// Adds a new scope with no open edges.
202-
pub fn add_scope_closed(&mut self, data: DATA) -> Scope {
203-
let scope = self.inner_scope_graph.add_scope(data);
204-
self.completeness
205-
.borrow_mut()
206-
.init_scope_with(HashSet::new());
207-
scope
208-
}
209-
}
210-
211-
impl<LABEL: Hash + Eq, DATA, CMPL> ScopeGraph<LABEL, DATA, CMPL>
212-
where
213-
DATA: Default,
214-
CMPL: CriticalEdgeBasedCompleteness<LABEL, DATA>,
215-
{
216-
/// Adds a new scope with some open edges and default data.
217-
pub fn add_scope_default_with<I>(&mut self, open_edges: I) -> Scope
218-
where
219-
I: IntoIterator<Item = LABEL>,
220-
{
221-
self.add_scope_with(DATA::default(), open_edges)
222-
}
223-
224-
/// Adds a new scope with no open edges and default data.
225-
pub fn add_scope_default_closed(&mut self) -> Scope {
226-
self.add_scope_with(DATA::default(), HashSet::new())
227-
}
228-
}
229-
230-
impl<LABEL: Hash + Eq, DATA> ScopeGraph<LABEL, DATA, ExplicitClose<LABEL>> {
231-
/// Closes an edge, (i.e., prohibit future new
232-
///
233-
/// For example, the following program will return an error.
234-
/// ```
235-
/// # use scopegraphs_lib::completeness::ExplicitClose;
236-
/// # use scopegraphs_lib::ScopeGraph;
237-
/// # use scopegraphs_macros::Label;
238-
/// # #[derive(Eq, Hash, PartialEq, Label)] enum Lbl { Def }
239-
/// # use Lbl::*;
240-
/// let mut sg = ScopeGraph::<Lbl, usize, _>::new(ExplicitClose::default());
241-
///
242-
/// let s1 = sg.add_scope_with(0, [Def]);
243-
/// let s2 = sg.add_scope_closed(42);
244-
///
245-
/// sg.close(s1, &Def);
246-
/// sg.add_edge(s1, Def, s2).expect_err("cannot add edge after closing edge");
247-
/// ```
248-
///
249-
/// Closing is required to permit queries to traverse these edges:
250-
/// ```
251-
///
252-
/// # use scopegraphs_lib::completeness::ExplicitClose;
253-
/// # use scopegraphs_lib::ScopeGraph;
254-
/// # use scopegraphs_lib::resolve::{DefaultDataEquiv, DefaultLabelOrder, EdgeOrData, Resolve};
255-
/// # use scopegraphs_macros::{compile_regex, Label};
256-
/// #
257-
/// # #[derive(Eq, Hash, PartialEq, Label, Debug, Copy, Clone)]
258-
/// # enum Lbl { Def }
259-
/// # use Lbl::*;
260-
/// # type LblD = EdgeOrData<Lbl>;
261-
/// #
262-
/// # compile_regex!(type Regex<Lbl> = Def);
263-
/// let mut sg = ScopeGraph::<Lbl, usize, _>::new(ExplicitClose::default());
264-
///
265-
/// let s1 = sg.add_scope_with(0, [Def]);
266-
/// let s2 = sg.add_scope_closed(42);
267-
///
268-
/// // Note: not calling `sg.close(s1, &Def)`
269-
///
270-
/// let query_result = sg.query()
271-
/// .with_path_wellformedness(Regex::new()) // regex: `Def`
272-
/// .with_data_wellformedness(|x: &usize| *x == 42) // match `42`
273-
/// .resolve(s1);
274-
///
275-
/// query_result.expect_err("require s1/Def to be closed");
276-
/// ```
277-
///
278-
/// Closing allows queries to resolve:
279-
/// ```
280-
///
281-
/// # use scopegraphs_lib::completeness::ExplicitClose;
282-
/// # use scopegraphs_lib::ScopeGraph;
283-
/// # use scopegraphs_lib::resolve::{DefaultDataEquiv, DefaultLabelOrder, EdgeOrData, Resolve};
284-
/// # use scopegraphs_macros::{compile_regex, Label};
285-
/// #
286-
/// # #[derive(Eq, Hash, PartialEq, Label, Debug, Copy, Clone)]
287-
/// # enum Lbl { Def }
288-
/// # use Lbl::*;
289-
/// # type LblD = EdgeOrData<Lbl>;
290-
/// #
291-
/// # compile_regex!(type Regex<Lbl> = Def);
292-
/// let mut sg = ScopeGraph::<Lbl, usize, _>::new(ExplicitClose::default());
293-
///
294-
/// let s1 = sg.add_scope_with(0, [Def]);
295-
/// let s2 = sg.add_scope_closed(42);
296-
///
297-
/// // Note: closing the edge *after* creating all edges, *before* doing the query
298-
/// sg.close(s1, &Def);
299-
///
300-
/// let query_result = sg.query()
301-
/// .with_path_wellformedness(Regex::new()) // regex: `Def`
302-
/// .with_data_wellformedness(|x: &usize| *x == 42) // match `42`
303-
/// .resolve(s1);
304-
///
305-
/// query_result.expect("query should return result");
306-
/// ```
307-
pub fn close(&self, scope: Scope, label: &LABEL) {
308-
self.completeness.borrow_mut().close(scope, label)
309-
}
310-
}

0 commit comments

Comments
 (0)