Abstract

Diamond Topic Map Query Language (DTMQL) was desined to query topic maps stored in RDB.
DTMQL uses SQL syntax with embeded 'dtmql' blocks. These blocks are predicate clauses in DNF form: (p1,1 ∧ p2,2 ∧ ... ∧ p1,k1)

[TODO : extend]

Inference rules

[TODO : describe that rules are kept as table views or tables in dtmq_rules schema]
  CREATE OR REPLACE VIEW dtmql_rules.author AS
  SELECT "$AUTHOR" as arg1
  FROM dtmql : { is-author-of($AUTHOR : author) } t;

Use Case Solutions

  1. Retrieve all author names:
      SELECT tmo_methods.getTopicName("$AUTHOR")
      FROM dtmql : { is-author-of($AUTHOR : author, $WORK : opus) } t; 
  2. Retrieve all author names sorted:
      SELECT tmo_methods.getTopicName("$AUTHOR")
      FROM dtmql : { is-author-of($AUTHOR : author, $WORK : opus) } t
      ORDER  BY tmo_methods.getTopicName("$AUTHOR"); 
  3. Retrieve the titles of all tutorials. The titles should be preferably those in scope en, de or in the unconstrained scope, in that order.
      SELECT CASE WHEN "$V_EN" IS NOT NULL THEN  "$V_EN"
             WHEN "$V_DE" IS NOT NULL THEN  "$V_DE"
             ELSE "$V_UN" END
      FROM dtmql : {
          tutorial($D),
          topic-name($D,$N_UN),
          scope($N_UN,unconstrained-scope),
          value($N_UN,$V_UN)
        } un
        LEFT OUTER JOIN
        dtmql : {
          tutorial($D),
          topic-name($D,$N_DE),
          scope($N_DE,de),
          value($N_DE,$V_DE)
        } de
        USING ("$D")
        LEFT OUTER JOIN
        dtmql : {
          tutorial($D),
          topic-name($D,$N_EN),
          scope($N_EN,en),
          value($N_EN,$V_EN)
        } en
        USING ("$D"); 
  4. Retrieve the names of all persons who have not authored anything
      SELECT tmo_methods.getTopicName("$AUTHOR")
      FROM dtmql : {
          person($PERSON),
          not(is-author-of($PERSON : author))
        } t; 
  5. Retrieve a list of all author names together with the title of their publications.
      SELECT tmo_methods.getTopicName("$PERSON"), tmo_methods.getTopicName("$WORK")
      FROM {is-author-of($PERSON : author, $WORK : opus)} t; 
  6. Retrieve a list of all titles of documents which are tutorials, sorted by publication date, descending
      SELECT tmo_methods.getTopicName("$TUTORIAL")
      FROM dtmql : {
          tutorial($TUTORIAL),
          publication-date($TUTORIAL, $DATE)
        } t
      ORDER  BY "$DATE" DESC; 
  7. Retrieve a list of documents, sorted by publication date (ascending), only number 3 to 5
      SELECT tmo_methods.getItem("$TUTORIAL")
      FROM dtmql : {
          tutorial($TUTORIAL),
          publication-date($TUTORIAL, $DATE)
        } t
      ORDER  BY "$DATE"
      LIMIT  2 OFFSET 3; 
  8. Retrieve all topic identifiers of documents which have a download URL
      SELECT "$DOCUMENT"
      FROM dtmql : {
          document($DOCUMENT),
          download($DOCUMENT, $URL)
        } t; 
  9. Retrieve a list of author's email addresses where the author has authored documents for which no download URL exists
      SELECT "$EMAIL"
      FROM dtmql : {
          is-author-of($AUTHOR : author, $DOCUMENT :  opus),
          email($AUTHOR, $EMAIL),
          not(download($DOCUMENT))
        } t; 
  10. Retrieve a list of author names where the author has written more than 1 document
      SELECT tmo_methods.getTopicName("$AUTHOR")
      FROM dtmql : { is-author-of($AUTHOR : author, $DOCUMENT : opus) } t
      GROUP  BY "$AUTHOR" HAVING count("$DOCUMENT") > 1; 
  11. A list of author names where the author has not written a single document with someone else
      SELECT DISTINCT tmo_methods.getTopicName("$A")
      FROM dtmql : { is-author-of($A : author, $D : opus) } t
      WHERE  "$A" NOT IN (
        SELECT "$A1" FROM dtmql : {
          is-author-of($A1 : author, $D : opus),
          is-author-of($A2 : author, $D : opus),
          $A1 <> $A2
        } t
      ); 
  12. Retrieve all topic identifiers of documents and their URLs which have a non-working URL at query time
      --
      -- This requires a PL/perl function, which is not yet written
      -- 
  13. Retrieve all topic identifiers for documents for which the abstract in english (i.e. the occurrence of type abstract in scope en) contains the phrase 'topic map' or 'topic maps', case-insensitive
      SELECT "$DOCUMENT"
      FROM dtmql : { abstract($DOCUMENT, $ABSTRACT,en) } t
      WHERE
        lower("$ABSTRACT") like '%topic  map%'
        OR lower("$ABSTRACT") like '%topic  maps%'; 
  14. Retrieve all documents which have a title in german (i.e. a basename in the scope de).
      SELECT "$DOCUMENT"
      FROM dtmql : {
          document($DOCUMENT),
          topic-name($DOCUMENT, $NAME),
          scope($NAME, de)
        } t; 
  15. Retrieve all topic identifiers of the pairs of documents which share at least one word in the title, ignoring stopwords like 'and', 'of', 'the'. No duplicates in this list are allowed. Note: Duplicates of the form (a, b) and (b, a) may be allowed. The result should be sorted by the identifiers.
      --
      -- This requires a PL/PgSQL string compare function, which is not yet written
      -- 
  16. Retrieve the identifiers of all topics which represent information resources on the ontopia.net server(s)
      SELECT "$TOPIC"
      FROM dtmql : { subject-locator($TOPIC, $URI) } t
      WHERE  "$URI" like '%ontopia.net%'; 
  17. Retrieve the topic identifiers of all documents which are not written in the language English
      SELECT "$DOCUMENT"
      FROM dtmql : {
          document($DOCUMENT),
          not(language($DOCUMENT, "english"))
        } t; 
  18. Retrieve the topic identifiers of all documents which are directly or indirectly influenced by something which Steve Pepper wrote.
      CREATE TEMPORARY TABLE "indirect-influence" AS
      SELECT "$OID" as oid, "$PID" as pid
      FROM
          dtmql : { is-influenced-by($OID : influenced, $PID :  influence) } t;
    
      SELECT "$INFLUENCED","$INFLUENCE"
      FROM
          dtmql : { is-author-of($INFLUENCE : opus,  steve-pepper : author) } t
          NATURAL JOIN
          dia_walkRecursive('"indirect-influence"') AS  anc("$INFLUENCED","$INFLUENCE");
    
  19. Retrieve all identifiers of topics which are either instances of paper or tutorial.
      SELECT "$DOCUMENT"
      FROM dtmql : {
          tutorial($DOCUMENT) | tutorial($DOCUMENT)
        } t; 
  20. Retrieve all titles of all publications (regardless their scope) together with their most specific class, i.e. that class where this publication is directly (and not indirectly) an instance of.
      SELECT "$V","$CLASS"
      FROM dtmql : {
          is-author-of($AUTHOR : author, $DOCUMENT :  opus),
          direct-instance-of($DOCUMENT, $CLASS),
          topic-name($DOCUMENT, $TITLE),
          value($TITLE,$V)
        } t; 
  21. Retrieve all authors (i.e. all topic items which play the role author in an is-author-of association).
      SELECT tmo_methods.getItem("$AUTHOR")
      FROM dtmql : { is-author-of($AUTHOR : author, $DOCUMENT : opus) } t; 
  22. Retrieve all basename items of topics which play the role author in an is-author-of association).
      SELECT tmo_methods.getItem("$TNAME")
      FROM dtmql : {
          is-author-of($AUTHOR : author, $DOCUMENT :  opus),
          topic-name($AUTHOR, $TNAME)
        } t; 
  23. Retrieve a list of all occurrence items being of type email.
      SELECT tmo_methods.item("$OCC")
      FROM dtmql : { occurrence($TOPIC, $OCC), type($OCC, email) } t;