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