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.owl;
020
021import java.util.Comparator;
022import java.util.Set;
023
024import org.dllearner.core.EvaluatedDescription;
025import org.dllearner.core.Score;
026import org.dllearner.reasoning.OWLPunningDetector;
027import org.semanticweb.owlapi.model.OWLClassExpression;
028import org.semanticweb.owlapi.model.OWLNaryBooleanClassExpression;
029import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom;
030
031import com.google.common.collect.ComparisonChain;
032
033/**
034 * Comparator for evaluated descriptions, which orders them by
035 * accuracy as first criterion, length as second criterion, and
036 * syntactic structure as third criterion.
037 * 
038 * @author Jens Lehmann
039 *
040 */
041public class EvaluatedDescriptionComparator implements Comparator<EvaluatedDescription<? extends Score>> {
042
043        /* (non-Javadoc)
044         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
045         */
046        @Override
047        public int compare(EvaluatedDescription<? extends Score> ed1, EvaluatedDescription<? extends Score> ed2) {
048                return ComparisonChain.start()
049                                .compare(ed1.getAccuracy(), ed2.getAccuracy()) // higher accuracy is better
050                                .compare(getLength(ed2), getLength(ed1)) // shorter is better
051                                .compare(ed1.getDescription(), ed2.getDescription()) // syntactic sorting
052                                .result();
053        }
054        
055        private int getLength(EvaluatedDescription<? extends Score> ed){
056                int length = 0;
057                OWLClassExpression ce = ed.getDescription();
058                if(ce instanceof OWLNaryBooleanClassExpression){
059                        Set<OWLClassExpression> operands = ((OWLNaryBooleanClassExpression) ce).getOperands();
060                        for (OWLClassExpression child : operands) {
061                                if(child instanceof OWLObjectSomeValuesFrom && ((OWLObjectSomeValuesFrom) child).getProperty() == OWLPunningDetector.punningProperty){
062                                        length += OWLClassExpressionUtils.getLength(((OWLObjectSomeValuesFrom)child).getFiller());
063                                } else {
064                                        length += OWLClassExpressionUtils.getLength(child);
065                                }
066                        }
067                        length += operands.size() - 1;
068                } else {
069                        length = OWLClassExpressionUtils.getLength(ce);
070                }
071                return length;
072        }
073
074}