QPL – is a turing-complete programming language intended to creation of data-processing programs where data is represented as unordered set of CPSO-statements. QPL is a production language since it consists of a number of rules (productions).
QPL is distinguished from other production languages by it's ability to explicitly control the time an order of rules invocations. The other main feature of QPL is distinguishing of extensional and intensional rules. These features makes QPL effective in practice.
Rule is a description of data processing that has two parts – antecedent and consequent, also referred to as left-hand side (LHS) and right-hand side (RHS) or Condition and Action respectively.
The logical expression in LHS describes Conditions under which Actions in RHS will be performed.
Condition is commonly a logical expression that uses only Get-queries (queries which don't modify statement base). And Action is a sequence of Set-queries (queries which modify statement base: setting or unsetting statements).
In Prolog language facts are represented as N-ary tuples or relations.
In RDF format facts are triple statements: Predicate Subject Object (PSO) that is binary relations named with Predicate term.
In most practical cases data is more complicated than a set of binary relations. However, almost all information models can be represented in such binary-relations view.
In VRB base facts are quadruple statements:
Context Predicate
Subject Object
(CPSO), that is ternary relations named with Predicate
term.
Production Programming is a programming paradigm in which data is represented as a set of facts and data processing logic is written if form of rules: condition->action. This paradigm is exploded in such languages as Prolog, Refal, XSLT.
The Rule is called Intensional if it is fired when any fact is to be modified.
The Rule is called Extensional if it is fired when any fact is to be queried.
For example, the rule:
If X is a man, then X is mortal
can be intensional or extensional.
In the first case the rule will add new facts “X is mortal” every time the fact “X is a man” is added to the base.
In the second case the rule will be fired on every query similar to “Get all mortals” or “Is X mortal?”. This will lead to sub-querying of “X is a man” facts.
The second, extensional case is used in Prolog language.
The statement-base interaction is performed with help of the following commands:
GET MASK – ask statement-base to return all statements matching MASK. For example: GET None instance-of * class.
SET STATEMENT – add STATEMENT to statement-base.
UNSET STATEMENT – remove STATEMENT from statement-base.
Each such command emerges additional processing defined by a sequence of Rules. Each command has it's own Rule sequence. One Rule is encountered only once in a sequence.
Rules are defined by a sequence of Blocks. Blocks may have embedded children blocks. Each block consists of an Anchor, Command and four Parameters. Each Parameter may be either Literal or Variable. Literals which have spaces or special symbols are enclosed with quotes. Variables are Literals having an '?'-symbol before their names.
Each Block consists of Anchor, Command with Parameters and a sequence children Blocks. Command returns a Result which may be one of the following:
MATCH – the block command was successfully executed (in some cases, parameters of the block were matched).
UNMATCH – parameters of the block were not matched, or BREAK was called inside one of its children.
The Block description starts from Anchor – a symbol which is interpreted as way the block Result processing should be done. Anchor may be one of the following with its own symbol:
'|'
CONTINUE-ALWAYS
– continue processing of the block sequence regardless result of
the block.
'-'
BREAK-ON-MATCH
-- stop processing the sequence if the block was matched or
continue otherwise.
'+'
BREAK-ON-UNMATCH
– stop processing the sequence if the block was unmatched or
continue otherwise.
'='
STOP-ON-MATCH
– stop processing the whole Rule if the block was matched or
continue otherwise.
'!'
STOP-ON-UNMATCH
– stop processing the whole Rule if the block was unmatched or
continue otherwise.
'x'
STOP-ALWAYS – stop
processing the whole Rule in any case.
Here is the table of all symbols of Anchors.
|
MATCH |
UNMATCH |
STOP |
=x |
x! |
CONTINUE |
| + ! |
| - = |
BREAK |
- |
+ |
|
MATCH |
UNMATCH |
NAME |
SHORT NAME |
---|---|---|---|---|
+ |
cont |
break |
break-on-unmatch |
break-U |
- |
break |
cont |
break-on-match |
break-M |
| |
cont |
cont |
continue-always |
| |
! |
cont |
stop |
stop-on-unmatch |
stop-U |
= |
stop |
cont |
stop-on-match |
stop-M |
x |
stop |
stop |
stop-always |
x |
The Command may be one of the following:
on-set
– execute in
case of setting statement in statement base (only for top-level
blocks);
on-unset
-execute in
case of unsetting statement in statement base (only for top-level
blocks);
on-get
– execute in
case of querying statement base (only for top-level blocks);
get
– query
statement base (with execution of on-get rules
) but
take only first statement from the query result;
iget
– query
statement base intermediately (without any rule execution);
set
– insert
statement into statement base (with execution of on-set
rules
);
iset
– insert
statement into statement base intermediately (without any rule
execution);
unset
– withdraw
statement from statement base;
iunset
– withdraw
statement from statement base intermediately;
if
– check if any
statement matching given parameters exists in statement base
(analogous to get);
if-not
– check if
there is no any statement matching given parameters.
foreach
– execute children blocks for each
statement matching parameters.
The command is followed by four parameters.
Each command requires four parameters. Each parameter may be a literal or a variable. During block execution its variables may be unified or not-unified. Almost all type of blocks unify their variables by themselves except for set and unset type of blocks which require all its parameters to be unified or return UNMATCH. After execution all blocks restore previous variable states those were before block execution.
IS-A logical support rules
It two classes class-a
и class-b
are
linked by is-a
relation, them each property p
,
belonging to class-a
(having as its domain) also belongs
to class-b
.
| on-set ?c is-a ?class-b ?class-a - foreach ?c domain ?p ?class-a - set ?c domain ?p ?class-b | on-set ?c domain ?p ?class-a - foreach ?c is-a ?class-b ?class-a - set ?c domain ?p ?class-b
Rule for Logical support of Functional Predicate
If predicate is described as functional
then
setting new value should lead to removing previous.
|on-set ?c ?p ?s ?o | if ?c functional ?p true | foreach ?c ?p ?s ?prev - unset ?c ?p ?s ?prev
Rule of indexing support
| on-set ?c student-group ?s ?g - set ?c group-student ?g ?s | on-unset ?c student-group ?s ?g - unset ?c group-student ?g ?s
Logging support
| on-set ?c ?p ?s ?o - set log instance-of ?txn set-transaction | set log txn-context ?txn ?c - set ?txn ?p ?s ?o | on-unset ?c ?p ?s ?o - set log instance-of ?txn unset-transaction | set log txn-context ?txn ?c - set ?txn ?p ?s ?o
Rules for aggregate value support
For example there is an aggregate agg
, which is a sum
of productions of fields amount
and price
of all instances of class product-position
, linked with
such aggregate by aggregate-products
. The following set
of rules updates the field sum
of the aggregate.
# it is supposed that position-sum is functional predicate | on-set ?c amount ?pp ?value - if ?c instance-of ?pp product-position - get ?c price ?pp ?price - get ?value * ?price ?position-sum - set ?c position-sum ?pp ?position-sum | on-set ?c price ?pp ?price - if ?c instance-of ?pp product-position - get ?c amount ?pp ?value - get ?value * ?price ?position-sum - set ?c position-sum ?pp ?position-sum | on-set ?c append-to-sum ?agg ?val - get ?c sum ?agg ?prevval - get ?prevval + ?val ?newval - unset ?c sum ?agg ?prevval - set ?c sum ?agg ?newval - set ?c sum ?agg ?val | on-set ?c remove-from-sum ?agg ?val - get ?c sum ?agg ?prevval - get ?prevval - ?val ?newval - unset ?c sum ?agg ?prevval - set ?c sum ?agg ?newval | on-set ?c position-sum ?pp ?ps - foreach ?c aggregate-products ?agg ?pp - set ?c append-to-sum ?agg ?ps | on-unset ?c position-sum ?pp ?ps - foreach ?c aggreage-producs ?agg ?pp - set ?c remove-from-sum ?agc ?ps
Prolog – logical programming language.
Programming paradigms on Wikipedia.org.
RDF – triplet data model.