001/**
002 * Copyright (C) 2007 - 2016, 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 */
019package org.dllearner.utilities;
020
021import java.util.HashSet;
022import java.util.Iterator;
023import java.util.List;
024import java.util.Set;
025
026import org.semanticweb.owlapi.model.ClassExpressionType;
027import org.semanticweb.owlapi.model.DataRangeType;
028import org.semanticweb.owlapi.model.OWLClass;
029import org.semanticweb.owlapi.model.OWLClassExpression;
030import org.semanticweb.owlapi.model.OWLDataIntersectionOf;
031import org.semanticweb.owlapi.model.OWLDataOneOf;
032import org.semanticweb.owlapi.model.OWLDataProperty;
033import org.semanticweb.owlapi.model.OWLDataPropertyExpression;
034import org.semanticweb.owlapi.model.OWLDataRange;
035import org.semanticweb.owlapi.model.OWLDatatype;
036import org.semanticweb.owlapi.model.OWLDatatypeRestriction;
037import org.semanticweb.owlapi.model.OWLEntity;
038import org.semanticweb.owlapi.model.OWLFacetRestriction;
039import org.semanticweb.owlapi.model.OWLIndividual;
040import org.semanticweb.owlapi.model.OWLLiteral;
041import org.semanticweb.owlapi.model.OWLObjectProperty;
042import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
043import org.semanticweb.owlapi.vocab.OWLFacet;
044
045import fuzzydl.Concept;
046import fuzzyowl2.ChoquetConcept;
047import fuzzyowl2.FuzzyLogic;
048import fuzzyowl2.FuzzyNominalConcept;
049import fuzzyowl2.LeftShoulderFunction;
050import fuzzyowl2.LinearFunction;
051import fuzzyowl2.LinearModifier;
052import fuzzyowl2.ModifiedConcept;
053import fuzzyowl2.ModifiedFunction;
054import fuzzyowl2.ModifiedProperty;
055import fuzzyowl2.OwaConcept;
056import fuzzyowl2.QowaConcept;
057import fuzzyowl2.QuasiSugenoConcept;
058import fuzzyowl2.RightShoulderFunction;
059import fuzzyowl2.SugenoConcept;
060import fuzzyowl2.TrapezoidalFunction;
061import fuzzyowl2.TriangularFunction;
062import fuzzyowl2.TriangularModifier;
063import fuzzyowl2.WeightedConcept;
064import fuzzyowl2.WeightedMaxConcept;
065import fuzzyowl2.WeightedMinConcept;
066import fuzzyowl2.WeightedSumConcept;
067
068/**
069 * Class translating from OWL 2 into fuzzyDL syntax.
070 *
071 * @author Fernando Bobillo
072 */
073public class FuzzyOwl2toFuzzyDL extends FuzzyOwl2
074{
075
076        private final double DOUBLE_MIN_VALUE = -1000000;
077        private final double DOUBLE_MAX_VALUE = 1000000;
078        private final double INTEGER_MIN_VALUE = -1000000;
079        private final double INTEGER_MAX_VALUE = 1000000;
080        
081        private Set<String> numericalDatatypes;
082        private Set<String> stringDatatypes;
083
084        public FuzzyOwl2toFuzzyDL(String input, String output)
085        {
086                super(input, output);
087                numericalDatatypes = new HashSet<>();
088                stringDatatypes = new HashSet<>();
089        }
090
091        @Override
092        public String getIndividualName(OWLIndividual i)
093        {
094                if (i.isAnonymous())
095                {
096                        printError("Anonymous individual " + i + " not supported");
097                        return null;
098                }
099                else
100                        return( getShortName( i.asOWLNamedIndividual() )) ;
101        }
102
103        @Override
104        protected String getTopConceptName()
105        {
106                return Concept.CONCEPT_TOP.toString();//("*top*");
107        }
108
109        @Override
110        protected String getBottomConceptName()
111        {
112                return("*bottom*");
113        }
114
115        @Override
116        protected String getAtomicConceptName(OWLClass c)
117        {
118                return getShortName(c);
119        }
120
121        @Override
122        protected String getObjectIntersectionOfName(Set<OWLClassExpression> operands)
123        {
124                String s = "(and ";
125                for(OWLClassExpression c : operands)
126                        s += getClassName(c) + " ";
127                s += ")";
128                return s;
129        }
130
131        @Override
132        protected String getObjectUnionOfName(Set<OWLClassExpression> operands)
133        {
134                String s = "(or ";
135                for(OWLClassExpression c : operands)
136                        s += getClassName(c) + " ";
137                s += ")";
138                return s;
139        }
140
141        @Override
142        protected String getObjectSomeValuesFromName(OWLObjectPropertyExpression p, OWLClassExpression c)
143        {
144                return "(some " + getObjectPropertyName(p) + " " + getClassName(c) + ")";
145        }
146
147        @Override
148        protected String getObjectAllValuesFromName(OWLObjectPropertyExpression p, OWLClassExpression c)
149        {
150                return "(all " + getObjectPropertyName(p) + " " + getClassName(c) + " )";
151        }
152
153        @Override
154        protected String getDataSomeValuesFromName(OWLDataPropertyExpression p, OWLDataRange range)
155        {
156                DataRangeType type = range.getDataRangeType();
157                if (type == DataRangeType.DATATYPE)
158                {
159                        String datatypeName = pm.getShortForm(range.asOWLDatatype());
160                        if (fuzzyDatatypes.containsKey(datatypeName))
161                                return "(some " + getDataPropertyName(p) + " " + datatypeName + ")";
162                }
163                else if (type == DataRangeType.DATA_ONE_OF)
164                {
165                        OWLDataOneOf o = (OWLDataOneOf) range;
166                        Set<OWLLiteral> set = o.getValues();
167                        if (!set.isEmpty())
168                        {
169                                OWLLiteral lit = set.iterator().next();
170                                return "(= " + getDataPropertyName(p) + " " + lit.getLiteral() + ")";
171                        }
172                }
173                printError("Data some values restriction with range " + range + " not supported");
174                return null;
175        }
176
177        @Override
178        protected String getDataAllValuesFromName(OWLDataPropertyExpression p, OWLDataRange range)
179        {
180                DataRangeType type = range.getDataRangeType();
181                if (type == DataRangeType.DATATYPE)
182                {
183                        String datatypeName = pm.getShortForm(range.asOWLDatatype());
184                        if (fuzzyDatatypes.containsKey(datatypeName))
185                                return "(all " + getDataPropertyName(p) + " " + datatypeName + ")";
186                }
187                printError("Data all values restriction with range " + range + " not supported");
188                return null;
189        }
190
191        @Override
192        protected String getObjectComplementOfName(OWLClassExpression c)
193        {
194                return "(not " + getClassName(c) + " )";
195        }
196
197        @Override
198        protected String getObjectHasSelfName(OWLObjectPropertyExpression p)
199        {
200                return "(self " + getObjectPropertyName(p) + ")";
201        }
202
203        @Override
204        protected String getObjectOneOfName(Set<OWLIndividual> set)
205        {
206                printError("OneOf concept not supported");
207                return null;
208        }
209
210        @Override
211        protected String getObjectHasValueName(OWLObjectPropertyExpression p, OWLIndividual i)
212        {
213                printError("Object has value concept not supported");
214                return null;
215        }
216
217        @Override
218        protected String getDataHasValueName(OWLDataPropertyExpression p, OWLLiteral lit)
219        {
220                printError("Data has value concept not supported");
221                return null;
222        }
223
224        @Override
225        protected String getObjectMinCardinalityRestrictionName(int card, OWLObjectPropertyExpression p, OWLClassExpression c)
226        {
227                printError("Object min cardinality restriction not supported");
228                return null;
229        }
230
231        @Override
232        protected String getObjectMinCardinalityRestrictionName(int card, OWLObjectPropertyExpression p)
233        {
234                printError("Object min cardinality restriction not supported");
235                return null;
236        }
237
238        @Override
239        protected String getObjectMaxCardinalityRestrictionName(int card, OWLObjectPropertyExpression p, OWLClassExpression c)
240        {
241                printError("Object max cardinality restriction not supported");
242                return null;
243        }
244
245        @Override
246        protected String getObjectMaxCardinalityRestrictionName(int card, OWLObjectPropertyExpression p)
247        {
248                printError("Object max cardinality restriction not supported");
249                return null;
250        }
251
252        @Override
253        protected String getObjectExactCardinalityRestrictionName(int card, OWLObjectPropertyExpression p, OWLClassExpression c)
254        {
255                printError("Object exact cardinality restriction not supported");
256                return null;
257        }
258
259        @Override
260        protected String getObjectExactCardinalityRestrictionName(int card, OWLObjectPropertyExpression p)
261        {
262                printError("Object exact cardinality restriction not supported");
263                return null;
264        }
265
266        @Override
267        protected String getDataMinCardinalityRestrictionName(int card, OWLDataPropertyExpression p, OWLDataRange range)
268        {
269                printError("Data min cardinality restriction not supported");
270                return null;
271        }
272
273        @Override
274        protected String getDataMinCardinalityRestrictionName(int card, OWLDataPropertyExpression p)
275        {
276                printError("Data min cardinality restriction not supported");
277                return null;
278        }
279
280        @Override
281        protected String getDataMaxCardinalityRestrictionName(int card, OWLDataPropertyExpression p, OWLDataRange range)
282        {
283                printError("Data max cardinality restriction not supported");
284                return null;
285        }
286
287        @Override
288        protected String getDataMaxCardinalityRestrictionName(int card, OWLDataPropertyExpression p)
289        {
290                printError("Data max cardinality restriction not supported");
291                return null;
292        }
293
294        @Override
295        protected String getDataExactCardinalityRestrictionName(int card, OWLDataPropertyExpression p, OWLDataRange range)
296        {
297                printError("Data exact cardinality restriction not supported");
298                return null;
299        }
300
301        @Override
302        protected String getDataExactCardinalityRestrictionName(int card, OWLDataPropertyExpression p)
303        {
304                printError("Data exact cardinality restriction not supported");
305                return null;
306        }
307
308        @Override
309        protected String getTopObjectPropertyName()
310        {
311                printError("Top object property not supported");
312                return null;
313        }
314
315        @Override
316        protected String getBottomObjectPropertyName()
317        {
318                printError("Bottom object property not supported");
319                return null;
320        }
321
322        @Override
323        protected String getAtomicObjectPropertyName(OWLObjectProperty p)
324        {
325                return getShortName(p);
326        }
327
328        @Override
329        protected String getTopDataPropertyName()
330        {
331                printError("Top data property not supported");
332                return null;
333        }
334
335        @Override
336        protected String getBottomDataPropertyName()
337        {
338                printError("Bottom data property not supported");
339                return null;
340        }
341
342        @Override
343        protected String getAtomicDataPropertyName(OWLDataProperty p)
344        {
345                return getShortName(p);
346        }
347
348        @Override
349        protected void writeFuzzyLogic(FuzzyLogic logic)
350        {
351                print("(define-fuzzy-logic " + logic + ")");
352        }
353
354        @Override
355        protected void writeConceptDeclaration(OWLClassExpression c)
356        {
357                print("(define-primitive-concept " + getClassName(c) + " " + getTopConceptName() + " )");
358        }
359
360        @Override
361        protected void writeDataPropertyDeclaration(OWLDataPropertyExpression dp)
362        {
363                writeFunctionalDataPropertyAxiom(dp);
364                print("(range " + getDataPropertyName(dp) + " *string* )");
365        }
366
367        @Override
368        protected void writeObjectPropertyDeclaration(OWLObjectPropertyExpression op)
369        {
370
371        }
372
373        @Override
374        protected void writeTriangularModifierDefinition(String name, TriangularModifier mod)
375        {
376                double a = mod.getA();
377                double b = mod.getB();
378                double c = mod.getC();
379                print("(define-modifier " + name + " triangular-modifier(" + a + ", " + b + ", " + c + ") )");
380        }
381
382        @Override
383        protected void writeLinearModifierDefinition(String name, LinearModifier mod)
384        {
385                double c = mod.getC();
386                print("(define-modifier " + name + " linear-modifier(" + c + ") )");
387        }
388
389        @Override
390        protected void writeLeftShoulderFunctionDefinition(String name, LeftShoulderFunction f)
391        {
392                double k1 = f.getMinValue();
393                double k2 = f.getMaxValue();
394                double a = f.getA();
395                double b = f.getB();
396                print("(define-fuzzy-concept " + name + " left-shoulder(" +
397                        k1 + ", " + k2 + ", " + a + ", " + b + ") )");
398        }
399
400        @Override
401        protected void writeRightShoulderFunctionDefinition(String name, RightShoulderFunction f)
402        {
403                double k1 = f.getMinValue();
404                double k2 = f.getMaxValue();
405                double a = f.getA();
406                double b = f.getB();
407                print("(define-fuzzy-concept " + name + " right-shoulder(" +
408                        k1 + ", " + k2 + ", " + a + ", " + b + ") )");
409        }
410
411        @Override
412        protected void writeLinearFunctionDefinition(String name, LinearFunction f)
413        {
414                double k1 = f.getMinValue();
415                double k2 = f.getMaxValue();
416                double a = f.getA();
417                double b = f.getB();
418                print("(define-fuzzy-concept " + name + " linear(" +
419                        k1 + ", " + k2 + ", " + a + ", " + b + ") )");
420        }
421
422        @Override
423        protected void writeTriangularFunctionDefinition(String name, TriangularFunction f)
424        {
425                double k1 = f.getMinValue();
426                double k2 = f.getMaxValue();
427                double a = f.getA();
428                double b = f.getB();
429                double c = f.getC();
430                print("(define-fuzzy-concept " + name + " triangular(" +
431                        k1 + ", " + k2 + ", " + a + ", " + b + ", " + c + ") )");
432        }
433
434        @Override
435        protected void writeTrapezoidalFunctionDefinition(String name, TrapezoidalFunction f)
436        {
437                double k1 = f.getMinValue();
438                double k2 = f.getMaxValue();
439                double a = f.getA();
440                double b = f.getB();
441                double c = f.getC();
442                double d = f.getD();
443                print("(define-fuzzy-concept " + name + " trapezoidal(" +
444                        k1 + ", " + k2 + ", " + a + ", " + b + ", " + c + ", " + d + ") )");
445        }
446
447        @Override
448        protected void writeModifiedFunctionDefinition(String name, ModifiedFunction dat)
449        {
450                print("(define-concept " + name + " ( " + dat.getMod() + " " + dat.getD() + " ) )");
451        }
452
453        @Override
454        protected void writeModifiedPropertyDefinition(String name, ModifiedProperty c)
455        {
456                printError("Modified property not supported");
457        }
458
459        @Override
460        protected void writeModifiedConceptDefinition(String name, ModifiedConcept c)
461        {
462                print("(define-concept " + name + " (" + c.getFuzzyModifier() + " " +
463                        c.getFuzzyConcept() + ") )");
464        }
465
466        @Override
467        protected void writeFuzzyNominalConceptDefinition(String name, FuzzyNominalConcept c)
468        {
469                printError("Fuzzy nominal not supported");
470        }
471
472        @Override
473        protected void writeWeightedConceptDefinition(String name, WeightedConcept c)
474        {
475                print("(define-concept " + name + " (" + c.getWeight() + " " +
476                        c.getFuzzyConcept() + ") )");
477        }
478
479        @Override
480        protected void writeWeightedMaxConceptDefinition(String name, WeightedMaxConcept c)
481        {
482                String s = "(define-concept " + name + " (w-max ";
483                List<WeightedConcept> list = c.getWeightedConcepts();
484                WeightedConcept wc = list.get(0);
485                s += "(" + wc.getWeight() + " " + wc.getFuzzyConcept() + ")";
486
487                for(int i=1; i<list.size(); i++)
488                {
489                        wc = list.get(i);
490                        s += " (" + wc.getWeight() + " " + wc.getFuzzyConcept() + ")";
491                }
492                s += " ) )";
493                print(s);
494        }
495
496        @Override
497        protected void writeWeightedMinConceptDefinition(String name, WeightedMinConcept c)
498        {
499                String s = "(define-concept " + name + " (w-min ";
500                List<WeightedConcept> list = c.getWeightedConcepts();
501                WeightedConcept wc = list.get(0);
502                s += "(" + wc.getWeight() + " " + wc.getFuzzyConcept() + ")";
503
504                for(int i=1; i<list.size(); i++)
505                {
506                        wc = list.get(i);
507                        s += " (" + wc.getWeight() + " " + wc.getFuzzyConcept() + ")";
508                }
509                s += " ) )";
510                print(s);
511        }
512
513        @Override
514        protected void writeWeightedSumConceptDefinition(String name, WeightedSumConcept c)
515        {
516                String s = "(define-concept " + name + " (w-sum ";
517                List<WeightedConcept> list = c.getWeightedConcepts();
518                WeightedConcept wc = list.get(0);
519                s += "(" + wc.getWeight() + " " + wc.getFuzzyConcept() + ")";
520
521                for(int i=1; i<list.size(); i++)
522                {
523                        wc = list.get(i);
524                        s += " (" + wc.getWeight() + " " + wc.getFuzzyConcept() + ")";
525                }
526                s += " ) )";
527                print(s);
528        }
529
530        @Override
531        protected void writeOwaConceptDefinition(String name, OwaConcept c)
532        {
533                String s = "(define-concept " + name + " (owa (";
534                List<Double> w = c.getWeights();
535                s += w.get(0);
536                for(int i=1; i<w.size(); i++)
537                        s += " " + w.get(i).toString();
538                s += ") (";
539                List<String> list = c.getConcepts();
540                s += list.get(0);
541                for(int i=1; i<list.size(); i++)
542                        s += " " + list.get(i);
543                s += ") ) )";
544                print(s);
545        }
546
547        @Override
548        protected void writeChoquetConceptDefinition(String name, ChoquetConcept c)
549        {
550                String s = "(define-concept " + name + " (choquet (";
551                List<Double> w = c.getWeights();
552                s += w.get(0);
553                for(int i=1; i<w.size(); i++)
554                        s += " " + w.get(i).toString();
555                s += ") (";
556                List<String> list = c.getConcepts();
557                s += list.get(0);
558                for(int i=1; i<list.size(); i++)
559                        s += " " + list.get(i);
560                s += ") ) )";
561                print(s);
562        }
563
564        @Override
565        protected void writeSugenoConceptDefinition(String name, SugenoConcept c)
566        {
567                String s = "(define-concept " + name + " (sugeno (";
568                List<Double> w = c.getWeights();
569                s += w.get(0);
570                for(int i=1; i<w.size(); i++)
571                        s += " " + w.get(i).toString();
572                s += ") (";
573                List<String> list = c.getConcepts();
574                s += list.get(0);
575                for(int i=1; i<list.size(); i++)
576                        s += " " + list.get(i);
577                s += ") ) )";
578                print(s);
579        }
580
581        @Override
582        protected void writeQuasiSugenoConceptDefinition(String name, QuasiSugenoConcept c)
583        {
584                String s = "(define-concept " + name + " (q-sugeno (";
585                List<Double> w = c.getWeights();
586                s += w.get(0);
587                for(int i=1; i<w.size(); i++)
588                        s += " " + w.get(i).toString();
589                s += ") (";
590                List<String> list = c.getConcepts();
591                s += list.get(0);
592                for(int i=1; i<list.size(); i++)
593                        s += " " + list.get(i);
594                s += ") ) )";
595                print(s);
596        }
597
598        @Override
599        protected void writeQowaConceptDefinition(String name, QowaConcept c)
600        {
601                String s = "(define-concept " + name + " (q-owa " + c.getQuantifier() + " ";
602                List<String> list = c.getConcepts();
603                s += list.get(0);
604                for(int i=1; i<list.size(); i++)
605                        s += " " + list.get(i);
606                s += ") )";
607                print(s);
608        }
609
610        @Override
611        protected void writeConceptAssertionAxiom(OWLIndividual i, OWLClassExpression c, double d)
612        {
613                print("(instance " + getIndividualName(i) + " " + getClassName(c) + " " + d + ")");
614        }
615
616        @Override
617        protected void writeObjectPropertyAssertionAxiom(OWLIndividual i1, OWLIndividual i2, OWLObjectPropertyExpression p, double d)
618        {
619                print("(related " + getIndividualName(i1) + " " + getIndividualName(i2) + " " + getObjectPropertyName(p) + " " + d + ")");
620        }
621
622        @Override
623        protected void writeDataPropertyAssertionAxiom(OWLIndividual i1, OWLLiteral i2, OWLDataPropertyExpression p, double d)
624        {
625                OWLDatatype dat = i2.getDatatype();
626                String dpName = getDataPropertyName(p);
627
628                if (dat == null)
629                        print("(instance " + getIndividualName(i1) + " (= " + dpName + " " + i2.getLiteral() + ") " + d + " )");
630                else
631                {
632                        String datatypeName = pm.getShortForm(dat.asOWLDatatype());
633                        if (fuzzyDatatypes.containsKey(datatypeName))                           
634                                print("(instance " + getIndividualName(i1) + " (some " + dpName + " " + datatypeName + ") " + d + " )");
635                        else
636                        {
637                                String l = i2.getLiteral();
638                                //String l2 = l.replaceAll("\\.", ",");
639                                //Scanner scanner = new Scanner(l2);
640                                //if (scanner.hasNextDouble() || scanner.hasNextInt())
641                                if (i2.isDouble() || i2.isInteger() || i2.isFloat())
642                                {
643                                        if (! numericalDatatypes.contains(dpName))
644                                        {
645                                                numericalDatatypes.add(dpName);
646                                                writeFunctionalDataPropertyAxiom(p);
647                                                if (i2.isInteger())     
648                                                        print("(range " + getDataPropertyName(p) + " *integer* " + INTEGER_MIN_VALUE + " " + INTEGER_MAX_VALUE + " )");
649                                                else
650                                                        print("(range " + getDataPropertyName(p) + " *real* " + DOUBLE_MIN_VALUE + " " + DOUBLE_MAX_VALUE + " )");
651                                                        
652                                        }
653                                        
654                                        if (i2.isDouble())
655                                                print("(instance " + getIndividualName(i1) + " (= " + dpName + " " + i2.parseDouble() + ") " + d + " )");                                       
656                                        else if (i2.isInteger())
657                                                print("(instance " + getIndividualName(i1) + " (= " + dpName + " " + i2.parseInteger() + ") " + d + " )");
658                                        else 
659                                                print("(instance " + getIndividualName(i1) + " (= " + dpName + " " + i2.parseFloat() + ") " + d + " )");
660                                }
661
662                                else
663                                {
664                                        if (! stringDatatypes.contains(dpName))
665                                        {
666                                                stringDatatypes.add(dpName);
667                                                writeDataPropertyDeclaration(p);
668                                        }
669                                        // Convert separators into "_"
670                                        l = l.replaceAll("\\s", "_");
671                                        // If first character is a number, add a "_"
672                                        char c = l.charAt(0);
673                                        if ((c >= '0') && (c <= '9'))
674                                                l = "_" + l;
675                                        print("(instance " + getIndividualName(i1) + " (= " + dpName + " \"" + l + "\" ) " + d + " )");
676                                }
677                        }
678                }
679        }
680
681        @Override
682        protected void writeNegativeObjectPropertyAssertionAxiom(OWLIndividual i1, OWLIndividual i2, OWLObjectPropertyExpression p, double d)
683        {
684                printError("Negative object property assertion not supported");
685        }
686
687        @Override
688        protected void writeNegativeDataPropertyAssertionAxiom(OWLIndividual i1, OWLLiteral i2, OWLDataPropertyExpression p, double d)
689        {
690                printError("Negative data property assertion not supported");
691        }
692
693        @Override
694        protected void writeSameIndividualAxiom(Set<OWLIndividual> set)
695        {
696                printError("Same individual axiom not supported");
697        }
698
699        @Override
700        protected void writeDifferentIndividualsAxiom(Set<OWLIndividual> set)
701        {
702                printError("Different individuals axiom not supported");
703        }
704
705        @Override
706        protected void writeDisjointClassesAxiom(Set<OWLClassExpression> set)
707        {
708                if (set.size() > 1)
709                {
710                        String s = "(disjoint ";
711                        for (OWLClassExpression c : set)
712/*                      {
713/*                              ClassExpressionType type = c.getClassExpressionType();
714                                if (type != ClassExpressionType.OWL_CLASS)
715                                {
716                                        System.out.println("Concept type " + type + " not supported in disjoint classes axiom");
717                                        return;
718                                }
719                                else
720*/                                      s += getShortName(c.asOWLClass()) + " ";
721//                      }
722                        s += ")";
723                        print(s);
724                }
725        }
726
727        @Override
728        protected void writeDisjointUnionAxiom(Set<OWLClassExpression> set)
729        {
730                if (set.size() > 1)
731                {
732                        String s = "(disjoint-union ";
733                        for (OWLClassExpression c : set)
734                        {
735                                ClassExpressionType type = c.getClassExpressionType();
736                                if (type != ClassExpressionType.OWL_CLASS)
737                                        exit("Concept type " + type + " not supported in disjoint union axiom");
738                                else
739                                        s += getShortName(c.asOWLClass()) + " ";
740                        }
741                        s += ")";
742                        print(s);
743                }
744        }
745
746        @Override
747        protected void writeSubclassOfAxiom(OWLClassExpression subclass, OWLClassExpression superclass, double d)
748        {
749//              if (superclass.isOWLThing() != false)
750                {
751                        ClassExpressionType type = subclass.getClassExpressionType();
752                        if ((type == ClassExpressionType.OWL_CLASS) && (d == 1))
753                                print("(define-primitive-concept " + getShortName(subclass.asOWLClass()) + " " + getClassName(superclass) + ")");
754                        else
755                                print("(implies " + getClassName(subclass) + " " + getClassName(superclass) + " " + d + ")");
756                }
757        }
758
759        @Override
760        protected void writeEquivalentClassesAxiom(Set<OWLClassExpression> set)
761        {
762                String name = null;
763                OWLClassExpression leftClass = null;
764                for (OWLClassExpression c : set)
765                        if (c.getClassExpressionType() == ClassExpressionType.OWL_CLASS)
766                        {
767                                name = getShortName(c.asOWLClass());
768                                leftClass = c;
769                                break;
770                        }
771
772                if (name == null)
773                        exit("Equivalent classes axiom " + set + " require at least one atomic class");
774
775                for (OWLClassExpression c : set)
776                        if (c != leftClass)
777                                print("(define-concept " + name + " " + getClassName(c) + " )");
778        }
779
780        @Override
781        protected void writeSubObjectPropertyOfAxiom(OWLObjectPropertyExpression subProperty, OWLObjectPropertyExpression superProperty, double d)
782        {
783//              if (superProperty.isOWLTopObjectProperty() == false)
784                        print("(implies-role " + getObjectPropertyName(subProperty) + " " + getObjectPropertyName(superProperty) + " " + d + ")");
785        }
786
787        @Override
788        protected void writeSubPropertyChainOfAxiom(List<OWLObjectPropertyExpression> chain, OWLObjectPropertyExpression superProperty, double d)
789        {
790                printError("Subproperty chain axiom not supported");
791        }
792
793        @Override
794        protected void writeSubDataPropertyOfAxiom(OWLDataPropertyExpression subProperty, OWLDataPropertyExpression superProperty, double d)
795        {
796//              if (superProperty.isOWLTopDataProperty() == false)
797                        print("(implies-role " + getDataPropertyName(subProperty) + " " + getDataPropertyName(superProperty) + " " + d + ")");
798        }
799
800        @Override
801        protected void writeEquivalentObjectPropertiesAxiom(Set<OWLObjectPropertyExpression> set)
802        {
803                Iterator<OWLObjectPropertyExpression> it = set.iterator();
804                OWLObjectPropertyExpression first = it.next();
805                while(it.hasNext())
806                {
807                        OWLObjectPropertyExpression property = it.next();
808                        print("(implies-role " + getObjectPropertyName(first) + " " + getObjectPropertyName(property) + ")");
809                        print("(implies-role " + getObjectPropertyName(property) + " " + getObjectPropertyName(first) + ")");
810                }
811        }
812
813        @Override
814        protected void writeEquivalentDataPropertiesAxiom(Set<OWLDataPropertyExpression> set)
815        {
816                Iterator<OWLDataPropertyExpression> it = set.iterator();
817                OWLDataPropertyExpression first = it.next();
818                while(it.hasNext())
819                {
820                        OWLDataPropertyExpression property = it.next();
821                        print("(implies-role " + getDataPropertyName(first) + " " + getDataPropertyName(property) + ")");
822                        print("(implies-role " + getDataPropertyName(property) + " " + getDataPropertyName(first) + ")");
823                }
824        }
825
826        @Override
827        protected void writeTransitiveObjectPropertyAxiom(OWLObjectPropertyExpression p)
828        {
829                print("(transitive " + getObjectPropertyName(p) + ")");
830        }
831
832        @Override
833        protected void writeSymmetricObjectPropertyAxiom(OWLObjectPropertyExpression p)
834        {
835                print("(symmetric " + getObjectPropertyName(p) + ")");
836        }
837
838        @Override
839        protected void writeAsymmetricObjectPropertyAxiom(OWLObjectPropertyExpression p)
840        {
841                printError("Asymmetric object property axiom not supported");
842        }
843
844        @Override
845        protected void writeReflexiveObjectPropertyAxiom(OWLObjectPropertyExpression p)
846        {
847                print("(reflexive " + getObjectPropertyName(p) + ")");
848        }
849
850        @Override
851        protected void writeIrreflexiveObjectPropertyAxiom(OWLObjectPropertyExpression p)
852        {
853                printError("Irreflexive object property axiom not supported");
854        }
855
856        @Override
857        protected void writeFunctionalObjectPropertyAxiom(OWLObjectPropertyExpression p)
858        {
859                print("(functional " + getObjectPropertyName(p) + ")");
860        }
861
862        @Override
863        protected void writeFunctionalDataPropertyAxiom(OWLDataPropertyExpression p)
864        {
865                print("(functional " + getDataPropertyName(p) + ")");
866        }
867
868        @Override
869        protected void writeInverseObjectPropertiesAxiom(OWLObjectPropertyExpression p1, OWLObjectPropertyExpression p2)
870        {
871                print("(inverse " + getObjectPropertyName(p1) + " " + getObjectPropertyName(p2) + ")");
872        }
873
874        @Override
875        protected void writeInverseFunctionalObjectPropertyAxiom(OWLObjectPropertyExpression p)
876        {
877                print("(inverse-functional " + getObjectPropertyName(p) + ")");
878        }
879
880        @Override
881        protected void writeObjectPropertyDomainAxiom(OWLObjectPropertyExpression p, OWLClassExpression c)
882        {
883                print("(domain " + getObjectPropertyName(p) + " " + getClassName(c) + " )");
884        }
885
886        @Override
887        protected void writeObjectPropertyRangeAxiom(OWLObjectPropertyExpression p, OWLClassExpression c)
888        {
889                print("(range " + getObjectPropertyName(p) + " " + getClassName(c) + " )");
890        }
891
892        @Override
893        protected void writeDataPropertyDomainAxiom(OWLDataPropertyExpression p, OWLClassExpression c)
894        {
895                print("(domain " + getDataPropertyName(p) + " " + getClassName(c) + " )");
896        }
897
898        @Override
899        protected void writeDataPropertyRangeAxiom(OWLDataPropertyExpression p, OWLDataRange range)
900        {
901                String rangeString = null;
902                String dpName = getDataPropertyName(p);
903                DataRangeType type = range.getDataRangeType();
904
905                if (type == DataRangeType.DATATYPE)
906                {
907                        OWLDatatype datatype = range.asOWLDatatype();
908                        if (datatype.isString())
909                        {
910                                stringDatatypes.add(getDataPropertyName(p));
911                                rangeString = "*string*";
912                        }
913                }
914                else if (type == DataRangeType.DATA_INTERSECTION_OF)
915                {
916                        int correctness = 0;
917                        int isInteger = 0;
918                        double min = 0;
919                        double max = 0;
920
921                        Set<OWLDataRange> set = ((OWLDataIntersectionOf) range).getOperands();
922                        if (set.size() == 2)
923                        {
924                                for (OWLDataRange dr2 : set)
925                                {
926                                        if (dr2.getDataRangeType() == DataRangeType.DATATYPE_RESTRICTION)
927                                        {
928                                                Set<OWLFacetRestriction> set2 = ((OWLDatatypeRestriction) dr2).getFacetRestrictions();
929                                                if (set2.size() != 1)
930                                                        continue;
931
932                                                OWLFacetRestriction facet = set2.iterator().next();
933                                                String val = facet.getFacetValue().getLiteral();
934                                                if (facet.getFacetValue().isInteger())
935                                                        isInteger++;
936                                                double k = Double.parseDouble(val);
937                                                if (facet.getFacet() == OWLFacet.MIN_INCLUSIVE)
938                                                {
939                                                        min = k;
940                                                        correctness++;
941                                                }
942                                                else if (facet.getFacet() == OWLFacet.MAX_INCLUSIVE)
943                                                {
944                                                        max = k;
945                                                        correctness++;
946                                                }
947                                        }
948                                }
949                        }
950
951                        if (correctness == 2)
952                        {
953                                if (isInteger == 2)
954                                        rangeString = "*integer* " + ((int) min) + " " + ((int) max) ;
955                                else
956                                        rangeString = "*real* " + min + " " + max;
957                                numericalDatatypes.add(dpName);
958                        }
959                }
960                if (rangeString != null)
961                {
962                        writeFunctionalDataPropertyAxiom(p);
963                        print("(range " + dpName + " " + rangeString + " )");
964                }
965                else
966                {
967                        if (type.toString().equals("DATA_ONE_OF"))
968                                printError("Data one of range axiom not supported");
969                        else
970                        {
971                                OWLDatatype rangeType = range.asOWLDatatype();
972                                if (rangeType.isFloat() || rangeType.isDouble() )
973                                {
974                                        writeFunctionalDataPropertyAxiom(p);
975                                        print("(range " + dpName + " *real* " + DOUBLE_MIN_VALUE + " " + DOUBLE_MAX_VALUE + " )");
976                                        numericalDatatypes.add(dpName);
977                                }
978                                else if (rangeType.isInteger())
979                                {
980                                        writeFunctionalDataPropertyAxiom(p);
981                                        print("(range " + dpName + " *integer* " + INTEGER_MIN_VALUE + " " + INTEGER_MAX_VALUE + " )");
982                                        numericalDatatypes.add(dpName);
983                                }
984                                else
985                                        printError("Data property range axiom with range " + range + " not supported");
986                        }
987                }
988        }
989
990        @Override
991        protected void writeDisjointObjectPropertiesAxiom(Set<OWLObjectPropertyExpression> set)
992        {
993                printError("Disjoint object properties axiom not supported");
994        }
995
996        @Override
997        protected void writeDisjointDataPropertiesAxiom(Set<OWLDataPropertyExpression> set)
998        {
999                printError("Disjoint data properties axiom not supported");
1000        }
1001
1002        /**
1003         * @param args Two arguments: the input OWL 2 ontology, and the output fuzzy ontology in fuzzyDL syntax.
1004         */
1005        public static void main(String[] args)
1006        {
1007                String[] returnValue = processParameters(args);
1008                FuzzyOwl2toFuzzyDL f = new FuzzyOwl2toFuzzyDL(returnValue[0], returnValue[1]);
1009                f.translateOwl2Ontology();
1010        }
1011        
1012        private boolean isReservedWord(String s)
1013        {
1014                if (s.equals("linear"))
1015                        return true;
1016                if (s.equals("triangular"))
1017                        return true;
1018                if (s.equals("trapezoidal"))
1019                        return true;
1020                if (s.equals("crisp"))
1021                        return true;
1022                if (s.equals("classical"))
1023                        return true;
1024                if (s.equals("disjoint"))
1025                        return true;
1026                if (s.equals("instance"))
1027                        return true;
1028                if (s.equals("related"))
1029                        return true;
1030                if (s.equals("domain"))
1031                        return true;
1032                if (s.equals("range"))
1033                        return true;
1034                
1035                // Avoid numbers
1036            try { 
1037                Double.parseDouble(s);
1038                return true;
1039            } catch(NumberFormatException e) { 
1040                return false; 
1041            }
1042        }
1043
1044        @Override
1045        public String getShortName(OWLEntity e)
1046        {
1047                String aux = pm.getShortForm(e);
1048                if (isReservedWord(aux))
1049                        return "_" + aux;
1050                else
1051                        return aux;
1052        }
1053
1054}