Difference in owl:hasValue and owl:oneOf support in Jena's OWLMicroReasoner? - jena

I'm playing with deriving instance type from its value information using value restrictions:
:SpaceMission rdf:type owl:Class .
:shuttleUsed rdf:type owl:ObjectProperty ;
rdfs:domain :SpaceMission .
:Apollo11 rdf:type owl:NamedIndividual .
:Mission11 rdf:type :SpaceMission , owl:NamedIndividual ;
:shuttleUsed :Apollo11 .
:ApolloMission rdf:type owl:Class ;
owl:equivalentClass [ rdf:type owl:Class ;
owl:intersectionOf ( :SpaceMission
[ rdf:type owl:Restriction ;
owl:onProperty :shuttleUsed ;
owl:hasValue :Apollo11
]
)
] .
The single value restriction owl:hasValue works fine and the SPARQL for type of :Mission11 returns :SpaceMission and :ApolloMission as expected. Then I add the second value restriction for definition of the class :ApolloMission:
:Apollo13 rdf:type owl:NamedIndividual .
:ApolloMission rdf:type owl:Class ;
owl:equivalentClass [ rdf:type owl:Class ;
owl:intersectionOf ( :SpaceMission
[ rdf:type owl:Restriction ;
owl:onProperty :shuttleUsed ;
owl:someValuesFrom [ rdf:type owl:Class ;
owl:oneOf ( :Apollo11
:Apollo13
)
]
]
)
] .
(The restriction type has automatically changed from owl:hasValue to owl:someValuesFrom). In this case the expected inference of type :ApolloMission for the individual :Mission11 is not returned, but only the :SpaceMission. Do I have something wrong? Or the the type inference is only possible with value restriction of type owl:hasValue?
I'm using Jena's OWLMicroReasoner and running the SPARQL query for
{<:Mission11> a ?type}. Maybe it is not able to infer from owl:someValuesFrom restriction. As I said the owl:hasValue restriction did work with Jena's micro reasoner. Does Jena's built-in reasoner support the owl:someValuesFrom restriction?

It's generally more helpful if you can provide an entire ontology that we can work with for testing. This one isn't too big, so it wasn't too hard to recreate. At any rate, I've reproduced it, and it's included at the end of this answer.
The inference is valid in OWL
The inference you're looking for is valid in OWL, and we can see that by using a logically complete OWL reasoner, e.g., Pellet. We'll see this in Protégé (but you could have used Pellet with Jena, too.) Here's what the ontology, recreated in Protégé look like:
Then, when we enable the Pellet reasoner and ask for instances of ApolloMission, we get Mission11, as expected:
Since you said you were asking for the types of Mission11, perhaps you used a query like asking for superclass of {Mission11}. This produces the expected classes, too:
Reproduced Ontology
#prefix : <http://stackoverflow.com/q/21223545/1281433/space.owl#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix space: <http://stackoverflow.com/q/21223545/1281433/space.owl#> .
<http://stackoverflow.com/q/21223545/1281433/space.owl>
a owl:Ontology .
space:Mission11 a owl:NamedIndividual , space:SpaceMission ;
space:shuttleUsed space:Apollo11 .
space:shuttleUsed a owl:ObjectProperty ;
rdfs:domain space:SpaceMission .
space:Apollo13 a owl:Thing , owl:NamedIndividual .
space:ApolloMission a owl:Class ;
owl:equivalentClass [ a owl:Class ;
owl:intersectionOf ( space:SpaceMission [ a owl:Restriction ;
owl:onProperty space:shuttleUsed ;
owl:someValuesFrom [ a owl:Class ;
owl:oneOf ( space:Apollo13 space:Apollo11 )
]
] )
] .
space:SpaceMission a owl:Class .
space:Apollo11 a owl:Thing , owl:NamedIndividual .
Why you don't get some results with Jena's reasoners
Jena's reasoners are not complete. That doesn't mean that they're not finished; complete is a technical term in formal reasoning describing a reasoner (or algorithm, etc.) that means that there are correct inferences according to the semantics of the language that the reasoner won't produce. The reason that Jena's reasoners are incomplete has to do with the implementation strategy (using a rule-based reasoner), and with efficiency considerations (we can accept a trade-off between speed and the inferences that we can get).
For more about Jena's reasoners, you should look at Reasoners and rule engines: Jena inference support from the documentation. It's not entirely up to date though, as it says, for instance:
The critical constructs which go beyond OWL/lite and are not supported
in the Jena OWL reasoner are complementOf and oneOf. As noted above
the support for unionOf is partial (due to limitations of the rule
based approach) but is useful for traversing class hierarchies.
but as the following code shows, there is, in fact, support for owl:oneOf in some of the reasoners, and so some of the reasoners can make the ApolloMission inference that you want.
Jena provides a number of reasoners, and the easiest way to get an OntModel that is connected to them is by using the static OntModelSpecs that are declared in OntModelSpec. The following Java code shows that with the final ontology that you provided, the different reasoners provide different results. (The reflective code for getting the different OntModelSpecs is a bit hackish, but for a quick example, it's fine.) The code constructs an OntModel for each of the declared specs starting with "OWL_", and runs the query against them.
import java.lang.reflect.Field;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.ResultSetFormatter;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
public class JenaReasonersSpaceExample {
private final static String QUERY =
"PREFIX : <http://stackoverflow.com/q/21223545/1281433/space.owl#>\n" +
"select ?type where {\n" +
" :Mission11 a ?type .\n" +
"}\n";
private final static Model base =
ModelFactory.createDefaultModel()
.read( "file:///home/taylorj/tmp/ontologies/space/space.owl" );
public static void main(final String[] args) throws IllegalArgumentException, IllegalAccessException {
// Iterate through the fields of OntModelSpec and for each one whose name
// begins with "OWL_", assume that it's a static field (so that getField
// can accept null), and that its value is an OntModelSpec (so that we
// can cast and create an OntModel with it and the base model).
// that begin with "OWL_", and assume t
for ( final Field field : OntModelSpec.class.getFields() ) {
if ( field.getName().startsWith("OWL_") ) {
final OntModelSpec spec = (OntModelSpec) field.get(null);
final OntModel model = ModelFactory.createOntologyModel( spec, base );
// Run the query against the model (that will use the specified reasoner)
// and show the field that we used and the results that we get.
System.out.println( "\n=== "+field.getName()+" ===" );
ResultSetFormatter.out(QueryExecutionFactory.create(QUERY, model).execSelect());
}
}
}
}
The output follows. Some of the reasoners can infer that Mission11 is an ApolloMission. These are the ones used by the specs: OWL_MEM_RULE_INF, OWL_MEM_MINI_RULE_INF, OWL_DL_MEM_RULE_INF, and OWL_LITE_MEM_RULES_INF. It looks like you might want to stick to reasoners that have RULE in the name.
=== OWL_MEM ===
------------------------------------------------------------------------
| type |
========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
------------------------------------------------------------------------
=== OWL_MEM_RDFS_INF ===
------------------------------------------------------------------------
| type |
========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
| <http://www.w3.org/2000/01/rdf-schema#Resource> |
------------------------------------------------------------------------
=== OWL_MEM_TRANS_INF ===
------------------------------------------------------------------------
| type |
========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
------------------------------------------------------------------------
=== OWL_MEM_RULE_INF ===
-------------------------------------------------------------------------
| type |
=========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
| <http://www.w3.org/2002/07/owl#Thing> |
| _:b0 |
| <http://www.w3.org/2000/01/rdf-schema#Resource> |
| _:b1 |
| <http://stackoverflow.com/q/21223545/1281433/space.owl#ApolloMission> |
-------------------------------------------------------------------------
=== OWL_MEM_MICRO_RULE_INF ===
------------------------------------------------------------------------
| type |
========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
| <http://www.w3.org/2002/07/owl#Thing> |
| <http://www.w3.org/2000/01/rdf-schema#Resource> |
------------------------------------------------------------------------
=== OWL_MEM_MINI_RULE_INF ===
-------------------------------------------------------------------------
| type |
=========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
| <http://www.w3.org/2002/07/owl#Thing> |
| _:b0 |
| <http://www.w3.org/2000/01/rdf-schema#Resource> |
| _:b1 |
| <http://stackoverflow.com/q/21223545/1281433/space.owl#ApolloMission> |
-------------------------------------------------------------------------
=== OWL_DL_MEM ===
------------------------------------------------------------------------
| type |
========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
------------------------------------------------------------------------
=== OWL_DL_MEM_RDFS_INF ===
------------------------------------------------------------------------
| type |
========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
| <http://www.w3.org/2000/01/rdf-schema#Resource> |
------------------------------------------------------------------------
=== OWL_DL_MEM_TRANS_INF ===
------------------------------------------------------------------------
| type |
========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
------------------------------------------------------------------------
=== OWL_DL_MEM_RULE_INF ===
-------------------------------------------------------------------------
| type |
=========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
| <http://www.w3.org/2002/07/owl#Thing> |
| _:b0 |
| <http://www.w3.org/2000/01/rdf-schema#Resource> |
| <http://stackoverflow.com/q/21223545/1281433/space.owl#ApolloMission> |
| _:b1 |
-------------------------------------------------------------------------
=== OWL_LITE_MEM ===
------------------------------------------------------------------------
| type |
========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
------------------------------------------------------------------------
=== OWL_LITE_MEM_TRANS_INF ===
------------------------------------------------------------------------
| type |
========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
------------------------------------------------------------------------
=== OWL_LITE_MEM_RDFS_INF ===
------------------------------------------------------------------------
| type |
========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
| <http://www.w3.org/2000/01/rdf-schema#Resource> |
------------------------------------------------------------------------
=== OWL_LITE_MEM_RULES_INF ===
-------------------------------------------------------------------------
| type |
=========================================================================
| <http://stackoverflow.com/q/21223545/1281433/space.owl#SpaceMission> |
| <http://www.w3.org/2002/07/owl#NamedIndividual> |
| <http://www.w3.org/2002/07/owl#Thing> |
| _:b0 |
| <http://www.w3.org/2000/01/rdf-schema#Resource> |
| <http://stackoverflow.com/q/21223545/1281433/space.owl#ApolloMission> |
| _:b1 |
-------------------------------------------------------------------------

Related

Include path has been specified but still failed to include the header in the path in a Bazel C++ project

I have projects with a directory structure like that
---root
| |--src
| |--project1
| |--model
| | |--incude
| | | |--model
| | | |--modelA.hpp
| | | |--modelB.hpp
| | |--modelA.cpp
| | |--modelB.cpp
| | |--BUILD #1
| |...
| |--view
| |...
| |--common
| | |--include
| | |--common
| | |--data_type.hpp
| |--BUILD #2
|--WORKSPACE
As I have other package in this project and some of them use the same self-defined data type, I defined them in a package named common.
Now I include the data_type.hpp in file modelA.hpp
...
#include "common/data_type.hpp
...
Refering to the stage3 example in the tutorial, the BUID(#1) is like that
cc_library(
name = "modelA",
hdrs = "include/model/modelA.hpp",
deps = ["//src/project/common:data_type"],
copts = ["-Isrc/project/common/include"],
)
and the BUILD(#2) which defines the depedency module data_typeis like that
cc_library(
name = "data_type",
hdrs = ["include/common/data_type.hpp"],
visibility = ["//visibility:public"],
)
However, when I built the code, I got
src/project/model/include/model/modelA.hpp: fatal error: common/data_type.hpp: No such file or directory
Why I have defined copts = ["-Isrc/heimdallr/common/include"] but still got this error?
Please check the Header inclusion checking section of C/C++ Rules from the Bazel document. Relative to the workspace directory, all include paths should be created. Kindly refer to this issue for more information. Thank you!

DRBD StandAlone with new resource

I have two nodes "A" (primary) & "B". Each node have 3 resources. On node "B" i replace disks and after that i add each resource as secondary. Two resources successfully connect and sync, but with one resource i have issue. When on node "B" i stop this resource, node "A" shows
lv1 role:Primary
disk:UpToDate
b.host connection:Connecting
When i starts this resource on node "B", node "A" shows:
lv1 role:Primary
disk:UpToDate
b.host connection:StandAlone
and node "B" shows:
lv1 role:Secondary
disk:Inconsistent
a.host connection:Connecting
I try everything, remove/add resource, metadata on node "B", remove data, rebuild raid drbdadm connect lv1 --discard-my-data etc.
One difference between worked an broken resources is This node was a crashed primary, and has not seen its peer since
+--< Current data generation UUID >-
| +--< Bitmap's base data generation UUID >-
| | +--< younger history UUID >-
| | | +-< older history >-
V V V V
E43824C7BC375B4A:626476078D91E933:CC1DC3FAD143EDCC:E4E71860FBA887C2:1:1:1:1:0:0:0:0:0:0:0:1
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
-< Data consistency flag >--+ | | | | | | | | | | |
-< Data was/is currently up-to-date >--+ | | | | | | | | | |
-< Node was/is currently primary >--+ | | | | | | | | |
-< This node was a crashed primary, and has not seen its peer since >--+ | | | | | | | |
-< The activity-log was applied, the disk can be attached >--+ | | | | | | |
-< The activity-log was disabled, peer is completely out of sync >--+ | | | | | |
-< This node was primary when it lost quorum >--+ | | | | |
-< Node was/is currently connected >--+ | | | |
-< The peer's disk was out-dated or inconsistent >--+ | | |
-< A fence policy other the dont-care was used >--+ | |
-< Node was in the progress of marking all blocks as out of sync >--+ |
-< At least once we saw this node with a backing device attached >--+
Any ideas how i can fix it?
UPD: Find new differences a kernel: drbd lv1/0 drbd1 b.host: The peer's disk size is too small! (999671944 < 1000196216 sectors)
In my case on node "A" (primary) i have LVM, on node "B" i have MDRAID. This differences give me difference in resource size in 524 272 sectors. What i do to save my data. I run both resources in primary mode, mount and copy data from "A" to "B", then i rebuild node "A" to MDRAID and sync resources.

How to get a parse NLP Tree object from bracketed parse string with nltk or spacy?

I have a sentence "You could say that they regularly catch a shower , which adds to their exhilaration and joie de vivre." and I can't achieve to get the NLP parse tree like the following example:
(ROOT (S (NP (PRP You)) (VP (MD could) (VP (VB say) (SBAR (IN that) (S (NP (PRP they)) (ADVP (RB regularly)) (VP (VB catch) (NP (NP (DT a) (NN shower)) (, ,) (SBAR (WHNP (WDT which)) (S (VP (VBZ adds) (PP (TO to) (NP (NP (PRP$ their) (NN exhilaration)) (CC and) (NP (FW joie) (FW de) (FW vivre))))))))))))) (. .)))
I want to replicate the solution to this question https://stackoverflow.com/a/39320379 but I have a string sentence instead of the NLP tree.
BTW, I am using python 3
Use the Tree.fromstring() method:
>>> from nltk import Tree
>>> parse = Tree.fromstring('(ROOT (S (NP (PRP You)) (VP (MD could) (VP (VB say) (SBAR (IN that) (S (NP (PRP they)) (ADVP (RB regularly)) (VP (VB catch) (NP (NP (DT a) (NN shower)) (, ,) (SBAR (WHNP (WDT which)) (S (VP (VBZ adds) (PP (TO to) (NP (NP (PRP$ their) (NN exhilaration)) (CC and) (NP (FW joie) (FW de) (FW vivre))))))))))))) (. .)))')
>>> parse
Tree('ROOT', [Tree('S', [Tree('NP', [Tree('PRP', ['You'])]), Tree('VP', [Tree('MD', ['could']), Tree('VP', [Tree('VB', ['say']), Tree('SBAR', [Tree('IN', ['that']), Tree('S', [Tree('NP', [Tree('PRP', ['they'])]), Tree('ADVP', [Tree('RB', ['regularly'])]), Tree('VP', [Tree('VB', ['catch']), Tree('NP', [Tree('NP', [Tree('DT', ['a']), Tree('NN', ['shower'])]), Tree(',', [',']), Tree('SBAR', [Tree('WHNP', [Tree('WDT', ['which'])]), Tree('S', [Tree('VP', [Tree('VBZ', ['adds']), Tree('PP', [Tree('TO', ['to']), Tree('NP', [Tree('NP', [Tree('PRP$', ['their']), Tree('NN', ['exhilaration'])]), Tree('CC', ['and']), Tree('NP', [Tree('FW', ['joie']), Tree('FW', ['de']), Tree('FW', ['vivre'])])])])])])])])])])])])]), Tree('.', ['.'])])])
>>> parse.pretty_print()
ROOT
|
S
______________________________________________________|_____________________________________________________________
| VP |
| ____|___ |
| | VP |
| | ___|____ |
| | | SBAR |
| | | ____|_______ |
| | | | S |
| | | | _______|____________ |
| | | | | | VP |
| | | | | | ____|______________ |
| | | | | | | NP |
| | | | | | | __________|__________ |
| | | | | | | | | SBAR |
| | | | | | | | | ____|____ |
| | | | | | | | | | S |
| | | | | | | | | | | |
| | | | | | | | | | VP |
| | | | | | | | | | ____|____ |
| | | | | | | | | | | PP |
| | | | | | | | | | | ____|_____________________ |
| | | | | | | | | | | | NP |
| | | | | | | | | | | | ________________|________ |
NP | | | NP ADVP | NP | WHNP | | NP | NP |
| | | | | | | ___|____ | | | | ____|_______ | ____|____ |
PRP MD VB IN PRP RB VB DT NN , WDT VBZ TO PRP$ NN CC FW FW FW .
| | | | | | | | | | | | | | | | | | | |
You could say that they regularly catch a shower , which adds to their exhilaration and joie de vivre .
I am going to assume there is a good reason as to why you need the dependency parse tree in that format. Spacy does a great job by using a CNN (Convolutional Neural Network) to produce CFGs (Context-Free Grammars), is production ready, and is super-fast. You can do something like the below to see for yourself (and then read the docs in the prior link):
import spacy
nlp = spacy.load('en')
text = 'You could say that they regularly catch a shower , which adds to their exhilaration and joie de vivre.'
for token in nlp(text):
print(token.dep_, end='\t')
print(token.idx, end='\t')
print(token.text, end='\t')
print(token.tag_, end='\t')
print(token.head.text, end='\t')
print(token.head.tag_, end='\t')
print(token.head.idx, end='\t')
print(' '.join([w.text for w in token.subtree]), end='\t')
print(' '.join([w.text for w in token.children]))
Now, you could make an algorithm to navigate this tree, and print accordingly (I couldn't find a quick example, sorry, but you can see the indexes and how to traverse the parse). Another thing you could do is to extract the CFG somehow, and then use NLTK to do the parsing and subsequent displaying in the format you desire. This is from the NLTK playbook (modified to work with Python 3):
import nltk
from nltk import CFG
grammar = CFG.fromstring("""
S -> NP VP
VP -> V NP | V NP PP
V -> "saw" | "ate"
NP -> "John" | "Mary" | "Bob" | Det N | Det N PP
Det -> "a" | "an" | "the" | "my"
N -> "dog" | "cat" | "cookie" | "park"
PP -> P NP
P -> "in" | "on" | "by" | "with"
""")
text = 'Mary saw Bob'
sent = text.split()
rd_parser = nltk.RecursiveDescentParser(grammar)
for p in rd_parser.parse(sent):
print(p)
# (S (NP Mary) (VP (V saw) (NP Bob)))
However, you can see that you need to define the CFG (so if you tried your original text in place of the example's, you saw that it didn't understand the tokens not defined in the CFG).
It seems the easiest way to obtain your desired format is using Stanford's NLP parser. Taken from this SO question (and sorry, I haven't tested it):
parser = StanfordParser(model_path='edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz')
parsed = parser.raw_parse('Jack payed up to 5% more for each unit')
for line in parsed:
print(line, end=' ') # This will print all in one line, as desired
I didn't test this because I don't have the time to install the Stanford Parser, which can be a bit of a cumbersome process (relative to installing Python modules), that is, assuming you are looking for a Python solution.
I hope this helps, and I'm sorry that it's not a direct answer.

Stardog 2.0 DataNotImpl cannot be cast to ClassExpression

I've created a (disk) database using stardog 2.0.0.
I've loaded my ontology and some data to this database.
I can see my ontology's axioms and this data when I execute the following command:
./stardog query -v --username user --passwd pass dbname "select * where { ?s ?p ?o }"
This is a selection of the returned axioms:
?s ?p ?o
| http://www.ugent.be/chest#Infection | rdf:type | owl:Class |
| http://www.ugent.be/chest#Infection | rdf:type | http://www.ugent.be/chest#RespiratoryInfection |
| http://www.ugent.be/chest#Infection | rdf:type | owl:NamedIndividual |
| http://www.ugent.be/chest#Infection | rdfs:subClassOf | http://www.ugent.be/chest#Pathology |
This is a selection of the returned data:
| <http://www.ugent.be/chest#Infection/4641> | rdf:type | <http://www.ugent.be/chest#Infection> |
| <http://www.ugent.be/chest#Infection/4642> | rdf:type | <http://www.ugent.be/chest#Infection> |
| <http://www.ugent.be/chest#Infection/4643> | rdf:type | <http://www.ugent.be/chest#Infection> |
| <http://www.ugent.be/chest#Infection/4644> | rdf:type | <http://www.ugent.be/chest#Infection> |
When I try to execute a query to retrieve all individuals with rdf:type Infection I get nothing.
./stardog query -v --username user --passwd pass "chest" "PREFIX : <http://www.ugent.be/chest#> select ?s where { ?s rdf:type :Infection }"
When I add reasoning type QL or EL I get
:Infection
When I add reasoning type DL I get:
com.clarkparsia.pellet.api.term.impl.entity.DataNotImpl cannot be cast to com.clarkparsia.pellet.api.term.entity.ClassExpression
The same goes for a consistency check.
Am i doiing something wrong?
DL reasoning is only permitted for queries over your TBox, so your given query won't be answered using reasoning; keep that in mind when using Stardog's reasoning capabilities.
With that said, you're never supposed to get a ClassCastException. Try with the latest Stardog, you're three releases behind, and if the problem still exists, send a self-contained minimal example to the mailing list and we'll be happy to fix it.

LALR Parser Generator Implementation Problem

I'm currently trying to implement a LALR parser generator as described in "compilers principles techniques and tools" (also called "dragon book").
A lot already works. The parser generator is currently able to generate the full goto-graph.
Example Grammar:
S' --> S
S --> C C
C --> c C
C --> d
Nonterminals: S', S, C
Terminals: c, d
Start: S'
The goto-graph:
I[0]---------------+ I[1]-------------+
| S' --> . S , $ |--S-->| S' --> S . , $ |
| S --> . C C , $ | +----------------+
| C --> . c C , c |
| C --> . c C , d | I[2]--------------+
| C --> . d , c | | S --> C . C , $ | I[3]--------------+
| C --> . d , d |--C-->| C --> . c C , $ |--C-->| S --> C C . , $ |
+------------------+ | C --> . d , $ | +-----------------+
| | +-----------------+
| | +--c--+ | |
| | | | c |
| | | v v |
| | I[4]--------------+ |
| c | C --> c . C , c | |
| | | C --> c . C , d | |
| | | C --> c . C , $ | d
| | | C --> . c C , c | |
| +---->| C --> . c C , d | |
| | C --> . c C , $ | |
d | C --> . d , c |--+ |
| +-----| C --> . d , d | | |
| | | C --> . d , $ | | |
| | +-----------------+ | |
| C | |
| | I[6]--------------+ | |
| | | C --> c C . , c | d |
| +---->| C --> c C . , d | | |
| | C --> c C . , $ | | |
| +-----------------+ | |
| | |
| I[5]------------+ | |
| | C --> d . , c |<---+ |
+------->| C --> d . , d | |
| C --> d . , $ |<-----+
+---------------+
I have trubbles with implementing the algorithm to generate the actions-table!
My algorithm computes the following output:
state | action
| c | d | $
------------------------
0 | s4 | s5 |
------------------------
1 | | | acc
------------------------
2 | s4 | s5 |
------------------------
3 | | | r?
------------------------
4 | s4 | s5 |
------------------------
5 | r? | r? | r?
------------------------
6 | r? | r? | r?
sx... shift to state x
rx... reduce to state x
The r? means that I don't know how to get the state (the ?) to which the parser should reduce. Does anyone know an algorithm to get ? using the goto-graph above?
If anything is describe no clearly enough, please ask and I will try to explain it better!
Thanks for your help!
A shift entry is attributed by the next state, but a reduce entry indicates a production.
When you shift, you push a state reference onto your stack and proceed to the next state.
When you reduce, this is for a specific production. The production was responsible for shifting n states onto your stack, where n is the number of symbols in that production. E.g. one for S', two for S, and two or one for C (i.e. for the first or second alternative for C).
After n entries are popped off the stack, you return to the state where you started processing that production. For that state and the nonterminal resulting from the production, you lookup the goto table to find the next state, which is then pushed.
So the reduce entries identify a production. In fact it may be sufficient to know the resulting nonterminal, and the number of symbols to pop.
Your table thus should read
state | action | goto
| c | d | $ | C | S
------------------------------------
0 | s4 | s5 | | 2 | 1
------------------------------------
1 | | | acc | |
------------------------------------
2 | s4 | s5 | | 3 |
------------------------------------
3 | | | r0 | |
------------------------------------
4 | s4 | s5 | | | 6
------------------------------------
5 | r3 | r3 | r3 | |
------------------------------------
6 | r2 | r2 | r2 | |
where rx indicates reduce by production x.
You need to pop the stack and and find the next state from there.
The rx means: reduce using the production with the number x!
Then everything gets clear!
Simple pop the body of the production and shift the head back onto the top!

Resources