Web data, quoted statements and placeholder names, without any new syntax.
terms.pl · output · proof · check · try it in the playground
Data on the web (the Semantic Web, RDF) is made of small statements called triples: subject – predicate – object, such as “this page – has title – hello”. Names are web addresses (IRIs), and text can carry a language tag (“hello”, in English).
Sometimes you also want to talk about a group of statements without claiming they are true — a quoted graph, like quoting someone’s words.
Can a small rule language handle all this without special features?
Everything is written as ordinary nested terms:
quoted(graph([triple(iri('https://example.org/s'), iri('https://example.org/p'), literal('hello', lang(en)))] )).
Read from the inside out:
iri(...) — a web address used as a name;literal('hello', lang(en)) — the text “hello”, tagged as English;triple(S, P, O) — one statement;graph([...]) — a list of statements, held as a quotation.member_of(X, [X|_]).
member_of(X, [_|Xs]) :- member_of(X, Xs).
includes(graph(Triples), Triple) :- member_of(Triple, Triples).
found(T) :+ quoted(G), includes(G, T).
witness(X, W) :+ quoted(X).
member_of finds an item in a list; includes looks inside a graph.found lists every triple inside the quoted graph.witness has a W that the rule never fills in. More on that below.found(triple(iri('https://example.org/s'), iri('https://example.org/p'), literal(hello, lang(en)))).
witness(graph([triple(iri('https://example.org/s'), iri('https://example.org/p'), literal(hello, lang(en)))]), sk_0).
witness, the unknown W became sk_0: a placeholder name
meaning “something exists here”. Eyedia invents such names when a
conclusion mentions something the rule never pinned down, and keeps them
stable from run to run.For found:
member_of line, with the rest of the list empty.includes rule.found rule, with G the graph and T the
triple.For witness: the quoted graph exists (fact 1), so the witness rule fires
with X the graph and W = sk_0.
Verdict: checked.
A quoted graph is just data: its triple is found, not asserted as true.
node bin/eyedia.js examples/terms.pl # the answers
node bin/eyedia.js --proof examples/terms.pl # with their proof
Or open it in the playground.
Add a second triple to the list, for example
triple(iri('https://example.org/s'), iri('https://example.org/p'), literal('hallo', lang(nl))),
and run again: two found lines appear, one for “hello” in English and one
for “hallo” in Dutch.
Web addresses, language-tagged text, statements and quotations all fit into plain terms, so the same simple, checkable reasoning works on them.