How to assert inverse triples via SHACL (provided that they do not yet exist?) - owl

I have an ontology in which each thematic role (e.g., has-agent) is represented via an object property. Furthermore, the inverse property is always defined (e.g., is-agent-of).
I want to assert in the ontology all inverse triples via SHACL rules PROVIDED THAT THEY DO NOT ALREADY EXIST.
Thus, I wrote the following rule:
:assertInverseTriplesOnHasAgent rdf:type sh:NodeShape;
sh:rule [rdf:type sh:TripleRule;
sh:condition
[
sh:not[
sh:property[
sh:path (TBox:has-agent TBox:is-agent-of);
sh:minCount 1;
sh:equals sh:this
]
]
];
sh:subject [sh:path TBox:has-agent];
sh:predicate TBox:is-agent-of;
sh:object sh:this
];
sh:targetSubjectsOf TBox:has-agent.
But it does not work: it asserts the inverse triples even when they already exist (and it shouldn't).
I suspect that "sh:equals sh:this" is not correct, i.e., that "sh:this" cannot be used within sh:property. On the other hand, "sh:minCount 1;" alone does not work because someone can be is-agent-of more than one action.
Can anyone help me? Thanks

Related

Query on TFP Probabilistic Model

In the TFP tutorial, the model output is Normal distribution. I noted that the output can be replaced by an IndependentNormal layer. In my model, the y_true is binary class. Therefore, I used an IndependentBernoulli layer instead of IndependentNormal layer.
After building the model, I found that it has two output parameters. It doesn't make sense to me since Bernoulli distribution has one parameter only. Do you know what went wrong?
# Define the prior weight distribution as Normal of mean=0 and stddev=1.
# Note that, in this example, the we prior distribution is not trainable,
# as we fix its parameters.
def prior(kernel_size, bias_size, dtype=None):
n = kernel_size + bias_size
prior_model = Sequential([
tfpl.DistributionLambda(
lambda t: tfd.MultivariateNormalDiag(loc=tf.zeros(n), scale_diag=tf.ones(n))
)
])
return prior_model
# Define variational posterior weight distribution as multivariate Gaussian.
# Note that the learnable parameters for this distribution are the means,
# variances, and covariances.
def posterior(kernel_size, bias_size, dtype=None):
n = kernel_size + bias_size
posterior_model = Sequential([
tfpl.VariableLayer(tfpl.MultivariateNormalTriL.params_size(n), dtype=dtype),
tfpl.MultivariateNormalTriL(n)
])
return posterior_model
# Create a probabilistic DL model
model = Sequential([
tfpl.DenseVariational(units=16,
input_shape=(6,),
make_prior_fn=prior,
make_posterior_fn=posterior,
kl_weight=1/X_train.shape[0],
activation='relu'),
tfpl.DenseVariational(units=16,
make_prior_fn=prior,
make_posterior_fn=posterior,
kl_weight=1/X_train.shape[0],
activation='sigmoid'),
tfpl.DenseVariational(units=tfpl.IndependentBernoulli.params_size(1),
make_prior_fn=prior,
make_posterior_fn=posterior,
kl_weight=1/X_train.shape[0]),
tfpl.IndependentBernoulli(1, convert_to_tensor_fn=tfd.Bernoulli.logits)
])
model.summary()
screenshot of the results executed the codes on Google Colab
I agree the summary display is confusing but I think this is an artifact of the way tfp layers are implemented to interact with keras. During normal operation, there will only be one return value from a DistributionLambda layer. But in some contexts (that I don't fully grok) DistributionLambda.call may return both a distribution and a side-result. I think the summary plumbing triggers this for some reason, so it looks like there are 2 outputs, but there will practically only be one. Try calling your model object on X_train, and you'll see you get a single distribution out (its type is actually something called TensorCoercible, which is a wrapper around a distribution that lets you pass it into tf ops that call tf.convert_to_tensor -- the resulting value for that op will be the result of calling your convert_to_tensor_fn on the enclosed distribution).
In summary, your distribution layer is fine but the summary is confusing. It could probably be fixed; I'm not keras-knowledgeable enough to opine on how hard it would be.
Side note: you can omit the event_shape=1 parameter -- the default value is (), or "scalar", which will behave the same.
HTH!

Multiple paths and existential quantification in SHACL rules (should I use sh:oneOrMorePath perhaps?)

I would like to understand how to handle multiple paths and existential quantification in SHACL rules. Let me exemplify my problem with a sample ontology.
The ontology includes the classes "Approve", "Legal", "Result", "Man", and "Machine", all disjoint. It has two properties "has-theme" and "come-from" and the following individuals:
:a rdf:type :Approve ;
:has-theme :r1,:r2 .
:r1 rdf:type :Result ;
:come-from :m1 .
:r2 rdf:type :Result ;
:come-from :m2 .
:m1 rdf:type :Man .
:m2 rdf:type :Machine .
Therefore: the Approve action ":a" has two themes: ":r1" and ":r2". The former comes from the Man ":m1", the latter comes from the Machine ":m2".
I want to write a SHACL rule stating that "Every Approve action having among its themes at least a Result that comes from a Man is Legal".
I tried this, that do NOT classify ":a" as Legal (but it should):
:testRule rdf:type sh:NodeShape;
sh:rule [rdf:type sh:TripleRule;
sh:condition :conditionTest;
sh:subject sh:this;
sh:predicate rdf:type;
sh:object ontology:Legal
];
sh:targetClass ontology:Approve.
:conditionTest
rdf:type sh:NodeShape;
sh:property
[
#IF the theme of the Approve action is a Result come from a Man
sh:path (ontology:has-theme ontology:come-from);
sh:class ontology:Man
].
The problem is that ":a" has two themes, one coming from a Man and the other from a Machine.
Then I read on the Web about sh:oneOrMorePath and I tried the following variants within sh:property:
sh:oneOrMorePath (ontology:has-theme ontology:come-from);
sh:path ([sh:oneOrMorePath ontology:has-theme] ontology:come-from);
sh:path (ontology:has-theme [sh:oneOrMorePath ontology:come-from]);
Nothing to do, these variants don't work either.
On the other hand, if I remove the triple ":r2 :come-from :m2" or the triple ":a :has-theme :r2"
it works, as there is no more in the ontology a branch leading from ":a" to a non-Man.
Could any of you be so kind to help me?
Thank you!
Livio
Your requirements states "having among its themes at least a Result that comes from a Man" which sounds like an existential constraint to me. So you cannot really use sh:class here, but you may rather want to use a qualified value constraint.
I have not tried it, but something like this may work:
:conditionTest
rdf:type sh:NodeShape ;
sh:property [
sh:path (ontology:has-theme ontology:come-from) ;
sh:qualifiedMinCount 1 ;
sh:qualifiedValueShape [
sh:class ontology:Man ;
]
] .
This should mean that at least one of the values of the path has-theme/come-from must conform to the qualified value shape, which means that it must be an instance of Man.
See https://www.w3.org/TR/shacl/#QualifiedValueShapeConstraintComponent for the specification of QVCs in SHACL.
If you can use SHACL-SPARQL and import the dash namespace, you could also simply write dash:hasValueWithClass ontology:Man, see http://datashapes.org/constraints.html#HasValueWithClassConstraintComponent

Embedding a path in the parameter of sh:lessThan

Connected to this question (and its previous ones):
Using sh:maxExclusive to compare (the values of) two datatype properties
I created a small ontology with three classes: DataSubject, MemberState, and Minor. There are two datatype properties: has-age and has-minimalage. The former is from DataSubject(s) to integers, the latter is from MemberState(s) to integers. Then there is an object property has-member-state from DataSubject(s) to MemberState(s).
Now we have the following individuals:
ontology:John
rdf:type ontology:DataSubject ;
ontology:has-age "20"^^xsd:positiveInteger ;
ontology:has-member-state ontology:Spain ;
.
ontology:Spain
rdf:type ontology:MemberState ;
ontology:has-minimalage "16"^^xsd:positiveInteger ;
.
And I want to write a SHACL rule saying that each DataSubject whose age is less than the minimal age of his member state is also an individual of the class Minor.
In light of the replies I got to my other questions, I tried:
sh:rule [
rdf:type sh:TripleRule ;
sh:condition [
sh:property [
sh:path ontology:has-age ;
sh:lessThan (ontology:has-member-state ontology:has-minimalage)
] ;
] ;
sh:subject sh:this ;
sh:predicate rdf:type;
sh:object ontology:Minor ;
] ;
Which does not work: it classifies John as Minor, but 20 is not less than 16. Of course I tried many other variants, e.g., "sh:lessThan[sh:node[sh:path (ontology:has-member-state ontology:has-minimalage)];];", many of which do not probably make any sense, but none of them work.
Can someone suggest me how to embed a path in the parameter of sh:lessThan?
I am sorry if I start being annoying with all these questions :-( I am new to SHACL and SPARQL but I am really trying my best to learn them out of all what I can find on the Web.
Thanks
Livio
The official spec is (hopefully) pretty clear that the values must be IRIs, i.e. only direct properties are permitted. You can however try to revert the logic and use a path at the property shape. Otherwise, fall back to SPARQL.

Is it possible to define a multi valued DataProperty in OWL2 specifying the different values it should take for a given case?

Im regenerating an ontology to OWL2 using the OWL-API and testing with Protégé.
There are some concepts that are subclass of many superclasses, and some DataProperties that should take multiple values, for example:
Artifactual Location & Artifactual Area
And I want to specify that:
• For Artifactual Location the DataProperty hasConcreteEntityType should take the values LOCATION and ARTIFACT
• For Artifactual Area the DataProperty hasConcreteEntityType should take the values ARTIFACTUAL_LOCATION and AREA
Class Tree & Class Descriptions
But after activating the reasoner, I get Artifactual Location misclassified to Nothing(but not both)
Inference Explanations
And I don't understand what's wrong with the inference explanation,but seems that there should be a third explanation like the second but related to the value AREA, so seems that doesn't support bi-valued properties like this, or, maybe there is another way to define and constraint the values of a multi-valued DataProperty or even the reasoner doesn't work fine with this,
im using Hermit 1.3.8.3
Quoting the comment on my previous answer (I've deleted the answer because it is incorrect)
[The ontology] should be here drive.google.com/file/d/0B2FYMQD3DD8DNWtteUlLcDgyTGM/ Look at the linguisticUnitType property for Morphosyntactic Unit, as I defined it (to have 2 values, MORPHOLOGICAL and SYNTACTIC) it is classified fine by the reasoner, but it doesn't behave the same with the properties hasConcreteEntityType and hasLocationType regarding the classes at Nothing Artifactual Area and Artifactual Location. I don't understand why for one case is fine but not for the other, because the properties and restrictions are defined in the same manner.
The problem is that Artifactual Area is defined as subclass of Location, which already restricts the values of hasConcreteType to only one value (LOCATION). In order to allow Artifactual Area to have exactly two values, the restriction on the superclass must be removed or amended.
For future reference, the fragment in Functional syntax is here:
Ontology(<http://localhost/pruebaLUO.owl>
DataPropertyDomain(:hasConcreteEntityType :ConcreteEntity)
DataPropertyRange(:hasConcreteEntityType DataOneOf("ARTIFACT"^^xsd:string "FOOD"^^xsd:string "LIVING_ENTITY"^^xsd:string "LOCATION"^^xsd:string "MATERIAL"^^xsd:string "ORGANIC_OBJECT"^^xsd:string "PHYSICAL_OBJECT"^^xsd:string "SUBSTANCE"^^xsd:string))
DataPropertyDomain(:hasLocationType :Location)
DataPropertyRange(:hasLocationType DataOneOf("3D"^^xsd:string "AREA"^^xsd:string "ARTIFACTUAL_LOCATION"^^xsd:string "GEOPOLITICAL"^^xsd:string "OPENING"^^xsd:string "OTHER"^^xsd:string))
DataPropertyDomain(:linguisticUnitType :LinguisticUnit)
DataPropertyRange(:linguisticUnitType DataOneOf("MORPHOLOGICAL"^^xsd:string "SEMANTIC"^^xsd:string "SYNTACTIC"^^xsd:string))
AnnotationAssertion(rdfs:label :Area "Area"#en)
SubClassOf(:Area :Location)
SubClassOf(:Area DataHasValue(:hasLocationType "AREA"^^xsd:string))
AnnotationAssertion(rdfs:label :Artifact "Artifact"#en)
SubClassOf(:Artifact :ConcreteEntity)
SubClassOf(:Artifact DataHasValue(:hasConcreteEntityType "ARTIFACT"^^xsd:string))
SubClassOf(:ArtifactualArea :Area)
SubClassOf(:ArtifactualArea :ArtifactualLocation)
SubClassOf(:ArtifactualArea DataExactCardinality(2 :hasLocationType DataOneOf("AREA"^^xsd:string "ARTIFACTUAL_ LOCATION"^^xsd:string)))
SubClassOf(:ArtifactualLocation :Artifact)
SubClassOf(:ArtifactualLocation :Location)
SubClassOf(:ArtifactualLocation DataHasValue(:hasLocationType "ARTIFACTUAL_ LOCATION"^^xsd:string))
SubClassOf(:ArtifactualLocation DataExactCardinality(2 :hasConcreteEntityType DataOneOf("ARTIFACT"^^xsd:string "LOCATION"^^xsd:string)))
SubClassOf(:Building :ArtifactualLocation)
SubClassOf(:ConcreteEntity :GenericEntity)
SubClassOf(:Entity :PropositionalComponent)
SubClassOf(:GenericEntity :Entity)
SubClassOf(:Location :ConcreteEntity)
SubClassOf(:Location DataHasValue(:hasConcreteEntityType "LOCATION"^^xsd:string))
SubClassOf(:MorphologicalUnit :LinguisticUnit)
SubClassOf(:MorphologicalUnit DataHasValue(:linguisticUnitType "MORPHOLOGICAL"^^xsd:string))
SubClassOf(:MorphosyntacticUnit :MorphologicalUnit)
SubClassOf(:MorphosyntacticUnit :Token)
SubClassOf(:MorphosyntacticUnit DataExactCardinality(2 :linguisticUnitType DataOneOf("MORPHOLOGICAL"^^xsd:string "SYNTACTIC"^^xsd:string)))
SubClassOf(:PropositionalComponent :SemanticUnit)
SubClassOf(:SemanticUnit :LinguisticUnit)
SubClassOf(:SemanticUnit DataHasValue(:linguisticUnitType "SEMANTIC"^^xsd:string))
SubClassOf(:SyntacticUnit :LinguisticUnit)
SubClassOf(:SyntacticUnit DataHasValue(:linguisticUnitType "SYNTACTIC"^^xsd:string))
SubClassOf(:Token :SyntacticUnit)
)

SystemVerilog: How to create an interface which is an array of a simpler interfaces?

I'm attempting to create an interface that is an array of a simpler interface. In VHDL I could simply define two types, a record and an array of records. But how to do this in SystemVerilog? Here's what I've tried:
`define MAX_TC 15
...
interface scorecard_if;
score_if if_score [`MAX_TC];
endinterface
interface score_if;
integer tc;
integer pass;
integer fail;
bit flag_match;
real bandwidth;
endinterface
But I get an error from Aldec Active-HDL:
Error: VCP2571 TestBench/m3_test_load_tb_interfaces.sv : (53, 34):
Instantiations must have brackets (): if_score.
I also tried
interface scorecard_if;
score_if [`MAX_TC] if_score;
endinterface
and
interface scorecard_if;
score_if [`MAX_TC];
endinterface
but both of those just resulted in "Unexpected token" syntax errors.
Is it even possible to do this? There are two workarounds that I can think of if there isn't a way to do this. First I could define all the individual elements of score_if as unpacked arrays:
interface score_if;
integer tc [1:`MAX_TC];
integer pass [1:`MAX_TC];
integer fail [1:`MAX_TC];
bit flag_match [1:`MAX_TC];
real bandwidth [1:`MAX_TC];
endinterface
This compiles, but it's ugly in that I can no longer refer to a single score as a group.
I might also be to instantiate an array of score_if (using the original code), but I really want to instantiate scorecard_if inside a generate loop that would allow me instantiate a variable number of scorecard_if interfaces based on a parameter.
Just to provide a bit of explanation of what I'me trying to do, score_if is supposed to be a record of the score for a given test case, and scorecard_if an array for all of the test cases. But my testbench has multiple independent stimulus generators, monitors and scorecards to deal with multiple independent modules inside the DUT where the multiple is a parameter.
Part 1 : Declaring an array of interfaces
Add parentheses to the end of the interface instantiation. According to IEEE Std 1800-2012, all instantiations of hierarchical instances need the parentheses for the port list even if the port list is blank. Some tools allow dropping the parentheses if the interfaces doesn't have any ports in the declaration and and the instantiation is simple; but this is not part of the standard. Best practice is to use parentheses for all hierarchical instantiation.
Solution:
score_if if_score [`MAX_TC] () ;
Syntax Citations:
§ 25.3 Interface syntax & § A.4.1.2 Interface instantiation
interface_instantiation ::= // from A.4.1.2
interface_identifier [ parameter_value_assignment ] hierarchical_instance { , hierarchical_instance } ;
§ A.4.1.1 Module instantiation
hierarchical_instance ::= name_of_instance ( [ list_of_port_connections ] )
Part 2: Accessing elements for that array
Hierarchical references must be constant. Arrayed hierarchical instances cannot be accessed by dynamic indexes. It is an rule/limitation since at least IEEE Std 1364. Read more about it in IEEE Std 1800-2012 § 23.6 Hierarchical names, and the syntax rule is:
hierarchical_identifier ::= [ $root . ] { identifier constant_bit_select . } identifier
You could use a generate-for-loop, as it does an static unroll at compile/elaboration time. The limitation is you cannot use your display message our accumulate your fail count in the loop. You could use the generate loop to copy data to a local array and sum that, but that defeated your intention.
An interface is normally a bundle of nets used to connect modules with class-base test-bench or shared bus protocols. You are using it as a nested score card. A typedef struct would likely be better suited to your purpose. A struct is a data type and does not have the hierarchical reference limitation as modules and interfaces. It looked like you were already trying rout in your previous question. Not sure why you switched to nesting interfaces.
It looks like you are trying to create a fairly complex test environment. If so, I suggest learning UVM before spending to much time reinventing for a advance testbench architecture. Start with 1.1d as 1.2 isn't mainstream yet.
This also works:
1. define a "container" interface:
interface environment_if (input serial_clk);
serial_if eng_if[`NUM_OF_ENGINES](serial_clk);
virtual serial_if eng_virtual_if[`NUM_OF_ENGINES];
endinterface
2. in the testbench instantiate env_if connect serial_if with generate, connect the virtual if with the non virtual and pass the virtual if to the verification env:
module testbench;
....
environment_if env_if(serial_clk);
.....
dut i_dut(...);
genvar eng_idx
generate
for(eng_idx=0; eng_idx<`NUM_OF_ENGINES; eng_idx++) begin
env_if.eng_if[eng_idx].serial_bit = assign i_dut.engine[eng_idx].serial_bit;
end
endgenerate
......
initial begin
env_if.eng_virtual_if = env_if.eng_if[0:`NUM_OF_ENGINES-1];
//now possible to iterate over eng_virtual_if[]
for(int eng_idx=0; eng_idx<`NUM_OF_ENGINES; eng_idx++)
uvm_config_db#(virtual serial_if)::set(null, "uvm_test_top.env", "tx_vif", env_if.env_virtual_if[eng_idx]);
end
endmodule

Resources