# Graql 2.0.0-alpha
---
## Public API changes and new features
The following changes impact how you use Graql and may require you to make changes if you migrate from 1.8.4 or earlier.
### 1) Concept ID
- Renamed `id` to `iid`, and thus the literal `id` is now free for user to use in their schema
- Only data (`thing`s) can be referred to by their `iid` now. Schema (`type`s) can only be referred to using their `label`.
- Changed regex of concept IIDs from: `('V'|'E')[a-z0-9-]* ;` (alpha numeric string starting with `V` or `E`) to `'0x'[0-9a-f]+` (a hexadecimal string).
Example: Instead of saying `match $x id V123; get $x;` you now say `match $x iid 0x04fa523; get $x;`.
> **Note that we continue to discourage you in using Concept `iid`.**
> The purpose of an `iid` is as an *"internal identifier"* that the server uses under-the-hood to refer to concepts. This was prematurely exposed in the earlier versions of Grakn. Referring to Concept `iid` is officially dangerous now: the `iid` of a concept before and after being committed to the database are different. So if you hold onto an `iid` of a concept you've just written to the database before you commit it, and try to use it to query the concept after it has been committed, it will not be a valid `iid`. If you would like to refer to a thing uniquely, you **must** declare a `@key` attribute for that thing, as a "primary key" to uniquely refer to the concept.
### 2) Attribute ownership in the schema
- Replaced `has` keyword in Type Variable properties, with `owns`
- Replace `key` keyword with a `@key` annotation that follows `has <type>`
For example, where previously you would write:
```graql
define
person sub entity,
key email,
has name;
```
You now write:
```graql
define
person sub entity,
owns email @key,
owns name;
```
To add or remove a `@key` annotation, re-define the ownership with or without it. For example, to set `email` to not be a `@key`, do:
```
define person owns email;
```
Note that the `has` keyword for `thing` variables remains unchanged. You still write:
```graql
match $x isa person, has name $name;
```
### 3) Roles are now scoped by their relations
Roles are now scoped by their relations, such that they will only be uniquely identifiable by `relation:role`. Previously, names of Role Types are globally unique. Now, that's no longer true. Role Types only need to be unique in the scope of their relation, and the relation they extend/inherit. This simplifies the effort of naming role types considerably. Thus, in order to refer to roles that a `thing` could `play`, we now refer to played roles as `relation:role`.
For example, previously we would say:
```
define
task sub entity,
plays dependency_dependee,
plays dependency_dependant;
dependency sub relation,
relates dependency_dependee,
relates dependency_dependant;
```
Now you can say:
```
define
task sub entity,
plays dependency:dependee,
plays dependency:dependant;
dependency sub relation,
relates dependee,
relates dependant;
```
### 4) Roles are inherited in a relation hierarchy
Previously, one had to "redeclare" a role type that they would like to inherit in a subtyping relation hierarchy. For example:
```graql
define
parenthood sub relation,
relates parenthood_parent,
relates parenthood_child;
motherhood sub parenthood,
relates parenthood_mother as parenthood_parent,
relates parenthood_child;
```
Now you no longer need to redeclare the `parenthood_child` roletype in the subtyping relation type `motherhood`. You can simply say the following and achieve the same goal (where `motherhood` also relates a `child`):
```graql
define
parenthood sub relation,
relates parent,
relates child;
motherhood sub parenthood,
relates mother as parent;
```
ps: you also don't need the `parenthood_` prefix on the role types because they are now scoped by their relation types.
### 5) Overriding attribute and role types
- override inherited attribute types by defining `has <type> as <inherted type>`
- override inherited played role types by defining `plays <type> as <inhierted type>`
- override inherited related role types by defining `relates <type> as <inherited type>`
The first two are new, and they do not clash with previous grammar. Previously, we were not able to override an inherited owned attribute or played role type. Now we can. Here's an example of all three usages:
```graql
define
company sub entity, has company-name;
charity sub company, has charity-name as company-name;
person sub entity, plays parentship:parent;
man sub person, plays fathership:father as parent;
parentship sub relation, relates parent;
fathership sub parentship, relates father as parent;
```
Once a type is overridden using `as`, the override type is no longer available. So in the above example, a `charity` can no longer own any instances of `company-name`, and only own `charity-name`.
### 6) Rule definition syntax
Rule definition no longer follows concept `type` definition syntax using `sub`. Rules now have their own syntax to be defined and undefined.
To `define` a rule, you now say:
```graql
define
rule transitive-ownership:
when {
(owned: $x, owner: $y) isa ownership;
(owned: $y, owner: $z) isa ownership;
} then {
(owned: $x, owner: $z) isa ownership;
};
```
To `undefine` a rule, you now say:
```graql
undefine
rule transitive-ownership;
```
### 7) Permitted Rule Semantics
Rules have been streamlined to produce consistent logical semantics: a rule can now only infer a full "fact".
Option 1: a rule inferring a new relation
```
rule transitive-ownership:
when {
(owned: $x, owner: $y) isa ownership;
(owned: $y, owner: $z) isa ownership;
} then {
(owned: $x, owner: $z) isa ownership;
};
```
Option 2: a rule can add an ownership between an existing concept and existing attribute
```
rule user-has-group-permissions:
when {
$x isa user; $g isa group, has permission-level $p;
(member: $x, member-of: $g) isa group-membership;
} then {
$x has $p;
}
```
Option 3: a rule can add an ownership of a potentially new attribute
```
rule voting-age-requirement:
when {
$x isa person, has age >= 18;
} then {
$x has may-vote true;
}
```
We **no longer permit** a rule to add new role players to an existing relation:
```
rule add-mutual-friend:
when {
$r ($x) isa friendship; $x isa person;
$r2 ($x, $y) isa friendship; $r2 != $r
} then {
$r (friend: $y) isa friendship;
}
```
We also **no longer permit** a rule to copy an attribute value (Note that this feature will be reintroduced with arithmetic in a later version of Grakn):
```
rule copy-id:
when {
$x has government-id $id;
} then {
$x has company-id $id;
}
```
Rules now have more flexibility in using variables for defining new relations:
```
rule binary-to-ternary-relations:
when {
$r ($rol: $x, $rol: $y) isa $rel;
$r2 ($rol: $x, $rol: $z) isa $rel;
} then {
($rol: $x, $rol: $y, $rol: $z) isa $rel;
}
```
Finally, on negation in rules: this is currently **not ready** for 2.0.0 release, so you won't be able to write negations in rules. However, we are planning to bring it back as soon as 2.1, and we will be permitting **multiple** negation blocks in the `when` clause of a rule, rather than just one.
```
rule person-not-in-any-marriage:
when {
$x isa person;
not { (husband: $x) isa marriage; };
not { (wife: $x) isa marriage; };
} then {
(unmarried: $x) isa not-married;
}
```
### 8) Concept equality, replacing concept inequality
We would like to streamline the attribute value constraints to be more consistent. Right now, `>`, `<`, `>=`, and`<=`, all operate on *"attribute values"*. However, `!=` operates on *"concept equality"*. And thus to evaluate *"attribute value equality"* and *"inequality"*, we must use `==` and `!==`. This was very inelegant and thus was error-prone as they were very close to `=` and `!=`. This behaviour was also inelegant for another reason: that it introduced a second way to do *"negation"*, other than through our `not` logical operator. This issue has also been raised through issue [#167](https://github.com/graknlabs/graql/issues/167).
Our conclusion is to remove *"concept inequality"* constraint (`!=`), and introduce new constraint operator: `is`. `is` would allow us to assert that 2 concepts are equal: `$x is $y`, which we can then negate by doing `not { $x is $y };` if we so wish to restrict them to not be equal to each other.
For example, previously this would be a valid query:
```graql
match
$c isa company; $x isa person; $y isa person;
(employer: $c, employee: $x) isa employment;
(employer: $c, employee: $y) isa employment;
$x != $y;
get $x, $y;
```
Now, to achieve the same goal as the above, you would write:
```graql
match
$c isa company; $x isa person; $y isa person;
(employer: $c, employee: $x) isa employment;
(employer: $c, employee: $y) isa employment;
not {$x is $y};
get $x, $y;
```
### 9) Attribute Value equality and inequality operators
Given the change on concept equality/inequality describe above, we can now use `=` and `!=` as *"attribute equality"* and *"attribute inequality"*, as opposed to using `==` and `!==`. Now all "math operators" (`=`, `!=` , `>`, `<`, `>=`, and`<=`) strictly only apply to attributes.
### 10) Get Query is now Match Query
In the codebase, we've renamed "Get Query" to be "Match Query". However, the implication of that at the user level is only very subtle: `get ...;` is now merely a filter on `match ...;`. Which means, match query `no longer needs` to be ended with `get;` all the time.
Where you previously would write:
```graql
match $x isa thing, has name $n; get;
```
You can now simply write:
```graql
match $x isa thing, has name $n;
```
In fact, if you end the query with `get;` (without any variables), an exception will be thrown as it is no longer a valid query. `get` is still available for use, but only if you would like to *"filter"* the results to a set of variables. For example, if you only want to get the `name` from the above query, you would write:
```graql
match $x isa thing, has name $n; get $n;
```
### 11) Graql `parse()` method renamed
Where you previously would write:
```java
Graql.parse(query)
```
You now write
```
Graql.parseQuery(query)
```
---
## Internal data structure & refactoring changes
The following change **do not** impact how you use Graql in your application, but **may** impact the impact the implementations of Graql plugins.
### 1) Semicolons
The grammar and parser has changed how it recognises semicolons, but they are still to be written the same way by the user. Semicolons previously were owned by the rule that it superseded. For example, `statement_thing` always need to end with `;`. However, now, `;` is no longer part of `statement_thing`, but expected to be provided to `delimit` multiple `statement_thing` when given in repetition. So effectively no change for the user.
### 2) Statements vs Variables, and Property vs Constraints
Previously, Graql's data structure was revolving around a `statement` which is basically a collection of `property`s on a given `variable`. We've changed that now, such that `variable`s are the first-class citizen of Graql query, and a `variable` may hold onto multiple `property`s (which are now called `constraint`s). A `constraint` in turn may refer to another `variable`. This gives a much more natural data structure for Graql to describe the query that it represents.
### 3) Numeric value types
Replaced all terminology of `INTEGER`, `FLOAT`, and `REAL`, and with only `LONG` and `DOUBLE`. In the context of the grammar, we simply renamed the tokens `INTEGER_`, `FLOAT_` and `REAL_` to `LONG_` and `DOUBLE_`.
### 4) Normal Forms
We've refactored Graql `pattern` data structures to have clean and consistent "normal forms". A `conjunction` or `disjunction` will have a *"[disjunctive normal form](https://en.wikipedia.org/wiki/Disjunctivenormalform)"*, where a disjunction holds a set of conjunctions, and each member of the conjunction (i.e. "conjunctable") can either be a `variable` or `negation`. A `variable` is always already in its normal form, but a negation will contain another "nested" pattern which itself will have a *"disjunctive normal form"*.