Skip to content

Instantly share code, notes, and snippets.

@BruJu
Last active July 8, 2020 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BruJu/45a42d833fb1e5e41e0bdebeb4b8dac0 to your computer and use it in GitHub Desktop.
Save BruJu/45a42d833fb1e5e41e0bdebeb4b8dac0 to your computer and use it in GitHub Desktop.
VecOrMoreComplexDataset
///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// Current status : It works
// SophiaExportQuad : https://github.com/BruJu/Portable-Reasoning-in-Web-Assembly/blob/bf9aefade845c9a9b15e8ba6196d33b42ea5701d/sophia-wasm/src/datamodel_quad.rs#L78
///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// This is an idea of implementation of a Sophia Dataset that can be either :
// - A complex dataset structure (D)
// - A vector of terms
//
// The idea is that the user can either choose to instanciate a D or a vector,
// and it remains the same type. Another idea is that the user could require a
// switch from the simple vector structure for a more complex dataset.
//
// This structure would be interesting for an export into RDF.JS because after
// a match operation, we could populate a Vec instead of a D for better
// performances.
//
// Two problems :
// - What are the types of the quads coming from Dataet::quads() ?
// - Rust enforces not changing the data of a const object.
use crate::datamodel_quad::SophiaExportQuad;
use sophia::dataset::Dataset;
use sophia::dataset::MutableDataset;
use sophia::term::BoxTerm;
use sophia::dataset::DQuadSource;
use sophia::quad::streaming_mode::ByValue;
use sophia::quad::streaming_mode::StreamedQuad;
use sophia::term::Term;
use sophia::term::TermData;
use sophia::dataset::MDResult;
#[cfg(test)]
use sophia::dataset::inmem::FastDataset;
#[cfg(test)]
use sophia::test_dataset_impl;
pub enum VecOrDataset<D> where D: Dataset + MutableDataset + Default {
Vector(Vec<([BoxTerm; 3], Option<BoxTerm>)>),
Dataset(D)
}
impl<D> VecOrDataset<D> where D: Dataset + MutableDataset + Default {
pub fn new() -> VecOrDataset<D> {
VecOrDataset::Dataset(D::default())
}
pub fn new_vector() -> VecOrDataset<D> {
VecOrDataset::Vector(vec!())
}
}
impl<D> Dataset for VecOrDataset<D> where D: Dataset + MutableDataset + Default {
type Quad = ByValue<SophiaExportQuad>;
type Error = D::Error;
fn quads(&self) -> DQuadSource<Self> {
match &self {
VecOrDataset::Vector(vect) => {
let qs = vect.into_iter()
.map(|q| SophiaExportQuad::new_from_quad(q))
.map(|q| Ok(StreamedQuad::by_value(q)));
Box::new(qs)
},
VecOrDataset::Dataset(d) => {
let qs = d.quads()
.map(|q| q.unwrap())
.map(|q| SophiaExportQuad::new_from_quad(&q))
.map(|q| Ok(StreamedQuad::by_value(q)));
Box::new(qs)
}
}
}
}
impl<D> MutableDataset for VecOrDataset<D> where D: Dataset + MutableDataset + Default {
type MutationError = D::MutationError;
fn insert<T, U, V, W>(
&mut self,
s: &Term<T>,
p: &Term<U>,
o: &Term<V>,
g: Option<&Term<W>>,
) -> MDResult<Self, bool>
where
T: TermData,
U: TermData,
V: TermData,
W: TermData,
{
match self {
VecOrDataset::Vector(vect) => Ok(MutableDataset::insert(vect, s, p, o, g).unwrap()),
VecOrDataset::Dataset(d) => MutableDataset::insert(d, s, p, o, g)
}
}
fn remove<T, U, V, W>(
&mut self,
s: &Term<T>,
p: &Term<U>,
o: &Term<V>,
g: Option<&Term<W>>,
) -> MDResult<Self, bool>
where
T: TermData,
U: TermData,
V: TermData,
W: TermData,
{
match self {
VecOrDataset::Vector(vect) => Ok(MutableDataset::remove(vect, s, p, o, g).unwrap()),
VecOrDataset::Dataset(d) => MutableDataset::remove(d, s, p, o, g)
}
}
}
#[cfg(test)]
pub type VecOrFast = VecOrDataset<FastDataset>;
#[cfg(test)]
sophia::test_dataset_impl!(test_vectorfastdatasetfast, VecOrFast, false);
#[cfg(test)]
sophia::test_dataset_impl!(test_vectorfastdatasetvect, VecOrFast, false, VecOrFast::new_vector);
# This is the script I used to generate every quads_with method
from collections import OrderedDict
template = ''' match &self {{
VecOrDataset::Vector(vect) => {{
let qs = vect.{0}
.map(|q| q.unwrap())
.map(|q| SophiaExportQuad::new_from_quad(&q))
.map(|q| Ok(StreamedQuad::by_value(q)));
Box::new(qs)
}},
VecOrDataset::Dataset(d) => {{
let qs = d.{0}
.map(|q| q.unwrap())
.map(|q| SophiaExportQuad::new_from_quad(&q))
.map(|q| Ok(StreamedQuad::by_value(q)));
Box::new(qs)
}}
}}'''
def make_function(s, p, o, g):
generics = []
parameters = OrderedDict()
if s:
generics.append("TS")
parameters["s"] = "&'s Term<TS>"
if p:
generics.append("TP")
parameters["p"] = "&'s Term<TP>"
if o:
generics.append("TO")
parameters["o"] = "&'s Term<TO>"
if g:
generics.append("TG")
parameters["g"] = "Option<&'s Term<TG>>"
print(" fn quads_with_{0}<'s{1}>(&'s self{2}) -> DQuadSource<'s, Self>".format(
"".join([x for x in parameters]),
"".join([", " + g for g in generics]),
"".join([", {}: {}".format(t, parameters[t]) for t in parameters])
))
print(" where " +
", ".join([x + ": TermData" for x in generics]))
print(" {")
to_call = "quads_with_" + "".join([x for x in parameters]) + \
"(" + ", ".join([x for x in parameters]) + ")"
print(template.format(to_call))
print(" }")
print
tf = [False, True]
for s in tf:
for p in tf:
for o in tf:
for g in tf:
if s or p or o or g:
make_function(s, p, o, g)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment