Schemantic

This is a brainstorming page. It has been superseded by SPARQL in Scheme.

Sparscheme (?)
So we define a language: term ::= symbol | literal | (term term ...) | (predicate (symbol ...) term) | (function (symbol ...) term) and any number of different 'satisfying interpretations'... we need
 * Alpha: the names of the formal parameters are undetectable
 * Beta: a redex ((predicate ...) term) or ((function ...) term has the same interpretation as the term obtained by substituting (when no capture will take place)

Interpretation: for each symbol, blah... something can be truish (said) or not.

Operators - a la ABLP
 * and
 * implies
 * says - (says G P) where G is a principal and P is a predicate... all predicates are serializable... aren't the ABLP axioms subsumed by alpha/beta ?

Axioms - what can we expect of all principals?
 * and distributes over says: (says P (and S T)) implies (says P S) and (says P T)
 * implication: (says P S) and (says P (implies S T)) implies (says P T)

"If you knew S, would you say Y?" "Yes, I would." - a promise.

Let's look into what happens when we generalize from mere statements S in (says P S) to S being an arbitrary predicate, so we don't have to write (exists (?x) (says P (foo ?x))) or whatever.

Subclass and subproperty could then be taken as special cases of implication.

For symmetry we might want (and P Q) where P and Q are subclasses to mean intersection, etc.

Is 'says' referentially transparent in any sense? (let ((y x)) (says G y)) =>  (says G x)  ?

In order to be able transmit a predicate to G, we have to be able to serialize it... so lambda is pretty much transparent (except maybe for the variable names). I.e. our interpretations (for lambdas at least) are term models...

kripke structures ...

prove consistency ...

maybe we're all talking about the same things, but just disagree about their properties. this only works under unique name assumption (different things have different names)... hmm.

if our interpretations always have the property that distinct names go to distinct things then this starts to make sense. Then the properties can also be part of the model: with each symbol S we associate both an individual and a series of predicates / functions, one for each arity... such that the interpretation of (f x y) if f's binary-thing applied to ... blah, this is like OWL Full. Need to check its model theory... or else introduce sorts, as OWL does. Or else enforce that each principal is individually well-sorted (even if not all principals agree on sorting). I.e. the interpretation of a symbol f is either an individual or a class or a .... all nicely setful. This seems OK.

We can do ML-like sort inference ... (has-sort f (sort (f-arg-sort) f-result-sort)) (same-sort f-arg-sort thing-sort)

= Previous version of this story =

This is a game where we make it look as if we're using Scheme variables to name entities that we talk about using RDF, OWL, and SPARQL. Actually the Scheme variables are bound to Scheme values that help us to formulate and pose queries.

@prefix log: . @prefix rdf: . @prefix rdfs: . @prefix owl: .

Model
The idea is that an S-expression can be interpreted in a number of different ways:
 * as itself,
 * as the value that is the result of evaluating it,
 * as a URI,
 * as an element of some domain of logical discourse (as in OWL or RDF).

To get best mileage out of the Scheme interpreter, we assume that all interpretations we care about can be applied to objects we'll call "intensions". For a Scheme expression that you would evaluate, (p x y) evaluates to the Scheme value of p applied to the Scheme values of x and y. To obtain the intension as a Scheme value, you use Scheme a macro (intension (p x y)) The intension of a symbol is the Scheme value that is the variable's value: (intension x) ==  x

[Another design would be to have (p x y) evaulate to an intension, and require an explicit request (run (p x y)) to initiate a local computation. That would probably be cleaner...]

Intension is compositional: (intension (f x)) ==>  (application-intension (intension f) (intension x))

Evaluation could factor through intension, but in practice we just use Scheme to do evaluations [but see above].

The overall effect is that participating Scheme expressions can be interpreted (in the RDF semantics sense) either by the running Scheme or by some other agent. That is, they "denote".

Entities
To be able to overload Scheme variable references for both query and immediate use as Scheme procedures, we pull the following trick:


 * When invoked in a kludgey secret side manner, the URI is returned
 * When invoked otherwise, it acts as an ordinary Scheme procedure

(define (make-entity uri proc)  (lambda args (if (or (null? args) (not (null? (cdr args))) (not (eq? (car args) '**term**)))        (apply proc args)         uri))) (define (entity->term entity)  (if (procedure? entity) (entity '**term**) entity)) (define foo (make-entity "http://..." (lambda (x y) ...)))

So, to form the statement (p x) so that you can ask it of someone else, you create the appropriate RDF out of the URIs obtained by (entity->intension p) and (entity->intension x). To consult the predicate f in the running Scheme implementation, you just say (p x y).

If you want to rely on some agent to answer questions about a predicate p, you arrange for the local procedure associated with p to ask that agent.

We might also want a registry associating entities with their Scheme names, so that they can be printed nicely. This would require two additional arguments to make-entity, the symbol and the registry. (The symbol belongs to the registry, not the entity, because one might want different registries in different Scheme 48 environments.)

Statements and predicates
A statement (p x ...) is an atomic proposition whose truth value is determined by the predicate p according to the values of the arguments x ... . If there are two or fewer arguments, we'll call it a simple statement.

A unary predicate is a class, a binary predicate is what RDF calls a 'property'. Nullary predicates have uses.

A statement involving a property maps to RDF in the obvious way (p x y) => x p y. Class membership maps using rdf:type (p x) => x rdf:type p. We should expect a statement using a nullary predicate to be interpreted as true or false. If (p) is true, then p is a nullary predicate interpreted as true: (p) => p rdf:type zzz:TruishNullaryPredicate.

I'm not sure how or whether predicates of more than 2 arguments should map to RDF. I'm inclined to say this should be decided on a case by case basis. They're therefore classified as non-simple.

An argument tuple x ... for which (p x ...) is true is what I call a witness for p. For classes, a witness is a member of the class (speaking somewhat loosely, as we may or may not want to confuse a singleton tuple with its member; I find it convenient to do this as witnesses and entities never mix). For a nullary predicate p, the empty tuple is the only witness if (p) is true, and there is no witness if (p) is false.

Conjunctions
Conjunctions are collections of propositions (and p q r ...) Conjunctions of simple statements can be rendered easily in RDF - they are 'graphs'.

Abstractions
Of course we need lambda. Since Scheme's lambda gives no way to obtain an extension, we define a corresponding macro to use instead:

(abstraction (?var ...) ?body) ==> (abstraction-intension       (lambda (?var ...) ?body)        '(?var ...)        (lambda (?var ...) (intension ?body))))

where abstraction-intension is a procedure that creates an appropriate entity (see above) that can be interpreted by serializers. Rather than immediately substitute the dummy variables (?var ...) into the intension of the ?body using let or apply, we leave that for downstream agents to do, so that they can choose the variable names themselves if they like (with the option of using the provided ones '(?var ...)).

A problem with having a single (abstraction ...) form is that it is impossible to tell whether a given abstraction is a predicate or a function. This makes a difference in how the abstraction is serialized. If abstractions can be nested this causes problems, as the distinction must be made statically (in the middle of serialization) and it is in general impossible to tell by context which is needed.

Therefore it would probably be better to have distinct syntactic forms (predicate (?var ...) ...) and (function (?var ...) ...). In (predicate (?x) (g ?x)), g is a class, while in (function (?x) (g ?x)), g is a function. The first intension serializes as select ?x where {?x rdf:type g.} while the second introduces a variable ?result and serializes as select ?result where {?x g ?result.}

[the discussion of what happens when the number of ?result values isn't 1 is below. (the-member-of ) ]

A predicate intension can be serialized as a SPARQL query. The variables become SELECT variables, and the intension returned by the intension-yielding procedure (see abstraction macro, above) becomes the query's WHERE clause.

In principle we could give data: URIs to SPARQL queries (MIME type application/sparql-query), but that would be sort of extreme.

Quotation
We can define ABLP says as a predicate relating principals to predicates (represented in Scheme as intensions): (says G (predicate (p x y))) This may be read in a number of ways; it's not so much whether the agent actually utters the predicate, but whether it can be held to it - whether it would agree with it, would say it again, or agrees to be censured if it says something that contradicts it.

says is modal, sort of like 'provable' or 'believed'. In particular it does not commute with not: (not (says G P)) does not imply (says G (predicate (not (P))).

Queries and their results
The truth of a quotation statement (says G S) might be determined by asking G. If G is a SPARQL endpoint, we might have: (ask G (predicate->SPARQL (predicate (p x y))))

When we pose a query/predicate that has variables, we are asking G for arguments that, when combined with a predicate (the query), will yield a statement that the agent would say is true.

That is, if Q is the query, and G is the agent, we learn from asking G query Q that G says (Q x ...). Each such putative witness x ... to Q is a result in the SPARQL result set.

So 'ask' generalizes from propositions to predicates (which include propositions). We would implement ask using SPARQL as follows:
 * 1) let U = the URI for G's SPARQL endpoint
 * 2) create a SPARQL 'select' query with a set of dummy variables
 * 3) make the request, with XML as result type
 * 4) the return value of the 'ask' procedure captures the result set

The result set is effectively a proposition of the form (and (Q x11 x12 ...) (Q x21 x22 ...))

From an 'ask', we learn first that (G says RS) where RS is the result set proposition. But if we may choose to interpret the result set, i.e. draw consequences from it other than (G says RS). If we give G authority over the predicate Q, then we might just believe RS (in ABLP, (controls G RS) => RS). If G's saying RS means something else to us (for example, if we know that G routinely lies about Q), then we should conclude that instead. That's the same as substituting a different predicate my-Q for Q: my rule: if (G says (Q ...)) then (my-Q ...) RS+ = (lambda (Q) (and (Q ...) (Q ...))) (RS+ my-Q) = (and (my-Q ...) (my-Q ...))

An empty result set doesn't mean that the principal is asserting that there are no witnesses; it just says that nothing is said, perhaps because it doesn't know of any, or doesn't want to tell you any.

... consider making the 'continuation' predicate my-Q be an argument to 'ask' ...

'ask' as presented is just a Scheme procedure that does not participate in the logical system. It might be used in either a predicate-like procedure or in a function-like procedure, or somewhere else altogether. For predicate-like procedures, if there are witnesses, then we have a positive answer to the question of occupation. This could be rendered as the value #t. For function-like procedures, the result set will have a single column, and we need to decide how to reduce the multiple witnesses to a single one. If there's only one, we could take it to be the value. If there's more than one, that could be an error (like the 'the' operator in Ontic), or one can be chosen arbitrarily (like blank nodes in RDF, or Skolemization). If fewer than one, again this is an exception of some kind.

To get someone to say that there are no witnesses (the predicate is void), you'd have to ask a different question.

TBD: We need to figure out what it means for the Scheme interpreter to 'believe' a proposition. Perhaps it's enough that it tells us that it does, and then forgets it. Alternatively, asking G may result in some kind of implicit side effect locally such as deposition in a triple store (caching) or forward chaining (as when Scheme believes that G controls some statement). (Compare with the way cwm works.)

Redexes
Abstractions are "authoritative" (they control all civil agents) in the sense that if A is an abstraction (predicate (?x) ... ?x ...), and B is an agent, then B is bound to agree with (A y) if and only if it agrees with the body ... ?x ... where ?x is replaced by y. That is, they can be substituted into intensions, if desired. (This condition may be too strong, but let's figure this out later.)

The reason we want this principle is that it enables us to build up queries modularly. If we define an abstraction A, and then use it in a query, we want subtitution ('procedure integration') to commute with utterance (i.e. either we or they can do the substitution and it doesn't matter).

Other nested abstractions are messy. Expressing the structure of a SPARQL query in RDF is nontrivial. The easiest way might be using a substitution [a Substituted; template ... xml literal or string ...; substitution ...] details TBD.

Existentials
We can ask an agent for witnesses to some predicate, but what if it wants to keep secret what they are, or believes there are witnesses but doesn't know what they are? About all you can do is deal with such assertions, and judge their truth independently. We might write (sometimes-true P) to say that a witness exists (or is believed to exist, or is asserted to exist), (always-false P), etc.

Implication
Suppose that a meta-predicate 'implies' is generic over predicates, meaning that all witnesses to one are witnesses to the other. For classes, this means the first is a subclass of the other. For properties, we have subproperty. For nullary predicates, we have unquantified implication (P) implies (Q).

ABLP logic says that if you say P, and you say (implies P Q), then say (can be held to) Q.

Cleanup
TBD: Establish the correspondence with description logic.

TBD: Understand which propositions to attribute to Scheme, and which to the person running Scheme. Do they ever believe different things? Do they have respectful disagreements? How credulous, trusting, or skeptical should Scheme be? We get to decide.

Ontology: Need to articulate the ontology and make sure it's acceptable: e.g. is it really OK for propositions to say propositions (as opposed to just imply them), and is it OK that propositions are both predicates and individuals. Maybe we want explicit coercions between predicates and 'sayers'. Entity (rdf:Resource) Predicate Property Class NullaryPredicate Truish Falsish Individual (owl:Thing) Principal Proposition (graph; maybe in log: ) Statement Etc.