User Tools

Site Tools


docs:loki-tutorial

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

docs:loki-tutorial [2017/09/19 14:31]
docs:loki-tutorial [2022/03/23 16:59] (current)
Line 1: Line 1:
 +====== Loki using tutorial ======
 +This is complete tutorial to usage of the Loki plugin by any DokuWiki user. It provides description of Loki features with functional examples. While reading this tutorial you will learn how to create simple Movies Knowledge Base in Loki. 
 +
 +===== First steps =====
 +Here we will show some new features you can see while working with the Loki for the first time. 
 +
 +==== New options in UI ====
 +The DokuWiki editor has its own Graphical User Interface for easier work with text. It's buttons are placed above the area of writing. Loki adds some new buttons to let you easily insert semantics into your text. All of them are listed below:
 +
 +  * First is the button with "pl". It allows you to place Prolog tag for inserting the Prolog code.
 +  * ''C'' inserts Category code
 +  * ''R'' places relation code
 +  * ''A'' is for attribute code
 +  * ''?'' places code for ASK queries
 +  * ''S'' is for inserting SPARQL code and gives us 3 options:
 +    * ''S'' - selecting data
 +    * ''A'' - asking
 +    * ''D'' - describing
 +
 +Since they are just UI buttons for inserting the code, I don't describe how to use it. It will be covered later.
 +
 +==== Special pages ====
 +Loki has special pages for every type of semantics it uses:
 +   * categories page for listing all Categories
 +   * relations page for listing all Relations
 +   * attributes page for listing all Attributes
 +
 +It also has groups of special pages associated with the three types mentioned before. For every attribute, relation and category used in our wiki we can create special page that describes it. After placing the attribute, relation or category in our article, we can create page like: ''special:category:our_category_name'' to describe it. After the article on the category (or relation/attribute) is created it will be listed under the special pages section in the Sitemap.
 +
 +===== Defining categories =====
 +
 +Let's start with simple example. In this case it will be small knowledge base of the movies and persons related to them. First we will create few pages containing only categories and titles of the movies. Then we will go further and add some details to our pages.
 +
 +The movie base will be kept in the ''movies'' namespace of DokuWiki. There we will create pages about the movies. Also we will need namespace named ''persons'' for keeping pages about directors and actors. First we will create a new movie page. We will name it ''raiders_of_the_lost_ark'' and write in it some header with the full title of the movie. It will be ''Indiana Jones and the Raiders of the Lost Ark''. Until now nothing was new for the users of the DokuWiki.
 +
 +Let's provide first semantic information into this page. ''raiders_of_the_lost_ark'' is a movie so it should belong to the category named ''movie''. Defining categories for pages is very similar to placing a link to another page. In order to place a category we write:
 +
 +<code loki>Raiders of the Lost Ark is a [[category:movie]]... </code>
 +
 +We can also change the display of the category name, by placing our custom text after ''|'' character:
 +
 +<code loki>It is one of the [[category:movie|movies]] from the Indiana Jones series.</code>
 +
 +If you don't want to show link to the category in the text just simply put space as a custom display:
 +
 +<code loki>[[category:movie| ]]</code>
 +
 +In that case category tag can be placed anywhere in the page text. The most popular are at the beginning and the end of text.
 +
 +In the same way we will create three additional pages with movies from the Indiana Jones series:
 +
 +  * temple_of_dooom
 +  * last_crusade
 +  * kingdom_of_the_crystal_skull
 +
 +All of them will have defined category ''movie'' and placed header with the full title. We will use them as a base of our example in the next points of this tutorial. 
 +
 +The final code of our movie page should look like this:
 +
 +<code loki>
 +==== Raiders of the Lost Ark ====
 +
 +[[category:movie| ]] 
 +</code>
 +
 +===== Defining attributes =====
 +Attributes are used to define information included in the article. They relate to basic information that can be presented as a number, date or any other generic, non-unique data type. Attribute values itself have no meaning like: 2008 can be year as good as an amount of leaves growing on the tree. Any values that correspond to the objects that can be defined and are somehow original should be placed as relations (described later). That way we separate simple data, that would not have description from the complicated one. Also attributes should be used when we say that the object has some property like: length, weight, size and so on. In that case attributes are immanently in the subject (page). Relations are about different connections between the subject and object. They are placed outside of the subject and are another objects. 
 +
 +Let's continue with our movie base. Each movie has defined year of the production. It is sort of property. Then we can insert semantic notation into every movie page about the year it was produced. We will to this by placing tag:
 +
 +<code loki>Indiana Jones and the Raiders of the Lost Ark were produced in [[production_year:=1981]].</code>
 +
 +Of course we can place it anywhere: in the sentence like above or just separately in the table with basic information on the movie. There is no difference for Loki. The name of the attribute can be any string. Also with spaces. It is important to remember that ''production_year'' and ''production year'' attributes are different ones for Loki. If you will use space or ''_'' symbol is up to you, but once you decide you have to be consistent.
 +
 +Also here you can use ''|'' symbol to separate value from the displayed string. And also here you can hide the value by placing empty space as a custom string.
 +
 +Now we will add another attributes to the movies:
 +  * title - full title of the movie
 +  * action_time - the time the action of the movie takes place
 +  * action_place - the places where the action takes place
 +  * language - primary language of the movie
 +
 +In the case of the language we can define it as a relation to the language page, but for the purposes of this tutorial we will keep it like that. Same with the action place, which can be link to the countries and places. But the countries will be used as a relation in another example.
 +
 +Loki does not allow for placing semantic tags inside another tags like headers. So our title of the movie will be defined below in the list of information.
 +
 +Now our page ''raiders_of_the_lost_ark'' should have the code like below:
 +
 +<code loki>
 +==== Raiders of the Lost Ark ====
 +
 +**Title**: [[title:=Raiders of the Lost Ark]]
 +
 +**Production Year**: [[production_year:=1981]]
 +
 +**Action time**: [[action_time:=1936]]
 +
 +**Action place**: [[action_place:=Peru]], [[action_place:=Egypt]]
 +
 +**Language**: [[language:=english]]
 +
 +[[category:movie| ]] 
 +</code>
 +
 +===== Defining relations =====
 +While attributes are immanent information on the subject of the page, relations are representing connection of one object to another. Unlike the attributes, relations create links to target objects (pages), so we can easily jump to it. The power of the relations will be used in the queries for information later. For now it is important to give every page some relations to another pages. 
 +
 +In the case of our movies example we can define many relations with persons involved in production, i.e. cast, director and screenplay writers.
 +
 +Adding relation is simple. For ''raiders_of_the_lost_ark'' it can be:
 +
 +<code loki>[[main_role::persons:harrison_ford|Harrison Ford]]</code>
 +
 +Usually the relation name should be stated as sort of connection like ''main_role_played_by''. Since we work on a simple example, it is not that much important. But in the real works that convention should be kept.
 +
 +Notice that the page used here as a value of the relation is from another namespace. It is good way of organizing our pages. In the ''persons'' namespace we can keep not only people related to the movies but also to other categories. It is important since we may have persons that work on the movies and do some other things like singing or painting. Then we don't have to create separate pages on them.
 +
 +Another important note is that we can define one relation type many times. That way we will tell that the page is related in the same way with other pages. The second relation of the same name does not overwrite the value of the first. It adds another one. 
 +
 +The value of the relation should always be written as shown above. We can also write it as:
 +
 +<code loki>[[main_role::persons:Harrison Ford]]</code>
 +
 +In that way DokuWiki will create the link to the page ''harrison_ford'', so one would say there's no difference. But in fact, there's a little trap. Semantic engine takes this value as it is: ''Harrison Ford''. So, if we will define on another page the value as ''harrison_ford'' it will be treated as something different than ''Harrison Ford'' - even if it looks the same on the rendered page. In conclusion, we can use the second way, but by doing it we have to be consistent or we will run into problems with proper reasoning in semantic queries.
 +
 +Usage of ''|'' is the same as in other cases.
 +
 +In the case of movies we will add more relations:
 +  * Genre - from ''genre'' namespace
 +  * Production country - from ''countries'' namespace
 +  * screenplay - the author(s) of the screenplay
 +  * directed_by - director
 +  * main_character - from ''characters'' namespace
 +  * supporting_role - like main_role
 +  * supporting_character - like main_character
 +  * series - from namespace ''series''
 +
 +Fully created code of the page ''raiders_of_the_lost_ark'' will be:
 +
 +<code loki>
 +==== Raiders of the Lost Ark ====
 +
 +**Title**: [[title:=Raiders of the Lost Ark]]
 +
 +**Genre**: [[genre::genres:adventure]]
 +
 +**Production Year**: [[production_year:=1981]]
 +
 +**Production country**: [[produced_in_country::countries:USA]]
 +
 +**Screenplay**: [[screenplay::persons:Lawrence Kasdan]],                [[screenplay::persons:George Lucas]]
 +
 +**Directed by**: [[directed_by::persons:steven_spielberg|Steven Spielberg]]
 +
 +**Cast**: 
 +
 +[[main_role::persons:harrison_ford|Harrison Ford]] - 
 +[[main_character::characters:indiana_jones|Indiana Jones]]
 +
 +[[supporting_role::persons:karen_allen|Karen Allen]] -
 +[[supporting_character::characters:marion_ravenwood|Marion Ravenwood]]
 +
 +[[supporting_role::persons:paul_freeman|Paul Freeman]] - 
 +[[supporting_character::characters:dr_rene_bellog|Dr RenĂ© Belloq]]
 +
 +**Action time**: [[action_time:=1936]]
 +
 +**Action place**: [[action_place:=Peru]], [[action_place:=Egypt]]
 +
 +**Series**: [[series::series:indiana_jones|Indiana Jones]]
 +
 +**Language**: [[language:=english]]
 +
 +[[category:movie| ]]
 +</code>
 +
 +Our page is ready. Now we will create some other pages for actors or directors to show the power of the semantic queries. But before that we need to insert other three movies from the Indiana Jones series. Below you will find prepared text with semantic code for those pages.
 +
 +**temple_of_doom**
 +
 +<code loki>
 +==== Indiana Jones and the Temple of Doom ====
 +**Title**: [[title:=Indiana Jones and the Temple of Doom]]
 +
 +**Genre**: [[genre::genres:adventure]]
 +
 +**Production Year**: [[production_year:=1984]]
 +
 +**Production country**: [[produced_in_country::countries:USA]]
 +
 +**Screenplay**: [[screenplay::persons:Willard Hyuck]],[[screenplay::persons:Gloria Katz]]
 +
 +**Directed by**: [[directed_by::persons:steven_spielberg|Steven Spielberg]]
 +
 +**Cast**: 
 +
 +[[main_role::persons:harrison_ford|Harrison Ford]] - 
 +[[main_character::characters:indiana_jones|Indiana Jones]]
 +
 +[[supporting_role::persons:Kate Capshaw]] -
 +[[supporting_character::characters:Willie Scott]]
 +
 +[[supporting_role::persons:Jonathan Ke Quan]] - 
 +[[supporting_character::characters:Short Round Ke Huy Quan]]
 +
 +**Action time**: [[action_time:=1935]]
 +
 +**Series**: [[series::series:indiana_jones|Indiana Jones]]
 +
 +**Language**: [[language:=english]]
 +
 +[[category:movie| ]] 
 +</code>
 +
 +**last_crusade**
 +
 +<code loki>
 +==== Indiana Jones and the Last Crusade ====
 +
 +**Title**: [[title:=Indiana Jones and the Last Crusade]]
 +
 +**Genre**: [[genre::genres:adventure]]
 +
 +**Production Year**: [[production_year:=1989]]
 +
 +**Production country**: [[produced_in_country::countries:USA]]
 +
 +**Screenplay**: [[screenplay::persons:Jeffrey Boam]]
 +
 +**Directed by**: [[directed_by::persons:steven_spielberg|Steven Spielberg]]
 +
 +**Cast**: 
 +
 +[[main_role::persons:harrison_ford|Harrison Ford]] - 
 +[[main_character::characters:indiana_jones|Indiana Jones]]
 +
 +[[supporting_role::persons:Sean Connery]] -
 +[[supporting_character::characters:Professor Henry Jones]]
 +
 +[[supporting_role::persons:Alison Doody]] - 
 +[[supporting_character::characters:Dr. Elsa Schneider]]
 +
 +**Action time**: [[action_time:=1938]]
 +
 +**Series**: [[series::series:indiana_jones|Indiana Jones]]
 +
 +**Language**: [[language:=english]]
 +
 +[[category:movie| ]] 
 +</code>
 +
 +**kingdom_of_the_crystal_skull**
 +
 +<code loki>
 +==== Indiana Jones and the Kingdom of the Crystal Skull ====
 +
 +**Title**: [[title:=Indiana Jones and the Kingdom of the Crystal Skull]]
 +
 +**Genre**: [[genre::genres:adventure]]
 +
 +**Production year**: [[production_year:=2008]]
 +
 +**Production country**: [[produced_in_country::countries:USA]]
 +
 +**Screenplay**: [[screenplay::persons:David Koepp]]
 +
 +**Directed by**: [[directed_by::persons:steven_spielberg|Steven Spielberg]]
 +
 +**Cast**: 
 +
 +[[main_role::persons:harrison_ford|Harrison Ford]] - 
 +[[main_character::characters:indiana_jones|Indiana Jones]]
 +
 +[[supporting_role::persons:Cate Blanchett]] -
 +[[supporting_character::characters:Irina Spalko]]
 +
 +[[supporting_role::persons:Karen Allen]] - 
 +[[supporting_character::characters:Marion Ravenwood]]
 +
 +**Action time**: [[action_time:=1957]]
 +
 +**Series**: [[series::series:indiana_jones|Indiana Jones]]
 +
 +**Language**: [[language:=english]]
 +
 +[[category:movie| ]] 
 +</code>
 +
 +===== ASK semantic queries =====
 +Since now we were creating pages that were containing some semantic information. But it is only the introduction to the most powerful feature of semantic wikis - Semantic Queries. Loki uses the ASK query syntax known from the Semantic Media Wiki. It allows us to ask for pages and information they contain by using special query code.
 +
 +The simplest form of ASK query has form:
 +
 +<code loki>
 +{{#ask: condition }}
 +</code>
 +
 +''condition'' is the semantic tag that will filter information from the knowledge base. For instance we can say that we ask for all pages that has a category ''movie'':
 +
 +<code loki>
 +{{#ask: [[category:movie]] }}
 +</code>
 +
 +By placing this on the page in wiki we will get list of pages that have defined category ''movie''. Just like our four pages we have created before. We can use many conditions by separating them with space.
 +
 +<code loki>
 +{{#ask: [[category:movie]] [[production_year:=2008]] }}
 +</code>
 +
 +That way we will get list of movies produced in 2008. In our case there should be ''kingdom_of_the_crystal_skull''. A condition can be category, attribute or relation. Let's create the page in the namespace ''persons'' names ''harrison_ford''. Here we can provide some information about the actor. The example code would be:
 +
 +<code loki>
 +[[category:actor| ]]
 +
 +Name: [[name:=Harrison Ford]]
 +
 +Full Name: [[full_name:=Harrison Ford]]
 +
 +Gender: [[gender:=M]]
 +
 +Birth date: [[birth_date:=1942-07-13]]
 +
 +From: [[is_from::countries:USA]]
 +</code>
 +
 +Now we can add some ask queries at the end of the page (or wherever we want to in the text). Let's say we want list of the movies with him playing main role in:
 +
 +<code loki>
 +{{#ask: [[category:movie]] [[[main_role::persons:harrison_ford]] }}
 +</code>
 +
 +That code will do the work. If we would like to include movies where he played supporting role we will use OR keyword:
 +
 +<code loki>
 +{{#ask: [[category:movie]] [[[main_role::persons:harrison_ford]] [[supporting_role::persons:harrison_ford]] }}
 +</code>
 +
 +But since we don't have such movie in the knowledge base we won't get any new movie on the list. We can also use OR with the same relation but different values and there is a shorter code possible here:
 +
 +<code loki>
 +{{#ask: [[category:movie]] [[[main_role::persons:harrison_ford]] [[main_role::persons:Sean Connery]] }}
 +</code>
 +
 +Notice that Sean Connery is placed here as it is not as ''sean_connery''. It is because in our examples we have put him that way as a value of the relation. If we would ask for ''sean_connery'' instead we wouldn't get any result. Of course there's also no movie in our knowledge base, with Sean Connery playing main role, so let's show that problem on another example:
 +
 +<code loki>
 +{{#ask: [[category:movie]] [[[main_role::persons:Harrison Ford]] }}
 +</code>
 +
 +This will return no result, since in our knowledge base there is no information that Harrison Ford plays any main role. It is ''harrison_ford'' that does. That is why we need to be consistent in placing values while writing pages. ''Sean Connery'' value is fine, since there's no page where he is written as ''sean_connery''. The different values were used in this example to show the problem. In the real wiki we should use style like ''Sean Connery'' or ''sean_connery'' consistently to all persons. 
 +
 +==== Subqueries ====
 +We can put subqueries into the conditions. It is done by inserting them between the ''<q></q>'' tags:
 +
 +<code loki>
 +{{#ask: [[category:movie]] [[[main_role::<q>[[category:singer]]</q>]] }}
 +</code>
 +
 +This example will give us list of movies, where main_role was played by a singer if we have any person with that category and there is a movie where the person is the value of the relation ''main_role''.
 +
 +We can nest subqueries by inserting another one in the ''<q></q>'' tags.
 +
 +==== Relation chains ====
 +We can use chains of relations as a condition in our query. For example, we can ask for movies where actor who plays main role is from the USA:
 +
 +<code loki>
 +{{#ask: [[category:movie]] [[main_role.is_from::countries:USA]] }}
 +</code>
 +
 +==== Displaying results ====
 +By default results are shown as a table with list of pages found as a result of the query. We can add columns to the table by placing additional attributes of the ASK query. Every attribute is separated with a ''|'' symbol. Every additional column name must be written with ''?'' symbol before. So if we want to get list of all movies with their director we will write:
 +
 +<code loki>
 +{{#ask: [[category:movie]] |
 +?directed_by
 +}}
 +</code>
 +
 +We can also define the header of the column to get rid of ''_'' symbol from the original:
 +
 +<code loki>
 +{{#ask: [[category:movie]] |
 +?directed_by=Directed by
 +}}
 +</code>
 +
 +We can check if the result belongs to given category:
 +
 +<code loki>
 +{{#ask: [[category:movie]] |
 +?directed_by=Directed by |
 +?category:movie
 +}}
 +</code>
 +
 +In the result the last column will have ''X'' symbol if the page has a category ''movie''. In our case every movie will be marked.
 +
 +==== Options for the ASK queries ====
 +We can also add options to customize the output of the query results. The options should be placed after the list of the columns described above. Options never begin with ''?'' symbol like columns. The options are:
 +
 +^ Option name ^ Allowed values ^ Description ^
 +| format | list of formats is available below | The output format of the results - table by default |
 +| limit | positive number | Maximum number of displayed results |
 +| offset | positive number | Defines from which result page start the display. Results with smaller count won't be displayed |
 +| sort | names of shown attributes | Sorting columns. Can be more then one, but separated with comma |
 +| order | asc, ascending, desc, descending, reverse, random | Sorting order. If there are more then one sort attributes, separate it with comma. By default it is set to ''asc'' |
 +| headers | show, hide | Show or hide headers of the result table. By default: show |
 +| mainlabel | text | Label of the main column containing list of returned pages. Empty by default. |
 +| link | all, subject, none | Defines which elements of the result are shown as a link. By default is set to ''all''. |
 +| default | text | Text shown when there are no results |
 +| intro | text | Text shown above the results |
 +| outro | text | Text shown below the results |
 +| sep | text | Only in ''list'' and ''csv'' formats. Defines separator for the results. By default: //,// |
 +
 +The list of formats contains:
 +  * table - default one
 +  * broadtable - table wide for the whole page
 +  * list - list separated with commas (or another char defined by ''sep'' option)
 +  * ol - ordered list. Additional columns shown in parentheses. 
 +  * ul - unordered list. Additional columns shown in parentheses. 
 +  * count - count of results
 +  * csv - generates file on the server with results and shows the link to the file
 +  * debug - shows query and goal in the Prolog code, list of column, options and count of found results
 +
 +Let's look at the example. It will show the table with information on the movies where Harrison Ford played the main role:
 +
 +<code loki>
 +{{#ask: [[category:movie]] [[[main_role::persons:harrison_ford]] |
 +?title |
 +?production_year |
 +sort=production_year
 +}}
 +</code>
 +
 +As you can see the movies are ordered chronologically by the production year.
 +
 +===== Usage of Prolog code =====
 +Under the mask Loki uses SWI Prolog environment to provide reasoning for DokuWiki. Features of categories, attributes, relations, queries are all just shortcuts to create knowledge base in Prolog. But what is the most powerful in Loki is possibility to insert knowledge manually in Prolog language. In that way any application written in Prolog can be used explicitly on the DokuWiki page and provide additional information into knowledge base.
 +
 +To place your code in Prolog you can use ''<pl></pl>'' tags. Basic usage is:
 +
 +<code prolog>
 +<pl>
 +woman('p:kate').
 +parent('p:kate','p:zoe').
 +mother(X,Y) :-
 +  woman(X),
 +  parent(X,Y).
 +</pl>
 +</code>
 +
 +In that way you can provide additional knowledge into the base of Loki. But you can do even more. ''pl'' tag takes some extra arguments:
 +  * ''file'' - name of the file placed in DokuWiki media directory. Knowledge placed in the file can be easily inserted into Loki knowledge on that page.
 +  * ''scope'' - usually used with ''goal''. Defines the scope of searching through knowledge. ''Scope='pl:family' '' will make Prolog search in the ''pl:family'' namespace.
 +  * ''url'' - link to the file with Prolog code (uses curl)
 +  * ''goal'' - allows to provide Prolog goal. If you set this, Prolog will return to the page results of reasoning. 
 +  * ''cache'' - allows you to define if the data from inside of the element are to be saved in the file for wiki. Then they will be available to other pages. Otherwise you can access them only in this tag (default = ''"true"'').
 +  * ''rdf'' - same as ''format='rdf' ''; see below; depreciated.
 +  * ''msgerr'' - defines where to show errors:
 +    *  ''display'' - will show errors on the wiki page.
 +    * ''tofile'' - will save errors into the file in tmp directory.
 +    * ''ignore'' - default action; errors will be hidden.
 +  * ''trace'' - allows you to trace chosen predicates; more than one should be separated with comma
 +  * ''format'' - defines the format of data placed inside the tag element. Choices are:
 +      * ''prolog'' - default
 +      * ''rdf'' - RDF code;
 +      * ''sparql''
 +
 +If you want, you can assign that way categories, attributes and relations. You just need to use predicates:
 +  * ''wiki_category(PAGE,CATEGORY_NAME)''
 +  * ''wiki_relation(PAGE,RELATION_NAME,VALUE_PAGE)''
 +  * ''wiki_attribute(PAGE,ATTR_NAME,ATTR_VALUE)''
 +
 +
 +===== Caching =====
 +By default Loki uses the cache for the pages. It may generate some problems. If you have page with ASK query, then its results will be loaded from cache. In that way, when you create new page that can be result of the query, it won't appear in the result.
 +
 +If you want the query and all semantics on the given page to be processed then you should use NOCACHE directive:
 +
 +<code loki>
 +~~NOCACHE~~
 +</code>
 +
 +It should be placed at the start of the chosen page.
 +
 +===== Creating pages for semantics =====
 +There are two ways of creating special page. The first one is by clicking on the generated link in our article. But it works only for categories links. In the case of attributes and relations we need to create it's pages manually by creating pages with address:
 +
 +<code>your_wiki_address.com/special:attribute:attribute_name</code>
 +
 +Where ''your_wiki_address.com'' is the wiki webpage domain/URL, and the ''attribute_name'' is the attribute name. In the case of relation it is pretty similar:
 +
 +<code>your_wiki_address.com/special:relation:relation_name</code>
 +
 +There's also third way of creating special pages. If we go to the ''special:categories'' page we will get the generated list of all categories used in the articles at our wiki. The unused categories won't be displayed here (but still may be already created). From that page we can easily start describing every category. With relations and attributes we can do the same.
 +
 +Special pages of single attribute, category or relation are for describing the purpose of the given semantic parameter. Also once the page for one of those is created it generates the list of pages using it, which is useful for tracking the semantic data on pages.
 +
 +Special pages ''special:categories'', ''special:relations'' and ''special:attributes'' generate lists of specific semantic vocabulary used in Wiki. They have to be created manually. It is important to place <code loki>~~NOCACHE~~</code> code on the page beginning to refresh lists on every page load.