diff --git a/behaviour/graql/language/BUILD b/behaviour/graql/language/BUILD
index eb9bf181..19813fd3 100644
--- a/behaviour/graql/language/BUILD
+++ b/behaviour/graql/language/BUILD
@@ -24,5 +24,6 @@ exports_files([
"get.feature",
"insert.feature",
"match.feature",
+ "rule-validation.feature",
"undefine.feature",
])
diff --git a/behaviour/graql/language/define.feature b/behaviour/graql/language/define.feature
index 263df98b..2f75bf28 100644
--- a/behaviour/graql/language/define.feature
+++ b/behaviour/graql/language/define.feature
@@ -1253,6 +1253,8 @@ Feature: Graql Define Query
# RULES #
#########
+ # Note: These tests verify only the ability to create rules, and are not concerned with their application.
+
Scenario: a rule can infer both an attribute and its ownership
Given graql define
"""
@@ -1281,7 +1283,7 @@ Feature: Graql Define Query
| RUL |
- Scenario: a rule can infer a relation
+ Scenario: when defining a rule using `sub rule`, the rule is successfully created
Given graql define
"""
define
diff --git a/behaviour/graql/language/insert.feature b/behaviour/graql/language/insert.feature
index e8a3fe11..5c821fe7 100644
--- a/behaviour/graql/language/insert.feature
+++ b/behaviour/graql/language/insert.feature
@@ -1427,6 +1427,43 @@ Feature: Graql Insert Query
| MIC | TAR |
+ Scenario: match-insert can take an attribute's value and copy it to an attribute of a different type
+ Given graql define
+ """
+ define
+ height sub attribute, value long;
+ person has height;
+ """
+ Given graql insert
+ """
+ insert
+ $x isa person, has name "Susie", has age 16, has ref 0;
+ $y isa person, has name "Donald", has age 25, has ref 1;
+ $z isa person, has name "Ralph", has age 18, has ref 2;
+ """
+ Given the integrity is validated
+ Given graql insert
+ """
+ match
+ $x isa person, has age 16;
+ insert
+ $x has height 16;
+ """
+ Given the integrity is validated
+ When get answers of graql query
+ """
+ match
+ $x has height $z;
+ get $x;
+ """
+ And concept identifiers are
+ | | check | value |
+ | SUS | key | ref:0 |
+ Then uniquely identify answer concepts
+ | x |
+ | SUS |
+
+
Scenario: if match-insert matches nothing, then nothing is inserted
Given graql define
"""
diff --git a/behaviour/graql/language/match.feature b/behaviour/graql/language/match.feature
index dcdac0d8..91e53e43 100644
--- a/behaviour/graql/language/match.feature
+++ b/behaviour/graql/language/match.feature
@@ -746,6 +746,75 @@ Feature: Graql Match Clause
| REF0 | REF1 |
+ Scenario: relations between distinct concepts are not retrieved when matching concepts that relate to themselves
+ Given graql insert
+ """
+ insert
+ $x isa person, has ref 1;
+ $y isa person, has ref 2;
+ (friend: $x, friend: $y) isa friendship, has ref 0;
+ """
+ Given the integrity is validated
+ When get answers of graql query
+ """
+ match (friend: $x, friend: $x) isa friendship; get;
+ """
+ Then answer size is: 0
+
+
+ Scenario: matching a chain of relations only returns answers if there is a chain of the required length
+ Given graql define
+ """
+ define
+
+ gift-delivery sub relation,
+ relates sender,
+ relates recipient;
+
+ person plays sender,
+ plays recipient;
+ """
+ Given the integrity is validated
+ Given graql insert
+ """
+ insert
+ $x1 isa person, has name "Soroush", has ref 0;
+ $x2a isa person, has name "Martha", has ref 1;
+ $x2b isa person, has name "Patricia", has ref 2;
+ $x2c isa person, has name "Lily", has ref 3;
+
+ (sender: $x1, recipient: $x2a) isa gift-delivery;
+ (sender: $x1, recipient: $x2b) isa gift-delivery;
+ (sender: $x1, recipient: $x2c) isa gift-delivery;
+ (sender: $x2a, recipient: $x2b) isa gift-delivery;
+ """
+ Given the integrity is validated
+ When get answers of graql query
+ """
+ match
+ (sender: $a, recipient: $b) isa gift-delivery;
+ (sender: $b, recipient: $c) isa gift-delivery;
+ get;
+ """
+ When concept identifiers are
+ | | check | value |
+ | SOR | key | ref:0 |
+ | MAR | key | ref:1 |
+ | PAT | key | ref:2 |
+ Then uniquely identify answer concepts
+ | a | b | c |
+ | SOR | MAR | PAT |
+ When get answers of graql query
+ """
+ match
+ (sender: $a, recipient: $b) isa gift-delivery;
+ (sender: $b, recipient: $c) isa gift-delivery;
+ (sender: $c, recipient: $d) isa gift-delivery;
+ get;
+ """
+ Then answer size is: 0
+
+
Scenario: an error is thrown when matching an entity type as if it were a role
Then graql get throws
"""
@@ -1308,14 +1377,43 @@ Feature: Graql Match Clause
| PER |
- Scenario: value comparison of unbound variables throws an error
+ @ignore
+ # TODO: re-enable when variables used in multiple value predicates are resolvable (grakn#5845)
+ Scenario: an attribute variable used in both `==` and `>=` predicates is correctly resolved
+ Given graql insert
+ """
+ insert
+ $x isa person, has name "Susie", has age 16, has ref 0;
+ $y isa person, has name "Donald", has age 25, has ref 1;
+ $z isa person, has name "Ralph", has age 18, has ref 2;
+ """
+ Given the integrity is validated
+ When get answers of graql query
+ """
+ match
+ $x has age == $z;
+ $z >= 17;
+ $z isa age;
+ get $x;
+ """
+ And concept identifiers are
+ | | check | value |
+ | DON | key | ref:1 |
+ | RAL | key | ref:2 |
+ Then uniquely identify answer concepts
+ | x |
+ | DON |
+ | RAL |
+
+
+ Scenario: concept comparison of unbound variables throws an error
Then graql get throws
"""
match $x != $y; get;
"""
- Scenario: concept comparison of unbound variables throws an error
+ Scenario: value comparison of unbound variables throws an error
Then graql get throws
"""
match $x !== $y; get;
diff --git a/behaviour/graql/reasoner/rule-validation.feature b/behaviour/graql/language/rule-validation.feature
similarity index 98%
rename from behaviour/graql/reasoner/rule-validation.feature
rename to behaviour/graql/language/rule-validation.feature
index f2f7a42c..f9129165 100644
--- a/behaviour/graql/reasoner/rule-validation.feature
+++ b/behaviour/graql/language/rule-validation.feature
@@ -15,7 +15,7 @@
# along with this program. If not, see .
#
-Feature: Graql Reasoner Rule Validation
+Feature: Graql Rule Validation
Background: Initialise a session and transaction for each scenario
Given connection has been opened
diff --git a/behaviour/graql/reasoner/BUILD b/behaviour/graql/reasoner/BUILD
index 5a77bb68..e111e635 100644
--- a/behaviour/graql/reasoner/BUILD
+++ b/behaviour/graql/reasoner/BUILD
@@ -18,6 +18,14 @@
package(default_visibility = ["//visibility:public"])
exports_files([
- "resolution.feature",
- "rule-validation.feature",
+ "attribute-attachment.feature",
+ "concept-inequality.feature",
+ "negation.feature",
+ "relation-inference.feature",
+ "roleplayer-attachment.feature",
+ "resolution-test-framework.feature",
+ "type-generation.feature",
+ "type-hierarchy.feature",
+ "value-predicate.feature",
+ "variable-roles.feature",
])
\ No newline at end of file
diff --git a/behaviour/graql/reasoner/resolution/attribute-attachment.feature b/behaviour/graql/reasoner/attribute-attachment.feature
similarity index 100%
rename from behaviour/graql/reasoner/resolution/attribute-attachment.feature
rename to behaviour/graql/reasoner/attribute-attachment.feature
diff --git a/behaviour/graql/reasoner/resolution/concept-inequality.feature b/behaviour/graql/reasoner/concept-inequality.feature
similarity index 76%
rename from behaviour/graql/reasoner/resolution/concept-inequality.feature
rename to behaviour/graql/reasoner/concept-inequality.feature
index 091ece0a..7e83b123 100644
--- a/behaviour/graql/reasoner/resolution/concept-inequality.feature
+++ b/behaviour/graql/reasoner/concept-inequality.feature
@@ -31,6 +31,9 @@ Feature: Concept Inequality Resolution
"""
define
+ person sub entity,
+ has name;
+
ball sub entity,
has name,
plays ball1,
@@ -395,3 +398,128 @@ Feature: Concept Inequality Resolution
# Then all answers are correct in reasoned keyspace
Then answer size in reasoned keyspace is: 36
# Then materialised and reasoned keyspaces are the same size
+
+
+ @ignore
+ # TODO: re-enable once grakn#5821 is fixed (in some answers, $typeof_ax is 'base-attribute' which is incorrect)
+ # TODO: re-enable all steps once implicit attribute variables are resolvable
+ # TODO: migrate to concept-inequality.feature
+ Scenario: when restricting concept types of a pair of inferred attributes with `!=`, the answers have distinct types
+ Given for each session, graql define
+ """
+ define
+ soft-drink sub entity,
+ has name,
+ has retailer;
+ base-attribute sub attribute, value string, abstract;
+ string-attribute sub base-attribute;
+ name sub base-attribute;
+ retailer sub base-attribute;
+ person has string-attribute;
+
+ tesco-sells-all-soft-drinks sub rule,
+ when {
+ $x isa soft-drink;
+ },
+ then {
+ $x has retailer 'Tesco';
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person, has string-attribute "Tesco";
+ $y isa soft-drink, has name "Tesco";
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ $x has base-attribute $ax;
+ $y has base-attribute $ay;
+ $ax isa! $typeof_ax;
+ $ay isa! $typeof_ay;
+ $typeof_ax != $typeof_ay;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ # x | ax | y | ay |
+ # PER | STA | SOF | NAM |
+ # PER | STA | SOF | RET |
+ # SOF | NAM | PER | STA |
+ # SOF | RET | PER | STA |
+ # SOF | NAM | SOF | STA |
+ # SOF | STA | SOF | NAM |
+ Then answer size in reasoned keyspace is: 6
+ Then materialised and reasoned keyspaces are the same size
+
+ @ignore
+ # TODO: re-enable once grakn#5821 is fixed
+ # TODO: re-enable all steps once implicit attribute variables are resolvable
+ # TODO: migrate to concept-inequality.feature
+ Scenario: inferred attribute matches can be simultaneously restricted by both concept type and attribute value
+ Given for each session, graql define
+ """
+ define
+ soft-drink sub entity,
+ has name,
+ has retailer;
+ base-attribute sub attribute, value string, abstract;
+ string-attribute sub base-attribute;
+ retailer sub base-attribute;
+ person has string-attribute;
+
+ transfer-string-attribute-to-other-people sub rule,
+ when {
+ $x isa person, has string-attribute $r1;
+ $y isa person;
+ },
+ then {
+ $y has string-attribute $r1;
+ };
+
+ tesco-sells-all-soft-drinks sub rule,
+ when {
+ $x isa soft-drink;
+ },
+ then {
+ $x has retailer 'Tesco';
+ };
+
+ if-ocado-exists-it-sells-all-soft-drinks sub rule,
+ when {
+ $x isa retailer;
+ $x == 'Ocado';
+ $y isa soft-drink;
+ },
+ then {
+ $y has retailer $x;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $w isa person, has string-attribute "Ocado";
+ $x isa person, has string-attribute "Tesco";
+ $y isa soft-drink, has name "Sprite";
+ $z "Ocado" isa retailer;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ $x has base-attribute $value;
+ $y has base-attribute $unwantedValue;
+ $value !== $unwantedValue;
+ $unwantedValue "Ocado";
+ $value isa! $type;
+ $unwantedValue isa! $type;
+ $type != $unwantedType;
+ $unwantedType type string-attribute;
+ get $x, $value, $type;
+ """
+ Then all answers are correct in reasoned keyspace
+ # x | value | type |
+ # Sprite | Tesco | retailer |
+ Then answer size in reasoned keyspace is: 1
+# Then materialised and reasoned keyspaces are the same size
diff --git a/behaviour/graql/reasoner/negation.feature b/behaviour/graql/reasoner/negation.feature
new file mode 100644
index 00000000..7726e10d
--- /dev/null
+++ b/behaviour/graql/reasoner/negation.feature
@@ -0,0 +1,243 @@
+#
+# Copyright (C) 2020 Grakn Labs
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+Feature: Negation Resolution
+
+ Background: Set up keyspaces for resolution testing
+
+ Given connection has been opened
+ Given connection delete all keyspaces
+ Given connection open sessions for keyspaces:
+ | materialised |
+ | reasoned |
+ Given materialised keyspace is named: materialised
+ Given reasoned keyspace is named: reasoned
+ Given for each session, graql define
+ """
+ define
+
+ person sub entity,
+ has name,
+ plays friend,
+ plays employee;
+
+ company sub entity,
+ has name,
+ plays employer;
+
+ place sub entity,
+ has name,
+ plays location-subordinate,
+ plays location-superior;
+
+ friendship sub relation,
+ relates friend;
+
+ employment sub relation,
+ relates employee,
+ relates employer;
+
+ location-hierarchy sub relation,
+ relates location-subordinate,
+ relates location-superior;
+
+ name sub attribute, value string;
+ """
+
+
+ # TODO: re-enable when fixed (#75)
+ Scenario: a rule can be triggered based on not having a particular attribute
+ Given for each session, graql define
+ """
+ define
+ person has age;
+ age sub attribute, value long;
+ not-ten sub rule,
+ when {
+ $x isa person;
+ not { $x has age 10; };
+ }, then {
+ $x has name "Not Ten";
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person, has age 10;
+ $y isa person, has age 20;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match $x has name "Not Ten", has age 20; get;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then for graql query
+ """
+ match $x has name "Not Ten", has age 10; get;
+ """
+ Then answer size in reasoned keyspace is: 0
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: a negation with a roleplayer but no relation variable checks that no relations have that roleplayer
+ Given for each session, graql define
+ """
+ define
+ employment relates manager;
+ person plays manager;
+
+ apple-employs-everyone sub rule,
+ when {
+ $p isa person;
+ $c isa company, has name "Apple";
+ }, then {
+ (employee: $p, employer: $c) isa employment;
+ };
+
+ anna-manages-carol sub rule,
+ when {
+ $r (employee: $x) isa employment;
+ $x has name "Carol";
+ $y isa person, has name "Anna";
+ }, then {
+ $r (manager: $y) isa employment;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person, has name "Anna";
+ $y isa person, has name "Carol";
+ $z isa person, has name "Edward";
+ $c isa company, has name "Apple";
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ (employee: $x, employer: $y) isa employment;
+ not {(manager: $x) isa employment;};
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ # Anna is not retrieved because she is someone's manager
+ Then answer size in reasoned keyspace is: 2
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: a negation with a roleplayer and relation variable checks that the relation doesn't have that roleplayer
+ Given for each session, graql define
+ """
+ define
+ employment relates manager;
+ person plays manager;
+
+ apple-employs-everyone sub rule,
+ when {
+ $p isa person;
+ $c isa company, has name "Apple";
+ }, then {
+ (employee: $p, employer: $c) isa employment;
+ };
+
+ anna-manages-carol sub rule,
+ when {
+ $r (employee: $x) isa employment;
+ $x has name "Carol";
+ $y isa person, has name "Anna";
+ }, then {
+ $r (manager: $y) isa employment;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person, has name "Anna";
+ $y isa person, has name "Carol";
+ $z isa person, has name "Edward";
+ $c isa company, has name "Apple";
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ $r (employee: $x, employer: $y) isa employment;
+ not {$r (manager: $x) isa employment;};
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ # Anna is retrieved because she is not a manager in her own employee-employment relation
+ Then answer size in reasoned keyspace is: 3
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: a negation with unbound roleplayer variables checks that the relation doesn't have any player for that role
+ Given for each session, graql define
+ """
+ define
+ employment relates manager;
+ person plays manager;
+
+ apple-employs-everyone sub rule,
+ when {
+ $p isa person;
+ $c isa company, has name "Apple";
+ }, then {
+ (employee: $p, employer: $c) isa employment;
+ };
+
+ anna-manages-carol sub rule,
+ when {
+ $r (employee: $x) isa employment;
+ $x has name "Carol";
+ $y isa person, has name "Anna";
+ }, then {
+ $r (manager: $y) isa employment;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person, has name "Anna";
+ $y isa person, has name "Carol";
+ $z isa person, has name "Edward";
+ $c isa company, has name "Apple";
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ $r (employee: $x, employer: $y) isa employment;
+ not {$r (manager: $z) isa employment;};
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ # Carol is not retrieved because her employment relation has a manager
+ Then answer size in reasoned keyspace is: 2
+ Then for graql query
+ """
+ match
+ $r (employee: $x, employer: $y) isa employment;
+ not {$r (employee: $z, manager: $z) isa employment;};
+ get;
+ """
+ # Now the negation block is harder to fulfil. Carol is not her own manager, so she is retrieved again
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 3
+ Then materialised and reasoned keyspaces are the same size
diff --git a/behaviour/graql/reasoner/relation-inference.feature b/behaviour/graql/reasoner/relation-inference.feature
new file mode 100644
index 00000000..97c3d968
--- /dev/null
+++ b/behaviour/graql/reasoner/relation-inference.feature
@@ -0,0 +1,1305 @@
+#
+# Copyright (C) 2020 Grakn Labs
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+Feature: Relation Inference Resolution
+
+ Background: Set up keyspaces for resolution testing
+
+ Given connection has been opened
+ Given connection delete all keyspaces
+ Given connection open sessions for keyspaces:
+ | materialised |
+ | reasoned |
+ Given materialised keyspace is named: materialised
+ Given reasoned keyspace is named: reasoned
+ Given for each session, graql define
+ """
+ define
+
+ person sub entity,
+ has name,
+ plays friend,
+ plays employee;
+
+ company sub entity,
+ has name,
+ plays employer;
+
+ place sub entity,
+ has name,
+ plays location-subordinate,
+ plays location-superior;
+
+ friendship sub relation,
+ relates friend;
+
+ employment sub relation,
+ relates employee,
+ relates employer;
+
+ location-hierarchy sub relation,
+ relates location-subordinate,
+ relates location-superior;
+
+ name sub attribute, value string;
+ """
+
+
+ #######################
+ # BASIC FUNCTIONALITY #
+ #######################
+
+ Scenario: a relation can be inferred on all concepts of a given type
+ Given for each session, graql define
+ """
+ define
+ dog sub entity;
+ people-are-employed sub rule,
+ when {
+ $p isa person;
+ }, then {
+ (employee: $p) isa employment;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person;
+ $y isa dog;
+ $z isa person;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ $x isa person;
+ ($x) isa employment;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 2
+ Then for graql query
+ """
+ match
+ $x isa dog;
+ ($x) isa employment;
+ get;
+ """
+ Then answer size in reasoned keyspace is: 0
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: a relation can be inferred based on an attribute ownership
+ Given for each session, graql define
+ """
+ define
+ haikal-is-employed sub rule,
+ when {
+ $p has name "Haikal";
+ }, then {
+ (employee: $p) isa employment;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person, has name "Haikal";
+ $y isa person, has name "Michael";
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ $x has name "Haikal";
+ ($x) isa employment;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then for graql query
+ """
+ match
+ $x has name "Michael";
+ ($x) isa employment;
+ get;
+ """
+ Then answer size in reasoned keyspace is: 0
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: a rule can infer a relation with an attribute as a roleplayer
+ Given for each session, graql define
+ """
+ define
+ item sub entity, has name, plays listed-item;
+ price sub attribute, value double, plays item-price;
+ item-listing sub relation, relates listed-item, relates item-price;
+ nutella-price sub rule,
+ when {
+ $x isa item, has name "3kg jar of Nutella";
+ $y 14.99 isa price;
+ }, then {
+ (listed-item: $x, item-price: $y) isa item-listing;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa item, has name "3kg jar of Nutella";
+ $y 14.99 isa price;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ $r (listed-item: $i, item-price: $p) isa item-listing;
+ $i isa item, has name $n;
+ $n "3kg jar of Nutella" isa name;
+ $p 14.99 isa price;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: a rule can infer a relation based on ownership of any instance of a specific attribute type
+ Given for each session, graql define
+ """
+ define
+ year sub attribute, value long, plays favourite-year;
+ employment relates favourite-year;
+ kronenbourg-employs-anyone-with-a-name sub rule,
+ when {
+ $x isa company, has name "Kronenbourg";
+ $p isa person, has name $n;
+ $y 1664 isa year;
+ }, then {
+ (employee: $p, employer: $x, favourite-year: $y) isa employment;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa company, has name "Kronenbourg";
+ $p isa person, has name "Ronald";
+ $p2 isa person, has name "Prasanth";
+ $y 1664 isa year;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ $x 1664 isa year;
+ ($x, employee: $p, employer: $y) isa employment;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 2
+ Then materialised and reasoned keyspaces are the same size
+
+
+ ###############
+ # REFLEXIVITY #
+ ###############
+
+ # nth triangle number = sum of all integers from 1 to n, inclusive
+ Scenario: when inferring relations on all pairs from n concepts, the number of relations is the nth triangle number
+ Given for each session, graql define
+ """
+ define
+ everyone-is-my-friend-including-myself sub rule,
+ when {
+ $x isa person;
+ $y isa person;
+ }, then {
+ (friend: $x, friend: $y) isa friendship;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $a isa person, has name "Abigail";
+ $b isa person, has name "Bernadette";
+ $c isa person, has name "Cliff";
+ $d isa person, has name "Damien";
+ $e isa person, has name "Eustace";
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match $r isa friendship; get;
+ """
+ Then all answers are correct in reasoned keyspace
+ # When there is 1 concept we have {aa}.
+ # Adding a 2nd concept gives us 2 new relations - where each relation contains b, and one other concept (a or b).
+ # Adding a 3rd concept gives us 3 new relations - where each relation contains c, and one other concept (a, b or c).
+ # Generally, the total number of relations is the sum of all integers from 1 to n inclusive.
+ Then answer size in reasoned keyspace is: 15
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: when matching all possible pairs inferred from n concepts, the answer size is the square of n
+ Given for each session, graql define
+ """
+ define
+ everyone-is-my-friend-including-myself sub rule,
+ when {
+ $x isa person;
+ $y isa person;
+ }, then {
+ (friend: $x, friend: $y) isa friendship;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $a isa person, has name "Abigail";
+ $b isa person, has name "Bernadette";
+ $c isa person, has name "Cliff";
+ $d isa person, has name "Damien";
+ $e isa person, has name "Eustace";
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match ($x, $y) isa friendship; get;
+ """
+ Then all answers are correct in reasoned keyspace
+ # Here there are n choices for x, and n choices for y, so the total answer size is n^2
+ Then answer size in reasoned keyspace is: 25
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: when a relation is reflexive, matching concepts are related to themselves
+ Given for each session, graql define
+ """
+ define
+ person plays employer;
+ self-employment sub rule,
+ when {
+ $x isa person;
+ }, then {
+ (employee: $x, employer: $x) isa employment;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $f isa person, has name "Ferhat";
+ $g isa person, has name "Gawain";
+ $h isa person, has name "Hattie";
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ (employee: $x, employer: $x) isa employment;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 3
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: inferred reflexive relations can be retrieved using multiple variables to refer to the same concept
+ Given for each session, graql define
+ """
+ define
+ person plays employer;
+ self-employment sub rule,
+ when {
+ $x isa person;
+ }, then {
+ (employee: $x, employer: $x) isa employment;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $i isa person, has name "Irma";
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ (employee: $x, employer: $y) isa employment;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: inferred relations between distinct concepts are not retrieved when matching concepts related to themselves
+ Given for each session, graql define
+ """
+ define
+ person plays employer;
+ robert-employs-jane sub rule,
+ when {
+ $x has name "Robert";
+ $y has name "Jane";
+ }, then {
+ (employee: $y, employer: $x) isa employment;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $r isa person, has name "Robert";
+ $j isa person, has name "Jane";
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ (employee: $x, employer: $x) isa employment;
+ get;
+ """
+ Then answer size in reasoned keyspace is: 0
+ Then materialised and reasoned keyspaces are the same size
+
+
+ ############
+ # SYMMETRY #
+ ############
+
+ # TODO: re-enable all steps when resolvable (currently takes too long)
+ Scenario: when a relation is symmetric, its symmetry can be used to make additional inferences
+ Given for each session, graql define
+ """
+ define
+
+ person plays coworker,
+ plays employer,
+ plays robot-pet-owner;
+
+ robot sub entity,
+ plays robot-pet,
+ plays coworker,
+ plays employee,
+ plays employer,
+ has name;
+
+ coworkers sub relation,
+ relates coworker;
+
+ robot-pet-ownership sub relation,
+ relates robot-pet,
+ relates robot-pet-owner;
+
+ people-work-with-themselves sub rule,
+ when {
+ $x isa person;
+ },
+ then {
+ (coworker: $x, coworker: $x) isa coworkers;
+ };
+
+ robots-work-with-their-owners-coworkers sub rule,
+ when {
+ (robot-pet: $c, robot-pet-owner: $m) isa robot-pet-ownership;
+ (coworker: $m, coworker: $op) isa coworkers;
+ },
+ then {
+ (coworker: $c, coworker: $op) isa coworkers;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $a isa robot, has name 'r1';
+ $b isa person, has name 'p';
+ $c isa robot, has name 'r2';
+ (robot-pet: $a, robot-pet-owner: $b) isa robot-pet-ownership;
+ (coworker: $b, coworker: $c) isa coworkers;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ (coworker: $x, coworker: $x) isa coworkers;
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ # (p,p) is a coworkers since people work with themselves.
+ # Applying the robot work rule we see that (r1,p) is a pet ownership, and (p,p) and (p,r2) are coworker relations,
+ # so (r1,p) and (r1,r2) are both coworker relations.
+ # Coworker relations are symmetric, so (r2,p), (p,r1) and (r2,r1) are all coworker relations.
+ # Applying the robot work rule a 2nd time, (r1,p) is a pet ownership and (p,r1) are coworkers,
+ # therefore (r1,r1) is a reflexive coworker relation. So the answers are [p] and [r1].
+ Then answer size in reasoned keyspace is: 2
+ Then for graql query
+ """
+ match
+ (coworker: $x, coworker: $y) isa coworkers;
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ # $x | $y |
+ # p | p |
+ # p | r2 |
+ # r1 | p |
+ # r1 | r2 |
+ # r2 | p |
+ # p | r1 |
+ # r2 | r1 |
+ # r1 | r1 |
+ Then answer size in reasoned keyspace is: 8
+ Then materialised and reasoned keyspaces are the same size
+
+
+ ################
+ # TRANSITIVITY #
+ ################
+
+ Scenario: a transitive rule will not infer any new relations when there are only two related entities
+ Given for each session, graql define
+ """
+ define
+ transitive-location sub rule,
+ when {
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ }, then {
+ (location-subordinate: $x, location-superior: $z) isa location-hierarchy;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa place, has name "Delhi";
+ $y isa place, has name "India";
+ (location-subordinate: $x, location-superior: $x) isa location-hierarchy;
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $y) isa location-hierarchy;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match $x isa location-hierarchy; get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 3
+ Then materialised and reasoned keyspaces are the same size
+
+
+ # TODO: re-enable all steps when 3-hop transitivity is resolvable
+ Scenario: when a query using transitivity has a limit exceeding the result size, answers are consistent between runs
+ Given for each session, graql define
+ """
+ define
+ transitive-location sub rule,
+ when {
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ }, then {
+ (location-subordinate: $x, location-superior: $z) isa location-hierarchy;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $a isa place, has name "University of Warsaw";
+ $b isa place, has name "Warsaw";
+ $c isa place, has name "Poland";
+ $d isa place, has name "Europe";
+
+ (location-subordinate: $a, location-superior: $b) isa location-hierarchy;
+ (location-subordinate: $b, location-superior: $c) isa location-hierarchy;
+ (location-subordinate: $c, location-superior: $d) isa location-hierarchy;
+ """
+# When materialised keyspace is completed
+ Then for graql query
+ """
+ match (location-subordinate: $x1, location-superior: $x2) isa location-hierarchy; get;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 6
+ Then answers are consistent across 5 executions in reasoned keyspace
+# Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: when a transitive rule's `then` matches a query, but its `when` is unmet, the material answers are returned
+
+ This test is included because internally, Reasoner uses backward chaining to answer queries, meaning it has to
+ perform resolution steps even if the conditions of a rule are never met. In this case, `transitive-location`
+ is never triggered because there are no location-hierarchy pairs that satisfy both conditions.
+
+ Given for each session, graql define
+ """
+ define
+
+ planned-trip sub relation,
+ relates planned-source,
+ relates planned-destination;
+
+ cycle-route sub relation,
+ relates cycle-route-start,
+ relates cycle-route-end;
+
+ place plays planned-source,
+ plays planned-destination,
+ plays cycle-route-start,
+ plays cycle-route-end;
+
+ transitive-location sub rule,
+ when {
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ }, then {
+ (location-subordinate: $x, location-superior: $z) isa location-hierarchy;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x1 isa place, has name "Waterloo";
+ $x2a isa place, has name "Embankment";
+ $x2b isa place, has name "Southwark";
+ $x2c isa place, has name "Victoria";
+ $x3 isa place, has name "Tower Hill";
+ $x4 isa place, has name "London";
+
+ (cycle-route-start: $x1, cycle-route-end: $x2a) isa cycle-route;
+ (cycle-route-start: $x1, cycle-route-end: $x2b) isa cycle-route;
+ (cycle-route-start: $x1, cycle-route-end: $x2c) isa cycle-route;
+
+ (planned-source: $x2a, planned-destination: $x3) isa planned-trip;
+ (planned-source: $x2b, planned-destination: $x3) isa planned-trip;
+ (planned-source: $x2c, planned-destination: $x3) isa planned-trip;
+
+ (location-subordinate: $x3, location-superior: $x4) isa location-hierarchy;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match (location-subordinate: $x, location-superior: $y) isa location-hierarchy; get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then materialised and reasoned keyspaces are the same size
+
+
+ #######################
+ # ROLEPLAYER MATCHING #
+ #######################
+
+ Scenario: an inferred relation with one player in a role is not retrieved when the role appears twice in a match query
+ Given for each session, graql define
+ """
+ define
+ employment-rule sub rule,
+ when {
+ $c isa company;
+ $p isa person;
+ }, then {
+ (employee: $p, employer: $c) isa employment;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person;
+ $c isa company;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match (employee: $x, employee: $y) isa employment; get;
+ """
+ Then answer size in reasoned keyspace is: 0
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: a relation with two roleplayers inferred by the same rule is retrieved when matching only one of the roles
+ Given for each session, graql define
+ """
+ define
+ employment-rule sub rule,
+ when {
+ $c isa company;
+ $p isa person;
+ }, then {
+ (employee: $p, employer: $c) isa employment;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person;
+ $c isa company;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match (employee: $x) isa employment; get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: when matching an inferred relation with repeated roles, answers contain all permutations of the roleplayers
+ Given for each session, graql define
+ """
+ define
+ alice-bob-and-charlie-are-friends sub rule,
+ when {
+ $a has name "Alice";
+ $b has name "Bob";
+ $c has name "Charlie";
+ }, then {
+ (friend: $a, friend: $b, friend: $c) isa friendship;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person, has name "Alice";
+ $y isa person, has name "Bob";
+ $z isa person, has name "Charlie";
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ (friend: $a, friend: $b, friend: $c) isa friendship;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 6
+ Then answer set is equivalent for graql query
+ """
+ match
+ $r (friend: $a, friend: $b, friend: $c) isa friendship;
+ get $a, $b, $c;
+ """
+ Then materialised and reasoned keyspaces are the same size
+
+
+ # TODO: re-enable all steps when fixed (#75), currently they are very slow
+ Scenario: inferred relations can be filtered by shared attribute ownership
+ Given for each session, graql define
+ """
+ define
+ selection sub relation, relates choice1, relates choice2;
+ person plays choice1, plays choice2;
+ symmetric-selection sub rule,
+ when {
+ (choice1: $x, choice2: $y) isa selection;
+ }, then {
+ (choice1: $y, choice2: $x) isa selection;
+ };
+ transitive-selection sub rule,
+ when {
+ (choice1: $x, choice2: $y) isa selection;
+ (choice1: $y, choice2: $z) isa selection;
+ }, then {
+ (choice1: $x, choice2: $z) isa selection;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person, has name "a";
+ $y isa person, has name "b";
+ $z isa person, has name "c";
+
+ (choice1: $x, choice2: $y) isa selection;
+ (choice1: $y, choice2: $z) isa selection;
+ """
+# When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ (choice1: $x, choice2: $y) isa selection;
+ $x has name $n;
+ $y has name $n;
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ # (a,a), (b,b), (c,c)
+ Then answer size in reasoned keyspace is: 3
+ Then for graql query
+ """
+ match
+ (choice1: $x, choice2: $y) isa selection;
+ $x has name $n;
+ $y has name $n;
+ $n == 'a';
+ get $x, $y;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then answer set is equivalent for graql query
+ """
+ match
+ (choice1: $x, choice2: $y) isa selection;
+ $x has name 'a';
+ $y has name 'a';
+ get;
+ """
+# Then materialised and reasoned keyspaces are the same size
+
+
+ #######################
+ # UNTYPED MATCH QUERY #
+ #######################
+
+ # TODO: re-enable all steps when fixed (#75)
+ Scenario: the relation type constraint can be excluded from a reasoned match query
+ Given for each session, graql define
+ """
+ define
+ transitive-location sub rule,
+ when {
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ }, then {
+ (location-subordinate: $x, location-superior: $z) isa location-hierarchy;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa place, has name "Turku Airport";
+ $y isa place, has name "Turku";
+ $z isa place, has name "Finland";
+
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ $a isa place, has name "Turku Airport";
+ ($a, $b);
+ $b isa place, has name "Turku";
+ ($b, $c);
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ # $c in {'Turku Airport', 'Finland'}
+ Then answer size in reasoned keyspace is: 2
+ Then materialised and reasoned keyspaces are the same size
+
+
+ # TODO: re-enable all steps when fixed (#75)
+ Scenario: when the relation type is excluded in a reasoned match query, all valid roleplayer combinations are matches
+ Given for each session, graql define
+ """
+ define
+ transitive-location sub rule,
+ when {
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ }, then {
+ (location-subordinate: $x, location-superior: $z) isa location-hierarchy;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa place, has name "Turku Airport";
+ $y isa place, has name "Turku";
+ $z isa place, has name "Finland";
+
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ """
+ When materialised keyspace is completed
+ Given for graql query
+ """
+ match
+ $a isa place, has name "Turku Airport";
+ ($a, $b);
+ $b isa place, has name "Turku";
+ get;
+ """
+# Given all answers are correct in reasoned keyspace
+ Given answer size in reasoned keyspace is: 1
+ Then for graql query
+ """
+ match
+ $a isa place, has name "Turku Airport";
+ ($a, $b);
+ $b isa place, has name "Turku";
+ ($c, $d);
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ # (2 db relations + 1 inferred) x 2 for variable swap
+ Then answer size in reasoned keyspace is: 6
+ Then materialised and reasoned keyspaces are the same size
+
+
+ # TODO: re-enable all steps when fixed (#75)
+ Scenario: when the relation type is excluded in a reasoned match query, all types of relations match
+ Given for each session, graql define
+ """
+ define
+
+ loc-hie sub relation, relates loc-sub, relates loc-sup;
+
+ place plays loc-sub, plays loc-sup;
+
+ transitive-location sub rule,
+ when {
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ }, then {
+ (location-subordinate: $x, location-superior: $z) isa location-hierarchy;
+ };
+
+ long-role-names-suck sub rule,
+ when {
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ }, then {
+ (loc-sub: $x, loc-sup: $y) isa loc-hie;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa place, has name "Turku Airport";
+ $y isa place, has name "Turku";
+ $z isa place, has name "Finland";
+
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ """
+ When materialised keyspace is completed
+ Given for graql query
+ """
+ match
+ ($a, $b) isa relation;
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ # Despite there being more inferred relations, the answer size is still 6 (as in the previous scenario)
+ # because the query is only interested in the related concepts, not in the relation instances themselves
+ Then answer size in reasoned keyspace is: 6
+ Then answer set is equivalent for graql query
+ """
+ match ($a, $b); get;
+ """
+# Then materialised and reasoned keyspaces are the same size
+
+
+ # TODO: re-enable all steps when fixed (#75)
+ Scenario: conjunctions of untyped reasoned relations are correctly resolved
+ Given for each session, graql define
+ """
+ define
+ transitive-location sub rule,
+ when {
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ }, then {
+ (location-subordinate: $x, location-superior: $z) isa location-hierarchy;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa place, has name "Turku Airport";
+ $y isa place, has name "Turku";
+ $z isa place, has name "Finland";
+
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ ($a, $b);
+ ($b, $c);
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ # a | b | c |
+ # AIR | TUR | FIN |
+ # AIR | FIN | TUR |
+ # AIR | TUR | AIR |
+ # AIR | FIN | AIR |
+ # TUR | AIR | FIN |
+ # TUR | FIN | AIR |
+ # TUR | AIR | TUR |
+ # TUR | FIN | TUR |
+ # FIN | AIR | TUR |
+ # FIN | TUR | AIR |
+ # FIN | AIR | FIN |
+ # FIN | TUR | FIN |
+ Then answer size in reasoned keyspace is: 12
+ Then materialised and reasoned keyspaces are the same size
+
+
+ #####################
+ # CHAINED INFERENCE #
+ #####################
+
+ # TODO: re-enable all steps when query is resolvable (currently takes too long)
+ Scenario: the types of entities in inferred relations can be used to make further inferences
+ Given for each session, graql define
+ """
+ define
+
+ big-place sub place,
+ plays big-location-subordinate,
+ plays big-location-superior;
+
+ big-location-hierarchy sub location-hierarchy,
+ relates big-location-subordinate as location-subordinate,
+ relates big-location-superior as location-superior;
+
+ transitive-location sub rule,
+ when {
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ }, then {
+ (location-subordinate: $x, location-superior: $z) isa location-hierarchy;
+ };
+
+ if-a-big-thing-is-in-a-big-place-then-its-a-big-location sub rule,
+ when {
+ $x isa big-place;
+ $y isa big-place;
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ }, then {
+ (big-location-subordinate: $x, big-location-superior: $y) isa big-location-hierarchy;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa big-place, has name "Mount Kilimanjaro";
+ $y isa place, has name "Tanzania";
+ $z isa big-place, has name "Africa";
+
+ (location-subordinate: $x, location-superior: $y) isa location-hierarchy;
+ (location-subordinate: $y, location-superior: $z) isa location-hierarchy;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match (big-location-subordinate: $x, big-location-superior: $y) isa big-location-hierarchy; get;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then materialised and reasoned keyspaces are the same size
+
+
+ # TODO: re-enable all steps when resolvable (currently takes too long)
+ Scenario: the types of inferred relations can be used to make further inferences
+ Given for each session, graql define
+ """
+ define
+
+ entity1 sub entity,
+ plays role11,
+ plays role12,
+ plays role21,
+ plays role22,
+ plays role31,
+ plays role32;
+
+ relation1 sub relation,
+ relates role11,
+ relates role12;
+
+ relation2 sub relation,
+ relates role21,
+ relates role22;
+
+ relation3 sub relation,
+ relates role31,
+ relates role32;
+
+ relation3-inference sub rule,
+ when {
+ (role11:$x, role12:$y) isa relation1;
+ (role21:$y, role22:$z) isa relation2;
+ (role11:$z, role12:$u) isa relation1;
+ },
+ then {
+ (role31:$x, role32:$u) isa relation3;
+ };
+
+ relation2-transitivity sub rule,
+ when {
+ (role21:$x, role22:$y) isa relation2;
+ (role21:$y, role22:$z) isa relation2;
+ },
+ then {
+ (role21:$x, role22:$z) isa relation2;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+
+ $x isa entity1;
+ $y isa entity1;
+ $z isa entity1;
+ $u isa entity1;
+ $v isa entity1;
+ $w isa entity1;
+ $q isa entity1;
+
+ (role11:$x, role12:$y) isa relation1;
+ (role21:$y, role22:$z) isa relation2;
+ (role21:$z, role22:$u) isa relation2;
+ (role21:$u, role22:$v) isa relation2;
+ (role21:$v, role22:$w) isa relation2;
+ (role11:$w, role12:$q) isa relation1;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match (role31: $x, role32: $y) isa relation3; get;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then materialised and reasoned keyspaces are the same size
+
+
+ Scenario: circular rule dependencies can be resolved
+ Given for each session, graql define
+ """
+ define
+
+ entity1 sub entity,
+ plays role11,
+ plays role12,
+ plays role21,
+ plays role22,
+ plays role31,
+ plays role32;
+
+ relation1 sub relation,
+ relates role11,
+ relates role12;
+
+ relation2 sub relation,
+ relates role21,
+ relates role22;
+
+ relation3 sub relation,
+ relates role31,
+ relates role32;
+
+ relation-1-to-2 sub rule,
+ when {
+ (role11:$x, role12:$y) isa relation1;
+ },
+ then {
+ (role21:$x, role22:$y) isa relation2;
+ };
+
+ relation-3-to-2 sub rule,
+ when {
+ (role31:$x, role32:$y) isa relation3;
+ },
+ then {
+ (role21:$x, role22:$y) isa relation2;
+ };
+
+ relation-2-to-3 sub rule,
+ when {
+ (role21:$x, role22:$y) isa relation2;
+ },
+ then {
+ (role31:$x, role32:$y) isa relation3;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+
+ $x isa entity1;
+ $y isa entity1;
+
+ (role11:$x, role12:$x) isa relation1;
+ (role11:$x, role12:$y) isa relation1;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match (role31: $x, role32: $y) isa relation3; get;
+ """
+ Then all answers are correct in reasoned keyspace
+ # Each of the two material relation1 instances should infer a single relation3 via 1-to-2 and 2-to-3
+ Then answer size in reasoned keyspace is: 2
+ Then for graql query
+ """
+ match (role21: $x, role22: $y) isa relation2; get;
+ """
+ Then all answers are correct in reasoned keyspace
+ # Relation-3-to-2 should not make any additional inferences - it should merely assert that the relations exist
+ Then answer size in reasoned keyspace is: 2
+ Then materialised and reasoned keyspaces are the same size
+
+
+ # TODO: re-enable all steps when we have a solution for materialisation of infinite graphs (#75)
+ Scenario: when resolution produces an infinite stream of answers, limiting the answer size allows it to terminate
+ Given for each session, graql define
+ """
+ define
+
+ dream sub relation,
+ relates dreamer,
+ relates dream-subject,
+ plays dream-subject;
+
+ person plays dreamer, plays dream-subject;
+
+ inception sub rule,
+ when {
+ $x isa person;
+ $z (dreamer: $x, dream-subject: $y) isa dream;
+ }, then {
+ (dreamer: $x, dream-subject: $z) isa dream;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person, has name "Yusuf";
+ # If only Yusuf didn't dream about himself...
+ (dreamer: $x, dream-subject: $x) isa dream;
+ """
+# When materialised keyspace is completed
+ Then for graql query
+ """
+ match $x isa dream; get; limit 10;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 10
+# Then materialised and reasoned keyspaces are the same size
+
+
+ # TODO: re-enable all steps when materialisation is possible (may be an infinite graph?) (#75)
+ Scenario: when relations' and attributes' inferences are mutually recursive, the inferred concepts can be retrieved
+ Given for each session, graql define
+ """
+ define
+
+ word sub entity,
+ plays subtype,
+ plays supertype,
+ plays prep,
+ plays pobj,
+ has name;
+
+ f sub word;
+ o sub word;
+
+ pobj sub role;
+ prep sub role;
+ subtype sub role;
+ supertype sub role;
+
+ inheritance sub relation,
+ relates supertype,
+ relates subtype;
+
+ pair sub relation,
+ relates prep,
+ relates pobj,
+ has typ,
+ has name;
+
+ name sub attribute, value string;
+ typ sub attribute, value string;
+
+ inference-all-pairs sub rule,
+ when {
+ $x isa word;
+ $y isa word;
+ $x has name !== 'f';
+ $y has name !== 'o';
+ },
+ then {
+ (prep: $x, pobj: $y) isa pair;
+ };
+
+ inference-pairs-ff sub rule,
+ when {
+ $f isa f;
+ (subtype: $prep, supertype: $f) isa inheritance;
+ (subtype: $pobj, supertype: $f) isa inheritance;
+ $p (prep: $prep, pobj: $pobj) isa pair;
+ },
+ then {
+ $p has name 'ff';
+ };
+
+ inference-pairs-fo sub rule,
+ when {
+ $f isa f;
+ $o isa o;
+ (subtype: $prep, supertype: $f) isa inheritance;
+ (subtype: $pobj, supertype: $o) isa inheritance;
+ $p (prep: $prep, pobj: $pobj) isa pair;
+ },
+ then {
+ $p has name 'fo';
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+
+ $f isa f, has name "f";
+ $o isa o, has name "o";
+
+ $aa isa word, has name "aa";
+ $bb isa word, has name "bb";
+ $cc isa word, has name "cc";
+
+ (supertype: $o, subtype: $aa) isa inheritance;
+ (supertype: $o, subtype: $bb) isa inheritance;
+ (supertype: $o, subtype: $cc) isa inheritance;
+
+ $pp isa word, has name "pp";
+ $qq isa word, has name "qq";
+ $rr isa word, has name "rr";
+ $rr2 isa word, has name "rr";
+
+ (supertype: $f, subtype: $pp) isa inheritance;
+ (supertype: $f, subtype: $qq) isa inheritance;
+ (supertype: $f, subtype: $rr) isa inheritance;
+ (supertype: $f, subtype: $rr2) isa inheritance;
+ """
+# When materialised keyspace is completed
+ Then for graql query
+ """
+ match $p isa pair, has name 'ff'; get;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 16
+ Then for graql query
+ """
+ match $p isa pair; get;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 64
+# Then materialised and reasoned keyspaces are the same size
diff --git a/behaviour/graql/reasoner/resolution/test-framework.feature b/behaviour/graql/reasoner/resolution-test-framework.feature
similarity index 100%
rename from behaviour/graql/reasoner/resolution/test-framework.feature
rename to behaviour/graql/reasoner/resolution-test-framework.feature
diff --git a/behaviour/graql/reasoner/resolution.feature b/behaviour/graql/reasoner/resolution.feature
deleted file mode 100644
index af66a107..00000000
--- a/behaviour/graql/reasoner/resolution.feature
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# Copyright (C) 2020 Grakn Labs
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-
-# TODO: these tests should be implemented somewhere, but probably not in a file called 'resolution.feature'
-Feature: Graql Reasoner Resolution
-
- Background: Initialise a session and transaction for each scenario
- Given connection has been opened
- Given connection delete all keyspaces
- Given connection open sessions for keyspaces:
- | test_resolution |
- Given transaction is initialised
-
- Scenario: `isa` matches inferred relations
-
- Scenario: `isa` matches inferred roleplayers in relation instances
-
- Scenario: `isa` matches inferred types that are subtypes of the thing's defined type
-
- Scenario: `isa` matches inferred types that are unrelated to the thing's defined type
diff --git a/behaviour/graql/reasoner/resolution/BUILD b/behaviour/graql/reasoner/resolution/BUILD
deleted file mode 100644
index 0c5624a4..00000000
--- a/behaviour/graql/reasoner/resolution/BUILD
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright (C) 2020 Grakn Labs
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-
-package(default_visibility = ["//visibility:public"])
-
-exports_files([
- "attribute-attachment.feature",
- "concept-inequality.feature",
- "test-framework.feature",
- "type-generation.feature",
- "type-hierarchy.feature",
- "value-predicate.feature",
- "variable-role.feature",
-])
\ No newline at end of file
diff --git a/behaviour/graql/reasoner/roleplayer-attachment.feature b/behaviour/graql/reasoner/roleplayer-attachment.feature
new file mode 100644
index 00000000..bf5f01f3
--- /dev/null
+++ b/behaviour/graql/reasoner/roleplayer-attachment.feature
@@ -0,0 +1,274 @@
+#
+# Copyright (C) 2020 Grakn Labs
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+Feature: Roleplayer Attachment Resolution
+
+ Background: Set up keyspaces for resolution testing
+
+ Given connection has been opened
+ Given connection delete all keyspaces
+ Given connection open sessions for keyspaces:
+ | materialised |
+ | reasoned |
+ Given materialised keyspace is named: materialised
+ Given reasoned keyspace is named: reasoned
+ Given for each session, graql define
+ """
+ define
+
+ person sub entity,
+ has name,
+ plays friend,
+ plays employee;
+
+ company sub entity,
+ has name,
+ plays employer;
+
+ place sub entity,
+ has name,
+ plays location-subordinate,
+ plays location-superior;
+
+ friendship sub relation,
+ relates friend;
+
+ employment sub relation,
+ relates employee,
+ relates employer;
+
+ location-hierarchy sub relation,
+ relates location-subordinate,
+ relates location-superior;
+
+ name sub attribute, value string;
+ """
+
+ # TODO: re-enable all steps when fixed (#75)
+ Scenario: a rule can attach an additional roleplayer to an existing relation
+ Given for each session, graql define
+ """
+ define
+ dominion sub relation, relates ruler, relates ruled-person;
+ giant-turtle sub entity, plays ruler;
+ person plays ruled-person;
+
+ giant-turtles-rule-the-world sub rule,
+ when {
+ $r (ruled-person: $p) isa dominion;
+ $gt isa giant-turtle;
+ }, then {
+ $r (ruler: $gt) isa dominion;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person;
+ $y isa person;
+ $z isa giant-turtle;
+
+ (ruled-person: $x) isa dominion;
+ (ruled-person: $y) isa dominion;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ (ruled-person: $x, ruler: $y) isa dominion;
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 2
+ Then materialised and reasoned keyspaces are the same size
+
+
+ # TODO: re-enable all steps when fixed (#75)
+ Scenario: additional roleplayers attached to relations can be retrieved without specifying the relation type
+ Given for each session, graql define
+ """
+ define
+ dominion sub relation, relates ruler, relates ruled-person;
+ giant-turtle sub entity, plays ruler;
+ person plays ruled-person;
+
+ giant-turtles-rule-the-world sub rule,
+ when {
+ $r (ruled-person: $p) isa dominion;
+ $gt isa giant-turtle;
+ }, then {
+ $r (ruler: $gt) isa dominion;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person;
+ $y isa person;
+ $z isa giant-turtle;
+
+ (ruled-person: $x) isa dominion;
+ (ruled-person: $y) isa dominion;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ (ruled-person: $x, ruler: $y);
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 2
+ Then materialised and reasoned keyspaces are the same size
+
+
+ # TODO: re-enable all steps when fixed (#75)
+ Scenario: a rule can make an existing relation roleplayer play an additional role in that relation
+ Given for each session, graql define
+ """
+ define
+ ship-crew sub relation, relates captain, relates navigator, relates chef;
+ person plays captain, plays navigator, plays chef;
+
+ i-am-the-cook-therefore-i-am-the-captain sub rule,
+ when {
+ $r (chef: $p) isa ship-crew;
+ }, then {
+ $r (captain: $p) isa ship-crew;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person, has name "Cook";
+ $y isa person, has name "Raleigh";
+
+ (navigator: $y, chef: $x) isa ship-crew;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ (captain: $x, navigator: $y) isa ship-crew;
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then answer set is equivalent for graql query
+ """
+ match
+ (captain: $x, navigator: $y, chef: $x) isa ship-crew;
+ get;
+ """
+ Then materialised and reasoned keyspaces are the same size
+
+
+ # TODO: re-enable all steps when fixed (#75)
+ Scenario: a rule can make an existing relation roleplayer play that role an additional time
+ Given for each session, graql define
+ """
+ define
+ ship-crew sub relation, relates captain, relates navigator, relates chef;
+ person plays captain, plays navigator, plays chef;
+
+ i-really-am-the-captain sub rule,
+ when {
+ $r (captain: $p) isa ship-crew;
+ }, then {
+ $r (captain: $p, captain: $p) isa ship-crew;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person, has name "Captain Obvious";
+ $y isa person, has name "Bob";
+
+ (navigator: $y, captain: $x) isa ship-crew;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ (captain: $x, captain: $x) isa ship-crew;
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then for graql query
+ """
+ match
+ (captain: $x, captain: $x, captain: $x) isa ship-crew;
+ get;
+ """
+ # too many captains - no match
+ Then answer size in reasoned keyspace is: 0
+ Then for graql query
+ """
+ match
+ (captain: $x) isa ship-crew;
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ # we have more captains than we need, but there is still only 1 matching relation instance
+ Then answer size in reasoned keyspace is: 1
+ Then materialised and reasoned keyspaces are the same size
+
+
+ # TODO: re-enable all steps when fixed (#75)
+ Scenario: when copying a roleplayer to another role, making it a duplicate role, the players are retrieved correctly
+ Given for each session, graql define
+ """
+ define
+ ship-crew sub relation, relates captain, relates navigator, relates chef;
+ person plays captain, plays navigator, plays chef;
+
+ the-captain-is-required-to-assist-the-navigator sub rule,
+ when {
+ $r (captain: $y, navigator: $z) isa ship-crew;
+ }, then {
+ $r (navigator: $y) isa ship-crew;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa person, has name "Maria";
+ $y isa person, has name "Isabella";
+
+ (captain: $x, navigator: $y) isa ship-crew;
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ (navigator: $x, navigator: $y) isa ship-crew;
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ # x | y |
+ # Maria | Isabella |
+ # Isabella | Maria |
+ Then answer size in reasoned keyspace is: 2
+ Then answer set is equivalent for graql query
+ """
+ match
+ (navigator: $x, navigator: $y) isa ship-crew;
+ $x != $y;
+ get;
+ """
+ Then materialised and reasoned keyspaces are the same size
diff --git a/behaviour/graql/reasoner/resolution/type-generation.feature b/behaviour/graql/reasoner/type-generation.feature
similarity index 100%
rename from behaviour/graql/reasoner/resolution/type-generation.feature
rename to behaviour/graql/reasoner/type-generation.feature
diff --git a/behaviour/graql/reasoner/resolution/type-hierarchy.feature b/behaviour/graql/reasoner/type-hierarchy.feature
similarity index 99%
rename from behaviour/graql/reasoner/resolution/type-hierarchy.feature
rename to behaviour/graql/reasoner/type-hierarchy.feature
index b399b3b9..9c1c21e1 100644
--- a/behaviour/graql/reasoner/resolution/type-hierarchy.feature
+++ b/behaviour/graql/reasoner/type-hierarchy.feature
@@ -28,6 +28,124 @@ Feature: Type Hierarchy Resolution
Given reasoned keyspace is named: reasoned
+ Scenario: subtypes trigger rules based on their parents; parent types don't trigger rules based on their children
+ Given for each session, graql define
+ """
+ define
+
+ person sub entity,
+ has name,
+ plays writer,
+ plays performer,
+ plays film-writer,
+ plays actor;
+
+ child sub person;
+
+ performance sub relation,
+ relates writer,
+ relates performer;
+
+ film-production sub relation,
+ relates film-writer,
+ relates actor;
+
+ name sub attribute, value string;
+
+ performance-to-film-production sub rule,
+ when {
+ $x isa child;
+ $y isa person;
+ (performer:$x, writer:$y) isa performance;
+ },
+ then {
+ (actor:$x, film-writer:$y) isa film-production;
+ };
+ """
+ Given for each session, graql insert
+ """
+ insert
+ $x isa child, has name "a";
+ $y isa person, has name "b";
+ $z isa person, has name "a";
+ $w isa person, has name "b2";
+ $v isa child, has name "a";
+
+ (performer:$x, writer:$z) isa performance; # child - person -> satisfies rule
+ (performer:$y, writer:$z) isa performance; # person - person -> doesn't satisfy rule
+ (performer:$x, writer:$v) isa performance; # child - child -> satisfies rule
+ (performer:$y, writer:$v) isa performance; # person - child -> doesn't satisfy rule
+ """
+ When materialised keyspace is completed
+ Then for graql query
+ """
+ match
+ $x isa person;
+ $y isa person;
+ (actor: $x, film-writer: $y) isa film-production;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ # Answers are (actor:$x, film-writer:$z) and (actor:$x, film-writer:$v)
+ Then answer size in reasoned keyspace is: 2
+ Then for graql query
+ """
+ match
+ $x isa person;
+ $y isa person;
+ (actor: $x, film-writer: $y) isa film-production;
+ $y has name 'a';
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 2
+ Then for graql query
+ """
+ match
+ $x isa person;
+ $y isa child;
+ (actor: $x, film-writer: $y) isa film-production;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ # Answer is (actor:$x, film-writer:$v) ONLY
+ Then answer size in reasoned keyspace is: 1
+ Then for graql query
+ """
+ match
+ $x isa person;
+ $y isa child;
+ (actor: $x, film-writer: $y) isa film-production;
+ $y has name 'a';
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then for graql query
+ """
+ match
+ $x isa child;
+ $y isa person;
+ (actor: $x, film-writer: $y) isa film-production;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ # Answers are (actor:$x, film-writer:$z) and (actor:$x, film-writer:$v)
+ Then answer size in reasoned keyspace is: 2
+ Then for graql query
+ """
+ match
+ $x isa child;
+ $y isa person;
+ (actor: $x, film-writer: $y) isa film-production;
+ $y has name 'a';
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 2
+ Then materialised and reasoned keyspaces are the same size
+
+
Scenario: when matching different roles to those that are actually inferred, no answers are returned
Given for each session, graql define
"""
@@ -232,124 +350,6 @@ Feature: Type Hierarchy Resolution
Then materialised and reasoned keyspaces are the same size
- Scenario: subtype instances trigger rules whose `when` block references their parent type; supertype instances do not
- Given for each session, graql define
- """
- define
-
- person sub entity,
- has name,
- plays writer,
- plays performer,
- plays film-writer,
- plays actor;
-
- child sub person;
-
- performance sub relation,
- relates writer,
- relates performer;
-
- film-production sub relation,
- relates film-writer,
- relates actor;
-
- name sub attribute, value string;
-
- performance-to-film-production sub rule,
- when {
- $x isa child;
- $y isa person;
- (performer:$x, writer:$y) isa performance;
- },
- then {
- (actor:$x, film-writer:$y) isa film-production;
- };
- """
- Given for each session, graql insert
- """
- insert
- $x isa child, has name "a";
- $y isa person, has name "b";
- $z isa person, has name "a";
- $w isa person, has name "b2";
- $v isa child, has name "a";
-
- (performer:$x, writer:$z) isa performance; # child - person -> satisfies rule
- (performer:$y, writer:$z) isa performance; # person - person -> doesn't satisfy rule
- (performer:$x, writer:$v) isa performance; # child - child -> satisfies rule
- (performer:$y, writer:$v) isa performance; # person - child -> doesn't satisfy rule
- """
- When materialised keyspace is completed
- Then for graql query
- """
- match
- $x isa person;
- $y isa person;
- (actor: $x, film-writer: $y) isa film-production;
- get;
- """
- Then all answers are correct in reasoned keyspace
- # Answers are (actor:$x, film-writer:$z) and (actor:$x, film-writer:$v)
- Then answer size in reasoned keyspace is: 2
- Then for graql query
- """
- match
- $x isa person;
- $y isa person;
- (actor: $x, film-writer: $y) isa film-production;
- $y has name 'a';
- get;
- """
- Then all answers are correct in reasoned keyspace
- Then answer size in reasoned keyspace is: 2
- Then for graql query
- """
- match
- $x isa person;
- $y isa child;
- (actor: $x, film-writer: $y) isa film-production;
- get;
- """
- Then all answers are correct in reasoned keyspace
- # Answer is (actor:$x, film-writer:$v) ONLY
- Then answer size in reasoned keyspace is: 1
- Then for graql query
- """
- match
- $x isa person;
- $y isa child;
- (actor: $x, film-writer: $y) isa film-production;
- $y has name 'a';
- get;
- """
- Then all answers are correct in reasoned keyspace
- Then answer size in reasoned keyspace is: 1
- Then for graql query
- """
- match
- $x isa child;
- $y isa person;
- (actor: $x, film-writer: $y) isa film-production;
- get;
- """
- Then all answers are correct in reasoned keyspace
- # Answers are (actor:$x, film-writer:$z) and (actor:$x, film-writer:$v)
- Then answer size in reasoned keyspace is: 2
- Then for graql query
- """
- match
- $x isa child;
- $y isa person;
- (actor: $x, film-writer: $y) isa film-production;
- $y has name 'a';
- get;
- """
- Then all answers are correct in reasoned keyspace
- Then answer size in reasoned keyspace is: 2
- Then materialised and reasoned keyspaces are the same size
-
-
Scenario: when a rule is recursive, its inferences respect type hierarchies
Given for each session, graql define
"""
diff --git a/behaviour/graql/reasoner/resolution/value-predicate.feature b/behaviour/graql/reasoner/value-predicate.feature
similarity index 82%
rename from behaviour/graql/reasoner/resolution/value-predicate.feature
rename to behaviour/graql/reasoner/value-predicate.feature
index d8e50fd7..1f19fe9d 100644
--- a/behaviour/graql/reasoner/resolution/value-predicate.feature
+++ b/behaviour/graql/reasoner/value-predicate.feature
@@ -46,7 +46,8 @@ Feature: Value Predicate Resolution
soft-drink sub entity,
has name,
- has retailer;
+ has retailer,
+ has price;
team sub relation,
relates leader,
@@ -58,6 +59,7 @@ Feature: Value Predicate Resolution
age sub attribute, value long;
name sub attribute, value string;
is-old sub attribute, value boolean;
+ price sub attribute, value double;
sub-string-attribute sub string-attribute;
unrelated-attribute sub attribute, value string;
"""
@@ -729,6 +731,8 @@ Feature: Value Predicate Resolution
# Then materialised and reasoned keyspaces are the same size
+ # TODO: re-enable all steps once implicit attribute variables are resolvable
+ # TODO: migrate to concept-inequality.feature
Scenario: when restricting the values of a pair of inferred attributes with `!=`, the answers have distinct types
Given for each session, graql define
"""
@@ -773,114 +777,177 @@ Feature: Value Predicate Resolution
Then materialised and reasoned keyspaces are the same size
- @ignore
- # TODO: re-enable once grakn#5821 is fixed (in some answers, $typeof_ax is 'base-attribute' which is incorrect)
- Scenario: when restricting concept types of a pair of inferred attributes with `!=`, the answers have distinct types
+ # TODO: re-enable all steps when fixed (#75)
+ Scenario: rules can divide entities into groups, linking each entity group to a specific concept by attribute value
Given for each session, graql define
"""
define
- base-attribute sub attribute, value string, abstract;
- string-attribute sub base-attribute;
- name sub base-attribute;
- retailer sub base-attribute;
- tesco-sells-all-soft-drinks sub rule,
+ soft-drink plays priced-item;
+
+ price-range sub attribute, value string,
+ plays price-category;
+
+ price-classification sub relation,
+ relates priced-item,
+ relates price-category;
+
+ expensive-drinks sub rule,
when {
- $x isa soft-drink;
- },
- then {
- $x has retailer 'Tesco';
+ $x has price >= 3.50;
+ $y "expensive" isa price-range;
+ }, then {
+ (priced-item: $x, price-category: $y) isa price-classification;
+ };
+
+ not-expensive-drinks sub rule,
+ when {
+ $x has price < 3.50;
+ $y "not expensive" isa price-range;
+ }, then {
+ (priced-item: $x, price-category: $y) isa price-classification;
+ };
+
+ low-price-drinks sub rule,
+ when {
+ $x has price < 1.75;
+ $y "low price" isa price-range;
+ }, then {
+ (priced-item: $x, price-category: $y) isa price-classification;
+ };
+
+ cheap-drinks sub rule,
+ when {
+ (priced-item: $x, price-category: $y) isa price-classification;
+ $y "not expensive" isa price-range;
+ (priced-item: $x, price-category: $y2) isa price-classification;
+ $y2 "low price" isa price-range;
+ $y3 "cheap" isa price-range;
+ }, then {
+ (priced-item: $x, price-category: $y3) isa price-classification;
};
"""
Given for each session, graql insert
"""
insert
- $x isa person, has string-attribute "Tesco";
- $y isa soft-drink, has name "Tesco";
+
+ $x isa soft-drink, has name "San Pellegrino Limonata", has price 3.99;
+ $y isa soft-drink, has name "Sprite", has price 2.00;
+ $z isa soft-drink, has name "Tesco Value Lemonade", has price 0.39;
+
+ $p1 "expensive" isa price-range;
+ $p2 "not expensive" isa price-range;
+ $p3 "low price" isa price-range;
+ $p4 "cheap" isa price-range;
"""
When materialised keyspace is completed
Then for graql query
"""
match
- $x has base-attribute $ax;
- $y has base-attribute $ay;
- $ax isa! $typeof_ax;
- $ay isa! $typeof_ay;
- $typeof_ax != $typeof_ay;
+ $x "not expensive" isa price-range;
+ ($x, priced-item: $y) isa price-classification;
get;
"""
Then all answers are correct in reasoned keyspace
- # x | ax | y | ay |
- # PER | STA | SOF | NAM |
- # PER | STA | SOF | RET |
- # SOF | NAM | PER | STA |
- # SOF | RET | PER | STA |
- # SOF | NAM | SOF | STA |
- # SOF | STA | SOF | NAM |
- Then answer size in reasoned keyspace is: 6
+ Then answer size in reasoned keyspace is: 2
+ Then for graql query
+ """
+ match
+ $x "low price" isa price-range;
+ ($x, priced-item: $y) isa price-classification;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then for graql query
+ """
+ match
+ $x "cheap" isa price-range;
+ ($x, priced-item: $y) isa price-classification;
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then for graql query
+ """
+ match
+ $x "expensive" isa price-range;
+ ($x, priced-item: $y) isa price-classification;
+ get;
+ """
+ Then all answers are correct in reasoned keyspace
+ Then answer size in reasoned keyspace is: 1
+ Then for graql query
+ """
+ match
+ $x isa price-range;
+ ($x, priced-item: $y) isa price-classification;
+ get;
+ """
+# Then all answers are correct in reasoned keyspace
+ # sum of all previous answers
+ Then answer size in reasoned keyspace is: 5
Then materialised and reasoned keyspaces are the same size
- @ignore
- # TODO: re-enable once grakn#5821 is fixed
- Scenario: inferred attribute matches can be simultaneously restricted by both concept type and attribute value
+
+ # TODO: re-enable all steps when resolvable (currently it takes too long to resolve) (#75)
+ Scenario: attribute comparison can be used to classify concept pairs as predecessors and successors of each other
Given for each session, graql define
"""
define
- base-attribute sub attribute, value string, abstract;
- string-attribute sub base-attribute;
- retailer sub base-attribute;
- transfer-string-attribute-to-other-people sub rule,
- when {
- $x isa person, has string-attribute $r1;
- $y isa person;
- },
- then {
- $y has string-attribute $r1;
- };
+ post sub entity,
+ plays original,
+ plays reply,
+ plays predecessor,
+ plays successor,
+ has creation-date;
- tesco-sells-all-soft-drinks sub rule,
- when {
- $x isa soft-drink;
- },
- then {
- $x has retailer 'Tesco';
- };
+ reply-of sub relation,
+ relates original,
+ relates reply;
- if-ocado-exists-it-sells-all-soft-drinks sub rule,
+ message-succession sub relation,
+ relates predecessor,
+ relates successor;
+
+ creation-date sub attribute, value datetime;
+
+ succession-rule sub rule,
when {
- $x isa retailer;
- $x == 'Ocado';
- $y isa soft-drink;
+ (original:$p, reply:$s) isa reply-of;
+ $s has creation-date $d1;
+ $d1 < $d2;
+ (original:$p, reply:$r) isa reply-of;
+ $r has creation-date $d2;
},
then {
- $y has retailer $x;
+ (predecessor:$s, successor:$r) isa message-succession;
};
"""
Given for each session, graql insert
"""
insert
- $w isa person, has string-attribute "Ocado";
- $x isa person, has string-attribute "Tesco";
- $y isa soft-drink, has name "Sprite";
- $z "Ocado" isa retailer;
+
+ $x isa post, has creation-date 2020-07-01;
+ $x1 isa post, has creation-date 2020-07-02;
+ $x2 isa post, has creation-date 2020-07-03;
+ $x3 isa post, has creation-date 2020-07-04;
+ $x4 isa post, has creation-date 2020-07-05;
+ $x5 isa post, has creation-date 2020-07-06;
+
+ (original:$x, reply:$x1) isa reply-of;
+ (original:$x, reply:$x2) isa reply-of;
+ (original:$x, reply:$x3) isa reply-of;
+ (original:$x, reply:$x4) isa reply-of;
+ (original:$x, reply:$x5) isa reply-of;
"""
- When materialised keyspace is completed
+# When materialised keyspace is completed
Then for graql query
"""
- match
- $x has base-attribute $value;
- $y has base-attribute $unwantedValue;
- $value !== $unwantedValue;
- $unwantedValue "Ocado";
- $value isa! $type;
- $unwantedValue isa! $type;
- $type != $unwantedType;
- $unwantedType type string-attribute;
- get $x, $value, $type;
+ match (predecessor:$x1, successor:$x2) isa message-succession; get;
"""
- Then all answers are correct in reasoned keyspace
- # x | value | type |
- # Sprite | Tesco | retailer |
- Then answer size in reasoned keyspace is: 1
- Then materialised and reasoned keyspaces are the same size
+# Then all answers are correct in reasoned keyspace
+ # the (n-1)th triangle number, where n is the number of replies to the first post
+ Then answer size in reasoned keyspace is: 10
+# Then materialised and reasoned keyspaces are the same size
diff --git a/behaviour/graql/reasoner/resolution/variable-role.feature b/behaviour/graql/reasoner/variable-roles.feature
similarity index 100%
rename from behaviour/graql/reasoner/resolution/variable-role.feature
rename to behaviour/graql/reasoner/variable-roles.feature