JAnnotation Tutorial

What is JAnnotation?

JAnnotation would be best described as an annotation engine. One could say it is simply an agenda, and could also go as far as declaring it to be a database system.
JAnnotation allows you to create annotations, stating all the information you want to store about it, and later querying your annotations to look for those which fulfill certain requirements. This allows you to note down everything you think of every day and whenever you have a moment to do something, or need to remember that amazing idea you had the other day, you can query JAnnotation to remind you exactly of what you want to remember at the moment.
Currently, JAnnotation works as a console application, which may and will make it complex or even useless to a lot of people, but ideally, one day a user interface would be built on top of the engine, which would allow for quicker, more direct and comfortable use. The plans for JAnnotation include shared agendas between different people, cloud synchronization of agendas, and extension to a generic database engine which could be used by other applications and not only by direct users.

 

Basic ingredients

JAnnotation can be said to have four basic ingredients: Properties, Annotations, Agendas and Criteria.
Annotations and agendas are the simplest of them. An annotation is simply what it sounds like, something you note down. It includes a name, a description and a set of properties (qualities) which you stated about them when creating them, such as how long it would take you to do so, when it should take place or how important it is.
Agendas are, plain and simple, sets of annotations which are put together.
Properties represent qualities of the annotations. How long it takes to perform the activity described by the annotation (Duration), when it takes place (Time), how important it is (Importance), or anything you could think of. Not all annotations have all types of properties, and one annotation can have more than one property of the same type. It makes no sense to set up a duration for an annotation on which you simply write down what your new friend's e-mail is, so you don't add any duration property to that annotation, etc...
Criteria are what puts it all together. A criterion describes a way to search for a collection of annotations within an agenda, depending on their properties. "All that have a duration below 1 hour", or "Those which are important.", or "Show them to me ordered by how urgent they are." are examples of criteria.

 

Console execution

As stated before, JAnnotation is currently a console application, meaning it is executed by typing commands which perform certain actions.
JAnnotation console uses LISP-like syntax to write down commands and all elements of the engine. Particularly, everything you can write down in the console is written as: "(what how1 how2 how3 ...)". "what" specifies what is being described, and the "hows" specify the particularities of whatever is being described.
This will probably leave readers exactly as they were, if they did not know what LISP was before reading this. Do not worry, as you shall understand better after reading the examples below.

 

Step by step explained usage

To explain the overall functionality of JAnnotation, lets start by creating two properties. We will create an importance property and an urgency property.
Open up your JAnnotation console and type:
(setvar property1 (pack (urgency Urgent)))
The console shall answer you with the following informative message:
Element assigned to variable @property1

What are we exactly doing here? With setvar we are specifying a command. All top-level elements introduced in the console must be commands to be executed. "setvar" takes a name and an element, and stores that element under that name, so that it can be accessed later on. In this case, the name chosen is "property1", and the element is an urgency property. To create the urgency property, we use urgency, which simply takes an urgency level description. As for the "pack" element, this simply makes the property into a "generic" element, which is what can be stored in a variable. It has no semantic meaning.

We can now create the second property:
(setvar property2 (pack (importance Important)))
Element assigned to variable @property2

Lets now create two annotations, one of them will have property1 at the start, and the other will have no properties.
(setvar annotation1 (pack (annotation "Annotation 1" "This is the first annotation" (set (getvar property1))))).
Element assigned to variable @annotation1
Annotations are created with a name, a description, and a set of properties.
We can now check what our annotation looks like with the describe command.
(describe (getvar annotation1))
("annotation"
 "Annotation 1"
 "This is the first annotation"
 ("set"
  ("urgencyprop"
   "Urgent")))

We can also check all variables in the environment with the list variables command.
(listvars)
{annotation1:("annotation"
 "Annotation 1"
 "This is the first annotation"
 ("set"
  ("urgencyprop"
   "Urgent"))),
property2:("importanceprop"
 "Important"),
property1:("urgencyprop"
 "Urgent")}

To create the second annotation, write:
(setvar annotation2 (pack (annotation "Annotation 2" "This is another annotation" (set))))
Element assigned to variable @annotation2

The second annotation has no properties, but we might want to indeed have property2 as its property. To do that after creating the property we can use the Add property command.
(<< (getvar annotation2) (getvar property2))
Property added to annotation..

The add property command takes an annotation and a property. Since the annotation and property we wanted to use were already created, we used getvar to retrieve them.
We can also add properties created "on the go"
(<< (getvar annotation2) (duration "3 hours"))
Property added to annotation.
(describe (getvar annotation2))
("annotation"
 "Annotation 2"
 "This is another annotation"
 ("set"
  ("importanceprop"
   "Important")
  ("durationprop"
   "10800 second")))

After having created two annotations with certain properties, we will want to add them to an agenda, to be able to query them. To do that, simply create the agenda with annotation1 as initial property.
(setvar agenda (pack (agenda (set (getvar annotation1)))))
Element assigned to variable @agenda
And we can, later, add annotation2 to the agenda.
(<= (getvar agenda) (getvar annotation2))
Annotation added to agenda.
(Of course, we could have directly created the agenda with both properties in it, but that way we would not have been able to show the add annotation command)

Lets now create a criterion. We will look for annotations which are urgent. For that we will use In Criteria.
(setvar criteria (pack (in (type UrgencyProperty) (discriminationtype "ANY") (set (getvar property1)))))
Element assigned to variable @criteria
This criterion looks for those annotations which have AT LEAST ONE ("ANY") property of type UrgencyProperty which is property1.
We can now query the agenda with the criterion.
(query (getvar criteria) (getvar agenda))
1 annotations were found:

Annotation 1: This is the first annotation

We can now add the first property to the second annotation to see what happens.
(<< (getvar annotation2) (getvar property1))
Property added to annotation.
And search on the agenda again.
(query (getvar criteria) (getvar agenda))
2 annotations were found:

Annotation 1: This is the first annotation
Annotation 2: This is another annotation

Criteria can be combined using specific criteria which takes other criteria. An easy example of this is the Intersection Criteria or simply "and".
We will extend the criteria we created before by specifying that we also want the annotations to have any property which relates to importance, at any level.
(setvar criteria2 (pack (and (getvar criteria) (hasproperty (type "ImportanceProperty")))))
Element assigned to variable @criteria2
(query (getvar criteria2) (getvar agenda))
1 annotations were found:

Annotation 2: This is another annotation

It is very important to understand the difference between elements and variables. An element exists further away from the variable. That is the reason, for example, that when we added a property to annotation2, we did not have to add it again to the agenda, because what was in the agenda was the exact same element.
One element can exist without having to be associated to a variable (an example of this would be the hasproperty criteria we just created on the last step), and the same element can be stored on more than one variable.
As such, the properties we created are there no matter what, and we can erase them from their respective variables to clean up the console.
(erase property1)
Variable "property1" deleted from the console.
(erase property2)
Variable "property2" deleted from the console.
However, the property still exists inside the annotations.
(describe (getvar agenda))
("agenda"
  ("set"
   ("annotation"
    "Annotation 1"
    "This is the first annotation"
    ("set"
     ("urgencyprop"
      "Urgent")))
   ("annotation"
    "Annotation 2"
    "This is another annotation"
    ("set"
     ("durationprop"
      "10800 second")
     ("urgencyprop"
      "Urgent")
     ("importanceprop"
      "Important")))))

Console environments can also be saved for later use. This is basic as otherwise you would not be able to keep your annotations from one day to the next.
(save (file "YourFilePathHere"))
Variable mappings saved to: YourFilePathHere
Thus, you can now safely close the console.
(exit)
Exiting agenda...
Open it up again, and recover your environment.
(load (file "YourFilePathHere"))
Variable mappings loaded from: YourFilePathHere

An important component of JAnnotation is what are called distances and orders. These are definitions of semantic aspects of different types of properties (distances between them, how they are ordered) that allow us to create very interesting criteria.
We will make an example with Time Properties.
First, create two time properties and add them to their respective annotations, one for every week on monday at 14:00:00, and another for each tuesday at 13:00:00
(setvar timeprop1 (pack (time "every week on monday 14:00:00")))
Element assigned to variable @timeprop1
(setvar timeprop2 (pack (time "day of week 2 hour 13 minute 0 second 0")))
Element assigned to variable @timeprop2
(setvar timeannot1 (pack (annotation "Time annotation 1" "." (set (getvar timeprop1)))))
Element assigned to variable @timeannot1
(setvar timeannot2 (pack (annotation "Time annotation 2" "." (set (getvar timeprop2)))))
Element assigned to variable @timeannot2
(setvar agenda2 (pack (agenda (set (getvar timeannot1) (getvar timeannot2)))))
Element assigned to variable @agenda2

Time orders are differentiated by the time frames on which they take place. As time properties often specify more than one date, time frames specify on which period of time we should look for dates under that expression, and take the first to order them.
Thus, in a time frame of a week, the first property always comes before the second, and so says JAnnotation if we ask him.
(query (order (type "TimeExpressionProperty") (timeorder (timeframe "Week")) (orderselectiontype "HIGHEST") (hasproperty (type "TimeExpressionProperty"))) (getvar agenda2))
2 annotations were found:

Time annotation 1: .
Time annotation 2: .

However, in a time frame of a day, the second property happens before (even if they never happen on the same day).
(query (order (type "TimeExpressionProperty") (timeorder (timeframe "Day")) (orderselectiontype "HIGHEST") (hasproperty (type "TimeExpressionProperty"))) (getvar agenda2))
2 annotations were found:

Time annotation 2: .
Time annotation 1: .

Time distances work in a similar fashion. If we set a third date corresponding to every week on tuesday at 12:00:00.
(setvar compareto (pack (time "every tuesday at 12:00:00")))
Element assigned to variable @compareto
In a time frame of a week, only the second property is within 5 hours of this third date.
(query (distancelessequal (type "TimeExpressionProperty") (getvar compareto) (timedistance (durationmeasure "Hour") (timeframe "Week")) (number 5) (discriminationtype "ANY")) (getvar agenda2))
1 annotations were found:

Time annotation 2: .

However, in a time frame of a day, both are within 5 hours of it.
(query (distancelessequal (type "TimeExpressionProperty") (getvar compareto) (timedistance (durationmeasure "Hour") (timeframe "Day")) (number 5) (discriminationtype "ANY")) (getvar agenda2))
2 annotations were found:

Time annotation 2: .
Time annotation 1: .

Guide index