QwalKeko provides an extension of the logic program querying language Ekeko. It allows developers and researchers to query the history and evolution of software projects stored in a VCS. To this end, QwalKeko constructs a graph of versions, in which each node represents a version, and successive versions are connected. Moving throughout this graph is done using Qwal, a graph query language implementing regular path expressions. Ekeko is used to express the characteristics that have to hold inside each version. QwalKeko ensures that Ekeko predicates are resolved in the correct version.
In the first example we find a method ?method that has been moved to ?other-method in a later version. The two first lines provide the setup for our query. The query starts in start-version, a clojure variable bound to a version. It ends in ?successive-version, a logic variable that will be bound after the query. Lines 3 and 4 are executed in the startversion, and bind ?method to any method in that version. Line 5 marks a transition to a successor of the start version. Lines 6 and 7 use a predefined rule that detects methods that are moved to another place.
(l/qwalkeko* [?method ?other-method ?successive-version]
(qwal/qwal graph start-version ?successive-version 
(jdt/ast :MethodDeclaration ?method))
(refactorings/method-moved ?method ?other-method))))
The implementation of the method-moved rule is written in regular core.logic.
(defn method-moved [?moved ?to]
(jdt/ast :MethodDeclaration ?to)
(method-method|equals ?moved ?to) ;;same signature
(has-similar-body ?moved ?to)))
In the second example we are looking for sequences of versions in which two authors commit repeatedly commit one after the other.
(logic/run* [ ?end ?authorA ?authorB]
(qwal/qwal graph root ?end 
(qwal/q=>*) ;;skip an arbitrary number of versions
(qwal/qtimes 2 ;;the following has to succeed at least 2 times
;;we use in-git-info instead of in-source-code as we only need meta-data, for which we dont have to checkout the version
(logic/== ?authorA (author curr)))
(logic/== ?authorB (author curr))
(logic/!= ?authorA ?authorB)) ;;ensure both authors are different
The query itself is not that difficult. We begin in the root version of our project. We skip an arbitrary number of versions, as we do not know where the collaboration may be. After skipping some versions, we look for a pattern that has to hold a number of times using the qtimes operator. The pattern binds the author of the current version to ?authorA, transitions to the next version and binds that author to ?authorB. We also ensure that both authors are different. Finally we transition to the next version.
Examples can be found in the experiments and demo folder. The two files you want to take a look at are selenium.clj and icsme-selenium.clj.
The source code and installation instructions can be found on github.