001    /**
002     * Copyright (C) 2007-2011, Jens Lehmann
003     *
004     * This file is part of DL-Learner.
005     *
006     * DL-Learner is free software; you can redistribute it and/or modify
007     * it under the terms of the GNU General Public License as published by
008     * the Free Software Foundation; either version 3 of the License, or
009     * (at your option) any later version.
010     *
011     * DL-Learner is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014     * GNU General Public License for more details.
015     *
016     * You should have received a copy of the GNU General Public License
017     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018     */
019    
020    package org.dllearner.utilities.owl;
021    
022    import java.util.HashSet;
023    import java.util.Set;
024    import java.util.Stack;
025    
026    import org.dllearner.algorithms.gp.ADC;
027    import org.dllearner.core.owl.Constant;
028    import org.dllearner.core.owl.Datatype;
029    import org.dllearner.core.owl.DatatypeExactCardinalityRestriction;
030    import org.dllearner.core.owl.DatatypeMaxCardinalityRestriction;
031    import org.dllearner.core.owl.DatatypeMinCardinalityRestriction;
032    import org.dllearner.core.owl.DatatypeProperty;
033    import org.dllearner.core.owl.DatatypeSomeRestriction;
034    import org.dllearner.core.owl.DatatypeValueRestriction;
035    import org.dllearner.core.owl.Description;
036    import org.dllearner.core.owl.DescriptionVisitor;
037    import org.dllearner.core.owl.DoubleMinValue;
038    import org.dllearner.core.owl.Intersection;
039    import org.dllearner.core.owl.NamedClass;
040    import org.dllearner.core.owl.Negation;
041    import org.dllearner.core.owl.Nothing;
042    import org.dllearner.core.owl.OWL2Datatype;
043    import org.dllearner.core.owl.ObjectAllRestriction;
044    import org.dllearner.core.owl.ObjectExactCardinalityRestriction;
045    import org.dllearner.core.owl.ObjectMaxCardinalityRestriction;
046    import org.dllearner.core.owl.ObjectMinCardinalityRestriction;
047    import org.dllearner.core.owl.ObjectOneOf;
048    import org.dllearner.core.owl.ObjectProperty;
049    import org.dllearner.core.owl.ObjectSomeRestriction;
050    import org.dllearner.core.owl.ObjectValueRestriction;
051    import org.dllearner.core.owl.SimpleDoubleDataRange;
052    import org.dllearner.core.owl.Thing;
053    import org.dllearner.core.owl.TypedConstant;
054    import org.dllearner.core.owl.Union;
055    import org.dllearner.core.owl.UntypedConstant;
056    import org.dllearner.parser.KBParser;
057    import org.dllearner.parser.ParseException;
058    import org.semanticweb.owlapi.apibinding.OWLManager;
059    import org.semanticweb.owlapi.model.IRI;
060    import org.semanticweb.owlapi.model.OWLClassExpression;
061    import org.semanticweb.owlapi.model.OWLDataFactory;
062    import org.semanticweb.owlapi.model.OWLDataProperty;
063    import org.semanticweb.owlapi.model.OWLDataRange;
064    import org.semanticweb.owlapi.model.OWLDatatype;
065    import org.semanticweb.owlapi.model.OWLIndividual;
066    import org.semanticweb.owlapi.model.OWLLiteral;
067    import org.semanticweb.owlapi.model.OWLObjectProperty;
068    import org.semanticweb.owlapi.vocab.OWLFacet;
069    import org.semanticweb.owlapi.vocab.XSDVocabulary;
070    
071    /**
072     * Converter from DL-Learner descriptions to OWL API descriptions based
073     * on the visitor pattern.
074     * 
075     * @author Jens Lehmann
076     *
077     */
078    public class OWLAPIDescriptionConvertVisitor implements DescriptionVisitor {
079    
080            // private OWLDescription description;
081            private Stack<OWLClassExpression> stack = new Stack<OWLClassExpression>();
082            
083            private OWLDataFactory factory = OWLManager.createOWLOntologyManager().getOWLDataFactory();
084            
085            public OWLClassExpression getOWLClassExpression() {
086                    return stack.pop();
087            }
088            
089            /**
090             * Converts a DL-Learner description into an OWL API decription.
091             * @param description DL-Learner description.
092             * @return Corresponding OWL API description.
093             */
094            public static OWLClassExpression getOWLClassExpression(Description description) {
095                    OWLAPIDescriptionConvertVisitor converter = new OWLAPIDescriptionConvertVisitor();
096                    description.accept(converter);
097                    return converter.getOWLClassExpression();
098            }
099            
100            /**
101             * Used for testing the OWL API converter.
102             * 
103             * @param args
104             */
105            public static void main(String[] args) {
106                    try {
107                            Description d = KBParser.parseConcept("(male AND (rich OR NOT stupid))");
108                            OWLClassExpression od = OWLAPIDescriptionConvertVisitor.getOWLClassExpression(d);
109                            System.out.println(d);
110                            System.out.println(od);
111                    } catch (ParseException e) {
112                            // TODO Auto-generated catch block
113                            e.printStackTrace();
114                    }
115            }
116            
117            /* (non-Javadoc)
118             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.Negation)
119             */
120            public void visit(Negation description) {
121                    description.getChild(0).accept(this);
122                    OWLClassExpression d = stack.pop();
123                    stack.push(factory.getOWLObjectComplementOf(d));                
124            }
125    
126            /* (non-Javadoc)
127             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.ObjectAllRestriction)
128             */
129            public void visit(ObjectAllRestriction description) {
130                    OWLObjectProperty role = factory.getOWLObjectProperty(
131                                    IRI.create(description.getRole().getName()));
132                    description.getChild(0).accept(this);
133                    OWLClassExpression d = stack.pop();
134                    stack.push(factory.getOWLObjectAllValuesFrom(role, d));         
135            }
136    
137            /* (non-Javadoc)
138             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.ObjectSomeRestriction)
139             */
140            public void visit(ObjectSomeRestriction description) {
141                    OWLObjectProperty role = factory.getOWLObjectProperty(
142                                    IRI.create(description.getRole().getName()));
143                    description.getChild(0).accept(this);
144                    OWLClassExpression d = stack.pop();
145                    stack.push(factory.getOWLObjectSomeValuesFrom(role, d));
146            }
147    
148            /* (non-Javadoc)
149             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.Nothing)
150             */
151            public void visit(Nothing description) {
152                    stack.push(factory.getOWLNothing());
153            }
154    
155            /* (non-Javadoc)
156             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.Thing)
157             */
158            public void visit(Thing description) {
159                    stack.push(factory.getOWLThing());
160            }
161    
162            /* (non-Javadoc)
163             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.Intersection)
164             */
165            public void visit(Intersection description) {
166                    Set<OWLClassExpression> descriptions = new HashSet<OWLClassExpression>();
167                    for(Description child : description.getChildren()) {
168                            child.accept(this);
169                            descriptions.add(stack.pop());
170                    }
171                    stack.push(factory.getOWLObjectIntersectionOf(descriptions));
172            }
173    
174            /* (non-Javadoc)
175             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.Union)
176             */
177            public void visit(Union description) {
178                    Set<OWLClassExpression> descriptions = new HashSet<OWLClassExpression>();
179                    for(Description child : description.getChildren()) {
180                            child.accept(this);
181                            descriptions.add(stack.pop());
182                    }
183                    stack.push(factory.getOWLObjectUnionOf(descriptions));
184            }
185    
186            /* (non-Javadoc)
187             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.ObjectMinCardinalityRestriction)
188             */
189            public void visit(ObjectMinCardinalityRestriction description) {
190                    // TODO Taken from ObjectSomeRestriction above, hope its correct
191                    //throw new Error("OWLAPIDescriptionConverter: not implemented");
192                    OWLObjectProperty role = factory.getOWLObjectProperty(
193                                    IRI.create(description.getRole().getName()));
194                    description.getChild(0).accept(this);
195                    OWLClassExpression d = stack.pop();
196                    int minmax = description.getCardinality();
197                    stack.push(factory.getOWLObjectMinCardinality(minmax, role, d));
198            }
199    
200            /* (non-Javadoc)
201             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.ObjectExactCardinalityRestriction)
202             */
203            public void visit(ObjectExactCardinalityRestriction description) {
204                    // TODO Taken from ObjectSomeRestriction above, hope its correct
205                    //throw new Error("OWLAPIDescriptionConverter: not implemented");
206                    OWLObjectProperty role = factory.getOWLObjectProperty(
207                                    IRI.create(description.getRole().getName()));
208                    description.getChild(0).accept(this);
209                    OWLClassExpression d = stack.pop();
210                    int minmax = description.getCardinality();
211                    stack.push(factory.getOWLObjectExactCardinality(minmax, role, d));
212                    
213            }
214    
215            /* (non-Javadoc)
216             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.ObjectMaxCardinalityRestriction)
217             */
218            public void visit(ObjectMaxCardinalityRestriction description) {
219                    // TODO Taken from ObjectSomeRestriction above, hope its correct
220                    //throw new Error("OWLAPIDescriptionConverter: not implemented");
221                    OWLObjectProperty role = factory.getOWLObjectProperty(
222                                    IRI.create(description.getRole().getName()));
223                    description.getChild(0).accept(this);
224                    OWLClassExpression d = stack.pop();
225                    int minmax = description.getCardinality();
226                    stack.push(factory.getOWLObjectMaxCardinality(minmax, role, d));
227            }
228    
229            /* (non-Javadoc)
230             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.ObjectValueRestriction)
231             */
232            public void visit(ObjectValueRestriction description) {
233                    OWLObjectProperty role = factory.getOWLObjectProperty(
234                                    IRI.create(((ObjectProperty)description.getRestrictedPropertyExpression()).getName()));
235                    OWLIndividual i = factory.getOWLNamedIndividual(IRI.create(description.getIndividual().getName()));
236                    stack.push(factory.getOWLObjectHasValue(role, i));
237            }
238    
239            /* (non-Javadoc)
240             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.DatatypeValueRestriction)
241             */
242            public void visit(DatatypeValueRestriction description) {
243                    // convert OWL constant to OWL API constant
244                    Constant c = description.getValue();
245                    OWLLiteral constant = convertConstant(c);
246                    /*
247                    if(c instanceof TypedConstant) {
248                            Datatype dt = ((TypedConstant)c).getDatatype();
249                            OWLDataType odt = convertDatatype(dt);
250                            constant = factory.getOWLTypedConstant(c.getLiteral(), odt);
251                    } else {
252                            UntypedConstant uc = (UntypedConstant) c;
253                            if(uc.hasLang()) {
254                                    constant = factory.getOWLUntypedConstant(uc.getLiteral(), uc.getLang());
255                            } else {
256                                    constant = factory.getOWLUntypedConstant(uc.getLiteral());
257                            }
258                    }
259                    */
260                                    
261                    // get datatype property
262                    DatatypeProperty dtp = description.getRestrictedPropertyExpression();
263                    OWLDataProperty prop = factory.getOWLDataProperty(IRI.create(dtp.getName()));
264                    
265                    stack.push(factory.getOWLDataHasValue(prop, constant)); 
266            }
267    
268            /* (non-Javadoc)
269             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.NamedClass)
270             */
271            public void visit(NamedClass description) {
272                    stack.push(factory.getOWLClass(IRI.create(description.getName())));
273            }
274    
275            /* (non-Javadoc)
276             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.algorithms.gp.ADC)
277             */
278            public void visit(ADC description) {
279                    // TODO Auto-generated method stub
280                    throw new Error("OWLAPIDescriptionConverter: not implemented");
281            }
282    
283            /* (non-Javadoc)
284             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.DatatypeMinCardinalityRestriction)
285             */
286            public void visit(DatatypeMinCardinalityRestriction description) {
287                    // TODO Auto-generated method stub
288                    throw new Error("OWLAPIDescriptionConverter: not implemented");
289            }
290    
291            /* (non-Javadoc)
292             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.DatatypeExactCardinalityRestriction)
293             */
294            public void visit(DatatypeExactCardinalityRestriction description) {
295                    // TODO Auto-generated method stub
296                    throw new Error("OWLAPIDescriptionConverter: not implemented");
297            }
298    
299            /* (non-Javadoc)
300             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.DatatypeMaxCardinalityRestriction)
301             */
302            public void visit(DatatypeMaxCardinalityRestriction description) {
303                    // TODO Auto-generated method stub
304                    throw new Error("OWLAPIDescriptionConverter: not implemented");
305            }
306    
307            /* (non-Javadoc)
308             * @see org.dllearner.core.owl.DescriptionVisitor#visit(org.dllearner.core.owl.DatatypeSomeRestriction)
309             */
310            public void visit(DatatypeSomeRestriction description) {
311                    
312                    // TODO: currently works only for double min/max
313                    
314                    DatatypeProperty dp = (DatatypeProperty) description.getRestrictedPropertyExpression();
315                    // currently only double restrictions implemented
316                    SimpleDoubleDataRange dr = (SimpleDoubleDataRange) description.getDataRange();
317                    double value = dr.getValue();
318                    
319                    OWLDatatype doubleDataType = factory.getOWLDatatype(XSDVocabulary.DOUBLE.getIRI());
320            OWLLiteral constant = factory.getOWLLiteral(value);
321    
322            OWLFacet facet;
323            if(dr instanceof DoubleMinValue)
324                    facet = OWLFacet.MIN_INCLUSIVE;
325            else 
326                    facet = OWLFacet.MAX_INCLUSIVE;
327            
328            OWLDataRange owlDataRange = factory.getOWLDatatypeRestriction(doubleDataType, facet, constant);
329            OWLDataProperty odp = factory.getOWLDataProperty(IRI.create(dp.getName()));
330            OWLClassExpression d = factory.getOWLDataSomeValuesFrom(odp, owlDataRange);
331    
332                    stack.push(d);  
333            }
334    
335            public OWLDatatype convertDatatype(Datatype datatype) {
336                    if(datatype.equals(OWL2Datatype.BOOLEAN.getDatatype()))
337                            return factory.getBooleanOWLDatatype();
338                    else if(datatype.equals(OWL2Datatype.INT.getDatatype()))
339                            return factory.getIntegerOWLDatatype();
340                    else if(datatype.equals(OWL2Datatype.DOUBLE.getDatatype()))
341                            return factory.getDoubleOWLDatatype();          
342    //              else if(datatype.equals(Datatype.STRING))
343    //                      return factory.getOWLDataType(Datatype.STRING.getURI());                
344                    
345                    throw new Error("OWLAPIDescriptionConverter: datatype "+datatype+" not implemented");                   
346            }
347            
348            private OWLLiteral convertConstant(Constant constant) {
349                    OWLLiteral owlConstant;
350                    if(constant instanceof TypedConstant) {
351                            Datatype dt = ((TypedConstant)constant).getDatatype();
352                            OWLDatatype odt = convertDatatype(dt);
353                            owlConstant = factory.getOWLLiteral(constant.getLiteral(), odt);
354                    } else {
355                            UntypedConstant uc = (UntypedConstant) constant;
356                            if(uc.hasLang()) {
357                                    owlConstant = factory.getOWLLiteral(uc.getLiteral(), uc.getLang());
358                            } else {
359                                    owlConstant = factory.getOWLLiteral(uc.getLiteral(), "");
360                            }
361                    }
362                    return owlConstant;
363            }
364    
365            @Override
366            public void visit(ObjectOneOf description) {
367                    stack.push(factory.getOWLObjectOneOf(OWLAPIConverter.getOWLAPIIndividuals(description.getIndividuals())));
368                    
369            }
370    }