Tutorial: TRIPLE by Example

This tutorial shows how to use the TRIPLE language (triple.semanticweb.org) by example.  See the Triple Tutorial and the Triple papers linked on the main web page for more explanation.  This page gives a few full, working example programs to illustrate some of the basic ideas.

Example 1 - ex1.trp

This example declares a few statements, then a rule that says Bill likes everything that Tom does.  The query then shows all triples, or all true statements.  The @ex1Model specifies that the statements, rule, and query are about the model named ex1Model.  A model is a set of true statements.

If you have installed everything correctly, to run this program, type: triple.sh ex1.trp

// ex1.trp - Example 1
//
// A Simple TRIPLE example

//Some statements, all in the same model

ellen[likes->tennis]@ex1Model.
john[likes->football]@ex1Model.
tom[likes->baseball]@ex1Model.
eric[likes->swimming]@ex1Model.
mark[likes->tennis]@ex1Model.

//A rule
FORALL X bill[likes-> X]@ex1Model <-
    tom[likes-> X]@ex1Model.

//A query, showing all the true statements
FORALL X,Y,Z <- X[Y->Z]@ex1Model.

/* OUTPUT

***
X = bill, Y = likes, Z = baseball
X = mark, Y = likes, Z = tennis
X = eric, Y = likes, Z = swimming
X = tom, Y = likes, Z = baseball
X = john, Y = likes, Z = football
X = ellen, Y = likes, Z = tennis

*/
// ex1b.trp - Example 1b
//
// A Simple TRIPLE example

//Some statements, all in the same model

ellen[likes->tennis].
john[likes->football].
tom[likes->baseball].
eric[likes->swimming].
mark[likes->tennis].

//A rule
FORALL X bill[likes-> X] <-
    tom[likes-> X].

//A query, showing all the true statements
FORALL X,Y,Z <- X[Y->Z].

/* OUTPUT (IDENTICAL)

***
X = bill, Y = likes, Z = baseball
X = mark, Y = likes, Z = tennis
X = eric, Y = likes, Z = swimming
X = tom, Y = likes, Z = baseball
X = john, Y = likes, Z = football
X = ellen, Y = likes, Z = tennis

*/

Example 2 - ex2.trp

// ex2.trp - Example 2
//
// A Simple TRIPLE example
//
// Same as ex1.trp, but with some syntax shortcuts

@myModel {

  //Some statements
  ellen[likes->tennis].
  john[likes->football].
  tom[likes->baseball].
  eric[likes->swimming].
  mark[likes->tennis].

  //A rule
  FORALL X bill[likes-> X] <- tom[likes-> X].
}

//A Query (show all facts)

FORALL X,Y,Z <- X[Y->Z]@myModel.

/* OUTPUT

***
X = bill, Y = likes, Z = baseball
X = mark, Y = likes, Z = tennis
X = eric, Y = likes, Z = swimming
X = tom, Y = likes, Z = baseball
X = john, Y = likes, Z = football
X = ellen, Y = likes, Z = tennis

*/

Example 3 - ex3.trp

This example has more than one model, world1 and world2, each with two statements.  Triple supports parameterized models, this example shows how to write a rule that transforms one model into another.  In this example, world1 gets transformed into sports(world1), and world2 into sports(world2).

// ex3.trp - Example 3
//
// A TRIPLE example with parameterized models
//

@world1 {
  tom [plays -> tennis].
  bob [plays -> baseball].
}

@world2 {
  fred [watches -> football].
  hank  [plays -> hockey].
}

FORALL Mdl @sports(Mdl) {

  FORALL O,P,V  O[P->V] <- O[P->V]@Mdl.
       //Everything true in @Mdl is true here, too

  FORALL O,V    O[watches->V] <- O[plays->V].
       //Assume that everyone who plays a sport also watches it
}

//A Query (show all facts in model sports(world1) then model sports(world2))

FORALL X,Y,Z <- X[Y->Z]@sports(world1).

FORALL X,Y,Z <- X[Y->Z]@sports(world2).

/* OUTPUT

***
X = tom, Y = watches, Z = tennis
X = tom, Y = plays, Z = tennis
X = bob, Y = watches, Z = baseball
X = bob, Y = plays, Z = baseball
***
X = fred, Y = watches, Z = football
X = hank, Y = watches, Z = hockey
X = hank, Y = plays, Z = hockey

*/

Example 4 - ex4.trp

Like Example 3, but with a little more complicated rules.

// ex4.trp - Example 4
//
// A TRIPLE example with parameterized models
//

@world1 {
  tom [plays -> tennis].
  bob [plays -> baseball].

  tom [marriedTo -> tina].
  bob [marriedTo -> betty].
}

@world2 {
  fred [watches -> football].
  hank  [plays -> hockey].

  fred [marriedTo -> fran].
  hank [marriedTo -> hariett].
}

FORALL Mdl @sports(Mdl) {

  //Everything true in @Mdl is true here, too
  FORALL O,P,V  O[P->V] <- O[P->V]@Mdl.

  //Assume that everyone who plays a sport also watches it
  FORALL O,V    O[watches->V] <- O[plays->V].

  //Assume that a wife watches the sport if her husband does
  FORALL Husband,Wife,Sport  Wife[watches->Sport] <-
                      Husband[watches->Sport] AND
                      Husband[marriedTo -> Wife].
}

//Queries (which wives watch which sports?)

FORALL X,Z <- X[watches->Z]@sports(world1) AND
              EXISTS W ( W[marriedTo -> X]@sports(world1) ).

FORALL X,Z <- X[watches->Z]@sports(world2) AND
              EXISTS W ( W[marriedTo -> X]@sports(world2) ).

/* OUTPUT

***
X = tina, Z = tennis
X = betty, Z = baseball
***
X = fran, Z = football
X = hariett, Z = hockey

*/

Example 5 - ex5.trp - Example6.rdf

The previous examples all define the true statements in the source code.  Triple can also read statement from RDF files, and has support for namespaces and resource identifiers, using the same syntax found in RDF.  Example 5 does nothing except print out all the true statements and the model name, to show how statements get loaded.

The following figure shows the structure of the ontology in Example6.rdf

Example 6 Figure
// ex5.trp - Example 5
//
// A TRIPLE example using RDF
//

// Run with the -rdfdata command line argument:
//
// triple.sh -rdfdata  Example6.rdf  http://local.example.com/localNameSpace#  localModelName ex5.trp

// No new facts or rules, just do a query that prints out the all of
// the facts and what model they belong to, this will show what
// happens when you load RDF data with the -rdfdata flag:

FORALL X,Y,Z,Mdl <- X[Y->Z]@Mdl.

/* OUTPUT

The RDF file looks like this:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE rdf:RDF [
     <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
     <!ENTITY example6 'http://argos.isi.edu/example6#'>
     <!ENTITY rdfs 'http://www.w3.org/TR/1999/PR-rdf-schema-19990303#'>
]>
<rdf:RDF xmlns:rdf="&rdf;"
     xmlns:example6="&example6;"
     xmlns:rdfs="&rdfs;">
<example6:Computer rdf:about="&example6;An_Old_Computer"
     rdfs:label="An_Old_Computer">
    <example6:Memory rdf:resource="&example6;Example6_Instance_23"/>
    <example6:OS rdf:resource="&example6;Windows 98"/>
</example6:Computer>
<example6:Digital_Camera rdf:about="&example6;Department_Camera"
     example6:Resolution="2.4 Megapixel"
     rdfs:label="Department_Camera">
    <example6:Memory rdf:resource="&example6;Example6_Instance_19"/>
</example6:Digital_Camera>
  ...
<example6:Operating_System rdf:about="&example6;Windows 98"
     rdfs:label="Windows 98"/>
<example6:Operating_System rdf:about="&example6;Windows XP Pro"
     rdfs:label="Windows XP Pro"/>
</rdf:RDF>

And the output of the above query will look like this:

***
X = 'http://argos.isi.edu/example6#':'Windows%20XP%20Pro', Y = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#':type, Z = 'http://argos.isi.edu/example6#':'Operating_System', Mdl = 'http://local.example.com/localNameSpace#':localModelName
X = 'http://argos.isi.edu/example6#':'Windows%20XP%20Pro', Y = 'http://www.w3.org/TR/1999/PR-rdf-schema-19990303#':label, Z = 'Windows XP Pro', Mdl = 'http://local.example.com/localNameSpace#':localModelName
X = 'http://argos.isi.edu/example6#':'Example6_Instance_13', Y = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#':type, Z = 'http://argos.isi.edu/example6#':'RAM_Value', Mdl = 'http://local.example.com/localNameSpace#':localModelName
X = 'http://argos.isi.edu/example6#':'Example6_Instance_13', Y = 'http://www.w3.org/TR/1999/PR-rdf-schema-19990303#':label, Z = '384', Mdl = 'http://local.example.com/localNameSpace#':localModelName
X = 'http://argos.isi.edu/example6#':'Example6_Instance_13', Y = 'http://argos.isi.edu/example6#':'Megabytes', Z = '384', Mdl = 'http://local.example.com/localNameSpace#':localModelName
  ...
X = 'http://argos.isi.edu/example6#':'Justins_Camera', Y = 'http://argos.isi.edu/example6#':'Memory', Z = 'http://argos.isi.edu/example6#':'Example6_Instance_23', Mdl = 'http://local.example.com/localNameSpace#':localModelName
X = 'http://argos.isi.edu/example6#':'Justins_Camera', Y = 'http://argos.isi.edu/example6#':'Resolution', Z = '1.2 Megapixels', Mdl = 'http://local.example.com/localNameSpace#':localModelName

End XSB (cputime 0.57 secs, elapsetime 4.54 secs)

*/

Example 6 - ex6.trp - Example6.rdf

Like Example 5, loads data from RDF, then copies some of the statements into a new model called newModel

// ex6.trp - Example 6
//
// A TRIPLE example using RDF
//
// Run with the -rdfdata command line argument:
//
// triple.sh -rdfdata Example6.rdf http://local.example.com/localNameSpace# localModelName ex6.trp

lns := "http://local.example.com/localNameSpace#".
rdf := "http://www.w3.org/1999/02/22-rdf-syntax-ns#".
ex6 := "http://argos.isi.edu/example6#".

@newModel {
   // Copy only the Computers into the new model
   FORALL O,P,V  O[P->V] <- O[P->V]@lns:localModelName AND
                 O[rdf:type -> ex6:Computer]@lns:localModelName.
}

//FORALL X,Y,Z,Mdl <- X[Y->Z]@Mdl.   //See all facts

FORALL X,Y,Z <- X[Y->Z]@newModel.   //See facts in @newModel

/* OUTPUT

***
X = 'http://argos.isi.edu/example6#':'ISI_Office_Computer', Y = 'http://www.w3.org/TR/1999/PR-rdf-schema-19990303#':label, Z = 'ISI_Office_Computer'
X = 'http://argos.isi.edu/example6#':'ISI_Office_Computer', Y = 'http://argos.isi.edu/example6#':'Memory', Z = 'http://argos.isi.edu/example6#':'Example6_Instance_13'
X = 'http://argos.isi.edu/example6#':'ISI_Office_Computer', Y = 'http://argos.isi.edu/example6#':'OS', Z = 'http://argos.isi.edu/example6#':'Linux%20Redhat%209.0'
   ...
X = 'http://argos.isi.edu/example6#':'Newer_Computer', Y = 'http://argos.isi.edu/example6#':'OS', Z = 'http://argos.isi.edu/example6#':'Windows%20XP%20Pro'
X = 'http://argos.isi.edu/example6#':'Newer_Computer', Y = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#':type, Z = 'http://argos.isi.edu/example6#':'Computer'
*/

Example 7 - ex7.trp - Example6.rdf

Like Example 6, but also adds new statements to the new model.

// ex7.trp - Example 7
//
// A TRIPLE example using RDF
//

// Run with the -rdfdata command line argument:
//
// triple.sh -rdfdata Example6.rdf http://local.example.com/localNameSpace# localModelName ex7.trp

lns := "http://local.example.com/localNameSpace#".
rdf := "http://www.w3.org/1999/02/22-rdf-syntax-ns#".
ex6 := "http://argos.isi.edu/example6#".

@newModel {

   // The new model contains just the computers from the loaded data
 
   FORALL O,P,V  O[P->V] <- O[P->V]@lns:localModelName AND
                            O[rdf:type -> ex6:Computer]@lns:localModelName.

   // Add a predicate about whether the computer has enough memory
   // (512 or 1024 Megabytes)

   FORALL O,X O[enoughMemory -> plenty] <-
              EXISTS P,V O[P->V] AND (
              ( (O[ex6:Memory -> X]@lns:localModelName) AND
                (X[ex6:Megabytes -> '1024']@lns:localModelName) )
                    OR
              ( (O[ex6:Memory -> X]@lns:localModelName) AND
                (X[ex6:Megabytes -> '512']@lns:localModelName) ) ).

   FORALL O,X O[enoughMemory -> notEnough] <-
              EXISTS P,V O[P->V] AND
              ( (O[ex6:Memory -> X]@lns:localModelName) AND
                (X[ex6:Megabytes -> '256']@lns:localModelName) ) .triple.sh -rdfdata Example6.rdf http://local.example.com/localNameSpace# localModelName ex7.trp
}

// Show the computers that have the enoughMemory predicate
FORALL X,Z <- X[enoughMemory -> Z]@newModel.

FORALL X,Y,Z <- X[Y -> Z] AND X[enoughMemory -> Z].

/* OUTPUT

***
X = 'http://argos.isi.edu/example6#':'An_Old_Computer', Z = notEnough
X = 'http://argos.isi.edu/example6#':'My_Home_Computer', Z = plenty
X = 'http://argos.isi.edu/example6#':'Newer_Computer', Z = plenty
***
X = 'http://argos.isi.edu/example6#':'An_Old_Computer', Y = enoughMemory, Z = notEnough
X = 'http://argos.isi.edu/example6#':'My_Home_Computer', Y = enoughMemory, Z = plenty
X = 'http://argos.isi.edu/example6#':'Newer_Computer', Y = enoughMemory, Z = plenty
*/

Note: It is a good habit to always return three variables from a query (like the second query above), so the result can later be serialized into an RDF representation.

You may also want to see the Example6.rdfs file.
[by Matthew Weathers, 11-Jun-2004]
[Back]