Skip to content

Commit a3d4a9f

Browse files
authored
Range queries (#40)
Implements range queries (e.g., `5..6 vertices`). Closes #20.
1 parent 5e6f004 commit a3d4a9f

File tree

10 files changed

+424
-213
lines changed

10 files changed

+424
-213
lines changed

README.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,17 @@ graphreveal search "10 edges, bipartite, no isolated vertices, 2 components"
3333
```
3434

3535
```shell
36-
graphreveal search --count "6 vertices, connected"
36+
graphreveal search --count "5..6 vertices, connected"
3737
```
3838

3939
Without `--count`, this command will print a list of graphs in [graph6](https://users.cecs.anu.edu.au/~bdm/data/formats.html) format. You can use [houseofgraphs.org](https://houseofgraphs.org/draw_graph) to visualize them.
4040

4141
### List of available properties
4242

43-
* [int] `vertices` (alternatives: `verts`,`V`, `nodes`)
44-
* [int] `edges` (alternative: `E`)
45-
* [int] `blocks` (alternative: `biconnected components`)
46-
* [int] `components` (alternative: `C`)
43+
* [N] `vertices` (alternatives: `verts`,`V`, `nodes`)
44+
* [N] `edges` (alternative: `E`)
45+
* [N] `blocks` (alternative: `biconnected components`)
46+
* [N] `components` (alternative: `C`)
4747
* `acyclic` (alternative: `forest`)
4848
* `bipartite`
4949
* `complete`
@@ -56,4 +56,5 @@ Without `--count`, this command will print a list of graphs in [graph6](https://
5656
* `regular`
5757
* `tree`
5858

59-
You can also negate these properties using `!` or `not`.
59+
As [N], you can use a simple number or range (e.g., `3-4`, `3..4`, `< 5`, `>= 2`).
60+
You can also negate any property using `!` or `not`.

src/graphreveal/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from platformdirs import user_data_dir
55

6-
__version__ = "0.2.2"
6+
__version__ = "0.3.0"
77

88
DATABASE_PATH = os.path.join(
99
user_data_dir(appname="graphreveal", appauthor="graphreveal"), "graphs.db"

src/graphreveal/translator/QueryLexer.g4

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ SEPERATOR: ',' | ';';
1313

1414
NOT: 'not' | '!';
1515

16+
LESS : '<';
17+
GREATER : '>';
18+
LESS_OR_EQUAL : '<=';
19+
GREATER_OR_EQUAL : '>=';
20+
RANGE_OPERATOR : '..' | '-';
21+
1622
VERTEX : 'vertex' | 'vertices' | 'vertexes' | 'verts' | 'V' | 'node' | 'nodes';
1723
EDGE : 'edge' | 'edges' | 'E';
1824
BLOCK:

src/graphreveal/translator/QueryParser.g4

+11-6
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,19 @@ query
1313
;
1414

1515
expr
16-
: numEntityProperty # simpleExpr
17-
| boolProperty # simpleExpr
18-
| NOT numEntityProperty # notExpr
19-
| NOT boolProperty # notExpr
16+
: entityProperty # simpleExpr
17+
| boolProperty # simpleExpr
18+
| NOT entityProperty # notExpr
19+
| NOT boolProperty # notExpr
2020
;
2121

22-
numEntityProperty
23-
: INTEGER entity
22+
entityProperty
23+
: INTEGER entity # numEntityProperty
24+
| op = LESS INTEGER entity # halfOpenRange
25+
| op = GREATER INTEGER entity # halfOpenRange
26+
| op = LESS_OR_EQUAL INTEGER entity # halfOpenRange
27+
| op = GREATER_OR_EQUAL INTEGER entity # halfOpenRange
28+
| INTEGER RANGE_OPERATOR INTEGER entity # closedRange
2429
;
2530

2631
entity

src/graphreveal/translator/QueryTranslator.py

+17
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,23 @@ def visitNumEntityProperty(self, ctx: QueryParser.NumEntityPropertyContext):
3939
entity = self.visit(ctx.entity())
4040
return NUM_ENTITY_PROPERTY_MAP[entity] + " = " + num
4141

42+
def visitHalfOpenRange(self, ctx: QueryParser.HalfOpenRangeContext):
43+
num = ctx.INTEGER().getText()
44+
entity = self.visit(ctx.entity())
45+
operator = {
46+
QueryParser.LESS: "<",
47+
QueryParser.GREATER: ">",
48+
QueryParser.LESS_OR_EQUAL: "<=",
49+
QueryParser.GREATER_OR_EQUAL: ">=",
50+
}[ctx.op.type]
51+
return NUM_ENTITY_PROPERTY_MAP[entity] + f" {operator} {num}"
52+
53+
def visitClosedRange(self, ctx: QueryParser.ClosedRangeContext):
54+
num_1 = ctx.INTEGER(0).getText()
55+
num_2 = ctx.INTEGER(1).getText()
56+
entity = self.visit(ctx.entity())
57+
return NUM_ENTITY_PROPERTY_MAP[entity] + " BETWEEN " + num_1 + " AND " + num_2
58+
4259
def visitEntity(self, ctx: QueryParser.EntityContext):
4360
return ctx.getChild(0).symbol.type
4461

src/graphreveal/translator/generated/QueryLexer.py

+161-143
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)