FunnyQT is a model querying and transformation library. It currently supports the Java Graph Laboratory and the Eclipse Modeling Framework.
News: The FunnyQT book (my dissertation) is now available in a dead-tree version or as gratis Open Access version, see here.
Check out the overview description, my dissertation, the generated API documentation, and the papers about FunnyQT.
The FunnyQT API is structured into the following sub-APIs realized in several namespaces.
The foundation is an extensive core API providing typical model management services such as creating, loading, and storing models, accessing, creating, and deleting model elements, and accessing model element properties. The core API is subdivided into two framework-specific namespaces (EMF or JGraLab) and one namespace providing functions working with either kind of model representation.
- funnyqt.emf: The EMF-specific core API
- funnyqt.tg: The TGraph-specific core API (JGraLab)
- funnyqt.generic: Core functions working with both kinds of models/model elements, and protocols extended on EMF and JGraLab interfaces
The functional querying API builds upon the core API and provides features such as navigation inside models in terms of role names, quantified expressions, and regular path expressions. Like the core API, some framework-specific parts are outsourced into their own two querying namespaces.
- funnyqt.query: Generic querying services such as quantified expressions, sorting functions, and generic regular path operators.
- funnyqt.query.emf: EMF-specific regular path operators
- funnyqt.query.tg: TGraph-specific regular path operators
FunnyQT's polymorphic function API provides constructs for defining functions dispatching on metamodel type.
- funnyqt.polyfns: Polymorphic function API
The pattern-matching API provides constructs for defining patterns using node and edge symbols. When a pattern is called on some model, it returns a lazy sequence of all matches in the model.
- funnyqt.pmatch: Pattern-matching in models
Based on the pattern-matching API, there's a in-place transformation API that allows to define rules consisting of a pattern and a sequence of actions. When a rule is invoked, it searches for a match in the model and applies its actions to it. Typical control structures such as as-long-as-possible application of a rule are provided as higher-order functions.
- funnyqt.in-place: In-place transformations and state-space exploration
FunnyQT provides two kinds of model transformation APIs. The extensional model transformation API builds upon GReTL's concepts of extensional semantics and is an operational transformation API, whereas the model2model API realizes a rule-based approach to model transformations.
- funnyqt.extensional: Extensional model transformation API
- funnyqt.model2model: The rule-based model transformation API
The relational querying API allows for Prolog-like logical querying of models using the core.logic library.
- funnyqt.relational: Generic relations for elements, relationships, attributes, and references
Based on the relational querying API, there's a bidirectional transformation API.
- funnyqt.bidi: Bidirectional model transformations
Such a transformation specifies correspondences between a left and a right model in terms of relations between elements in those models. Such a transformation can be used to generate a new right model from a given left model and vice versa. Additionally, it can be used to synchronize between two existing models in either direction.
For TGraphs, there is a co-evolution transformation API.
- funnyqt.coevo.tg: Co-evolution transformations
Co-evolution transformations allow to evolve a schema and a conforming graph simultaneously at runtime.
Finally, there are some utility and helper APIs.
- funnyqt.utils: Generic utility functions
- funnyqt.visualization: Visualizing models using GraphViz
- funnyqt.xmltg: Converting arbitrary XML documents to DOM-like TGraphs and back again
- funnyqt.edn: Persistence of model-related data in the EDN format.
My dissertation A Functional, Comprehensive and Extensible Multi-Platform Querying and Transformation Approach discusses any aspect of FunnyQT (version 1.0.x) in detail with examples and motivations. You can buy the book here:
- Directly at the publisher Logos Verlag Berlin GmbH
- From Amazon
Alternatively, the electronic Open Access version (CC BY-NC 3.0 DE) of the book is also available (gratis!) from several sources.
The FunnyQT API docs generated for the current release are here.
-
Model Querying with FunnyQT, Tassilo Horn, ICMT 2013, http://dx.doi.org/10.1007/978-3-642-38883-5_7
-
Solving the TTC 2013 Flowgraphs Case with FunnyQT, Tassilo Horn, TTC 2013, http://dx.doi.org/10.4204/EPTCS.135.7
-
Solving the Class Diagram Restructuring Transformation Case with FunnyQT, Tassilo Horn, TTC 2013, http://dx.doi.org/10.4204/EPTCS.135.9
-
Solving the Petri-Nets to Statecharts Transformation Case with FunnyQT, Tassilo Horn, TTC 2013, http://dx.doi.org/10.4204/EPTCS.135.11
-
Bidirectional Model Transformations With FunnyQT, Tassilo Horn, rejected at both BX'14 and ICMT'14, but I consider it to be my best paper so far anyway (and the only one about FunnyQT bidirectional transformations), http://userpages.uni-koblenz.de/~horn/mypapers/funnyqt-bidi2014.pdf
-
Solving the TTC Movie Database Case with FunnyQT, Tassilo Horn, TTC 2014
-
Solving the TTC FIXML Case with FunnyQT, Tassilo Horn, TTC 2014
-
Solving the TTC Model Execution Case with FunnyQT, Tassilo Horn, TTC 2015
-
Solving the TTC Java Refactoring Case with FunnyQT, Tassilo Horn, TTC 2015
-
Solving the TTC Train Benchmark Case with FunnyQT, Tassilo Horn, TTC 2015
-
Graph Pattern Matching as an Embedded Clojure DSL, Tassilo Horn, ICGT 2015
There are two ways of getting FunnyQT. When you want to use it for writing your own queries and transformations, you should get the latest release available with Leiningen. If you want to have the bleeding edge version from git, e.g., to validate that some bug has been fixed, see how to get the git version.
If you don't intend to hack on FunnyQT itself but you just want to use it for writing queries and transformations, the easiest possibility is to use the latest FunnyQT release that's available via the Clojars Maven repository.
To create query/transformation project using FunnyQT, simply perform the following steps:
-
Install the
lein
shell (or bat) script as explained on the Leiningen homepage. -
Create a new project.
$ lein new my-funnyqt-transform
Generating a project called my-funnyqt-transform based on the 'default' template.
To see other templates (app, lein plugin, etc), try `lein help new`.
- Declare that your project depends on FunnyQT. Replace 0.42.0 below with whatever is the the current FunnyQT release.
$ cd my-funnyqt-transform
$ edit project.clj
# add funnyqt in the project :dependencies
(defproject my-funnyqt-transform "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:dependencies [ [funnyqt "1.0.6"] ])
- Now start a REPL and start hacking. Leiningen will take care of fetching all dependencies such as Clojure and FunnyQT.
$ lein repl
Welcome to FunnyQT!
nREPL server started on port 38865 on host 127.0.0.1 - nrepl://127.0.0.1:38865
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
OpenJDK 64-Bit Server VM 1.8.0_121-b13
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=>
FunnyQT uses Leiningen for retrieving all its dependencies from various Maven repositories, building, publishing, and test automation.
Getting started is really simple:
-
Install the
lein
shell (or bat) script as explained on the Leiningen homepage. -
Clone the FunnyQT git repository:
$ git clone https://github.com/jgralab/funnyqt.git
- Just to be sure everything's fine, you might want to execute the test cases.
$ cd funnyqt
$ lein test
- You are ready to go. Start a REPL and start hacking.
$ lein repl
# ...some output omitted...
user=> (use 'funnyqt.tg)
nil
user=> (def g (load-graph "test/input/greqltestgraph.tg"))
#<Graph c06de1c7-f4ec0906-21cfbc86-28c31aa1 (1175): RouteMap>>
user=> (vseq g 'localities.City)
(#<v6: localities.City> #<v7: localities.City> #<v8: localities.City>)
FunnyQT is developed by Tassilo Horn (tsdh). If you want, you can get in touch with me via email, IRC, Gitter, or G+.
Join us on the official JGraLab IRC Channel
(channel #jgralab
on irc.freenode.net
). If you don't have or don't want to
install an IRC client, you can also
chat directly in your browser.
FunnyQT also has a Gitter channel: .
If I'm not around, just ask your question and come back later. I'll reply as soon as I can.
Although that should be quite impossible and is surely an error on your side
>:)
, if you found a bug or miss an important feature, file a bug report in
the FunnyQT issue tracker.
Copyright (C) 2011-2017 Tassilo Horn [email protected] & The JGraLab Team [email protected]
Distributed under the General Public License, Version 3 with the following additional grant:
Additional permission under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or combining it
with Eclipse (or a modified version of that program or an Eclipse plugin),
containing parts covered by the terms of the Eclipse Public License (EPL),
the licensors of this Program grant you additional permission to convey the
resulting work. Corresponding Source for a non-source form of such a
combination shall include the source code for the parts of JGraLab used as
well as that of the covered work.