I am working on ontologies issues. I code in java and I'm using Jena in order to manipulate some RDF/Turtle files.
Now I would like collect all the informations of an OntClass just knowing his name.
For example, I have this OntClass:
#prefix isys: <http://myonto.installsys/rule#> .
isys:Rule
rdf:type owl:Class ;
rdfs:comment "design principle rules are used in SIDP documents"^^xsd:string ;
rdfs:label "rule"^^xsd:string ;
rdfs:subClassOf owl:Thing ;
owl:equivalentClass [
rdf:type owl:Restriction ;
owl:onProperty ata:ata_number ;
owl:someValuesFrom xsd:integer ;
] ;
owl:equivalentClass [
rdf:type owl:Restriction ;
owl:onProperty isys:Number ;
owl:someValuesFrom xsd:integer ;
] ;
owl:equivalentClass [
rdf:type owl:Restriction ;
owl:onProperty isys:Object_1_a ;
owl:someValuesFrom xsd:string ;
] ;
.
And I suppose that I just have the prefix and Rule so I can do
OntClass Rule = onto.getOntClass("http://myonto.installsys/rule#Rule");
I am aware that I can use functions like listEquivalentClassor listSublClasse.
But I would like to know if there is a way to know all those informations with "one" function or I have to do it explicitly ?
Thank you, if you need more explications I will be glad to discuss
Related
I have such grammar:
grammar SearchQuery;
queryDeclaration : predicateGroupItem predicateGroupItemWithBooleanOperator* ;
predicateGroupItemWithBooleanOperator : groupOperator predicateGroupItem ;
predicateGroupItem : LEFT_BRACKET variable variableDelimiter
expression expressionWithBoolean* RIGHT_BRACKET ;
variable : VARIABLE_STRING ;
variableDelimiter : VAR_DELIMITER ;
expressionWithBoolean : boolOperator expression ;
expression : value ;
value : polygonType;
boolOperator : or
;
or : OR ;
groupOperator : AND ;
polygonType : POLYGON LEFT_BRACKET pointList (POLYGON_DELIMITER pointList)* RIGHT_BRACKET ;
longType : LONG ;
doubleType : DOUBLE ;
pointList : point
| LEFT_BRACKET point ( POLYGON_DELIMITER point)* RIGHT_BRACKET
;
point : latitude longitude ;
latitude : longType
| doubleType
;
longitude : longType
| doubleType
;
POLYGON : [pP] [oO] [lL] [yY] [gG] [oO] [nN] ;
LONG : DIGIT+ ;
DOUBLE : DIGIT+ '.' DIGIT*
| '.' DIGIT+
;
AND : [aA] [nN] [dD] ;
OR : COMMA
| [oO] [rR]
;
VARIABLE_STRING : [a-zA-Z0-9.]+ ;
COMMA : ',' ;
POLYGON_DELIMITER : ';' ;
VAR_DELIMITER : ':' ;
RIGHT_BRACKET : ')' ;
LEFT_BRACKET : '(' ;
WS : [ \t\r\n]+ -> skip ;
fragment DIGIT : [0-9] ;
Problem is that I can't use COMMA tag with different rules simultaneously in polygonType, pointList rules (I need to use COMMA except for POLYGON_DELIMITER) and boolOperator rule (there is COMMA used)
Other words, if we will change POLYGON_DELIMITER to COMMA and
test such grammar with a value like this
(polygons: polygon(20 30.4, 23.4 23),
polygon(20 30.4, 23.4 23),
polygon(20 30.4, 23.4 23))
we will get an error
mismatch input: ',' expecting {',', ')'}
I will happy if somebody will help me to understand the problem.
P.S. if we will not change current grammar the value for the testing it is
(poligons: polygon(20 30.4; 23.4 23),
polygon(20 30.4; 23.4 23),
polygon(20 30.4; 23.4 23))
Because of these rules:
OR : COMMA
| [oO] [rR]
;
COMMA : ',' ;
the lexer will never produce a COMMA token since it is already matched by the OR token. And because OR is defined before COMMA, it gets precedence.
That is what the error message mismatch input: ',' expecting {',', ')'} really means. In other words: mismatch input: OR expecting {COMMA, RIGHT_BRACKET}
What you should do (if the OR operator can be either "or" or ",") is let the parser rule or match the COMMA:
or : OR
| COMMA
;
OR : [oO] [rR]
;
COMMA : ',' ;
This is freaking me out, I just can't find a solution to it. I have a grammar for search queries and would like to match any searchterm in a query composed out of printable letters except for special characters "(", ")". Strings enclosed in quotes are handled separately and work.
Here is a somewhat working grammar:
/* ANTLR Grammar for Minidb Query Language */
grammar Mdb;
start
: searchclause EOF
;
searchclause
: table expr
;
expr
: fieldsearch
| searchop fieldsearch
| unop expr
| expr relop expr
| lparen expr relop expr rparen
;
lparen
: '('
;
rparen
: ')'
;
unop
: NOT
;
relop
: AND
| OR
;
searchop
: NO
| EVERY
;
fieldsearch
: field EQ searchterm
;
field
: ID
;
table
: ID
;
searchterm
:
| STRING
| ID+
| DIGIT+
| DIGIT+ ID+
;
STRING
: '"' ~('\n'|'"')* ('"' )
;
AND
: 'and'
;
OR
: 'or'
;
NOT
: 'not'
;
NO
: 'no'
;
EVERY
: 'every'
;
EQ
: '='
;
fragment VALID_ID_START
: ('a' .. 'z') | ('A' .. 'Z') | '_'
;
fragment VALID_ID_CHAR
: VALID_ID_START | ('0' .. '9')
;
ID
: VALID_ID_START VALID_ID_CHAR*
;
DIGIT
: ('0' .. '9')
;
/*
NOT_SPECIAL
: ~(' ' | '\t' | '\n' | '\r' | '\'' | '"' | ';' | '.' | '=' | '(' | ')' )
; */
WS
: [ \r\n\t] + -> skip
;
The problem is that searchterm is too restricted. It should match any character that is in the commented out NOT_SPECIAL, i.e., valid queries would be:
Person Name=%
Person Address=^%Street%%%$^&*#^
But whenever I try to put NOT_SPECIAL in any way into the definition of searchterm it doesn't work. I have tried putting it literally into the rule, too (commenting out NOT_SPECIAL) and many others things, but it just doesn't work. In most of my attempts the grammar just complained about extraneous input after "=" and said it was expecting EOF. But I also cannot put EOF into NOT_SPECIAL.
Is there any way I can simply parse every text after "=" in rule fieldsearch until there is a whitespace or ")", "("?
N.B. The STRING rule works fine, but the user ought not be required to use quotes every time, because this is a command line tool and they'd need to be escaped.
Target language is Go.
You could solve that by introducing a lexical mode that you'll enter whenever you match an EQ token. Once in that lexical mode, you either match a (, ) or a whitespace (in which case you pop out of the lexical mode), or you keep matching your NOT_SPECIAL chars.
By using lexical modes, you must define your lexer- and parser rules in their own files. Be sure to use lexer grammar ... and parser grammar ... instead of the grammar ... you use in a combined .g4 file.
A quick demo:
lexer grammar MdbLexer;
STRING
: '"' ~[\r\n"]* '"'
;
OPAR
: '('
;
CPAR
: ')'
;
AND
: 'and'
;
OR
: 'or'
;
NOT
: 'not'
;
NO
: 'no'
;
EVERY
: 'every'
;
EQ
: '=' -> pushMode(NOT_SPECIAL_MODE)
;
ID
: VALID_ID_START VALID_ID_CHAR*
;
DIGIT
: [0-9]
;
WS
: [ \r\n\t]+ -> skip
;
fragment VALID_ID_START
: [a-zA-Z_]
;
fragment VALID_ID_CHAR
: [a-zA-Z_0-9]
;
mode NOT_SPECIAL_MODE;
OPAR2
: '(' -> type(OPAR), popMode
;
CPAR2
: ')' -> type(CPAR), popMode
;
WS2
: [ \t\r\n] -> skip, popMode
;
NOT_SPECIAL
: ~[ \t\r\n()]+
;
Your parser grammar would start like this:
parser grammar MdbParser;
options {
tokenVocab=MdbLexer;
}
start
: searchclause EOF
;
// your other parser rules
My Go is a bit rusty, but a small Java test:
String source = "Person Address=^%Street%%%$^&*#^()";
MdbLexer lexer = new MdbLexer(CharStreams.fromString(source));
CommonTokenStream tokens = new CommonTokenStream(lexer);
tokens.fill();
for (Token t : tokens.getTokens()) {
System.out.printf("%-15s %s\n", MdbLexer.VOCABULARY.getSymbolicName(t.getType()), t.getText());
}
print the following:
ID Person
ID Address
EQ =
NOT_SPECIAL ^%Street%%%$^&*#^
OPAR (
CPAR )
EOF <EOF>
In the course of trying to selectively invoke shapes/rules when classes are asserted, I'm working with the following example shapes definition (in TTL):
# baseURI: http://example.org/familyShapes
# imports: http://datashapes.org/dash
# prefix: familyShapes
#prefix dash: <http://datashapes.org/dash#> .
#prefix familyShapes: <http://example.org/familyShapes#> .
#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 sh: <http://www.w3.org/ns/shacl#> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://example.org/familyShapes>
rdf:type owl:Ontology ;
owl:imports <http://datashapes.org/dash> ;
.
familyShapes:FemaleShape
rdf:type sh:NodeShape ;
rdfs:label "Female shape" ;
sh:property [
sh:path familyShapes:gender ;
sh:hasValue familyShapes:female ;
] ;
.
familyShapes:Gender
rdf:type rdfs:Class ;
rdfs:label "Gender" ;
rdfs:subClassOf rdfs:Resource ;
.
familyShapes:GrandpaRuleShape
rdf:type sh:NodeShape ;
rdfs:label "Grandpa rule shape" ;
sh:rule [
rdf:type sh:SPARQLRule ;
rdfs:comment "Shape to infer grandpa/grandchild relationship" ;
rdfs:label "Infer grandpas and grandchildren" ;
sh:construct """
PREFIX familyShapes: <http://example.org/familyShapes#>
CONSTRUCT {
?child familyShapes:grandPa $this .
$this familyShapes:grandChild ?child .
}
WHERE {
{
?child familyShapes:mother ?mom .
?mom familyShapes:father $this .
}
UNION
{
?child familyShapes:father ?dad .
?dad familyShapes:father $this .
}
}
""" ;
sh:order 10 ;
] ;
sh:targetClass familyShapes:Person ;
.
familyShapes:MaleShape
rdf:type sh:NodeShape ;
rdfs:label "Male shape" ;
sh:property [
sh:path familyShapes:gender ;
sh:hasValue familyShapes:male ;
] ;
.
familyShapes:Person
rdf:type rdfs:Class ;
rdf:type sh:NodeShape ;
rdfs:label "Person" ;
rdfs:subClassOf rdfs:Resource ;
sh:property [
rdf:type sh:PropertyShape ;
sh:path familyShapes:father ;
sh:class familyShapes:Person ;
sh:description "A Person's father." ;
sh:maxCount 1 ;
sh:name "father" ;
sh:node familyShapes:MaleShape ;
sh:nodeKind sh:IRI ;
sh:sparql [
sh:message "A person cannot be a father to that same person." ;
sh:select """PREFIX familyShapes: <http://example.org/familyShapes#>
SELECT $this
WHERE {
$this familyShapes:father $this .
}""" ;
] ;
] ;
sh:property [
rdf:type sh:PropertyShape ;
sh:path familyShapes:firstName ;
sh:datatype xsd:string ;
sh:description "A Person's first name (aka given name)." ;
sh:minCount 1 ;
sh:name "first name" ;
] ;
sh:property [
rdf:type sh:PropertyShape ;
sh:path familyShapes:gender ;
sh:class familyShapes:Gender ;
sh:description "A Person's gender." ;
sh:maxCount 1 ;
sh:minCount 1 ;
sh:name "gender" ;
] ;
sh:property [
rdf:type sh:PropertyShape ;
sh:path familyShapes:lastName ;
sh:datatype xsd:string ;
sh:description "A Person's last name (aka family name)." ;
sh:maxCount 1 ;
sh:minCount 1 ;
sh:name "last name" ;
] ;
sh:property [
rdf:type sh:PropertyShape ;
sh:path familyShapes:mother ;
sh:class familyShapes:Person ;
sh:description "A Person's mother." ;
sh:maxCount 1 ;
sh:name "mother" ;
sh:node familyShapes:FemaleShape ;
sh:nodeKind sh:IRI ;
sh:sparql [
rdfs:comment "A person cannot be that same person's mother." ;
sh:message "A person cannot be that same person's mother." ;
sh:select """PREFIX familyShapes: <http://example.org/familyShapes#>
SELECT $this
WHERE {
$this familyShapes:mother $this .
}""" ;
] ;
] ;
sh:rule [
rdf:type sh:SPARQLRule ;
rdfs:label "Infer grandmas and grandchildren" ;
sh:construct """PREFIX familyShapes: <http://example.org/familyShapes#>
CONSTRUCT {
?child familyShapes:grandMa $this .
$this familyShapes:grandChild ?child .
}
WHERE {
{
?child familyShapes:mother ?mom .
?mom familyShapes:mother $this .
}
UNION
{
?child familyShapes:father ?dad .
?dad familyShapes:mother $this .
}
}
""" ;
] ;
.
familyShapes:female
rdf:type familyShapes:Gender ;
rdfs:label "female" ;
.
familyShapes:firstName
rdf:type rdf:Property ;
rdfs:comment "A Person's first name (aka given name)." ;
rdfs:label "first name" ;
.
familyShapes:grandChild
rdf:type owl:ObjectProperty ;
rdfs:domain familyShapes:Person ;
rdfs:label "grand child" ;
rdfs:range familyShapes:Person ;
.
familyShapes:grandMa
rdf:type owl:ObjectProperty ;
rdfs:domain familyShapes:Person ;
rdfs:label "grand ma" ;
rdfs:range familyShapes:Person ;
.
familyShapes:grandPa
rdf:type owl:ObjectProperty ;
rdfs:domain familyShapes:Person ;
rdfs:label "grand pa" ;
rdfs:range familyShapes:Person ;
.
familyShapes:male
rdf:type familyShapes:Gender ;
rdfs:label "male" ;
.
familyShapes:mother
rdf:type rdf:Property ;
rdfs:comment "A Person's mother." ;
rdfs:label "mother" ;
.
I'm focused at this time on the familyShapes:GrandpaRuleShape shape (starting on line 30) which, I believe, on line 58 targets the familyShapes:Person class.
The SHACL API's RuleUtil.getShapesWithTargetNode method returns an empty list, which is not the result I was expecting, so I've created a temporary local copy of the RuleUtil.getShapesWithTargetNode method as shown below to help me debug my own code.
private static List<Shape> getShapesWithTargetNode(RDFNode focusNode, ShapesGraph shapesGraph) {
// TODO: Not a particularly smart algorithm - walks all shapes that have rules
List<Shape> shapes = new ArrayList<>();
for(Shape shape : shapesGraph.getRootShapes()) {
SHShape sr = shape.getShapeResource();
boolean shapeHasRule = sr.hasProperty(SH.rule);
boolean shapeFocused = sr.hasTargetNode(focusNode);
if(shapeHasRule && shapeFocused) {
shapes.add(shape);
}
}
return shapes;
}
I've stopped execution in the debugger in this method with focusNode=http://example.org/familyShapes#Person and the shapesGraph representing the shapes file above. The breakpoint is at the conditional in the for loop, after the two booleans have been assigned. The first value of shape is familyShapes:GrandpaRuleShape. However, the boolean shapeFocused is false. The boolean shapeHasRule is true as expected.
I was expecting that shapeFocused would be true at this point of execution. At a higher level, I was expecting that this method would return a list at least containing the grandpa shape, but it returns empty. I think I must be setting up the call to this method incorrectly, but I'm not sure what I'm doing wrong. Any suggestions?
I think it works correctly. Person is a class and the rule shape has the sh:targetClass Person. This means that the focus/target nodes are the instances of that class. If you invoke the function with a specific instance of Person then it should work.
I have implemented a function in ANTLR4.
Eg. - FUNCTION("A","B")
Grammar :
parse
: block EOF
;
block
: 'FUNCTION' LPAREN (atom)? COMMA (atom)? LPAREN
;
atom
: NIL #nilAtom
| list #arrayAtom
| type=(INT | DOUBLE) #numberAtom
| ID #idAtom
;
list
: BEGL array? ENDL
;
array
: array_element ( COMMA array_element )* # arrayValues
;
array_element
:
atom # array_element_types
;
COMMA : ',';
BEGL : '[';
LPAREN : '(';
RPAREN : ')';
ENDL : ']';
NIL : '' | 'null';
INT : [0-9]+ ;
DOUBLE : [0-9]+ '.' [0-9]* | '.' [0-9]+ ;
COMMENT : '#' ~[\r\n]* -> skip ;
SPACE : [ \t\r\n] -> skip ;
OTHER : . ;
For input FUNCTION(,"B"),
Not able to differentiate between first and second parameter.
Getting "B" as first parameter.
Thanks for help.
If you don't mind interpreting [] as list with one blank element:
list
: BEGL array ENDL
;
array
: array_element ( COMMA array_element )* # arrayValues
;
array_element
:
atom? # array_element_types
;
I try to write some parser rules for my assignment. In the assignment, we need to do the part "variable declaration" with some types. I had tried successfully with all types. For example:
int i;
or:
boolean bc;
But it does not work with the Array type. For example:
int a[5];
Here is the code I wrote:
vardecl: pritype id (COMMA id)* SEMI ;
pritype: INTTYPE | BOOLEANTYPE | FLOATTYPE | STRINGTYPE ;
id: ID | ID LSB INTLIT RSB ;
INTTYPE: 'int' ;
BOOLEANTYPE: 'boolean' ;
FLOATTYPE: 'float' ;
STRINGTYPE: 'string' ;
ID: [_a-zA-Z] [_a-zA-Z0-9]* ;
INTLIT: [0-9]+ -> type(INTTYPE) ;
LSB: '[' ;
RSB: ']' ;
COMMA: ',' ;
SEMI: ';' ;
Can you show me what I did wrong in order for the Array type to work. Thanks in advance!!
Your solution was very close, but channeling INTLIT to another channel was causing problems. I simplified it a bit and added handling for whitespace. But I added an array rule that will allow you to more easily handle this construct in your visitor or listener:
grammar Vardecl;
vardecl: pritype id (COMMA id)* SEMI ;
pritype: INTTYPE | BOOLEANTYPE | FLOATTYPE | STRINGTYPE ;
id: ID | ID array ;
array : LSB INTLIT RSB;
INTTYPE: 'int' ;
BOOLEANTYPE: 'boolean' ;
FLOATTYPE: 'float' ;
STRINGTYPE: 'string' ;
ID: [_a-zA-Z] [_a-zA-Z0-9]* ;
INTLIT: [0-9]+ ;
LSB: '[' ;
RSB: ']' ;
COMMA: ',' ;
SEMI: ';' ;
WS: [ \t\r\n] -> skip;
With this input:
int i[5], a[10];
You get this lexer tokenization:
[#0,0:2='int',<'int'>,1:0]
[#1,4:4='i',<ID>,1:4]
[#2,5:5='[',<'['>,1:5]
[#3,6:6='5',<INTLIT>,1:6]
[#4,7:7=']',<']'>,1:7]
[#5,8:8=',',<','>,1:8]
[#6,10:10='a',<ID>,1:10]
[#7,11:11='[',<'['>,1:11]
[#8,12:13='10',<INTLIT>,1:12]
[#9,14:14=']',<']'>,1:14]
[#10,15:15=';',<';'>,1:15]
[#11,16:15='<EOF>',<EOF>,1:16]
And this parse tree:
So I think you're good to go now.