aboutsummaryrefslogtreecommitdiff
path: root/src/uk/ac/ox/cs/pagoda/reasoner/ELHOUQueryReasoner.java
blob: 15dfa03e5615a861ea7fc2c069f0d433f1afd98c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
package uk.ac.ox.cs.pagoda.reasoner;

import org.semanticweb.karma2.profile.ELHOProfile;
import org.semanticweb.owlapi.model.OWLOntology;
import uk.ac.ox.cs.pagoda.multistage.MultiStageQueryEngine;
import uk.ac.ox.cs.pagoda.owl.EqualitiesEliminator;
import uk.ac.ox.cs.pagoda.owl.OWLHelper;
import uk.ac.ox.cs.pagoda.query.AnswerTuples;
import uk.ac.ox.cs.pagoda.query.QueryRecord;
import uk.ac.ox.cs.pagoda.query.QueryRecord.Step;
import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine;
import uk.ac.ox.cs.pagoda.reasoner.light.KarmaQueryEngine;
import uk.ac.ox.cs.pagoda.rules.DatalogProgram;
import uk.ac.ox.cs.pagoda.util.Timer;
import uk.ac.ox.cs.pagoda.util.Utility;
import uk.ac.ox.cs.pagoda.util.disposable.DisposedException;

class ELHOUQueryReasoner extends QueryReasoner {

    DatalogProgram program;

    BasicQueryEngine rlLowerStore;
    BasicQueryEngine rlUpperStore;

    OWLOntology elho_ontology;
    KarmaQueryEngine elLowerStore = null;

    boolean multiStageTag, equalityTag;
    String originalMarkProgram;
    private Timer t = new Timer();

    public ELHOUQueryReasoner(boolean multiStageTag, boolean considerEqualities) {
        this.multiStageTag = multiStageTag;
        this.equalityTag = considerEqualities;
        rlLowerStore = new BasicQueryEngine("rl-lower-bound");
        elLowerStore = new KarmaQueryEngine("el-lower-bound");

        if(!multiStageTag)
            rlUpperStore = new BasicQueryEngine("rl-upper-bound");
        else
            rlUpperStore = new MultiStageQueryEngine("rl-upper-bound", false);
    }

    @Override
    public void evaluate(QueryRecord queryRecord) {
        if(isDisposed()) throw new DisposedException();
        AnswerTuples rlAnswer = null;
        t.reset();
        try {
            rlAnswer = rlLowerStore.evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables());
            queryRecord.updateLowerBoundAnswers(rlAnswer);
        } finally {
            if(rlAnswer != null) rlAnswer.dispose();
        }
        queryRecord.addProcessingTime(Step.LOWER_BOUND, t.duration());

        String extendedQueryText = queryRecord.getExtendedQueryText().get(0);
        String[] toQuery = queryRecord.getQueryText().equals(extendedQueryText) ?
                new String[]{queryRecord.getQueryText()} :
                new String[]{queryRecord.getQueryText(), extendedQueryText};

        for(String queryText : toQuery) {
            rlAnswer = null;
            t.reset();
            try {
                rlAnswer = rlUpperStore.evaluate(queryText, queryRecord.getAnswerVariables());
                queryRecord.updateUpperBoundAnswers(rlAnswer);
            } finally {
                if(rlAnswer != null) rlAnswer.dispose();
            }
            queryRecord.addProcessingTime(Step.UPPER_BOUND, t.duration());

            if(queryRecord.isProcessed()) {
                queryRecord.setDifficulty(Step.UPPER_BOUND);
                return;
            }
        }

        AnswerTuples elAnswer = null;
        t.reset();
        try {
            elAnswer =
                    elLowerStore.evaluate(extendedQueryText, queryRecord.getAnswerVariables(), queryRecord.getLowerBoundAnswers());
            queryRecord.updateLowerBoundAnswers(elAnswer);
        } finally {
            if(elAnswer != null) elAnswer.dispose();
        }
        queryRecord.addProcessingTime(Step.EL_LOWER_BOUND, t.duration());
    }

    @Override
    public void evaluateUpper(QueryRecord queryRecord) {
        if(isDisposed()) throw new DisposedException();
        AnswerTuples rlAnswer = null;
        try {
            rlAnswer = rlUpperStore.evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables());
            queryRecord.updateUpperBoundAnswers(rlAnswer, true);
        } finally {
            if(rlAnswer != null) rlAnswer.dispose();
        }
    }

    @Override
    public void dispose() {
        super.dispose();
        if(elLowerStore != null) elLowerStore.dispose();
        if(rlUpperStore != null) rlUpperStore.dispose();
    }

    @Override
    public void loadOntology(OWLOntology o) {
        if(isDisposed()) throw new DisposedException();
        if(!equalityTag) {
            EqualitiesEliminator eliminator = new EqualitiesEliminator(o);
            o = eliminator.getOutputOntology();
            eliminator.save();
        }

        OWLOntology ontology = o;
        program = new DatalogProgram(ontology);

        importData(program.getAdditionalDataFile());

        elho_ontology = new ELHOProfile().getFragment(ontology);
        elLowerStore.processOntology(elho_ontology);
        originalMarkProgram = OWLHelper.getOriginalMarkProgram(ontology);
    }

    @Override
    public boolean preprocess() {
        if(isDisposed()) throw new DisposedException();
        String name = "data", datafile = getImportedData();

        String lowername = "lower program";
        String rlLowerProgramText = program.getLower().toString();

        rlUpperStore.importRDFData(name, datafile);
        rlUpperStore.materialise("saturate named individuals", originalMarkProgram);

        int flag = rlUpperStore.materialiseRestrictedly(program, null);
        if(flag != 1) {
            if(flag == -1) return false;
            rlUpperStore.dispose();

            if(!multiStageTag)
                rlUpperStore = new BasicQueryEngine("rl-upper-bound");
            else
                rlUpperStore = new MultiStageQueryEngine("rl-upper-bound", false);
            rlUpperStore.importRDFData(name, datafile);
            rlUpperStore.materialise("saturate named individuals", originalMarkProgram);
            rlUpperStore.materialiseFoldedly(program, null);
        }
        Utility.logInfo("upper store ready.");

        rlLowerStore.importRDFData(name, datafile);
        rlLowerStore.materialise(lowername, rlLowerProgramText);
        Utility.logInfo("lower store ready.");

        elLowerStore.importRDFData(name, datafile);
        elLowerStore.materialise("saturate named individuals", originalMarkProgram);
        elLowerStore.materialise(lowername, rlLowerProgramText);

        elLowerStore.initialiseKarma();
        Utility.logInfo("EL lower store ready.");

        if(!isConsistent()) {
            Utility.logInfo("The dataset is not consistent with the ontology.");
            return false;
        }
        Utility.logInfo("The dataset is consistent.");
        return true;
    }

    @Override
    public boolean isConsistent() {
        if(isDisposed()) throw new DisposedException();
        Utility.logInfo("Start checking consistency... ");
        String[] X = new String[]{"X"};
        AnswerTuples ans = null;
        try {
            ans = rlUpperStore.evaluate(QueryRecord.botQueryText, X);
            if(!ans.isValid()) return true;
        } finally {
            if(ans != null) ans.dispose();
        }

        ans = null;
        try {
            ans = elLowerStore.evaluate(QueryRecord.botQueryText, X);
            if(ans.isValid()) return false;
        } finally {
            if(ans != null) ans.dispose();
        }

        Utility.logDebug("The consistency of the data has not been determined yet.");
        return true;
    }

}