@@ -72,6 +72,100 @@ packages/extension-map examples):
7272
7373 bin/sparql --shex-manifest tests/ShExMap/manifest.yaml
7474
75+ # Algae 3
76+
77+ lib/Algae3Parser.ypp, lib/Algae3Scanner.lpp and lib/Algae3.{hpp,cpp}
78+ implement Algae 3, a pipeline-of-actions query language (a modernized
79+ Algae2); bin/algae3 is the CLI. The language itself — data model,
80+ actions, pattern combinators, the two evaluation modes — is specified
81+ in the proposal repo, https://github.com/ericprud/algae3 (doc/).
82+
83+ Run the examples from tests/ (load paths are relative):
84+
85+ cd tests
86+ ../bin/algae3 Algae3/evidence-dnf.topdown.a3 # the flagship (below)
87+ ../bin/algae3 --mode bottomup Algae3/evidence-dnf.bottomup.a3
88+ ../bin/algae3 --proofs Algae3/rule.a3 # per-row provenance
89+ ../bin/algae3 --algebra Algae3/connectives.a3 # print the algebra tree
90+ ../bin/algae3 --debug Algae3/negation-scoped-topdown.a3 # REPL debugger
91+ # step/next/into/where/print/bindings/watch/try/mode/break/run/reset
92+ ../bin/algae3 --serve 8080 Algae3/evidence-dnf.topdown.a3
93+ # then open SPARQL-explorer.html (repo root): paste a raw
94+ # .rq and sparql-to-a3.js compiles it to either mode and
95+ # steps the evaluation visually
96+
97+ tests/test_Algae3.cpp is the suite (golden results plus differential
98+ topdown-vs-bottomup runs); tests/Algae3/regen-compiled.mjs regenerates
99+ the compiled .a3 forms from the .rq sources via sparql-to-a3.js.
100+
101+ The flagship query, tests/Algae3/evidence-dnf.rq, is a DNF rule engine
102+ abstracted from a production query: a rule fires when ALL selectors
103+ pass, a selector when ANY disjunct passes, a disjunct when ALL its
104+ conjuncts pass — universal quantification by counting, at two levels,
105+ with the proof log assembled by nested GROUP_CONCATs:
106+
107+ SELECT (STRAFTER(STR(?rule), "#") AS ?ruleHash) ?message ?evidences ?log
108+ FROM <data/evidence-rules.ttl>
109+ FROM <data/evidence-groups.ttl>
110+ FROM <data/evidence.ttl>
111+ WHERE { {
112+ ?rule a ex:Rule ; ex:action [ ex:message ?message ] .
113+ { SELECT ?rule (COUNT(?selector) AS ?selectorsPassed) … (…AS ?log) …
114+ WHERE {
115+ ?rule ex:selector ?selector .
116+ { SELECT ?evidence ?selector … WHERE {
117+ ?selector ex:or ?disjunct
118+ { SELECT ?evidence ?disjunct (COUNT(?conjunct) AS ?conjunctsPassed) …
119+ WHERE {
120+ ?disjunct ex:and ?conjunct .
121+ { # conjunct kinds: group membership (via bnode
122+ # memberships!), attribute comparison, type test —
123+ # each with positive and MINUS-based negative polarity
124+ …
125+ } } GROUP BY ?evidence ?disjunct }
126+ { SELECT ?disjunct (COUNT(*) AS ?conjunctCount) WHERE {
127+ ?disjunct ex:and ?conjunct . } GROUP BY ?disjunct }
128+ FILTER (?conjunctsPassed = ?conjunctCount) # ALL conjuncts
129+ } } GROUP BY ?rule } }
130+ { SELECT ?rule (COUNT(*) AS ?selectorCount) WHERE {
131+ ?rule ex:selector ?selector . } GROUP BY ?rule }
132+ FILTER (?selectorCount = ?selectorsPassed) # ALL selectors
133+ } }
134+ ORDER BY ?message ?evidences ?ruleHash
135+
136+ (abridged — see the file for the runnable whole). Expected: two rows,
137+ "confound-sensitive" firing on OBS-2214 and "underpowered" on
138+ OBS-2214 + RNC-0859.1, each with a log like
139+ confound(confound_selector0(OBS-2214, …or0(…and0∧…)∨…or1(…))).
140+ Both compiled forms agree across both evaluation modes.
141+
142+ # Told bnodes (BNodeResolver)
143+
144+ lib/BNodeResolver.{hpp,cpp} emulates "told bnodes" (rejected in SPARQL
145+ 1.0): executing over a SPARQL endpoint, each response blank node is
146+ identified by a minimal uniqueness-verified fragment of in/out arcs
147+ (found by instrumenting the query with interrogation round trips,
148+ recursing through neighbor bnodes) and interned to a stable proxy that
149+ later queries can mention. RemoteGraphProvider caches fetched triple
150+ patterns with subsumption and feeds both ShEx validation over an
151+ endpoint (Validator::NeighborhoodSource) and remote Algae 3 execution
152+ (Engine::remote). The algorithm is written up in the algae3 repo,
153+ doc/told-bnodes.md.
154+
155+ Run it:
156+
157+ ctest --test-dir build -R BNodeResolver # or:
158+ cd tests && ../build/test_BNodeResolver
159+
160+ The suite runs everything against a client that freshly relabels every
161+ response bnode, so nothing can pass by label luck. Its flagship case
162+ executes evidence-dnf.topdown.a3 (the query above, whose group
163+ memberships are anonymous bnodes) purely through that client — no
164+ local load — and requires the exact local golden results, proof logs
165+ included. CLI `attach` to a live endpoint additionally needs an HTTP
166+ SPARQL client wired into a3::Engine::attachClientFactory; only the
167+ in-process test client exists today.
168+
75169# More info
76170
77171To learn more about SWObjects, checkout some tutorials given at SWAT4LS in 2010 and 2011:
0 commit comments