Skip to content

Optimize OWLOntology#referencingAxioms(OWLPrimitive) #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sszuev opened this issue Mar 4, 2020 · 1 comment
Closed

Optimize OWLOntology#referencingAxioms(OWLPrimitive) #11

sszuev opened this issue Mar 4, 2020 · 1 comment
Labels
enhancement New feature or request

Comments

@sszuev
Copy link
Contributor

sszuev commented Mar 4, 2020

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));
}
@sszuev sszuev added the enhancement New feature or request label Mar 4, 2020
sszuev added a commit that referenced this issue Mar 8, 2020
…ncingAxioms(OWLClass) functionality (see issue #11) + add new test data (camera, food/wine, people, travel, koala ontologies)
sszuev added a commit that referenced this issue Mar 15, 2020
…mitive) + change test-data (people & travel ontologies), see issue #11 rest
sszuev added a commit that referenced this issue Mar 29, 2020
…Statement) (no need), add BaseSearcher abstraction (preparation for #11)
sszuev added a commit that referenced this issue Mar 29, 2020
sszuev added a commit that referenced this issue Mar 31, 2020
…sue #11) + InternalModel#containsOWLDeclaration(OWLEntity) (i.e. OWLOntology#isDeclared(OWLEntity))
sszuev added a commit that referenced this issue Mar 31, 2020
…ous individuals), remove Models#getRootStatments(Statement) with test (no need, move to ByEntity), add new test data (travel.ttl) and fix ReferencingAxiomsTest to catch error -- in bounds of issue #11
sszuev added a commit that referenced this issue Apr 3, 2020
sszuev added a commit that referenced this issue Apr 5, 2020
sszuev added a commit that referenced this issue Apr 8, 2020
…ange InternalModel#useReferencingAxiomsGraphOptimization strategy, changes in ReferencingAxiomsTest
sszuev added a commit that referenced this issue Apr 12, 2020
sszuev added a commit that referenced this issue Apr 12, 2020
@sszuev
Copy link
Contributor Author

sszuev commented Apr 16, 2020

done

@sszuev sszuev closed this as completed Apr 16, 2020
sszuev added a commit that referenced this issue May 6, 2020
…to #reduce() and list* #methods) + add tests for OWLOntology#subClassAxiomsForSuperClass (#11)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant