From 38e4dcd9a34dd9798d0a81b0fa526adbefb20d86 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 3 Jun 2019 22:01:52 +0200 Subject: [PATCH] Concept method to check of a "thing" is inferred --- lib/grakn/answer.ex | 3 +++ lib/grakn/concept/action.ex | 2 ++ lib/grakn/concept/thing.ex | 13 ++++++++++- lib/grakn/transaction.ex | 8 +++++++ lib/grakn/transaction/request.ex | 4 ++++ test/grakn/concept/thing_test.exs | 39 +++++++++++++++++++++++++++++++ test/test_helper.exs | 14 ++++++++++- 7 files changed, 81 insertions(+), 2 deletions(-) diff --git a/lib/grakn/answer.ex b/lib/grakn/answer.ex index 617a92f..fb549d1 100644 --- a/lib/grakn/answer.ex +++ b/lib/grakn/answer.ex @@ -100,5 +100,8 @@ defmodule Grakn.Answer do def unwrap({:schemaConcept_getLabel_res, %Session.SchemaConcept.GetLabel.Res{label: label}}), do: label + def unwrap({:thing_isInferred_res, %Session.Thing.IsInferred.Res{inferred: inferred}}), + do: inferred + def unwrap(other), do: other end diff --git a/lib/grakn/concept/action.ex b/lib/grakn/concept/action.ex index 4e05230..da6b531 100644 --- a/lib/grakn/concept/action.ex +++ b/lib/grakn/concept/action.ex @@ -12,6 +12,7 @@ defmodule Grakn.Concept.Action do | :get_schema_concept | :get_attribute_types | :concept_label + | :is_inferred? @type t :: %__MODULE__{name: name()} defstruct [:name] @@ -24,6 +25,7 @@ defmodule Grakn.Concept.Action do def get_schema_concept, do: new(:get_schema_concept) def get_attribute_types, do: new(:get_attribute_types) def concept_label, do: new(:concept_label) + def is_inferred?, do: new(:is_inferred?) end defimpl DBConnection.Query, for: Grakn.Concept.Action do diff --git a/lib/grakn/concept/thing.ex b/lib/grakn/concept/thing.ex index ea58bbb..03aeefb 100644 --- a/lib/grakn/concept/thing.ex +++ b/lib/grakn/concept/thing.ex @@ -9,7 +9,7 @@ defmodule Grakn.Concept.Thing do @doc """ Get all attributes of the specified types associated with this instance """ - @spec get_attributes(Concept.t(), [String.t()], DBConnection.t()) :: + @spec get_attributes(Concept.t(), [String.t()], DBConnection.t(), keyword()) :: {:ok, any()} | {:error, any()} def get_attributes(%{id: concept_id} = concept, attribute_types, conn, opts \\ []) do with :ok <- assert_is_thing(concept) do @@ -17,6 +17,17 @@ defmodule Grakn.Concept.Thing do end end + @doc """ + Check if a given instance is inferred (i.e. implicit) + """ + @spec is_inferred?(Concept.t(), DBConnection.t(), keyword()) :: + {:ok, any()} | {:error, any()} + def is_inferred?(%{id: concept_id} = concept, conn, opts \\ []) do + with :ok <- assert_is_thing(concept) do + DBConnection.execute(conn, Action.is_inferred?(), [concept_id], opts) + end + end + defp assert_is_thing(concept) do if Concept.is_thing(concept) do :ok diff --git a/lib/grakn/transaction.ex b/lib/grakn/transaction.ex index 62c670c..46325da 100644 --- a/lib/grakn/transaction.ex +++ b/lib/grakn/transaction.ex @@ -128,6 +128,14 @@ defmodule Grakn.Transaction do end end + def is_inferred?(tx, concept_id) when is_binary(concept_id) do + send_request(tx, Request.is_inferred?(concept_id)) + + with {:ok, %{res: answer}} <- get_response(tx) do + {:ok, Grakn.Answer.unwrap(answer)} + end + end + def concept_label(tx, concept_id) when is_binary(concept_id) do send_request(tx, Request.concept_label(concept_id)) diff --git a/lib/grakn/transaction/request.ex b/lib/grakn/transaction/request.ex index 1e87861..ec11d50 100644 --- a/lib/grakn/transaction/request.ex +++ b/lib/grakn/transaction/request.ex @@ -50,6 +50,10 @@ defmodule Grakn.Transaction.Request do concept_method_request(concept_id, :type_attributes_req, Session.Type.Attributes.Req.new()) end + def is_inferred?(concept_id) do + concept_method_request(concept_id, :thing_isInferred_req, Session.Thing.IsInferred.Req.new()) + end + def concept_label(concept_id) do concept_method_request( concept_id, diff --git a/test/grakn/concept/thing_test.exs b/test/grakn/concept/thing_test.exs index 0e5028a..4fd48d5 100644 --- a/test/grakn/concept/thing_test.exs +++ b/test/grakn/concept/thing_test.exs @@ -59,4 +59,43 @@ defmodule Grakn.Concept.ThingTest do assert "alex" === name end end + + describe "is_inferred?/3" do + test "we can detect inferred atttributes", context do + assert {:ok, _} = + Grakn.transaction( + context[:conn], + fn conn -> + Grakn.query!( + conn, + Query.graql( + "insert $p isa person, has identifier \"1234\", has name \"alex\";" + ) + ) + end, + keyspace: @keyspace, + type: Grakn.Transaction.Type.write() + ) + + assert {:ok, true} === + Grakn.transaction( + context[:conn], + fn conn -> + [%{"is_named" => is_named}] = + Grakn.query!( + conn, + Query.graql( + "match $p isa person, has identifier \"1234\"; $p has is_named $is_named; get;" + ), + include_inferences: true + ) + + {:ok, value} = Concept.Thing.is_inferred?(is_named, conn) + value + end, + keyspace: @keyspace, + type: Grakn.Transaction.Type.write() + ) + end + end end diff --git a/test/test_helper.exs b/test/test_helper.exs index 7a8abe4..6566be3 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -31,8 +31,20 @@ defmodule TestHelper do defp define_base_schema(conn) do Grakn.query!(conn, Query.graql("define name sub attribute, datatype string;")) + Grakn.query!(conn, Query.graql("define is_named sub attribute, datatype boolean;")) Grakn.query!(conn, Query.graql("define identifier sub attribute, datatype string;")) - Grakn.query!(conn, Query.graql("define person sub entity, has name, has identifier;")) + + Grakn.query!( + conn, + Query.graql("define person sub entity, has name, has is_named, has identifier;") + ) + + Grakn.query!( + conn, + Query.graql( + "define r1 sub rule, when { $p isa person; $p has name $name; }, then { $p has is_named true; };" + ) + ) end end