User Tools

Site Tools


tutorials:xl-queries-and-operators

XL queries and operators

Queries

Graph queries are used to analyse the actual structure (graph), which can be for example a plant structure.

In XL, queries are enclosed in asterixed parentheses (* *).

The elements in a query are given in their expected order, e.g. (* A A B *) searches for a subgraph which consists of a sequence of nodes of the types A A B, connected by successor edges.

To try out how queries work, we first create a simple plant model.

Test model

module Bud extends Sphere(0.1).(setShader(GREEN));
 
module Internode(int age, super.length) extends Cylinder(length, 0.1).(setShader(YELLOW));
 
module Leaf(int age, super.length, double width) extends Parallelogram(length, width).(setShader(GREEN)) 
{
    double area;
 
    { setArea(); }
 
    void setArea() {
        area = length*width;
    }
}
 
protected void init()
[
    Axiom ==> Bud;
]
 
public void run()
[
    Bud ==> 
        Internode(1, 1) 
        [RL(60) Leaf(1, 1, 1)] 
        RH(180)
        Bud
    ;
 
    i:Internode ::> { i[age]++; i[length] += 1; }
    l:Leaf ::> { l[age]++; l[length] += 1; l.setArea(); }
]

We create a new method called analyse(). The method will appear as a new button in the RGG toolbar. Before running the analyse() method, press the Reset button in the RGG Toolbar, to reset the graph structure. Inside this method, we first call the run() method for 3 steps. The result is a simple plant made of 3 internodes and 3 leaves.

public void analyse()
{
    for (apply(3)) { run(); }
 
    println("add here a query example");
}

The underlying 2d graph of the generated structure given below:

Beginning from RGGRoot, we have the sequence of three Internodes where to each is a Leaf linked by a branching edge. The last internode, additionally, has a Bud node successor.

Query examples

Replace the text (in red) inside the println() one by one by the queries below.

Below each query, there is a result of the print command, for illustration. Note, that the ids will differ with different model execution.

  • Find all the internodes in the structure:
(* Internode *)

The query will return ids of all the internodes in the plant structure.

answer

answer

Model.Internode[id=1911]@ecc95fb

Model.Internode[id=1906]@7b431a06

Model.Internode[id=1901]@5753e950

Note:

Internode with the id=1901 is the first internode from the bottom (with the highest age: 3).

Internode with the id=1911 is the top internode (with the lowest age: 1)

Notice, that when you click with a mouse on an internode in the 3D View window, information about the selected internode will be displayed in the Attribute Editor. In the Attribute Editor, you can check the internode id (e.g. Model$Internode [Internode.1756]) and compare it with the one that was printed in the XL Console. Another option is to look at the node ids in the 2D Graph (Panels → 2D → Graph, in the graph window: View → Redraw).

  • Find all newly created internode(s), with age == 1:
(* i:Internode, (i[age] == 1) *)

answer

answer

Model.Internode[id=1911]@ecc95fb

  • Find the internode below the bud:

(* Bud < RH < Internode *)

< represents a successor edge in the indicated direction

answer

answer

Model.Internode[id=1911]@ecc95fb

  • Find all leaves connected to an internode:
(* Internode +> RL > Leaf *)

This is just to illustrate how to define different edge types inside a query. +> represents a branch edge.

answer

answer

Model.Leaf[id=1913]@4b0f7bd

Model.Leaf[id=1908]@1c6dbfa5

Model.Leaf[id=1903]@668c1f97

Note: Leaf with the id=1903 is the first (and the oldest) leaf, leaf with the id=1913 is the last (and the yongest) leaf.

Aggregators

Aggregate operations are used to collect multiple values when traversing the graph structure and return a single value.

Standard aggregate operations are: count, sum, empty, exist, forall, first, last, max, min, mean, selectRandomly, selectWhereMin, selectWhereMax, …

  • Count all leaves:
count((* Leaf *))

answer

answer

3

  • Sum up the area of all leaves:
sum((* Leaf *)[area])

answer

answer

6.0

  • Sum up the length of internodes:
sum((* Internode *)[length])

answer

answer

6.0

In this particular example with internodes forming (only) the main stem, the query will return stem length.

  • Select the leaf with the highest leaf area:
selectWhereMax((* l:Leaf *), (l[area]))

answer

answer

Model.Leaf[id=1903]@668c1f97

  • Count internodes that are older than 2 (time units):
count((* i:Internode, (i[age] >= 2) *))

answer

answer

2

tutorials/xl-queries-and-operators.txt · Last modified: 2024/12/11 12:52 by MH