InvalidTermReplacement error on reasoning with transitivity

Hello,
I am trying to test out some the reasoning functionality with Stardog. I have set up some virtual graphs that I have used to test some SPARQL queries already. I have now added a schema called "test_rules" that defines a property to be transitive using rules, as follows:

@prefix : <http://api.stardog.com/> .
@prefix famo: <http://ontology.eil.utoronto.ca/FAMO/famo/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix stardog: <tag:stardog:api:> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

:transitive_subroleof a <tag:stardog:api:rule:SPARQLRule> ;
    <tag:stardog:api:rule:content> """IF {
   ?x <http://ontology.eil.utoronto.ca/FAMO/famo/subRoleOf> ?y .
   ?y <http://ontology.eil.utoronto.ca/FAMO/famo/subRoleOf> ?z 
}
THEN {
   ?x <http://ontology.eil.utoronto.ca/FAMO/famo/subRoleOf> ?z .
}
""" .

When I run the query without reasoning, it successfully returns some results, however when I run the query with reasoning on the test_rules schema, I get the following error message:

"com.complexible.stardog.plan.eval.operator.OperatorException: Uncaught error during query evaluation: InvalidTermReplacement: Cannot transform a service node: SERVICE virtual://aiw in=[] out=[] {
  VirtualGraphSql<virtual://aiw> [#1] {
  RelNode=
     LogicalProject(aiw_role_id=[$0], project_phase_uuid=[$1], parent_role_id_verified=[$11])
       LogicalJoin(condition=[AND(=($1, $12), $2, IS NOT NULL($11))], joinType=[inner])
         JdbcTableScan(table=[[public, aiw_real_role_record_tbl]])
         JdbcTableScan(table=[[public, aiw_capital_phase_tbl]])
  Query=
     SELECT "aiw_real_role_record_tbl"."aiw_role_id", "aiw_real_role_record_tbl"."project_phase_uuid", "aiw_real_role_record_tbl"."parent_role_id_verified"
     FROM "public"."aiw_real_role_record_tbl"
     INNER JOIN "public"."aiw_capital_phase_tbl" ON "aiw_real_role_record_tbl"."project_phase_uuid" = "aiw_capital_phase_tbl"."phase_uuid" AND "aiw_real_role_record_tbl"."new_role" AND "aiw_real_role_record_tbl"."parent_role_id_verified" IS NOT NULL
  Vars=
     ?x2 <- TEMPLATE(_:{project_phase_uuid/1}_{aiw_role_id/0})
     ?x3 <- TEMPLATE(_:{project_phase_uuid/1}_{parent_role_id_verified/2}_role3)
  }
}"

Any insight into the error message and what is going wrong?

Thanks!
Megan

Hi Megan,

This might be a known issue based on the error message you're reporting. Could you attach the query plan for this query as well as the full error and stack trace from stardog.log? Lastly, is the virtual.transparency database option set to true?

Thanks,
-Paul

Hi Paul,
Thanks for the quick reply!
The query plan is:


The Query Plan:

prefix famo: <http://ontology.eil.utoronto.ca/FAMO/famo/>

From named <virtual://aiw>
Distinct
`─ Projection(?g, ?x2, ?x3) [#1]
   `─ PropertyPath(?x2 -> ?x3 in ?g, minLength=1) [#60K]
      `─ Bind(<virtual://aiw> AS ?g) [#4]
         `─ Union [#4]
            +─ Union [#3]
            │  +─ Union [#2]
            │  │  +─ VirtualGraphSql<virtual://aiw> [#1] {
            │  │  │  +─ RelNode=
            │  │  │  +─    LogicalProject(aiw_role_id=[$0], project_phase_uuid=[$1], parent_role_id_verified=[$11])
            │  │  │  +─      LogicalJoin(condition=[AND(=($1, $12), $2, IS NOT NULL($11))], joinType=[inner])
            │  │  │  +─        JdbcTableScan(table=[[public, aiw_real_role_record_tbl]])
            │  │  │  +─        JdbcTableScan(table=[[public, aiw_capital_phase_tbl]])
            │  │  │  +─ Query=
            │  │  │  +─    SELECT "aiw_real_role_record_tbl"."aiw_role_id", "aiw_real_role_record_tbl"."project_phase_uuid", "aiw_real_role_record_tbl"."parent_role_id_verified"
            │  │  │  +─    FROM "public"."aiw_real_role_record_tbl"
            │  │  │  +─    INNER JOIN "public"."aiw_capital_phase_tbl" ON "aiw_real_role_record_tbl"."project_phase_uuid" = "aiw_capital_phase_tbl"."phase_uuid" AND "aiw_real_role_record_tbl"."new_role" AND "aiw_real_role_record_tbl"."parent_role_id_verified" IS NOT NULL
            │  │  │  +─ Vars=
            │  │  │  +─    ?x2 <- TEMPLATE(_:{project_phase_uuid/1}_{aiw_role_id/0})
            │  │  │  +─    ?x3 <- TEMPLATE(_:{project_phase_uuid/1}_{parent_role_id_verified/2}_role3)
            │  │  │  }
            │  │  `─ VirtualGraphSql<virtual://aiw> [#1] {
            │  │     +─ RelNode=
            │  │     +─    LogicalProject(aiw_role_id=[$0], project_phase_uuid=[$1], parent_role_id_on_wms_record=[$10])
            │  │     +─      LogicalJoin(condition=[AND(=($1, $12), IS NOT NULL($10), NOT($2))], joinType=[inner])
            │  │     +─        JdbcTableScan(table=[[public, aiw_real_role_record_tbl]])
            │  │     +─        JdbcTableScan(table=[[public, aiw_capital_phase_tbl]])
            │  │     +─ Query=
            │  │     +─    SELECT "aiw_real_role_record_tbl"."aiw_role_id", "aiw_real_role_record_tbl"."project_phase_uuid", "aiw_real_role_record_tbl"."parent_role_id_on_wms_record"
            │  │     +─    FROM "public"."aiw_real_role_record_tbl"
            │  │     +─    INNER JOIN "public"."aiw_capital_phase_tbl" ON "aiw_real_role_record_tbl"."project_phase_uuid" = "aiw_capital_phase_tbl"."phase_uuid" AND "aiw_real_role_record_tbl"."parent_role_id_on_wms_record" IS NOT NULL AND NOT "aiw_real_role_record_tbl"."new_role"
            │  │     +─ Vars=
            │  │     +─    ?x2 <- TEMPLATE(_:{project_phase_uuid/1}_{aiw_role_id/0}_role1)
            │  │     +─    ?x3 <- TEMPLATE(_:{project_phase_uuid/1}_{parent_role_id_on_wms_record/2}_role0)
            │  │     }
            │  `─ VirtualGraphSql<virtual://aiw> [#1] {
            │     +─ RelNode=
            │     +─    LogicalProject(aiw_role_id=[$0], project_phase_uuid=[$1], parent_role_id_verified=[$11])
            │     +─      LogicalJoin(condition=[AND(=($1, $12), IS NOT NULL($11), NOT($2))], joinType=[inner])
            │     +─        JdbcTableScan(table=[[public, aiw_real_role_record_tbl]])
            │     +─        JdbcTableScan(table=[[public, aiw_capital_phase_tbl]])
            │     +─ Query=
            │     +─    SELECT "aiw_real_role_record_tbl"."aiw_role_id", "aiw_real_role_record_tbl"."project_phase_uuid", "aiw_real_role_record_tbl"."parent_role_id_verified"
            │     +─    FROM "public"."aiw_real_role_record_tbl"
            │     +─    INNER JOIN "public"."aiw_capital_phase_tbl" ON "aiw_real_role_record_tbl"."project_phase_uuid" = "aiw_capital_phase_tbl"."phase_uuid" AND "aiw_real_role_record_tbl"."parent_role_id_verified" IS NOT NULL AND NOT "aiw_real_role_record_tbl"."new_role"
            │     +─ Vars=
            │     +─    ?x2 <- TEMPLATE(_:{project_phase_uuid/1}_{aiw_role_id/0}_role2)
            │     +─    ?x3 <- TEMPLATE(_:{project_phase_uuid/1}_{parent_role_id_verified/2}_role3)
            │     }
            `─ VirtualGraphSql<virtual://aiw> [#1] {
               +─ RelNode=
               +─    LogicalProject(aiw_role_id=[$0], project_phase_uuid=[$1], parent_role_id_verified=[$11])
               +─      LogicalJoin(condition=[AND(=($1, $12), IS NOT NULL($11), NOT($2))], joinType=[inner])
               +─        JdbcTableScan(table=[[public, aiw_real_role_record_tbl]])
               +─        JdbcTableScan(table=[[public, aiw_capital_phase_tbl]])
               +─ Query=
               +─    SELECT "aiw_real_role_record_tbl"."aiw_role_id", "aiw_real_role_record_tbl"."project_phase_uuid", "aiw_real_role_record_tbl"."parent_role_id_verified"
               +─    FROM "public"."aiw_real_role_record_tbl"
               +─    INNER JOIN "public"."aiw_capital_phase_tbl" ON "aiw_real_role_record_tbl"."project_phase_uuid" = "aiw_capital_phase_tbl"."phase_uuid" AND "aiw_real_role_record_tbl"."parent_role_id_verified" IS NOT NULL AND NOT "aiw_real_role_record_tbl"."new_role"
               +─ Vars=
               +─    ?x2 <- TEMPLATE(_:{project_phase_uuid/1}_{aiw_role_id/0}_role3)
               +─    ?x3 <- TEMPLATE(_:{project_phase_uuid/1}_{parent_role_id_verified/2}_role3)
               }

I have attached the stardog.log file here stardog.log (68.0 KB), and I can confirm that the virtual.transparency option is set to true on the database.

Thanks again,
Megan

Hi Meagen,

Thanks for this information. It confirms what I suspected.

The very abbreviated version is that this specific problem is fixed with PLAT-2400 in version 7.6.4, which was released yesterday.

The longer version is that we have a couple problems with transitive property paths working with virtual transparency. (Transitive PP are queries with a + or * operator like in ?x <http://ontology.eil.utoronto.ca/FAMO/famo/subRoleOf>+ ?y. They are how our reasoning engine handles the rule in your example.)

PLAT-2400 fixes the case where a transitive PP appears in a variable context - a graph clause with a variable - like this:

SELECT * FROM NAMED stardog:context:all {
    GRAPH ?g {
        ?x <http://ontology.eil.utoronto.ca/FAMO/famo/subRoleOf>+ ?y
    }
}

but we still have the problem with transitive PP using the default context:

SELECT * FROM stardog:context:all {
    ?x <http://ontology.eil.utoronto.ca/FAMO/famo/subRoleOf>+ ?y
}

The distinction is that the former requires the entire chain of triples to be in the same graph while the latter can create chains using triples from different graphs. Your example fits the first example so 7.6.4 should work for you.

Thanks,
-Paul

Great, thank you! It's now working with the update. As an aside - there was also an issue in that the error message I received for this issue when working in Stardog Studio was confusing/not very appropriate, something like: "failed to run query: unexpected end of json".

Thanks again,
Megan

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.