001package conexp.fx.core.dl.deprecated;
002
003/*
004 * #%L
005 * Concept Explorer FX
006 * %%
007 * Copyright (C) 2010 - 2019 Francesco Kriegel
008 * %%
009 * This program is free software: you can redistribute it and/or modify
010 * it under the terms of the GNU General Public License as
011 * published by the Free Software Foundation, either version 3 of the
012 * License, or (at your option) any later version.
013 * 
014 * This program is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017 * GNU General Public License for more details.
018 * 
019 * You should have received a copy of the GNU General Public
020 * License along with this program.  If not, see
021 * <http://www.gnu.org/licenses/gpl-3.0.html>.
022 * #L%
023 */
024
025import java.io.File;
026import java.io.IOException;
027import java.util.ArrayList;
028import java.util.Collections;
029import java.util.HashSet;
030import java.util.List;
031import java.util.Set;
032import java.util.function.Consumer;
033import java.util.stream.Collectors;
034
035import org.openrdf.model.Resource;
036import org.openrdf.model.Statement;
037import org.openrdf.model.vocabulary.RDF;
038import org.openrdf.model.vocabulary.RDFS;
039import org.openrdf.repository.Repository;
040import org.openrdf.repository.RepositoryConnection;
041import org.openrdf.repository.RepositoryException;
042import org.openrdf.repository.RepositoryResult;
043import org.openrdf.repository.sail.SailRepository;
044import org.openrdf.rio.RDFFormat;
045import org.openrdf.rio.RDFParseException;
046import org.openrdf.sail.memory.MemoryStore;
047import org.semanticweb.owlapi.apibinding.OWLManager;
048import org.semanticweb.owlapi.model.IRI;
049import org.semanticweb.owlapi.model.OWLClass;
050import org.semanticweb.owlapi.model.OWLClassExpression;
051import org.semanticweb.owlapi.model.OWLDataFactory;
052import org.semanticweb.owlapi.model.OWLNamedIndividual;
053import org.semanticweb.owlapi.model.OWLObjectIntersectionOf;
054import org.semanticweb.owlapi.model.OWLObjectProperty;
055import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom;
056
057import com.google.common.collect.Sets;
058
059import conexp.fx.core.collections.Pair;
060import conexp.fx.core.context.MatrixContext;
061import uk.ac.manchester.cs.owl.owlapi.OWLObjectIntersectionOfImpl;
062
063@Deprecated
064public class OWLInterpretation2 {
065
066  protected final Matrix3D<OWLNamedIndividual, OWLObjectProperty, OWLClass>           concepts;
067  protected final Matrix3D<OWLNamedIndividual, OWLObjectProperty, OWLNamedIndividual> roles;
068  protected final OWLDataFactory                                                      df;
069  protected final OWLObjectProperty                                                   type;
070
071  public OWLInterpretation2(final int individuals, final int concepts, final int roles) {
072    super();
073    this.concepts = new Matrix3D<OWLNamedIndividual, OWLObjectProperty, OWLClass>(individuals, 1, concepts);
074    this.roles =
075        new Matrix3D<OWLNamedIndividual, OWLObjectProperty, OWLNamedIndividual>(individuals, roles, individuals);
076    this.df = OWLManager.getOWLDataFactory();
077    this.type = df.getOWLObjectProperty(IRI.create(RDF.TYPE.stringValue()));
078    this.concepts.addM(type);
079  }
080
081  public final void addIndividual(final OWLNamedIndividual d) {
082    concepts.addG(d);
083    roles.addG(d);
084    roles.addW(d);
085  }
086
087  public final void addIndividual(final String d) {
088    this.addIndividual(df.getOWLNamedIndividual(IRI.create(d)));
089  }
090
091  public final void addConcept(final OWLClass c) {
092    concepts.addW(c);
093  }
094
095  public final void addConcept(final String c) {
096    this.addConcept(df.getOWLClass(IRI.create(c)));
097  }
098
099  public final void addRole(final OWLObjectProperty r) {
100    roles.addM(r);
101  }
102
103  public final void addRole(final String r) {
104    this.addRole(df.getOWLObjectProperty(IRI.create(r)));
105  }
106
107  public final void addConceptAssertion(final OWLNamedIndividual d, final OWLClass c) {
108    concepts.add(d, type, c);
109  }
110
111  public final void addConceptAssertion(final String d, final String c) {
112    this.addConceptAssertion(df.getOWLNamedIndividual(IRI.create(d)), df.getOWLClass(IRI.create(c)));
113  }
114
115  public final void
116      addRoleAssertion(final OWLNamedIndividual d, final OWLObjectProperty r, final OWLNamedIndividual e) {
117    roles.add(d, r, e);
118  }
119
120  public final void addRoleAssertion(final String d, final String r, final String e) {
121    this
122        .addRoleAssertion(
123            df.getOWLNamedIndividual(IRI.create(d)),
124            df.getOWLObjectProperty(IRI.create(r)),
125            df.getOWLNamedIndividual(IRI.create(e)));
126  }
127
128  public final Set<OWLNamedIndividual> getIndividuals() {
129    return Sets.union(concepts.getGs(), Sets.union(roles.getGs(), roles.getWs()));
130  }
131
132  public final Set<OWLClass> getConcepts() {
133    return concepts.getWs();
134  }
135
136  public final Set<OWLObjectProperty> getRoles() {
137    return roles.getMs();
138  }
139
140  public final Set<OWLNamedIndividual> getIndividuals(final String clazz) {
141    return getIndividuals(df.getOWLClass(IRI.create(clazz)));
142  }
143
144  public final Set<OWLNamedIndividual> getIndividuals(final OWLClass clazz) {
145    return concepts.row(type, clazz).collect(Collectors.toSet());
146  }
147
148  public final Set<Pair<OWLNamedIndividual, OWLNamedIndividual>> getIndividuals(final OWLObjectProperty role) {
149    return null;
150  }
151
152  public final boolean isInstanceOf(final OWLNamedIndividual i, final OWLClassExpression c) {
153    if (c.equals(df.getOWLThing()))
154      return true;
155    if (c.equals(df.getOWLNothing()))
156      return false;
157    if (c instanceof OWLClass)
158      return concepts.get(i, type, (OWLClass) c);
159    if (c instanceof OWLObjectSomeValuesFrom)
160      return roles
161          .cut(i, (OWLObjectProperty) ((OWLObjectSomeValuesFrom) c).getProperty())
162          .anyMatch(j -> isInstanceOf(j, ((OWLObjectSomeValuesFrom) c).getFiller()));
163    if (c instanceof OWLObjectIntersectionOf)
164      return ((OWLObjectIntersectionOf) c).asConjunctSet().stream().allMatch(d -> isInstanceOf(i, d));
165    return false;
166  }
167
168  public final boolean isInstanceOf(final String i, final String c) {
169    return this.isInstanceOf(df.getOWLNamedIndividual(IRI.create(i)), df.getOWLClass(IRI.create(c)));
170  }
171
172  public final OWLClassExpression
173      getMMSC(final Set<OWLNamedIndividual> individuals, final int roleDepth, final DescriptionLogic dl) {
174    final Set<OWLClassExpression> conjuncts = new HashSet<OWLClassExpression>();
175    concepts.cut(individuals.stream(), type).forEach(new Consumer<OWLClass>() {
176
177      @Override
178      public void accept(OWLClass conceptName) {
179        conjuncts.add(conceptName);
180      }
181    });
182    if (roleDepth > 0)
183      for (OWLObjectProperty role : roles.getMs())
184        for (Constructor constructor : dl.constructors)
185          for (Set<OWLNamedIndividual> successor : minimalSuccessorSets(individuals, role, constructor))
186            switch (constructor) {
187            case EXISTENTIAL_RESTRICTION:
188              conjuncts.add(df.getOWLObjectSomeValuesFrom(role, getMMSC(successor, roleDepth - 1, dl)));
189              break;
190            case VALUE_RESTRICTION:
191              conjuncts.add(df.getOWLObjectAllValuesFrom(role, getMMSC(successor, roleDepth - 1, dl)));
192              break;
193            case QUALIFIED_AT_LEAST_RESTRICTION:
194//              conjuncts.add(df.getOWLObjectMinCardinality(cardinality, role, getMMSC(successor, roleDepth - 1, dl)));
195              break;
196            case UNQUALIFIED_AT_MOST_RESTRICTION:
197//              conjuncts.add(df.getOWLObjectMaxCardinality(cardinality, role, getMMSC(successor, roleDepth - 1, dl)));
198              break;
199            case CONJUNCTION:
200            default:
201            }
202    if (conjuncts.size() > 1)
203      return new OWLObjectIntersectionOfImpl(conjuncts);
204    if (conjuncts.size() == 1)
205      return conjuncts.iterator().next();
206    return df.getOWLThing();
207  }
208
209  public final OWLClassExpression
210      getMMSC_(final Set<String> individuals, final int roleDepth, final DescriptionLogic dl) {
211    return getMMSC(
212        individuals.stream().map(i -> df.getOWLNamedIndividual(IRI.create(i))).collect(Collectors.toSet()),
213        roleDepth,
214        dl);
215  }
216
217  private final Set<Set<OWLNamedIndividual>>
218      minimalSuccessorSets(Set<OWLNamedIndividual> individuals, OWLObjectProperty role, Constructor constructor) {
219    switch (constructor) {
220    case EXISTENTIAL_RESTRICTION:
221      final Set<OWLNamedIndividual> successors0 = new HashSet<OWLNamedIndividual>();
222      for (OWLNamedIndividual individual : individuals)
223        successors0.addAll(roles.cut(individual, role).collect(Collectors.toSet()));
224      // succerssors0 contains all r-successors of individuals in individuals
225//      final Set<Set<OWLNamedIndividual>> minSets =
226//          Sets
227//              .powerSet(successors0)
228//              .stream()
229//              .filter(
230//                  set -> set.stream().allMatch(
231//                      individual -> roles.row(role, individual).filter(individuals::contains).findFirst().isPresent()))
232//              .collect(Collectors.toSet());
233      final Set<Set<OWLNamedIndividual>> minSets = Sets.newHashSet(Sets.powerSet(successors0));
234      final Set<Set<OWLNamedIndividual>> t = new HashSet<Set<OWLNamedIndividual>>();
235      for (Set<OWLNamedIndividual> set : minSets) {
236        for (OWLNamedIndividual individual : individuals)
237          if (roles.cut(individual, role).noneMatch(set::contains))
238            t.add(set);
239      }
240      minSets.removeAll(t);
241      // minSets should here contain all subsets of successors0, that contain at least one r-successor
242      // for every individual in individuals
243//      final Set<Set<OWLNamedIndividual>> minSets = Sets.newHashSet(Sets.powerSet(successors0));
244      final Set<Set<OWLNamedIndividual>> nonMinSets = new HashSet<Set<OWLNamedIndividual>>();
245      for (Set<OWLNamedIndividual> x : minSets)
246        for (Set<OWLNamedIndividual> y : minSets)
247          if (!x.equals(y) && x.containsAll(y)) {
248            nonMinSets.add(x);
249            break;
250          }
251      minSets.removeAll(nonMinSets);
252      return minSets;
253    case VALUE_RESTRICTION:
254      final Set<OWLNamedIndividual> successors = new HashSet<OWLNamedIndividual>();
255      for (OWLNamedIndividual individual : individuals)
256        successors.addAll(roles.cut(individual, role).collect(Collectors.toSet()));
257      return Collections.singleton(successors);
258    case QUALIFIED_AT_LEAST_RESTRICTION:
259      return Collections.emptySet();
260    case UNQUALIFIED_AT_MOST_RESTRICTION:
261      return Collections.emptySet();
262    case CONJUNCTION:
263    default:
264      return Collections.emptySet();
265    }
266  }
267
268  public final MatrixContext<OWLNamedIndividual, OWLClassExpression>
269      toLogicalContext(final int roleDepth, final DescriptionLogic dl) {
270    MatrixContext<OWLNamedIndividual, OWLClassExpression> cxt =
271        new MatrixContext<OWLNamedIndividual, OWLClassExpression>(false);
272    cxt.rowHeads().addAll(concepts.getGs());
273    cxt.colHeads().addAll(createMMSCConjuncts(roleDepth, dl));
274    for (OWLNamedIndividual i : cxt.rowHeads())
275      for (OWLClassExpression c : cxt.colHeads())
276        if (isInstanceOf(i, c))
277          cxt.addFast(i, c);
278    return cxt;
279  }
280
281  private final List<OWLClassExpression> createMMSCConjuncts(final int roleDepth, final DescriptionLogic dl) {
282    final List<OWLClassExpression> mmscConjuncts = new ArrayList<OWLClassExpression>();
283//            (int) (1 + concepts.getWs().size() + roles.getMs().size()
284//            * Math.pow(2, concepts.getGs().size())));
285    mmscConjuncts.add(df.getOWLNothing());
286    mmscConjuncts.addAll(concepts.getWs());
287    if (roleDepth > 0) {
288      for (Set<OWLNamedIndividual> s : Sets.powerSet(concepts.getGs()))
289        if (!s.isEmpty()) {
290          final OWLClassExpression mmsc = getMMSC(s, roleDepth - 1, dl);
291          for (OWLObjectProperty role : roles.getMs()) {
292            for (Constructor constructor : dl.constructors)
293              switch (constructor) {
294              case EXISTENTIAL_RESTRICTION:
295                mmscConjuncts.add(df.getOWLObjectSomeValuesFrom(role, mmsc));
296                break;
297              case VALUE_RESTRICTION:
298                mmscConjuncts.add(df.getOWLObjectAllValuesFrom(role, mmsc));
299                break;
300              case QUALIFIED_AT_LEAST_RESTRICTION:
301              case UNQUALIFIED_AT_MOST_RESTRICTION:
302              case CONJUNCTION:
303              default:
304              }
305          }
306        }
307    }
308    return mmscConjuncts;
309  }
310
311  public static final OWLInterpretation2 importFromRDFFile(final File rdfFile, final String baseURI)
312      throws RepositoryException, RDFParseException, IOException {
313    final Repository repo = new SailRepository(new MemoryStore());
314    final RepositoryConnection connection = repo.getConnection();
315    connection.add(rdfFile, baseURI, RDFFormat.forFileName(rdfFile.getName(), RDFFormat.RDFXML));
316    connection.commit();
317    connection.close();
318    return importFromRDFRepository(repo);
319  }
320
321  public static final OWLInterpretation2 importFromRDFRepository(final Repository repo) throws RepositoryException {
322    final RepositoryConnection connection = repo.getConnection();
323
324    final Set<Resource> properties = new HashSet<Resource>();
325    final RepositoryResult<Statement> statements = connection.getStatements(null, RDF.TYPE, RDF.PROPERTY, true);
326    while (statements.hasNext())
327      properties.add(statements.next().getSubject());
328    statements.close();
329
330    final Set<Resource> classes = new HashSet<Resource>();
331    final RepositoryResult<Statement> statements2 = connection.getStatements(null, RDF.TYPE, RDFS.CLASS, true);
332    while (statements2.hasNext())
333      classes.add(statements2.next().getSubject());
334    statements2.close();
335
336    final Set<Resource> individuals = new HashSet<Resource>();
337    final RepositoryResult<Statement> statements3 = connection.getStatements(null, RDF.TYPE, null, true);
338    while (statements3.hasNext()) {
339      final Statement stmt = statements3.next();
340      if (!stmt.getObject().equals(RDF.PROPERTY) && !stmt.getObject().equals(RDFS.CLASS))
341        individuals.add(stmt.getSubject());
342    }
343    statements3.close();
344
345    final OWLInterpretation2 i = new OWLInterpretation2(individuals.size(), classes.size(), properties.size());
346    for (Resource individual : individuals)
347      i.addIndividual(individual.stringValue());
348    for (Resource clazz : classes)
349      i.addConcept(clazz.stringValue());
350    for (Resource property : properties)
351      i.addRole(property.stringValue());
352
353    final RepositoryResult<Statement> statements4 = connection.getStatements(null, RDF.TYPE, null, true);
354    while (statements4.hasNext()) {
355      final Statement stmt = statements4.next();
356      if (!stmt.getObject().equals(RDF.PROPERTY) && !stmt.getObject().equals(RDFS.CLASS))
357        i.addConceptAssertion(stmt.getSubject().stringValue(), stmt.getObject().stringValue());
358    }
359    statements4.close();
360
361    final RepositoryResult<Statement> statements5 = connection.getStatements(null, null, null, true);
362    while (statements5.hasNext()) {
363      final Statement stmt = statements5.next();
364      if (!stmt.getPredicate().equals(RDF.TYPE) && !stmt.getObject().equals(RDF.PROPERTY)
365          && !stmt.getObject().equals(RDFS.CLASS))
366        i
367            .addRoleAssertion(
368                stmt.getSubject().stringValue(),
369                stmt.getPredicate().stringValue(),
370                stmt.getObject().stringValue());
371    }
372    statements5.close();
373
374    connection.close();
375    return i;
376  }
377
378}