From 39f044e18a717bb6252af87efcc03755a517d9f2 Mon Sep 17 00:00:00 2001 From: Alex Walker Date: Tue, 28 Jul 2020 11:55:06 +0100 Subject: [PATCH] Migrate ReasoningIT to BDD (#81) ## What is the goal of this PR? To identify and de-duplicate integration tests that test the fundamentals of Reasoner, categorise them appropriately and migrate them to BDD scenarios. This PR focuses on ReasoningIT in grakn. This PR forms part of the work towards https://github.com/graknlabs/grakn/issues/5721 ## What are the changes implemented in this PR? Added tests that were migrated from the relevant IT files in grakn. Also moved some tests around, so that everything is in the right place. --- behaviour/graql/language/BUILD | 1 + behaviour/graql/language/define.feature | 4 +- behaviour/graql/language/insert.feature | 37 + behaviour/graql/language/match.feature | 102 +- .../rule-validation.feature | 2 +- behaviour/graql/reasoner/BUILD | 12 +- .../attribute-attachment.feature | 0 .../concept-inequality.feature | 128 ++ behaviour/graql/reasoner/negation.feature | 243 +++ .../graql/reasoner/relation-inference.feature | 1305 +++++++++++++++++ ...ture => resolution-test-framework.feature} | 0 behaviour/graql/reasoner/resolution.feature | 34 - behaviour/graql/reasoner/resolution/BUILD | 28 - .../reasoner/roleplayer-attachment.feature | 274 ++++ .../{resolution => }/type-generation.feature | 0 .../{resolution => }/type-hierarchy.feature | 236 +-- .../{resolution => }/value-predicate.feature | 215 ++- ...le-role.feature => variable-roles.feature} | 0 18 files changed, 2361 insertions(+), 260 deletions(-) rename behaviour/graql/{reasoner => language}/rule-validation.feature (98%) rename behaviour/graql/reasoner/{resolution => }/attribute-attachment.feature (100%) rename behaviour/graql/reasoner/{resolution => }/concept-inequality.feature (76%) create mode 100644 behaviour/graql/reasoner/negation.feature create mode 100644 behaviour/graql/reasoner/relation-inference.feature rename behaviour/graql/reasoner/{resolution/test-framework.feature => resolution-test-framework.feature} (100%) delete mode 100644 behaviour/graql/reasoner/resolution.feature delete mode 100644 behaviour/graql/reasoner/resolution/BUILD create mode 100644 behaviour/graql/reasoner/roleplayer-attachment.feature rename behaviour/graql/reasoner/{resolution => }/type-generation.feature (100%) rename behaviour/graql/reasoner/{resolution => }/type-hierarchy.feature (99%) rename behaviour/graql/reasoner/{resolution => }/value-predicate.feature (82%) rename behaviour/graql/reasoner/{resolution/variable-role.feature => variable-roles.feature} (100%) 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