Package org.semanticweb.HermiT.datatypes.owlreal

Source Code of org.semanticweb.HermiT.datatypes.owlreal.OWLRealDatatypeHandler

/* Copyright 2008, 2009, 2010 by the Oxford University Computing Laboratory

   This file is part of HermiT.

   HermiT is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   HermiT is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with HermiT.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.semanticweb.HermiT.datatypes.owlreal;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.semanticweb.HermiT.Prefixes;
import org.semanticweb.HermiT.datatypes.DatatypeHandler;
import org.semanticweb.HermiT.datatypes.MalformedLiteralException;
import org.semanticweb.HermiT.datatypes.UnsupportedFacetException;
import org.semanticweb.HermiT.datatypes.ValueSpaceSubset;
import org.semanticweb.HermiT.model.Constant;
import org.semanticweb.HermiT.model.DatatypeRestriction;

/**
* Implements a handler for the numeric datatypes derived from owl:real. This class
* makes am important assumption that all data values are represented with objects
* whose .equals() method behaves as expected. This means that, for numbers represented
* using Java's classes, one needs to use the most specific class. For example, a decimal
* 1.0 *must* be represented as Integer 1, and a rational 7/2 *must* be represented
* as BigDecimal 3.5.
*/
public class OWLRealDatatypeHandler implements DatatypeHandler {
    protected static final String OWL_NS=Prefixes.s_semanticWebPrefixes.get("owl");
    protected static final String XSD_NS=Prefixes.s_semanticWebPrefixes.get("xsd");

    protected static final Map<String,NumberInterval> s_intervalsByDatatype=new HashMap<String,NumberInterval>();
    protected static final Map<String,ValueSpaceSubset> s_subsetsByDatatype=new HashMap<String,ValueSpaceSubset>();
    static {
        Object[][] initializer=new Object[][] {
            { OWL_NS+"real",              NumberRange.REAL,    MinusInfinity.INSTANCE,BoundType.EXCLUSIVE,PlusInfinity.INSTANCE,                  BoundType.EXCLUSIVE },
            { OWL_NS+"rational",          NumberRange.RATIONAL,MinusInfinity.INSTANCE,BoundType.EXCLUSIVE,PlusInfinity.INSTANCE,                  BoundType.EXCLUSIVE },
            { XSD_NS+"decimal",           NumberRange.DECIMAL, MinusInfinity.INSTANCE,BoundType.EXCLUSIVE,PlusInfinity.INSTANCE,                  BoundType.EXCLUSIVE },
            { XSD_NS+"integer",           NumberRange.INTEGER, MinusInfinity.INSTANCE,BoundType.EXCLUSIVE,PlusInfinity.INSTANCE,                  BoundType.EXCLUSIVE },
            { XSD_NS+"nonNegativeInteger",NumberRange.INTEGER, Integer.valueOf(0),    BoundType.INCLUSIVE,PlusInfinity.INSTANCE,                  BoundType.EXCLUSIVE },
            { XSD_NS+"positiveInteger",   NumberRange.INTEGER, Integer.valueOf(0),    BoundType.EXCLUSIVE,PlusInfinity.INSTANCE,                  BoundType.EXCLUSIVE },
            { XSD_NS+"nonPositiveInteger",NumberRange.INTEGER, MinusInfinity.INSTANCE,BoundType.EXCLUSIVE,Integer.valueOf(0),                     BoundType.INCLUSIVE },
            { XSD_NS+"negativeInteger",   NumberRange.INTEGER, MinusInfinity.INSTANCE,BoundType.EXCLUSIVE,Integer.valueOf(0),                     BoundType.EXCLUSIVE },
            { XSD_NS+"long",              NumberRange.INTEGER, Long.MIN_VALUE,        BoundType.INCLUSIVE,Long.MAX_VALUE,                         BoundType.INCLUSIVE },
            { XSD_NS+"int",               NumberRange.INTEGER, Integer.MIN_VALUE,     BoundType.INCLUSIVE,Integer.MAX_VALUE,                      BoundType.INCLUSIVE },
            { XSD_NS+"short",             NumberRange.INTEGER, (int)Short.MIN_VALUE,  BoundType.INCLUSIVE,(int)Short.MAX_VALUE,                   BoundType.INCLUSIVE },
            { XSD_NS+"byte",              NumberRange.INTEGER, (int)Byte.MIN_VALUE,   BoundType.INCLUSIVE,(int)Byte.MAX_VALUE,                    BoundType.INCLUSIVE },
            { XSD_NS+"unsignedLong",      NumberRange.INTEGER, Integer.valueOf(0),    BoundType.INCLUSIVE,new BigInteger("18446744073709551615"), BoundType.INCLUSIVE },
            { XSD_NS+"unsignedInt",       NumberRange.INTEGER, Integer.valueOf(0),    BoundType.INCLUSIVE,4294967295L,                            BoundType.INCLUSIVE },
            { XSD_NS+"unsignedShort",     NumberRange.INTEGER, Integer.valueOf(0),    BoundType.INCLUSIVE,65535,                                  BoundType.INCLUSIVE },
            { XSD_NS+"unsignedByte",      NumberRange.INTEGER, Integer.valueOf(0),    BoundType.INCLUSIVE,255,                                    BoundType.INCLUSIVE },
        };
        for (Object[] row : initializer) {
            String datatypeURI=(String)row[0];
            NumberInterval interval=new NumberInterval((NumberRange)row[1],NumberRange.NOTHING,(Number)row[2],(BoundType)row[3],(Number)row[4],(BoundType)row[5]);
            s_intervalsByDatatype.put(datatypeURI,interval);
            s_subsetsByDatatype.put(datatypeURI,new OWLRealValueSpaceSubset(interval));
        }
    }
    protected static final ValueSpaceSubset EMPTY_SUBSET=new OWLRealValueSpaceSubset();
    protected static final Set<String> s_supportedFacetURIs=new HashSet<String>();
    static {
        s_supportedFacetURIs.add(XSD_NS+"minInclusive");
        s_supportedFacetURIs.add(XSD_NS+"minExclusive");
        s_supportedFacetURIs.add(XSD_NS+"maxInclusive");
        s_supportedFacetURIs.add(XSD_NS+"maxExclusive");
    }
    protected static final Map<String,Set<String>> s_datatypeSupersets=new HashMap<String,Set<String>>();
    protected static final Map<String,Set<String>> s_datatypeDisjoints=new HashMap<String,Set<String>>();
    static {
        for (String datatypeURI : s_intervalsByDatatype.keySet()) {
            s_datatypeSupersets.put(datatypeURI,new HashSet<String>());
            s_datatypeDisjoints.put(datatypeURI,new HashSet<String>());
        }
        for (Map.Entry<String,NumberInterval> entry1 : s_intervalsByDatatype.entrySet()) {
            String datatypeURI1=entry1.getKey();
            NumberInterval interval1=entry1.getValue();
            for (Map.Entry<String,NumberInterval> entry2 : s_intervalsByDatatype.entrySet()) {
                String datatypeURI2=entry2.getKey();
                NumberInterval interval2=entry2.getValue();
                NumberInterval intersection=interval1.intersectWith(interval2);
                if (intersection==null)
                    s_datatypeDisjoints.get(datatypeURI1).add(datatypeURI2);
                else if (intersection==interval1) {
                    // The above test depends on the fact that NumberInterval.intersectWith() will not
                    // create a new interval object if interval1 is contained in interval2.
                    s_datatypeSupersets.get(datatypeURI1).add(datatypeURI2);
                }
            }
        }
    }

    public Set<String> getManagedDatatypeURIs() {
        return s_intervalsByDatatype.keySet();
    }
    public Object parseLiteral(String lexicalForm,String datatypeURI) throws MalformedLiteralException {
        assert s_intervalsByDatatype.keySet().contains(datatypeURI);
        try {
            if ((OWL_NS+"real").equals(datatypeURI))
                throw new MalformedLiteralException(lexicalForm,datatypeURI);
            else if ((OWL_NS+"rational").equals(datatypeURI))
                return Numbers.parseRational(lexicalForm);
            else if ((XSD_NS+"decimal").equals(datatypeURI))
                return Numbers.parseDecimal(lexicalForm);
            else
                return Numbers.parseInteger(lexicalForm);
        }
        catch (NumberFormatException error) {
            throw new MalformedLiteralException(lexicalForm,datatypeURI);
        }
    }
    public void validateDatatypeRestriction(DatatypeRestriction datatypeRestriction) throws UnsupportedFacetException {
        assert s_intervalsByDatatype.keySet().contains(datatypeRestriction.getDatatypeURI());
        for (int index=datatypeRestriction.getNumberOfFacetRestrictions()-1;index>=0;--index) {
            String facetURI=datatypeRestriction.getFacetURI(index);
            if (!s_supportedFacetURIs.contains(facetURI))
                throw new UnsupportedFacetException("Facet with URI '"+facetURI+"' is not supported on datatypes derived from owl:real.");
            Constant facetValue=datatypeRestriction.getFacetValue(index);
            Object facetDataValue=facetValue.getDataValue();
            if (!(facetDataValue instanceof Number))
                throw new UnsupportedFacetException("Facet with URI '"+facetURI+"' takes only numbers as values.");
            if (!Numbers.isValidNumber((Number)facetDataValue))
                throw new UnsupportedFacetException("Facet with URI '"+facetURI+"' does not support '"+facetValue.toString()+"' as value.");
        }
    }
    public ValueSpaceSubset createValueSpaceSubset(DatatypeRestriction datatypeRestriction) {
        assert s_intervalsByDatatype.keySet().contains(datatypeRestriction.getDatatypeURI());
        if (datatypeRestriction.getNumberOfFacetRestrictions()==0)
            return s_subsetsByDatatype.get(datatypeRestriction.getDatatypeURI());
        NumberInterval interval=getIntervalFor(datatypeRestriction);
        if (interval==null)
            return EMPTY_SUBSET;
        else
            return new OWLRealValueSpaceSubset(interval);
    }
    public ValueSpaceSubset conjoinWithDR(ValueSpaceSubset valueSpaceSubset,DatatypeRestriction datatypeRestriction) {
        assert s_intervalsByDatatype.keySet().contains(datatypeRestriction.getDatatypeURI());
        NumberInterval interval=getIntervalFor(datatypeRestriction);
        if (interval==null)
            return EMPTY_SUBSET;
        else {
            OWLRealValueSpaceSubset realSubset=(OWLRealValueSpaceSubset)valueSpaceSubset;
            List<NumberInterval> oldIntervals=realSubset.m_intervals;
            List<NumberInterval> newIntervals=new ArrayList<NumberInterval>();
            for (int index=0;index<oldIntervals.size();index++) {
                NumberInterval oldInterval=oldIntervals.get(index);
                NumberInterval intersection=oldInterval.intersectWith(interval);
                if (intersection!=null)
                    newIntervals.add(intersection);
            }
            if (newIntervals.isEmpty())
                return EMPTY_SUBSET;
            else
                return new OWLRealValueSpaceSubset(newIntervals);
        }
    }
    public ValueSpaceSubset conjoinWithDRNegation(ValueSpaceSubset valueSpaceSubset,DatatypeRestriction datatypeRestriction) {
        assert s_intervalsByDatatype.keySet().contains(datatypeRestriction.getDatatypeURI());
        NumberInterval interval=getIntervalFor(datatypeRestriction);
        if (interval==null)
            return valueSpaceSubset;
        else {
            NumberInterval complementInterval1=null;
            if (!interval.m_lowerBound.equals(MinusInfinity.INSTANCE))
                complementInterval1=new NumberInterval(NumberRange.REAL,NumberRange.NOTHING,MinusInfinity.INSTANCE,BoundType.EXCLUSIVE,interval.m_lowerBound,interval.m_lowerBoundType.getComplement());
            NumberInterval complementInterval2=null;
            if (!interval.m_baseRange.equals(NumberRange.REAL))
                complementInterval2=new NumberInterval(NumberRange.REAL,interval.m_baseRange,interval.m_lowerBound,interval.m_lowerBoundType,interval.m_upperBound,interval.m_upperBoundType);
            NumberInterval complementInterval3=null;
            if (!interval.m_upperBound.equals(PlusInfinity.INSTANCE))
                complementInterval3=new NumberInterval(NumberRange.REAL,NumberRange.NOTHING,interval.m_upperBound,interval.m_upperBoundType.getComplement(),PlusInfinity.INSTANCE,BoundType.EXCLUSIVE);
            OWLRealValueSpaceSubset realSubset=(OWLRealValueSpaceSubset)valueSpaceSubset;
            List<NumberInterval> oldIntervals=realSubset.m_intervals;
            List<NumberInterval> newIntervals=new ArrayList<NumberInterval>();
            for (int index=0;index<oldIntervals.size();index++) {
                NumberInterval oldInterval=oldIntervals.get(index);
                if (complementInterval1!=null) {
                    NumberInterval intersection=oldInterval.intersectWith(complementInterval1);
                    if (intersection!=null)
                        newIntervals.add(intersection);
                }
                if (complementInterval2!=null) {
                    NumberInterval intersection=oldInterval.intersectWith(complementInterval2);
                    if (intersection!=null)
                        newIntervals.add(intersection);
                }
                if (complementInterval3!=null) {
                    NumberInterval intersection=oldInterval.intersectWith(complementInterval3);
                    if (intersection!=null)
                        newIntervals.add(intersection);
                }
            }
            if (newIntervals.isEmpty())
                return EMPTY_SUBSET;
            else
                return new OWLRealValueSpaceSubset(newIntervals);
        }
    }
    protected NumberInterval getIntervalFor(DatatypeRestriction datatypeRestriction) {
        NumberInterval baseInterval=s_intervalsByDatatype.get(datatypeRestriction.getDatatypeURI());
        if (datatypeRestriction.getNumberOfFacetRestrictions()==0)
            return baseInterval;
        NumberRange baseRange=baseInterval.m_baseRange;
        NumberRange excludedRange=baseInterval.m_excludedRange;
        Number lowerBound=baseInterval.m_lowerBound;
        BoundType lowerBoundType=baseInterval.m_lowerBoundType;
        Number upperBound=baseInterval.m_upperBound;
        BoundType upperBoundType=baseInterval.m_upperBoundType;
        for (int index=datatypeRestriction.getNumberOfFacetRestrictions()-1;index>=0;--index) {
            String facetURI=datatypeRestriction.getFacetURI(index);
            Number facetDataValue=(Number)datatypeRestriction.getFacetValue(index).getDataValue();
            if ((XSD_NS+"minInclusive").equals(facetURI)) {
                int comparison=Numbers.compare(facetDataValue,lowerBound);
                if (comparison>0) {
                    lowerBound=facetDataValue;
                    lowerBoundType=BoundType.INCLUSIVE;
                }
                // If the numbers are equal, nothing needs to be done to the bound type because
                // the existing one is at least as restrictive as INCLUSIVE.
            }
            else if ((XSD_NS+"minExclusive").equals(facetURI)) {
                int comparison=Numbers.compare(facetDataValue,lowerBound);
                if (comparison>0) {
                    lowerBound=facetDataValue;
                    lowerBoundType=BoundType.EXCLUSIVE;
                }
                else if (comparison==0) {
                    // EXCLUSIVE is guaranteed to be the more restrictive bound.
                    lowerBoundType=BoundType.EXCLUSIVE;
                }
            }
            else if ((XSD_NS+"maxInclusive").equals(facetURI)) {
                int comparison=Numbers.compare(facetDataValue,upperBound);
                if (comparison<0) {
                    upperBound=facetDataValue;
                    upperBoundType=BoundType.INCLUSIVE;
                }
                // If the numbers are equal, nothing needs to be done to the bound type because
                // the existing one is at least as restrictive as INCLUSIVE.
            }
            else if ((XSD_NS+"maxExclusive").equals(facetURI)) {
                int comparison=Numbers.compare(facetDataValue,upperBound);
                if (comparison<0) {
                    upperBound=facetDataValue;
                    upperBoundType=BoundType.EXCLUSIVE;
                }
                else if (comparison==0) {
                    // EXCLUSIVE is guaranteed to be the more restrictive bound.
                    upperBoundType=BoundType.EXCLUSIVE;
                }
            }
            else
                throw new IllegalStateException("Internal error: facet '"+facetURI+"' is not supported by owl:real.");
        }
        if (NumberInterval.isIntervalEmpty(baseRange,excludedRange,lowerBound,lowerBoundType,upperBound,upperBoundType))
            return null;
        else
            return new NumberInterval(baseRange,excludedRange,lowerBound,lowerBoundType,upperBound,upperBoundType);
    }
    public boolean isSubsetOf(String subsetDatatypeURI,String supersetDatatypeURI) {
        assert s_intervalsByDatatype.keySet().contains(subsetDatatypeURI);
        assert s_intervalsByDatatype.keySet().contains(supersetDatatypeURI);
        return s_datatypeSupersets.get(subsetDatatypeURI).contains(supersetDatatypeURI);
    }
    public boolean isDisjointWith(String datatypeURI1,String datatypeURI2) {
        assert s_intervalsByDatatype.keySet().contains(datatypeURI1);
        assert s_intervalsByDatatype.keySet().contains(datatypeURI2);
        return s_datatypeDisjoints.get(datatypeURI1).contains(datatypeURI2);
    }
}
TOP

Related Classes of org.semanticweb.HermiT.datatypes.owlreal.OWLRealDatatypeHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.