001package org.dllearner.learningproblems;
002
003import java.util.*;
004
005import org.dllearner.core.AbstractComponent;
006import org.dllearner.core.AbstractReasonerComponent;
007import org.dllearner.core.ComponentAnn;
008import org.dllearner.core.ComponentInitException;
009import org.dllearner.core.config.ConfigOption;
010import org.dllearner.reasoning.SPARQLReasoner;
011import org.dllearner.utilities.Helper;
012import org.dllearner.utilities.OWLAPIUtils;
013import org.semanticweb.owlapi.model.OWLClassExpression;
014import org.semanticweb.owlapi.model.OWLDataFactory;
015import org.semanticweb.owlapi.model.OWLIndividual;
016import org.springframework.beans.factory.annotation.Autowired;
017import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl;
018
019/**
020 * Load positive and negative examples from Class Expression
021 */
022@ComponentAnn(description = "Load examples from Class Expression",
023              name = "ExampleLoader",
024              shortName = "ExampleLoader",
025              version = 0.1)
026public class ExampleLoader extends AbstractComponent {
027        private PosNegLP posNegLP = null;
028        private PosOnlyLP posOnlyLP = null;
029        private AbstractReasonerComponent reasonerComponent;
030        private static OWLDataFactory dataFactory = new OWLDataFactoryImpl();
031
032        @ConfigOption(description = "class expression of positive examples", required = false)
033        OWLClassExpression positiveExamplesCE = null;
034        @ConfigOption(description = "class expression of negative examples", required = false)
035        OWLClassExpression negativeExamplesCE = null;
036
037        @ConfigOption(description = "randomly choose only so many positive examples", required = false)
038        int positiveRandomCount = 0;
039        @ConfigOption(description = "randomly choose only so many negative examples", required = false)
040        int negativeRandomCount = 0;
041
042        @ConfigOption(description = "random seed for deterministic example choice")
043        long randomSeed = -1;
044
045        @Override
046        public void init() throws ComponentInitException {
047                Random r1 = randomSeed > -1 ? new Random(randomSeed) : new Random();
048                Random r2 = randomSeed > -1 ? new Random(randomSeed) : new Random();
049
050                if (positiveExamplesCE != null && (posNegLP != null || posOnlyLP != null)) {
051                        positiveExamplesCE = OWLAPIUtils.classExpressionPropertyExpander(positiveExamplesCE, reasonerComponent, dataFactory, true);
052
053                        // sanity check to verify the existence of all entities in the concept
054                        if (!Helper.checkConceptEntities(reasonerComponent, positiveExamplesCE)) {
055                                throw new ComponentInitException("Some entities in the concept \"" + positiveExamplesCE + "\" defining the pos. examples " +
056                                                " do not exist. Make sure you spelled it correctly.");
057                        }
058
059                        Set<OWLIndividual> posEx = reasonerComponent.getIndividuals(positiveExamplesCE);
060                        if (positiveRandomCount > 0) {
061                                List<OWLIndividual> sample = new ArrayList<>(posEx);
062                                Collections.shuffle(sample, r1);
063                                posEx = new HashSet<>(sample.subList(0, positiveRandomCount));
064                        }
065                        if (posNegLP != null)
066                                posNegLP.setPositiveExamples(posEx);
067                        if (posOnlyLP != null)
068                                posOnlyLP.setPositiveExamples(posEx);
069                        initialized = true;
070                }
071
072                if (negativeExamplesCE != null && posNegLP != null) {
073                        negativeExamplesCE = OWLAPIUtils.classExpressionPropertyExpander(negativeExamplesCE, reasonerComponent, dataFactory, true);
074
075                        // sanity check to verify the existence of all entities in the concept
076                        if (!Helper.checkConceptEntities(reasonerComponent, negativeExamplesCE)) {
077                                throw new ComponentInitException("Some entities in the concept \"" + negativeExamplesCE + "\" defining the pos. examples " +
078                                                " do not exist. Make sure you spelled it correctly.");
079                        }
080
081                        Set<OWLIndividual> negEx;
082                        if (reasonerComponent instanceof SPARQLReasoner) {
083                                negEx = ((SPARQLReasoner) reasonerComponent).getIndividuals(negativeExamplesCE, negativeRandomCount);
084                        } else {
085                                negEx = reasonerComponent.getIndividuals(negativeExamplesCE);
086                        }
087                        if (negativeRandomCount > 0) {
088                                List<OWLIndividual> sample = new ArrayList<>(negEx);
089                                Collections.shuffle(sample, r2);
090                                negEx = new HashSet<>(sample.subList(0, negativeRandomCount));
091                        }
092                        posNegLP.setNegativeExamples(negEx);
093                        initialized = true;
094                }
095
096                initialized = true;
097        }
098
099        public OWLClassExpression getPositiveExamplesCE() {
100                return positiveExamplesCE;
101        }
102
103        public void setPositiveExamplesCE(OWLClassExpression positiveExamplesCE) {
104                this.positiveExamplesCE = positiveExamplesCE;
105        }
106
107        public OWLClassExpression getNegativeExamplesCE() {
108                return negativeExamplesCE;
109        }
110
111        public void setNegativeExamplesCE(OWLClassExpression negativeExamplesCE) {
112                this.negativeExamplesCE = negativeExamplesCE;
113        }
114
115        public int getPositiveRandomCount() {
116                return positiveRandomCount;
117        }
118
119        public void setPositiveRandomCount(int positiveRandomCount) {
120                this.positiveRandomCount = positiveRandomCount;
121        }
122
123        public int getNegativeRandomCount() {
124                return negativeRandomCount;
125        }
126
127        public void setNegativeRandomCount(int negativeRandomCount) {
128                this.negativeRandomCount = negativeRandomCount;
129        }
130
131        public long getRandomSeed() {
132                return randomSeed;
133        }
134
135        public void setRandomSeed(long randomSeed) {
136                this.randomSeed = randomSeed;
137        }
138
139        public AbstractReasonerComponent getReasonerComponent() {
140                return reasonerComponent;
141        }
142
143        @Autowired
144        public void setReasonerComponent(AbstractReasonerComponent reasonerComponent) {
145                this.reasonerComponent = reasonerComponent;
146        }
147
148        public PosNegLP getPosNegLP() {
149                return posNegLP;
150        }
151
152        public void setPosNegLP(PosNegLP posNegLP) {
153                this.posNegLP = posNegLP;
154        }
155
156        public PosOnlyLP getPosOnlyLP() {
157                return posOnlyLP;
158        }
159
160        public void setPosOnlyLP(PosOnlyLP posOnlyLP) {
161                this.posOnlyLP = posOnlyLP;
162        }
163}