Giter Club home page Giter Club logo

ont-api's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

ont-api's Issues

2.0.0: Jena Ontology API refactoring

For the upcoming release v2.0.0, the root domain name has been already changed,
so we can safely modify any other parts of the API.
This is the last chance, after the release, such an opportunity will no longer exist, so need to do it finally.

(note: this is a continuation of the issue https://github.com/avicomp/ont-api/issues/83)

So, there are following propositions:

1) changes in Ont[Graph]Model components naming

  • OntSWRL:
    • OntSWRL.Atom.BuiltIn -> OntSWRL.Atom.WithBuiltin
    • OntSWRL.Atom.OntClass -> OntSWRL.Atom.WithClass
    • OntSWRL.Atom.DataRange -> OntSWRL.Atom.WithDataRange
    • OntSWRL.Atom.ObjectProperty -> OntSWRL.Atom.WithObjectProperty
    • OntSWRL.Atom.DataProperty -> OntSWRL.Atom.WithDataProperty
    • OntSWRL.Atom.DifferentIndividuals -> OntSWRL.Atom.WithDifferentIndividuals
    • OntSWRL.Atom.SameIndividuals -> OntSWRL.Atom.WithSameIndividuals
  • Entities (OntEntity)
    • OntClass -> OntClass.Named
    • OntDT -> OntDataRange.Named
    • OntNOP -> OntObjectProperty.Named
    • OntNAP -> OntAnnotationProperty
    • OntNDP -> OntDataProperty
  • Class and Data Range expressions :
    • OntCE -> OntClass
    • OntDR -> OntDataRange
  • Property expressions:
    • OntOPE -> OntObjectProperty
    • OntProperty -> OntNamedProperty
    • OntDOP -> OntRealProperty
    • OntPE -> OntProperty
  • etc:
    • OntFR -> OntFacetRestriction
    • OntNPA.ObjectAssertion -> OntNegativeAssertion.WithObjectProperty
    • OntNPA.DataAssertion -> OntNegativeAssertion.WithDataProperty

2) changes in methods signatures

  • OntStatement#isAnnotation ->isAnnotationAssertion
  • OntStatement#isBulkAnnotation -> belongsToAnnotation
  • OntResource#getRoot -> getMainStatement
  • CreateRanges.* -> uniformity with CreateClasses
    • createOneOfDataRange -> createDataOneOf
    • createComplementOfDataRange -> createDataComplementOf
    • createUnionOfDataRange -> createDataUnionOf
    • createIntersectionOfDataRange -> createDataIntersectionOf
    • createRestrictionDataRange ->
  • CreateClasses.* -> uniformity with CreateRanges
    • createOneOf -> createObjectOneOf
    • createComplementOf -> createObjectComplementOf
    • createUnionOf -> createObjectUnionOf
    • createIntersectionOf -> createObjectIntersectionOf
  • etc ?

3) remove methods

  • OntStatement#isRoot
  • OntStatement#isObject
  • OntStatement#isData

Plans for new version to use OWL-API 5.1.16

There is a fix in OWL-API 5.1.16 that our project needs. We are currently using ONT-API 2.0.0 and appreciate the integration with Jena. Are there plans to create a new version of ONT-API that pulls in the latest OWL-API? It looks like Jena also has a more recent release.

Thanks for supporting this library.

Exception while axiom deletion when it reuse external components

The testcase:

    String ns = "http://x#";
    OntologyManager m = OntManagers.createONT();

    OntologyModel o = m.createOntology();
    OntGraphModel g = o.asGraphModel();
    g.createOntClass(ns + "X").addSuperClass(g.createOntClass(ns + "Y"));
    g.write(System.out, "ttl");
    o.axioms().forEach(System.out::println);

    List<RemoveAxiom> changes = o.axioms().map(x -> new RemoveAxiom(o, x)).collect(Collectors.toList());
    m.applyChanges(changes);
    g.write(System.out, "ttl");
    o.axioms().forEach(System.out::println);

Possible refactoring (general & changes due to switch to java11 in 3.x.x)

  • rename *Impl classes from the com.github.owlcs.ontapi.owlapi package (just delete prefix OWL) so as not to confuse them with the original OWLAPI-impl ones (also applicable for 2.x.x)
  • replace com.github.owlcs.ontapi.jena.utils.Iter#toUnmodifiable* with Collectors.* methods
  • Collections.unmodifiable* -> *.of,
  • replace new HashMap<>{ {put()} } syntax with Map.of (OntVocabulary, AxiomParserProvider, OWLCommonTransform)
  • diamond syntax for anonymous class instances
  • etc

2.0.0: Rename public API classes and other refactoring

Since the root package and the artifact names have been changed, there is an idea to change names of several major classes as well (for coming release 2.0.0).

Currently this proposition includes the following changes:

  1. com.github.owlcs.ontapi.OntologyModel (former ru.avicomp.ontapi.OntologyModel) -> com.github.owlcs.ontapi.Ontology.
    Why ?
    The suffix 'Model' is absent in OWL-API. Also it is a part name of graph-model (the current OntGraphModel). To distinguish RDF-view and OWL-view, better to leave suffix 'Model' for things from the first category.

  2. ONT-API top components:

    • OntologyID -> ID
      Because in this system only ontologies can have ids. Additional indication that this id belongs to the ontology is silly. Also, note, there is OntID in jena subsystem, where prefix Ont means it is OntObject. On top level there is no such mnemonic rule.
      Also, this class is an internal impl, actually it does no matter what is it name - nobody use it directly.
  3. com.github.owlcs.ontapi.jena.model.OntGraphModel (former ru.avicom.ontapi.jena.model.OntGraphModel) -> com.github.owlcs.ontapi.jena.model.OntModel.
    Why?
    Because the name OntModel is shorter, and therefore better.
    It makes no sense to emphasize it is a Graph model, since this fact is already encoded in the full class name (the package is *.jena.model.*). Any model in Jena is a graph model.
    The main argument why such a name (i.e. OntGraphModel) was chosen was desire to distinguish our model with jena org.apache.jena.ontology.OntModel.
    Now I think, this was not quit correct - both models hardly can live in one snippet simultaneously, and it would be better for clients to use only one model, either Jena’s or ours. Well, they actually can mix whatever they want, but it is just a marker of poor design. In functional sense, there should not be anything that org.apache.jena.ontology.OntModel could do, but our model (com.github.owlcs.ontapi.jena.model.OntModel) could not. Well, with except of inference.
    And we could not use the prefix Owl or OWL : the first one is just incorrect, and the second one is reserved by OWL-API. The prefix ONT is also incorrect - it is abbreviation, not acronym.
    So, the only right prefix is Ont, which leads to the same name - OntModel

  4. Jena Ontology API (RDF Model components) refactoring, see #8

  5. Move/rename com.github.owlcs.ontapi.jena.utils.BuiltIIn ( -> com.github.owlcs.ontapi.jena.OntVocabulary as analogue of org.semanticweb.owlapi.vocab.OWLRDFVocabulary ) + rename methods (add get prefix for methods returning collections, i.e. for all)

  6. com.github.owlcs.ontapi.transforms.Transform refactoring: get rid of Transform abstraction, that accept model/graph as constructor parameter, instead there should be stateless interface (currently it is GraphTransforms.Maker - but this is a bad name)

Optimize methods for searching OWLAxioms by OWLObject & Position & AxiomType

Not all methods of such kind have optimizations yet.
This could be critical for some systems and big ontologies.
This is the old issue, the source: https://github.com/avicomp/ont-api/issues/33

List of methods for optimization --

  • for OWLDatatype:
1 ::: Stream<OWLDatatypeDefinitionAxiom> axioms(OWLDatatype)
2 ::: Stream<OWLDatatypeDefinitionAxiom> datatypeDefinitions(OWLDatatype)
  • for OWLClass:
1 ::: Stream<OWLClassAxiom> axioms(OWLClass)
2 ::: Stream<OWLEquivalentClassesAxiom> equivalentClassesAxioms(OWLClass)
3 ::: Stream<OWLSubClassOfAxiom> subClassAxiomsForSuperClass(OWLClass)
4 ::: Stream<OWLSubClassOfAxiom> subClassAxiomsForSubClass(OWLClass)
5 ::: Stream<OWLDisjointClassesAxiom> disjointClassesAxioms(OWLClass)
6 ::: Stream<OWLDisjointUnionAxiom> disjointUnionAxioms(OWLClass)
7 ::: Stream<OWLClassAssertionAxiom> classAssertionAxioms(OWLClassExpression)
8 ::: Stream<OWLHasKeyAxiom> hasKeyAxioms(OWLClass)
  • for OWLIndividual:
1 ::: Stream<OWLIndividualAxiom> axioms(OWLIndividual)
2 ::: Stream<OWLClassAssertionAxiom> classAssertionAxioms(OWLIndividual)
3 ::: Stream<OWLSameIndividualAxiom> sameIndividualAxioms(OWLIndividual)
4 ::: Stream<OWLDifferentIndividualsAxiom> differentIndividualAxioms(OWLIndividual)
5 ::: Stream<OWLObjectPropertyAssertionAxiom> objectPropertyAssertionAxioms(OWLIndividual)
6 ::: Stream<OWLNegativeObjectPropertyAssertionAxiom> negativeObjectPropertyAssertionAxioms(OWLIndividual)
7 ::: Stream<OWLDataPropertyAssertionAxiom> dataPropertyAssertionAxioms(OWLIndividual)
8 ::: Stream<OWLNegativeDataPropertyAssertionAxiom> negativeDataPropertyAssertionAxioms(OWLIndividual)
  • for OWLObjectProperty:
1 ::: Stream<OWLObjectPropertyAxiom> axioms(OWLObjectPropertyExpression)
2 ::: Stream<OWLEquivalentObjectPropertiesAxiom> equivalentObjectPropertiesAxioms(OWLObjectPropertyExpression)
3 ::: Stream<OWLSubObjectPropertyOfAxiom> objectSubPropertyAxiomsForSuperProperty(OWLObjectPropertyExpression)
4 ::: Stream<OWLSubObjectPropertyOfAxiom> objectSubPropertyAxiomsForSubProperty(OWLObjectPropertyExpression)
5 ::: Stream<OWLInverseObjectPropertiesAxiom> inverseObjectPropertyAxioms(OWLObjectPropertyExpression)
6 ::: Stream<OWLFunctionalObjectPropertyAxiom> functionalObjectPropertyAxioms(OWLObjectPropertyExpression)
7 ::: Stream<OWLInverseFunctionalObjectPropertyAxiom> inverseFunctionalObjectPropertyAxioms(OWLObjectPropertyExpression)
8 ::: Stream<OWLSymmetricObjectPropertyAxiom> symmetricObjectPropertyAxioms(OWLObjectPropertyExpression)
9 ::: Stream<OWLAsymmetricObjectPropertyAxiom> asymmetricObjectPropertyAxioms(OWLObjectPropertyExpression)
10 ::: Stream<OWLTransitiveObjectPropertyAxiom> transitiveObjectPropertyAxioms(OWLObjectPropertyExpression)
11 ::: Stream<OWLReflexiveObjectPropertyAxiom> reflexiveObjectPropertyAxioms(OWLObjectPropertyExpression)
12 ::: Stream<OWLIrreflexiveObjectPropertyAxiom> irreflexiveObjectPropertyAxioms(OWLObjectPropertyExpression)
13 ::: Stream<OWLObjectPropertyDomainAxiom> objectPropertyDomainAxioms(OWLObjectPropertyExpression)
14 ::: Stream<OWLObjectPropertyRangeAxiom> objectPropertyRangeAxioms(OWLObjectPropertyExpression)
15 ::: Stream<OWLDisjointObjectPropertiesAxiom> disjointObjectPropertiesAxioms(OWLObjectPropertyExpression)
  • for OWLDataProperty:
1 ::: Stream<OWLDataPropertyAxiom> axioms(OWLDataProperty)
2 ::: Stream<OWLEquivalentDataPropertiesAxiom> equivalentDataPropertiesAxioms(OWLDataProperty)
3 ::: Stream<OWLSubDataPropertyOfAxiom> dataSubPropertyAxiomsForSuperProperty(OWLDataPropertyExpression)
4 ::: Stream<OWLSubDataPropertyOfAxiom> dataSubPropertyAxiomsForSubProperty(OWLDataProperty)
5 ::: Stream<OWLFunctionalDataPropertyAxiom> functionalDataPropertyAxioms(OWLDataPropertyExpression)
6 ::: Stream<OWLDataPropertyDomainAxiom> dataPropertyDomainAxioms(OWLDataProperty)
7 ::: Stream<OWLDataPropertyRangeAxiom> dataPropertyRangeAxioms(OWLDataProperty)
8 ::: Stream<OWLDisjointDataPropertiesAxiom> disjointDataPropertiesAxioms(OWLDataProperty)
  • for OWLAnnotationProperty:
1 ::: Stream<OWLAnnotationAxiom> axioms(OWLAnnotationProperty)
2 ::: Stream<OWLSubAnnotationPropertyOfAxiom> subAnnotationPropertyOfAxioms(OWLAnnotationProperty)
3 ::: Stream<OWLAnnotationPropertyRangeAxiom> annotationPropertyRangeAxioms(OWLAnnotationProperty)
4 ::: Stream<OWLAnnotationPropertyDomainAxiom> annotationPropertyDomainAxioms(OWLAnnotationProperty)

Need graph-way for collecting ontology signature and other non-axiom objects

The existing way is cache-based, but cache is optional.
Also need to add contains functionality.

The original issue: https://github.com/avicomp/ont-api/issues/91

Here is the result of research for OWLClass:

PIZZA_DEF :::: 0.004917777777777773 (iter=1800)
PIZZA_OP1 :::: 0.005793888888888896 (iter=1800)
PIZZA_OP2 :::: 2.0111111111111122E-4 (iter=1800)

FAMILY_DEF :::: 0.0057155555555555605 (iter=1800)
FAMILY_OP1 :::: 0.01308277777777759 (iter=1800)
FAMILY_OP2 :::: 1.5666666666666674E-4 (iter=1800)

PEOPLE_DEF :::: 0.0015594444444444451 (iter=1800)
PEOPLE_OP1 :::: 0.0026055555555555554 (iter=1800)
PEOPLE_OP2 :::: 1.661111111111112E-4 (iter=1800)

CAMERA_DEF :::: 4.7777777777777814E-4 (iter=1800)
CAMERA_OP1 :::: 7.361111111111111E-4 (iter=1800)
CAMERA_OP2 :::: 9.27777777777778E-5 (iter=1800)

KOALA_DEF :::: 7.161111111111113E-4 (iter=1800)
KOALA_OP1 :::: 0.001042777777777777 (iter=1800)
KOALA_OP2 :::: 2.255555555555557E-4 (iter=1800)

TRAVEL_DEF :::: 9.677777777777774E-4 (iter=1800)
TRAVEL_OP1 :::: 0.0015283333333333342 (iter=1800)
TRAVEL_OP2 :::: 2.127777777777779E-4 (iter=1800)

WINE_DEF :::: 0.004534444444444434 (iter=1800)
WINE_OP1 :::: 0.006112777777777789 (iter=1800)
WINE_OP2 :::: 1.4888888888888897E-4 (iter=1800)

FOOD_DEF :::: 0.0026238888888888904 (iter=1800)
FOOD_OP1 :::: 0.0031288888888888846 (iter=1800)
FOOD_OP2 :::: 2.1722222222222236E-4 (iter=1800)

NCBITAXON_CUT_DEF :::: 0.014476111111110846 (iter=1800)
NCBITAXON_CUT_OP1 :::: 0.02335722222222164 (iter=1800)
NCBITAXON_CUT_OP2 :::: 5.700000000000004E-4 (iter=1800)

HP_CUT_DEF :::: 7.311111111111114E-4 (iter=1800)
HP_CUT_OP1 :::: 0.0011872222222222217 (iter=1800)
HP_CUT_OP2 :::: 5.1666666666666664E-5 (iter=1800)

FAMILY_PEOPLE_UNION_DEF :::: 3.833333333333336E-4 (iter=1800)
FAMILY_PEOPLE_UNION_OP1 :::: 7.41111111111111E-4 (iter=1800)
FAMILY_PEOPLE_UNION_OP2 :::: 3.5222222222222247E-4 (iter=1800)

TMP_HP_NM_DEF :::: 1.7008555555555547 (iter=360)
TMP_HP_NM_OP1 :::: 2.225877777777778 (iter=360)
TMP_HP_NM_OP2 :::: 0.015452777777777758 (iter=360)

TMP_TTO_NM_DEF :::: 1.0611944444444465 (iter=360)
TMP_TTO_NM_OP1 :::: 2.481030555555556 (iter=360)
TMP_TTO_NM_OP2 :::: 0.02709444444444447 (iter=360)

DEF - is a classic way (loading axioms + parsing axioms's cache)
OP1 - loading axioms + reading graph
OP2 - reading graph

Optimize AxiomTranslator#containsONTObject(..) and #findONTObject(..) for the case of anonymous expression in main triple (Node.ANY)

this is a continuation of #20

Several axioms, such as SubClassOf, usually have named subject and anonymous object.
There is a searching by predicate (i.e. $any rdfs:subClassOf $any + filter) and refined searching for the case of named triple (exact match with $some rdfs:subClassOf $some - issue #20) .

Need a general way to optimize the cases of $some $some $any and $any $some $some.

ONTAPI loading behavior differs from OWLAPI-impl one

The behavior is different for ONTAPI and OWLAPI-impl.
e.g.

@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 xsd:  <http://www.w3.org/2001/XMLSchema#> .

<http://Y>  rdf:type  owl:Class .

[ <http://RP>  42 ] .

<http://RP>  rdf:type  rdf:Property .

<http://D>  rdf:type  rdfs:Datatype .

<http://DP>  rdf:type  owl:DatatypeProperty .

<http://X>  rdf:type  rdfs:Class .

ONTAPI axioms:

Declaration(Class(<http://Y>))
Declaration(Datatype(<http://D>))
Declaration(AnnotationProperty(<http://RP>))
Declaration(DataProperty(<http://DP>))
AnnotationAssertion(<http://RP> _:d218b4c5a8fa42a2481225de8088780e "42"^^xsd:integer)

OWLAPI-impl axioms:

Declaration(Class(<http://X>))
Declaration(DataProperty(<http://DP>))
Declaration(Class(<http://Y>))
Declaration(Datatype(<http://D>))
AnnotationAssertion(<http://RP> _:genid2147483648 "42"^^xsd:integer)

UDD
Now I think it's ok as the default behavior: you always can configure that behavior by adding/removing custom/builtin transformers.
So this is wontfix issue

Add OntExpression#asNamed() functionality

Nested interfaces and using class-types may confuse and look a bit difficult.
The functionality OntExpression#asNamed() seems to be a little more convenient than OntExpression#as(Named.class).
This would allow not to use '.Named' part everywhere, but use only OntClass, OntDataRange, etc, without their named parts implicitly. Therefore client-code would look better.

Although this is minor (i.e. "sugar") improvement, I don't see reasons why not.
In the OWL-community there are a lot of students and newbies, which might appreciate this functionality.

ont-api-OntModel: add syntactic sugar that corresponds to jena-OntModel functionality

  1. equivalent of jena's org.apache.jena.ontology.OntClass#listDeclaredProperties(direct:boolean),
    see doc https://jena.apache.org/documentation/notes/rdf-frames.html

  2. analogue of org.apache.jena.ontology.OntProperty#listDeclaringClasses(direct:boolean),

  3. etc

  4. maybe it's worth adding the class-properties functionality too
    https://github.com/sszuev/ont-dot/blob/master/src/main/java/com/github/sszuev/ontdot/utils/ClassPropertyMapImpl.java#L57 (listRelatedProperties ?)

Wrong equals/hashcode for several numeric literals (mismatch with default impl)

Not sure if this is a mistake/regression or is it due to recent changes in OWL-API.
Anyway it is a bug of ONT-API.
The testcase:

        OWLDataFactory owlapi = OntManagers.createOWL().getOWLDataFactory();
        DataFactory ontapi = OntManagers.getDataFactory();
        String value = "1922";
        OWL2Datatype dt = OWL2Datatype.XSD_POSITIVE_INTEGER;
        OWLLiteral x = owlapi.getOWLLiteral(value, dt);
        OWLLiteral z = ontapi.getOWLLiteral(value, dt);
        System.out.println(x.hashCode() + " ? " + z.hashCode());
        Assert.assertEquals(x, z);

review (improve) concurrent (rw) graph impl

the current implementation is time based - it use delays,
it doesn't seem to be very good solution,
also, there are other questionable solutions, e.g. each of the Iterator produced by the graph holds Thread reference, this may lead to memory leak.

[investigation] possible load optimization: use Seekable/Parallel reading

In case the serialization format (lang) is not provided we have to iterate all supported formats to find the best suitable.
This peace of code can be optimized using file rewinding or parallel running.
To compare:

Standard sequence reading

    private static void loadStd(Path p, int n, long lines) throws IOException {
        int step = n / 100;
        for (int i = 0; i < n; i++) {
            if (i % step == 0) {
                System.out.print("#");
            }
            try (BufferedReader r = Files.newBufferedReader(p)) {
                if (lines != r.lines().count()) {
                    throw new IllegalStateException();
                }
            }
        }
        System.out.println();
    }

vs SeekableByteChannel reading

    private static void loadNio(Path p, int n, long lines) throws IOException {
        int step = n / 100;
        try (SeekableByteChannel chanel = Files.newByteChannel(p, StandardOpenOption.READ)) {
            for (int i = 0; i < n; i++) {
                if (i % step == 0) {
                    System.out.print("#");
                }
                BufferedReader r = new BufferedReader(Channels.newReader(chanel, StandardCharsets.UTF_8));
                if (lines != r.lines().count()) {
                    throw new IllegalStateException();
                }
                chanel.position(0);
            }
        }
        System.out.println();
    }

vs concurrent reading

    private static void loadParallel(Path p, int n, long lines) throws ExecutionException, InterruptedException {
        System.out.println("Go");
        ExecutorService service = Executors.newWorkStealingPool();
        CompletableFuture<?>[] futures = IntStream.range(0, n).mapToObj(x -> CompletableFuture.runAsync(() -> {
            try (BufferedReader r = Files.newBufferedReader(p)) {
                if (lines != r.lines().count()) {
                    throw new IllegalStateException();
                }
                System.out.println(Thread.currentThread() + " is done.");
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }, service)).toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(futures).get();
        System.out.println("Done");
    }

Optimize OWLOntology#referencingAxioms(OWLPrimitive)

Current implementation based on searching over existing axiom caches is extremely inefficient.
The graph optimized way is, as usual, much more faster.
Here is statistic:

START::: 2020-03-03T17:18:20.695Z
========================================
TEST PIZZA:::: CLASSES=100 ||| AXIOMS=945 |||| iter = 10
DEF::: 0.0431 s.
GRH::: 0.07750000000000003 s.
========================================
TEST FAMILY:::: CLASSES=58 ||| AXIOMS=2845 |||| iter = 10
DEF::: 0.020599999999999997 s.
GRH::: 0.029400000000000003 s.
========================================
TEST PS:::: CLASSES=6038 ||| AXIOMS=38872 |||| iter = 5
DEF::: 8.541 s.
GRH::: 0.183 s.
========================================
TEST GALEN:::: CLASSES=23142 ||| AXIOMS=96463 |||| iter = 1
DEF::: 1484.803 s.
GRH::: 4.399 s.
========================================
TEST HP:::: CLASSES=15984 ||| AXIOMS=143855 |||| iter = 1
DEF::: 516.407 s.
GRH::: 3.229 s.
========================================
TEST TTO:::: CLASSES=38705 ||| AXIOMS=336291 |||| iter = 1
DEF::: 655.279 s.
GRH::: 1.467 s.
========================================
TEST GO:::: CLASSES=49797 ||| AXIOMS=556475 |||| iter = 1
DEF::: 4839.628 s.
GRH::: 6.022 s.
TOTAL::: PT2H6M40.32S


The code (for the ont-api.wiki project, AxiomReferencesTmp.java) follows:

private static final Set<Class<? extends OntClass.CardinalityRestrictionCE<?, ?>>> OBJECT_CARDINALITY_TYPES =
        Stream.of(OntClass.ObjectMaxCardinality.class,
                OntClass.ObjectMinCardinality.class, OntClass.ObjectCardinality.class).collect(Collectors.toSet());
private static final Set<AxiomTranslator<? extends OWLAxiom>> CLASS_TRANSLATORS = OWLContentType.all()
        .filter(x -> x.hasComponent(OWLComponentType.CLASS))
        .map(OWLContentType::getAxiomType)
        .map(AxiomParserProvider::get).collect(Collectors.toSet());

public static void main(String... args) throws Exception {
    Instant s = Instant.now();
    System.out.println("START::: " + s);

    testReferences(TestData.PIZZA, 10);
    testReferences(TestData.FAMILY, 10);
    testReferences(TestData.PS, 5);

    testReferences(TestData.GALEN, 1);
    testReferences(TestData.HP, 1);
    testReferences(TestData.TTO, 1);
    testReferences(TestData.GO, 1);

    System.out.println("TOTAL::: " + Duration.between(s, Instant.now()));
}

private static void testReferences(TestData data, int num) throws Exception {
    System.out.println("========================================");
    OntologyManager m = OntManagers.createONT();
    Ontology o = m.loadOntologyFromOntologyDocument(data.getDocumentSource());
    Set<OWLClass> classes = o.classesInSignature().collect(Collectors.toSet());
    System.out.printf("TEST %s:::: CLASSES=%d ||| AXIOMS=%d |||| iter = %d%n",
            data, classes.size(), o.getAxiomCount(), num);

    long count1 = measure("DEF", num, () -> classes.stream().flatMap(o::referencingAxioms));
    long count2 = measure("GRH", num, () -> classes.stream().flatMap(x -> referencingAxioms(o, x)));
    if (count1 != count2) throw new IllegalStateException();
}

private static long measure(String pref, int num, Supplier<Stream<?>> get) {
    long count = 0;
    double d = 0;
    for (int i = 0; i < num; i++) {
        Instant s = Instant.now();
        count += get.get().distinct().count();
        d += getDurationInSeconds(Duration.between(s, Instant.now()));
    }
    count /= num;
    d /= num;
    System.out.println(pref + "::: " + d + " s.");
    return count;
}

public static double getDurationInSeconds(Duration d) {
    return (double) d.getSeconds() + d.getNano() / 1_000_000_000d;
}

public static Stream<OWLAxiom> referencingAxioms(Ontology o, OWLClass c) {
    OntModel m = o.asGraphModel();
    OntClass clazz = m.getOntClass(c.getIRI().getIRIString());
    Stream<OntStatement> candidates = Stream.concat(m.statements(clazz, null, null),
            m.statements(null, null, clazz).flatMap(AxiomReferencesTmp::roots));
    if (OWL.Thing.equals(clazz)) {
        candidates = Stream.concat(candidates, specialForThing(m).flatMap(AxiomReferencesTmp::roots));
    }
    return candidates.flatMap(s -> translators(s).map(x -> x.toAxiom(s).getOWLObject()));
}

private static Stream<OntStatement> specialForThing(OntModel m) {
    return Stream.of(OWL.cardinality, OWL.maxCardinality, OWL.minCardinality)
            .flatMap(p -> m.statements(null, p, null))
            .filter(AxiomReferencesTmp::isObjectRestriction);
}

private static boolean isObjectRestriction(OntStatement s) {
    return OBJECT_CARDINALITY_TYPES.stream().anyMatch(t -> s.getSubject().canAs(t));
}

private static Stream<? extends AxiomTranslator<? extends OWLAxiom>> translators(OntStatement s) {
    return CLASS_TRANSLATORS.stream().filter(x -> x.testStatement(s));
}

private static Stream<OntStatement> roots(OntStatement s) {
    return roots(s.getModel(), s, new HashSet<>());
}

private static Stream<OntStatement> roots(OntModel m, OntStatement st, Set<OntStatement> seen) {
    Resource s = st.getSubject();
    if (s.isURIResource()) {
        return Stream.of(st);
    }
    Set<OntStatement> set = m.statements(null, null, s).filter(seen::add).collect(Collectors.toSet());
    if (set.isEmpty()) return Stream.of(st);
    return set.stream().flatMap(x -> roots(m, x, seen));
}

More human friendly order of OWLNaryAxiom' operands when writing to a graph

Consider the following ontology:

Declaration(Class(<http://www.ex.org/tribe#foremother>))
EquivalentClasses(<http://www.ex.org/tribe#foremother> ObjectIntersectionOf(<http://www.co-ode.org/roberts/family-tree.owl#Woman> ObjectSomeValuesFrom(<http://www.co-ode.org/roberts/family-tree.owl#isForemotherOf> <http://www.co-ode.org/roberts/family-tree.owl#Person>)) )

There are two forms of graph serialization:

  • 1
t:foremother  a              owl:Class ;
        owl:equivalentClass  [ a                   owl:Class ;
                               owl:intersectionOf  ( f:Woman
                                                     [ a                   owl:Restriction ;
                                                       owl:onProperty      f:isForemotherOf ;
                                                       owl:someValuesFrom  f:Person
                                                     ]
                                                   )
                             ] .

and

  • 2

[ a                    owl:Class ;
  owl:equivalentClass  t:foremother ;
  owl:intersectionOf   ( f:Woman
                         [ a                   owl:Restriction ;
                           owl:onProperty      f:isForemotherOf ;
                           owl:someValuesFrom  f:Person
                         ]
                       )
] .

t:foremother  a  owl:Class .

Think, that the first form is more preferable, but ONT-API chooses the second one that corresponds the natural OWLObject order provided by OWL-API.
So, need to change the order.
It is a minor enhancement - both forms are actually equivalent.

Getting error pulling maven deps

This error is being generated when I execute the clojure command-line clj -X:deps tree after including this project as a dependency.

Error generating tree: Could not find artifact com.github.sszuev:concurrent-rdf-graph:jar:1.0.0 in central (https://repo1.maven.org/maven2/)

Version 3.0.4

Need some additional functionality to facilitate mapping single Triple -> OWLAxiom

This includes following functionalities:

  • Utility method OntModels#toOntStatement(Triple, OntModel) - which can return main statement (i.e. OntObject#getMainStatement) if needed.
  • add new AixomTranslator#toAxiom(OntStatement, ONTObjectFactory, AxiomsSettings) (there is already toAxiom but without parameters)
  • add static factory method to get AxiomTranslator by AxiomType (i.e. move AxiomParserProvider#get and make it deprecated)

The functionality copyOntology(..) does not work correctly in case of cyclic imports and OntologyCopy.SHALLOW

The testcase:

    public static void main(String ... args) {
        OntologyManager m1 = OntManagers.createONT();
        Ontology a = m1.createOntology(IRI.create("A"));
        Ontology b = m1.createOntology(IRI.create("B"));
        a.asGraphModel().addImport(b.asGraphModel());
        b.asGraphModel().addImport(a.asGraphModel());

        testManager(m1);

        OntologyManager m2 = OntManagers.createONT();
        m1.ontologies().forEach(x -> m2.copyOntology(x, OntologyCopy.SHALLOW));

        testManager(m2);
    }

    private static void testManager(OntologyManager m) {
        Assert.assertEquals(2, m.ontologies().peek(x -> {
            System.out.println("TEST: " + x);
            Assert.assertEquals(2, Graphs.baseGraphs(((Ontology)x).asGraphModel().getGraph()).count());
        }).count());
    }

Additional info:
The method copyOntology with OntologyCopy.SHALLOW is used in RDF Protege.
The example of ontology with cyclic imports is http://www.w3.org/TR/owl-guide/wine.rdf

Optimize AxiomTranslator#containsONTObject(..) and AxiomTranslator#findONTObject(..) for the case of named triple

If subject and object are URIs then there is no need to iterate for searching.

This is an optimization for the direct mode (i.e. when cache is disabled).
And it is, probably, the last thing for the 2.1.0 release

Update: add simplified contains/find for the case if the subject and object are anonymous individuals - since they are unique within the system and does not require complex hashCode/equlas.

For a case when triples has one anonymous expression (as subject or object), the optimization is also needed, but this can be next issue.

OWLEntity#isBuiltIn() throws an exception in case an entity is alredy deleted

This is actually known behavior which is by design.
There is no guarantee that any method of unattached (i.e. deleted) object will not throw an exception.
It is already deleted, so it has no connection with the graph.
Unlike OWL-API default impl, in ONT-API there is a dynamic object's state, which depends on graph and model's settings, it is true even for isBuiltIn parameter-property.

But for OWLEntity#isBuiltIn() it is better to make an exception:
there is an example of code in Protege where an entity is still in use even after its deletion (see org.protege.editor.owl.model.hierarchy.OWLAnnotationPropertyHierarchyProvider#handleChanges(...)).
Moreover - it is always possible to safely determine whether an entity is builtin even it is deleted.

The testcase:

    OntologyManager m = OntManagers.createONT();
    DataFactory df = m.getOWLDataFactory();
    Ontology o = m.createOntology();
    OWLAxiom a = df.getOWLDeclarationAxiom(df.getOWLAnnotationProperty("a"));
    o.add(a);
    OWLEntity e1 = o.signature().filter(AsOWLAnnotationProperty::isOWLAnnotationProperty)
            .findFirst().orElseThrow(AssertionError::new);
    Assert.assertFalse(e1.isBuiltIn());

    o.remove(a);
    Assert.assertFalse(e1.isBuiltIn());

Compilation errors on Maven build

I cloned the repo and ran a Maven build. I get these two errors, which I also get if I import the code into Eclipse as a Maven project:
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /home/camfe/andy/ws/sadl/git/ont-api/ont-api/src/test/java/com/github/owlcs/ontapi/tests/managers/SimpleLoadTest.java:[120,45] incompatible types: inference variable T has incompatible bounds
equality constraints: org.semanticweb.owlapi.model.OWLAxiom
lower bounds: java.lang.Object
[ERROR] /home/camfe/andy/ws/sadl/git/ont-api/ont-api/src/test/java/com/github/owlcs/ontapi/utils/SP.java:[206,15] reference to Module is ambiguous
both interface org.topbraid.spin.model.Module in org.topbraid.spin.model and class java.lang.Module in java.lang match

Is it possible to run Hermit reasoner when running a SPARQL query?

I loaded an ontology with SWRL rules:

IRI iri = IRI.create(BASE_URL);
OntologyManager manager = OntManagers.createManager();
// Load an ontology
Ontology mergedOntology = manager.loadOntologyFromOntologyDocument(iri);

Then I instantiate a Hermit reasoner:

import org.semanticweb.HermiT.ReasonerFactory;

OWLReasonerFactory reasonerFactory = new ReasonerFactory();
OWLReasoner reasoner = reasonerFactory.createReasoner(mergedOntology);

Finally, I query:

try (
    QueryExecution qexec = QueryExecutionFactory.create(QueryFactory
        .create("SELECT ?s ?p ?o WHERE { ?s ?p ?o }"), mergedOntology.asGraphModel())
) {
    ResultSet res = qexec.execSelect();
    while (res.hasNext()) {
        System.out.println(res.next());
    }
}

However the reasoner wasn't used. Is there a way to do what I want?

Implement custom ONTObject#toString()

Since ONTObjectImpl (in contradistinction to OWLObjectImpl) has ref to prefixed model inside, it would be nice to replace default toString implementation (which is based on SimpleRenderer) with new one that reflects model settings

[tests] switch to junit5

it is more convenient: e.g. there is a possibility to combine parameterized test-cases and a regular one in a single class

support org.apache.jena.ontology.OntDocumentManager

The org.apache.jena.ontology.OntDocumentManager is a part of org.apache.jena.ontology.OntModel.

Since we going to support all jena ont-model functionality, we should probably support this mechanism as well.

(related to #45)

Open question to OWL community: project feedbacks

If you are reading this issue, you are probably know what ONTAPI is: it is an alternative OWLAPI implementation, which (I believe) has comparable performance and memory consumption.
But according to my observations (on github projects), sometimes people are using ONTAPI as a simple conversion tool only, or even after a while since beginning of use ONTAPI, they decide to give up it in favor of the default implementation.
This seems strange, and it would be very valuable to know the reasons of such decisions.
So, if there is a lack of performance you faced, or something else, it would be nice to have some feedback on it (as a response on this issue or as a new issue whatever).
Then, perhaps, we can try to fix these cases.

Silence cannot be a driving force in the open source world.
Thanks in advance.

GraphDocumentSourceTest#testBrokenOntGraphDocumentSource() fails on linux

Exceptions are not properly handled in case of linux (differences in try-with-resource, Pipe[Input/Output]Streams ? - not sure)
The environment:

Linux ... 5.0.0-36-generic #39~18.04.1-Ubuntu SMP Tue Nov 12 11:09:50 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)

thread-safe OntModel

concurrent RDF-Graph (https://github.com/sszuev/concurrent-rdf-graph) is not enough.
OntModel methods are still not protected properly.

There is already concurrent implementation (com.github.owlcs.ontapi.OntologyModelImpl.Concurrent.asGraphModel), but it does not cover all cases.

TODO:

  • Need to protect all write operations and all complex read-operations (such as Model#write, Model#write)
  • Simple read operations should not be protected in performance sake (there is already protection for Iterator on graph level with internal own lock)
  • The same protection should be done for OntObjects as well

Can't read FileDocumentSource owl api - loadOntologyFromOntologyDocument

Hi,

I'm using the latest Maven project Ont-api version 2.0.0 .
I'm trying to lead a local ontology with the instructions below :

String pathFileInTest = "Misc/Ontologies_Input/pizza.owl";
String iriFileTest = "http://www.co-ode.org/ontologies/pizza/pizza.owl";
OntologyManager m = OntManagers.createONT();
OWLDataFactory df = m.getOWLDataFactory();
OWLOntology ontology = m.loadOntologyFromOntologyDocument(new File(pathFileIn));

Here's the output :

Exception in thread "main" org.semanticweb.owlapi.io.UnparsableOntologyException: Problem parsing file:/Users/--/Misc/Ontologies_Input/pizza.owl
Could not parse ontology.  Either a suitable parser could not be found, or parsing failed.

Suppressed: com.github.owlcs.ontapi.OntologyFactoryImpl$UnsupportedFormatException: Can't read FileDocumentSource file:/Users/--/Misc/Ontologies_Input/pizza.owl.

Suppressed: com.github.owlcs.ontapi.OntologyFactoryImpl$UnsupportedFormatException: org.apache.jena.riot.RiotException: [line: 22, col: 32] {E201} Multiple children of property element. Format: RDF_XML. IRI: <file:/Users/--/Misc/Ontologies_Input/pizza.owl>. Cause: '[line: 22, col: 32] {E201} Multiple children of property element'
Caused by: org.apache.jena.riot.RiotException: [line: 22, col: 32] {E201} Multiple children of property element

Suppressed: com.github.owlcs.ontapi.OntologyFactoryImpl$UnsupportedFormatException: org.apache.jena.riot.RiotException: [line: 1, col: 7 ] Bad character in IRI (space): <?xml[space]...>. Format: TURTLE. IRI: <file:/Users/--/Misc/Ontologies_Input/pizza.owl>. Cause: '[line: 1, col: 7 ] Bad character in IRI (space): <?xml[space]...>'
Caused by: org.apache.jena.riot.RiotException: [line: 1, col: 7 ] Bad character in IRI (space): <?xml[space]...>

Suppressed: com.github.owlcs.ontapi.OntologyFactoryImpl$UnsupportedFormatException: org.apache.jena.riot.thrift.RiotThriftException: org.apache.thrift.protocol.TProtocolException: don't know what type: 15. Format: RDF_THRIFT. IRI: <file:/Users/--/Misc/Ontologies_Input/pizza.owl>. Cause: 'org.apache.thrift.protocol.TProtocolException: don't know what type: 15'
Caused by: org.apache.jena.riot.thrift.RiotThriftException: org.apache.thrift.protocol.TProtocolException: don't know what type: 15

When I load this same ontology with the method loadOntology (from internet) : it works.
It also works when I load a RDF format file like the wine.rdf ontology.

the method loadOntologyFromOntologyDocument seems to parse with JENA and not with OWLAPI but I can't figure it out why.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.