moonsparql

    Bounded in-process SPARQL query evaluation over RDF graphs in MoonBit

    sparql
    rdf
    query
    knowledge-graph
    Download zip
    Author
    Version
    0.1.0
    License
    Apache-2.0
    Last updated
    2 hours ago
    Downloads
    3

    #MoonSparql

    MoonSparql is a bounded, in-process RDF query engine written in MoonBit. It extends existing RDF IO libraries with query execution: joins, optional facts, aggregates and paths return bindings or a derived graph.

    Module: yyyt0807/moonsparql@0.1.0. Repository: yyyt0807/MoonSparql. Repository owner and maintenance commit identity: yyyt0807.

    moon add yyyt0807/moonsparql@0.1.0

    #Run

    Requires MoonBit 0.10.16 or newer and a C compiler for the Native CLI.

    moon update moon check --target all --deny-warn moon build --target all --deny-warn moon test --target all --deny-warn moon run examples/asset_inventory --target native moon run examples/catalog_discovery --target native moon run examples/research_summary --target native moon run examples/scale --target native --release moon run cmd/main --target native -- examples/data/catalog.ttl examples/data/catalog.rq json

    On Windows, Moon 20261016 may pass extended DOS paths rejected by its OCaml compiler. Run ./tools/windows/moon.ps1 instead of moon for these commands; the adapter builds with MSVC and invokes the installed official compiler. It changes process-local overrides only.

    CI uses the validated official compiler/core pair 0.10.16+b1a0e846e on Ubuntu and Windows. For independent common-profile verification after building the Native CLI:

    python -m venv .venv # Activate the environment; on Windows use .venv/Scripts/python.exe. python -m pip install -r scripts/requirements-interop.txt python scripts/compare_rdflib.py _build/native/debug/build/cmd/main/main.exe

    The 15 RDFLib comparisons cover shared semantics only; they do not certify the full SPARQL standard. Python is a development oracle, not a runtime requirement. scripts/verify_repository.py checks real source/history and excludes private contest material from tracked paths and package ZIPs.

    #Library use

    Import the module in the consuming package's moon.pkg:

    import { "yyyt0807/moonsparql" @q, }

    let data = @q.Dataset::from_turtle(
    "<urn:item> <urn:owner> \"Alice\" .",
    )
    let query = @q.prepare("SELECT ?owner {<urn:item> <urn:owner> ?owner}")
    let result = query.execute(data)
    assert_eq(result.rows()[0].get("owner").unwrap().lexical(), "Alice")
    println(result.to_json())

    Programmatic datasets use iri, blank, literal, typed_literal, language_literal, quad and Dataset::from_quads. Named graphs are available through that API. Datasets copy input collections and return copies; bindings expose lookup and variable names without mutable internal maps.

    #Three complete applications

    • Asset impact: join ownership facts with transitive dependencies, retaining assets whose optional owner is missing. This supports inventories, software catalogs, equipment maintenance and change planning.
    • Metadata discovery: combine catalog topic and publisher facts with VALUES restrictions. This supports datasets, documents, product catalogs and institutional metadata.
    • Research summaries: group observations by site, calculate exact SUM/AVG, filter groups and construct a derived RDF view. This supports research, public data and reusable analytical metadata.

    Each example contains assertions for its outputs. The 10,000-fact scale example verifies indexed lookup work and an exact aggregate, without claiming a timing advantage over another engine.

    #Supported release profile

    SELECT, ASK and CONSTRUCT; PREFIX with absolute IRIs; BGP, OPTIONAL, UNION, MINUS, FILTER, BIND, VALUES and GRAPH; inverse/sequence/alternative/*/+/? paths; DISTINCT, GROUP BY, HAVING, COUNT/SUM/AVG/MIN/MAX/SAMPLE, ORDER BY, OFFSET/LIMIT. See the exact profile for limitations and expression functions.

    This is an explicit subset of SPARQL 1.1, not a claim of full conformance. SERVICE, UPDATE, DESCRIBE, subqueries, entailment and remote loading are excluded. Unsupported syntax is rejected. Exhausted budgets fail the query without returning a partial-success table.

    #Ecosystem integration and sources

    MoonTTL provides RDF parsing and materialization. MoonSHACL validates RDF contracts and JSON-LD supplies linked-data interchange. MoonSparql adds query execution over RDF datasets; it does not replace those packages. The dated topic-search evidence and contest materials are stored outside public Git.

    Apache-2.0. Dependency sources, AI assistance and original fixture provenance are recorded in THIRD_PARTY_NOTICES.md. Architecture and costs: docs/architecture.md.

    #十一月新增功能

    精确前置条件的原子数据补丁(Dataset::apply_patch);SELECT结果多重集变化分析(QueryResult::binding_delta)。详见功能、用途和边界,运行 moon run examples/november --target native --deny-warn。这些功能纳入 0.1.0 首次公开发布。

    QueryError

    pub(all) suberror QueryError {
    InvalidTerm(String)
    Syntax(Int, String)
    Unsupported(Int, String)
    Resource(String)
    Evaluation(String)
    InvalidInput(String)
    } derive(
    Debug
    )

    QueryError::message

    fn QueryError::message(self : QueryError) -> String

    Binding

    pub struct Binding {
    // private fields
    }

    Binding::get

    fn Binding::get(self : Binding, variable : String) -> Term?

    Binding::length

    fn Binding::length(self : Binding) -> Int

    Binding::variables

    fn Binding::variables(self : Binding) -> Array[String]

    BindingDelta

    pub(all) struct BindingDelta {
    added : Array[Binding]
    removed : Array[Binding]
    retained : Int
    }

    Dataset

    pub struct Dataset {
    // private fields
    }

    Dataset::apply_patch

    fn Dataset::apply_patch(self : Dataset, remove : Array[Quad], add : Array[Quad], limits? : Limits) -> Dataset raise QueryError

    Host-side exact patch, not SPARQL UPDATE. All preconditions are checked on the original snapshot; failure leaves the dataset and its indexes unchanged.

    Dataset::from_quads

    fn Dataset::from_quads(quads : Array[Quad], limits? : Limits) -> Dataset raise QueryError

    Dataset::from_turtle

    fn Dataset::from_turtle(source : String, limits? : Limits) -> Dataset raise QueryError

    Dataset::graph_names

    fn Dataset::graph_names(self : Dataset) -> Array[Term]

    Dataset::length

    fn Dataset::length(self : Dataset) -> Int

    Dataset::matching

    fn Dataset::matching(self : Dataset, subject? : Term, predicate? : Term, object? : Term, graph? : Term, limits? : Limits) -> Array[Quad] raise QueryError

    Dataset::quads

    fn Dataset::quads(self : Dataset) -> Array[Quad]

    ExecutionStats

    pub(all) struct ExecutionStats {
    steps : Int
    peak_bindings : Int
    path_pairs : Int
    } derive(Eq,
    Debug
    )

    ExecutionStats::equal

    ExecutionStats::not_equal

    fn ExecutionStats::not_equal(x : ExecutionStats, y : ExecutionStats) -> Bool

    Limits

    pub(all) struct Limits {
    max_triples : Int
    max_query_chars : Int
    max_tokens : Int
    max_depth : Int
    max_steps : Int
    max_bindings : Int
    max_results : Int
    max_path_pairs : Int
    max_numeric_digits : Int
    } derive(Eq,
    Debug
    )

    Limits::default

    fn Limits::default() -> Limits

    Limits::equal

    fn Limits::equal(Limits, Limits) -> Bool

    Limits::not_equal

    fn Limits::not_equal(x : Limits, y : Limits) -> Bool

    Limits::to_repr

    PreparedQuery

    pub struct PreparedQuery {
    // private fields
    }

    PreparedQuery::execute

    fn PreparedQuery::execute(self : PreparedQuery, data : Dataset) -> QueryResult raise QueryError

    PreparedQuery::form

    fn PreparedQuery::form(self : PreparedQuery) -> String

    Quad

    pub struct Quad {
    // private fields
    } derive(Eq,
    Debug
    )

    Quad::equal

    fn Quad::equal(Quad, Quad) -> Bool

    Quad::graph

    fn Quad::graph(self : Quad) -> Term?

    Quad::not_equal

    fn Quad::not_equal(x : Quad, y : Quad) -> Bool

    Quad::object

    fn Quad::object(self : Quad) -> Term

    Quad::predicate

    fn Quad::predicate(self : Quad) -> Term

    Quad::subject

    fn Quad::subject(self : Quad) -> Term

    Quad::to_repr

    QueryResult

    pub struct QueryResult {
    // private fields
    }

    QueryResult::answer

    fn QueryResult::answer(self : QueryResult) -> Bool?

    QueryResult::binding_delta

    fn QueryResult::binding_delta(self : QueryResult, newer : QueryResult, limits? : Limits) -> BindingDelta raise QueryError

    Bag-sensitive SELECT comparison: term identity, unbound values and duplicate occurrence counts matter; ordering does not. Blank node IDs must share scope.

    QueryResult::graph

    fn QueryResult::graph(self : QueryResult) -> Array[Quad]

    QueryResult::rows

    fn QueryResult::rows(self : QueryResult) -> Array[Binding]

    QueryResult::statistics

    fn QueryResult::statistics(self : QueryResult) -> ExecutionStats

    QueryResult::to_json

    fn QueryResult::to_json(self : QueryResult) -> String

    QueryResult::to_ntriples

    fn QueryResult::to_ntriples(self : QueryResult) -> String

    QueryResult::to_tsv

    fn QueryResult::to_tsv(self : QueryResult) -> String

    QueryResult::variables

    fn QueryResult::variables(self : QueryResult) -> Array[String]

    Term

    pub struct Term {
    // private fields
    } derive(Eq,
    Debug
    )

    Term::datatype

    fn Term::datatype(self : Term) -> String?

    Term::equal

    fn Term::equal(Term, Term) -> Bool

    Term::kind

    fn Term::kind(self : Term) -> TermKind

    Term::language

    fn Term::language(self : Term) -> String?

    Term::lexical

    fn Term::lexical(self : Term) -> String

    Term::not_equal

    fn Term::not_equal(x : Term, y : Term) -> Bool

    Term::ntriples

    fn Term::ntriples(self : Term) -> String

    Term::to_repr

    TermKind

    pub(all) enum TermKind {
    IriKind
    BlankKind
    LiteralKind
    } derive(Eq,
    Debug
    )

    TermKind::equal

    fn TermKind::equal(TermKind, TermKind) -> Bool

    TermKind::not_equal

    fn TermKind::not_equal(x : TermKind, y : TermKind) -> Bool

    TermKind::to_repr

    blank

    fn blank(value : String) -> Term raise QueryError

    iri

    fn iri(value : String) -> Term raise QueryError

    language_literal

    fn language_literal(value : String, language : String) -> Term raise QueryError

    literal

    fn literal(value : String) -> Term

    prepare

    fn prepare(source : String, limits? : Limits) -> PreparedQuery raise QueryError

    quad

    fn quad(subject : Term, predicate : Term, object : Term, graph? : Term) -> Quad raise QueryError

    rdf_namespace

    fn rdf_namespace() -> String

    typed_literal

    fn typed_literal(value : String, datatype : String) -> Term raise QueryError

    validate_result_json

    fn validate_result_json(source : String) -> Bool

    xsd_namespace

    fn xsd_namespace() -> String

    Powered by MoonBit

    Site sourceReport issueModulesSkillsBuild queueStatistics

    © 2026 mooncakes.io