Sunday, May 7, 2017

Rust - the Programming Language on ARM (May 2017)

I have experimented with the programming language Rust on an ARM computer. For me, Rust would be the perfect language and Redox OS the perfect OS. ARM based processors are very interesting for the internet of things (IoT), but have also much potential for most desktop applications, not to speak of smartphones.

Environment: Odroid XU4  with Debian Jessie

I mostly experiment with Odroix XU4 with all files on a SSD; an inexpensive (< 150 Euro) but very comfortable and snappy environment. I start with Meveric's minimal Debian Jessie OS ( Follow the instructions there to copy it to an SD card and install. After apt-get update and apt-get dist-upgrade copy all the files to a labeled partition of 4-15 GB on the SSD. (For example mount the SSD partition to /mnt and use
 rsync -aAXv --exclude="/dev/*" --exclude="/proc/*" --exclude="/sys/*" --exclude="/tmp/*" --exclude="/run/*" --exclude="/mnt/*" --exclude="/media/*" --exclude="/lost+found" --exclude="/stFolder/*" /* /mnt 
Then edit in /boot/boot.ini the setenv line to include  your partition label here brienz:
 setenv bootrootfs “console=tty1 console=ttySAC2,115200n8 root=LABEL=brienz rootwait ro”
Reboot should start a snappy bare system, to which you add (following againg ( a desktop with tasksel (for me XFCE4 works best) and add the recommended files.
This procedure gives  a nice and usable platform for experiments (and would be good enough for daily use). With gparted you can copy the partition and are ready to start each experiment with the same initial configuration (again, use labels to select the root, because all partitions have the same UUID).

Installing RUST - the language:

To prepare I added at the end of .bashrc
export PATH="$HOME/.cargo/bin:$PATH

and installed
sudo apt-get install curl linux-compiler-gcc-4.8-arm llvm clang-3.8
Then I followed the instrctions, which means using
    curl -sSf | sh
Takes less than 5 minutes for download. To test:
rustc --version 
rustc 1.17.0 (56124baa9 2017-04-24) 

cargo --version
cargo 0.18.0 (fe7b0cdcf 2017-04-24)

Continue with the hello-world example from the Rust documentation.
My next plan is:
Installing Servo - the browser:

Wednesday, March 22, 2017

The Haskell Tool Stack for Multi-Package Projects

I organize my coding in projects, which include several packages, but are managed in a single git repository; a single repository coordinates changes in different packages to be able to reproduce consistent states of the code. In this blog I want to document methods to deal with such arrangements using the new Haskell Stack build methods and postpone a discussion of such Multi-Package Project organization for another time.

The Stack project is an effort to overcome one of the major impediments of complex Haskell projects. Haskell packages are versioned and cabal and the linker check

  • the dependencies between packages and their versions, assuring that an acceptable version of a dependent (used) packages is present
  • from each package only one version is present in the build.

It may be difficult to find a set of versions of the required packages, which are consistent; finding such consistent sets is partially automated by cabal install. Two major issues are observed:
  • solutions are not really reproducible and may change by actions outside of the programmers control (e.g. new package version appear)
  • the algorithm may not find an acceptable solution; with some tricks and detective work, a solution can be found, sometimes not - the frustration is known as "cabal hell"

Haskell Stack overcomes these impediments by proposing curated sets of package version which are known to fit together; these are known as snapshots or "lts" and are imported from  Stackage (similar to importing data about versions found on Hackage in cabal).

Using the Haskell Tool Stack starts following the installation guidelins   is installing a complete Haskell environment in locations different than what GHC and cabal usually uses (i.e. you get a new copy of ghc in ~/.stack)

Directories used
  • ghc and other global things go into ~/.stack
  • binaries go into ~/.local/bin  (the result of getAppUserDataDirectory)

The guidelines    to install stack and to run a simple new project are easy to follow and work; in the following, I assume an installed stack.

The example project used here consists of two packages, a and b, a is a library (and a test suite), b is an executable using some of the functions in a. 

Stack relies on a stack.yaml file, which for this project is

flags: {}
extra-package-dbs: []
- a
- b
extra-deps: []
resolver: lts-8.2

This fixes the snapshot to lts-8.2 (newest in march 2017 would be 8.5), which uses ghc 8.0.2 (lts-7.20 is the latest for ghc 8.0.1, for others see on stackage). As long as the resolver for a project is not changed, the same versions of packages are used and the build is repeatable.

The difference to a single package project stack.yaml file is to replace for packages the entry 
- "." 
with the names of the package directories.

Extending the multi-project test with a subdirectory with libraries m and n (in the librarySubdir branch) requires additions to stack.yaml
flags: {}
extra-package-dbs: []
- a
- b
- libs/m
- libs/n
extra-deps: []
resolver: lts-8.2
Stack builds the project and updates the required parts after updates automatically.

Autocompletion for stack requires
    eval "$(stack --bash-completion-script stack)" 

which can be included in .bashrc

Sunday, January 8, 2017

A short tutorial to use Virtuoso RDF database to store some RDF data and execute a SPARQL query

I have used 4store, which is easy to install ("apt-get install 4store") and very easy to use. For 4store exist a short but reasonable documentation Unfortunately, the code has not been much developed lately on github ( and new constructs in SPARQL are not implemented (e.g. subselect queries). My task required queries, where select clauses are nested and I was forced to look for another RDF database and SPARQL endpoint. 


My understanding of "easy to install" is "apt-get install" or very close. Virtuoso was the next candidate I found for Debian stretch it ready to install. The installation is smooth but it is necessary to enter a password during installation - write it down, it is required later! 

sudo apt-get install virtuoso-opensource 

which gives version 6.1.6 at the time of writing. 


The Virtuoso tutorial does not start at the beginning and points to various places not connected to my task and sometimes not even working, but you can see in it, that you should point your browser at http://localhost:8890/conductor (obvious!), where the default user is "dba" but the default password is not what is stated in the tutorial but the password you set during installation. "the rest is self-explanatory" says the "tutorial".

The initial screen, after login,  invites you to 5 major themes (from Business Process Integration to Enterprise Collaboration) none of them relevant for wanting just to load RDF data and execute a query. Bewildering! 

On top of the screen a list of 9 tabs includes "LinkedData", which opens a second list of tabs and a screen for "SPARQL Execution" - closer. But how to load data? 

Load data

Check the other 8 tabs... perhaps: "QuadStore Upload"? Correct: with the browse tab find the file (in my case Ntriples with .nt extension) and extend the proposed "Named Graph IRI" to with some name (e.g. xx) to "http://localhost:8890/DAVxx". The value will be required for the query. Click on upload. The filename will disappear and in the upper right you can read - if you look there - "upload finished". Done. 


Now click on the SPARQL tab again, paste the "Named Graph IRI" value into the "Default Graph IRI" field and the query into the query field. Test with 

SELECT * WHERE { ?s ?p ?o } LIMIT 10

and you should see underneath the list of s, p and o value. Neat. 

A more complex query can be pasted in, e.g. 

SELECT ?filename ?fpath ?count ?md5group 
    ?unit dove:md5 ?md5group . 
    ?unit dove:filename ?filename . 
    ?unit dove:filepath ?fpath . 
        { SELECT  ?md5group (Count(?unitgroup) as ?count) 
             WHERE { 
                   ?unitgroup dove:md5 ?md5group . 
             } GROUP BY ?md5group Having (count(?unitgroup) > 1) 
   } order by ?md5group ?fpath 

 and produces the expected results. 

The above complex query relies on the extension of the "Namespace" in its tab with the prefix value for "dove" with "". 

Queries can be saved (clicking on "Save") by giving a "File of XML template value" starting with "/DAV/", e.g. "/DAV/groupsWC" and a description text. In the SPARQL Execution tab, selecting saved queries shows a list of the stored ones and one can click "Edit" to get them back into the query window and execute them as above or click the query name, which executes them and opens the XML file in the browser (the URL, in my case http://localhost:8890/DAV/groupsWC can be opened in any browser and produces the XML doc - could be useful). 


My purpose, loading data and executing a SPARQL query was satisfied and I did, for now, not venture deeper into Virtuoso and conductor. I hope this short tutorial helps to get started quickly and easily with Virtuoso and it shows, implicitly,  what is wrong with (a) tutorials which do not start at the beginning, (b) inconsistent terminology and (c) software which is not modular but includes "all but the kitchen sink". 


I had some trouble with loading RDF and found:
  1. The RDF triples can be provided as gziped file (no other compression method is currently supported) - this saves a lot of disk space!
  2. There is a bulk loader process which can be used; it took me a while to understand that the directory from which the file is loaded must be included in the /etc/virtuoso/virtuoso.ini file: 
    DirsAllowed              = ., /usr/share/virtuoso-opensource-6.1/vad, /home/frank/virtuosoData, /home/frank/.Dove
    You can then use the isql-vt console (in debian, may have a diffferent name in other distributions) as 
    sudo isql-vt localhost usernaem password 
    ld_dir('/home/frank/virtuosoData/', '*.*', 'http://graphname');