Package org.mindswap.pellet

Source Code of org.mindswap.pellet.RBox$ValueIterator

// Portions Copyright (c) 2006 - 2008, Clark & Parsia, LLC. <http://www.clarkparsia.com>
// Clark & Parsia, LLC parts of this source code are available under the terms of the Affero General Public License v3.
//
// Please see LICENSE.txt for full license terms, including the availability of proprietary exceptions.
// Questions, comments, or requests for clarification: licensing@clarkparsia.com
//
// ---
// Portions Copyright (c) 2003 Ron Alford, Mike Grove, Bijan Parsia, Evren Sirin
// Alford, Grove, Parsia, Sirin parts of this source code are available under the terms of the MIT License.
//
// The MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

package org.mindswap.pellet;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.mindswap.pellet.exceptions.UnsupportedFeatureException;
import org.mindswap.pellet.taxonomy.Taxonomy;
import org.mindswap.pellet.utils.ATermUtils;
import org.mindswap.pellet.utils.iterator.FilterIterator;
import org.mindswap.pellet.utils.iterator.IteratorUtils;
import org.mindswap.pellet.utils.iterator.MapIterator;

import aterm.ATerm;
import aterm.ATermAppl;
import aterm.ATermList;

/**
* <p>
* Title:
* </p>
*
* <p>
* Description:
* </p>
*
* <p>
* Copyright: Copyright (c) 2007
* </p>
*
* <p>
* Company: Clark & Parsia, LLC. <http://www.clarkparsia.com>
* </p>
*
* @author Evren Sirin
*/
public class RBox {
  public static Logger log = Logger.getLogger(RBox.class.getName());
 
  private static class ValueIterator extends MapIterator<Map.Entry<ATermAppl, Set<Set<ATermAppl>>>, ATermAppl> {
        public ValueIterator(Iterator<Entry<ATermAppl, Set<Set<ATermAppl>>>> iterator) {
          super(iterator);
        }

    @Override
        public ATermAppl map(Entry<ATermAppl, Set<Set<ATermAppl>>> e) {
          return e.getKey();
        }
   
  }
 
  private static class DomainRangeIterator extends FilterIterator<Map.Entry<ATermAppl, Set<Set<ATermAppl>>>> {
    final ATermAppl p;
    final boolean isDomain;
   
        public DomainRangeIterator(Map<ATermAppl, Set<Set<ATermAppl>>> map, Role role, boolean isDomain) {
          super(map.entrySet().iterator());
          this.p = role.getName();
          this.isDomain = isDomain;
        }

    @Override
        public boolean filter(Map.Entry<ATermAppl, Set<Set<ATermAppl>>> entry) {
      final Set<Set<ATermAppl>> allExplanations = entry.getValue();

      final Set<ATermAppl> explanation = Collections.singleton(isDomain ? ATermUtils
                      .makeDomain(p, entry.getKey()) : ATermUtils.makeRange(p, entry.getKey()));
      return !allExplanations.contains(explanation);
        }
  }

  private final Map<ATermAppl, Role> roles = new HashMap<ATermAppl, Role>();
  private final Set<Role> reflexiveRoles = new HashSet<Role>();
 
  private final Map<Role,Map<ATermAppl,Set<Set<ATermAppl>>>> domainAssertions;
  private final Map<Role,Map<ATermAppl,Set<Set<ATermAppl>>>> rangeAssertions;
 
  private Taxonomy<ATermAppl> objectTaxonomy;
  private Taxonomy<ATermAppl> dataTaxonomy;
  private Taxonomy<ATermAppl> annotationTaxonomy;

  private final FSMBuilder fsmBuilder;

  public RBox() {
    domainAssertions = new HashMap<Role, Map<ATermAppl,Set<Set<ATermAppl>>>>();
    rangeAssertions = new HashMap<Role, Map<ATermAppl,Set<Set<ATermAppl>>>>();

    fsmBuilder = new FSMBuilder(this);

    addDatatypeRole(ATermUtils.TOP_DATA_PROPERTY);
    addDatatypeRole(ATermUtils.BOTTOM_DATA_PROPERTY);
    Role topObjProp = addObjectRole(ATermUtils.TOP_OBJECT_PROPERTY);
    Role bottomObjProp = addObjectRole(ATermUtils.BOTTOM_OBJECT_PROPERTY);

    topObjProp.setTransitive(true, DependencySet.INDEPENDENT);
    topObjProp.setReflexive(true, DependencySet.INDEPENDENT);

    bottomObjProp.setIrreflexive(true, DependencySet.INDEPENDENT);
    bottomObjProp.setAsymmetric(true, DependencySet.INDEPENDENT);

    addEquivalentRole(topObjProp.getName(), topObjProp.getInverse().getName(), DependencySet.INDEPENDENT);
    addEquivalentRole(bottomObjProp.getName(), bottomObjProp.getInverse().getName(), DependencySet.INDEPENDENT);

  }

  /**
   * Return the role with the given name
   *
   * @param r
   *            Name (URI) of the role
   * @return
   */
  public Role getRole(ATerm r) {
    return roles.get(r);
  }

  /**
   * Return the role with the given name and throw and exception if it is not found.
   *
   * @param r
   *            Name (URI) of the role
   * @return
   */
  public Role getDefinedRole(ATerm r) {
    Role role = roles.get(r);

    if (role == null) {
      throw new RuntimeException(r + " is not defined as a property");
    }

    return role;
  }

  public Role addRole(ATermAppl r) {
    Role role = getRole(r);

    if (role == null) {
      role = new Role(r, PropertyType.UNTYPED);
      roles.put(r, role);
    }

    return role;
  }

  /**
   * Add a non-asserted property range axiom
   *
   * @param p
   *            The property
   * @param a
   *            A class expression for the domain
   * @param explanation
   *            A set of {@link ATermAppl}s that explain the range axiom.
   * @return <code>true</code> if range add was successful, <code>false</code> else
   * @throws IllegalArgumentException
   *             if <code>p</code> is not a defined property.
   */
  public boolean addRange(ATerm p, ATermAppl range, Set<ATermAppl> explanation) {
    final Role r = getRole(p);
    if (r == null) {
      throw new IllegalArgumentException(p + " is not defined as a property");
    }
   
    Map<ATermAppl,Set<Set<ATermAppl>>> ranges = rangeAssertions.get(r);
    if( ranges == null) {
      ranges = new HashMap<ATermAppl, Set<Set<ATermAppl>>>();
      rangeAssertions.put(r, ranges);
    }
   
    Set<Set<ATermAppl>> allExplanations = ranges.get(range);   
    if (allExplanations == null ) {
      allExplanations = new HashSet<Set<ATermAppl>>();
      ranges.put(range, allExplanations);
    }
   
    return allExplanations.add(explanation);
  }

  /**
   * Add an asserted property range axiom
   *
   * @param p
   *            The property
   * @param a
   *            A class expression for the range
   * @return <code>true</code> if range add was successful, <code>false</code> else
   * @throws IllegalArgumentException
   *             if <code>p</code> is not a defined property.
   */
  public boolean addRange(ATerm p, ATermAppl range) {
    final Set<ATermAppl> ds = Collections.singleton(ATermUtils.makeRange(p, range));

    return addRange(p, range, ds);
  }

  public Role addObjectRole(ATermAppl r) {
    Role role = getRole(r);
    PropertyType roleType = (role == null) ? PropertyType.UNTYPED : role.getType();

    switch (roleType) {
      case DATATYPE:
        role = null;
        break;
      case OBJECT:
        break;
      default:
        if (role == null) {
          role = new Role(r, PropertyType.OBJECT);
          roles.put(r, role);
        }
        else {
          role.setType(PropertyType.OBJECT);
        }

        ATermAppl invR = ATermUtils.makeInv(r);
        Role invRole = new Role(invR, PropertyType.OBJECT);
        roles.put(invR, invRole);

        role.setInverse(invRole);
        invRole.setInverse(role);

        addSubRole(ATermUtils.BOTTOM_OBJECT_PROPERTY, role.getName(), DependencySet.INDEPENDENT);
        addSubRole(role.getName(), ATermUtils.TOP_OBJECT_PROPERTY, DependencySet.INDEPENDENT);
        addSubRole(ATermUtils.BOTTOM_OBJECT_PROPERTY, role.getName(), DependencySet.INDEPENDENT);
        addSubRole(role.getName(), ATermUtils.TOP_OBJECT_PROPERTY, DependencySet.INDEPENDENT);

        break;
    }

    return role;
  }

  public Role addDatatypeRole(ATermAppl r) {
    Role role = getRole(r);

    if (role == null) {
      role = new Role(r, PropertyType.DATATYPE);
      roles.put(r, role);

      addSubRole(ATermUtils.BOTTOM_DATA_PROPERTY, role.getName(), DependencySet.INDEPENDENT);
      addSubRole(role.getName(), ATermUtils.TOP_DATA_PROPERTY, DependencySet.INDEPENDENT);
    }
    else {
      switch (role.getType()) {
        case DATATYPE:
          break;
        case OBJECT:
          role = null;
          break;
        default:
          role.setType(PropertyType.DATATYPE);
          addSubRole(ATermUtils.BOTTOM_DATA_PROPERTY, role.getName(), DependencySet.INDEPENDENT);
          addSubRole(role.getName(), ATermUtils.TOP_DATA_PROPERTY, DependencySet.INDEPENDENT);
          break;
      }
    }

    return role;
  }

  public Role addAnnotationRole(ATermAppl r) {
    Role role = getRole(r);

    if (role == null) {
      role = new Role(r, PropertyType.ANNOTATION);
      roles.put(r, role);
    }
    else {
      switch (role.getType()) {
        case ANNOTATION:
          break;
        case OBJECT:
          role = null;
          break;
        default:
          role.setType(PropertyType.ANNOTATION);
          break;
      }
    }

    return role;
  }

  @Deprecated
  public Role addOntologyRole(ATermAppl r) {
    return addAnnotationRole(r);
  }

  public boolean addSubRole(ATerm sub, ATerm sup) {
    DependencySet ds = PelletOptions.USE_TRACING ? new DependencySet(ATermUtils.makeSubProp(sub, sup))
                    : DependencySet.INDEPENDENT;
    return addSubRole(sub, sup, ds);
  }

  public boolean addSubRole(ATerm sub, ATerm sup, DependencySet ds) {
    Role roleSup = getRole(sup);
    Role roleSub = getRole(sub);

    if (roleSup == null) {
      return false;
    }
    else if (sub.getType() == ATerm.LIST) {
      roleSup.addSubRoleChain((ATermList) sub, ds);
    }
    else if (roleSub == null) {
      return false;
    }
    else {
      roleSup.addSubRole(roleSub, ds);
      roleSub.addSuperRole(roleSup, ds);
    }

    // TODO Need to figure out what to do about about role lists
    // explanationTable.add(ATermUtils.makeSub(sub, sup), ds);
    return true;
  }

  public boolean addEquivalentRole(ATerm s, ATerm r) {
    DependencySet ds = PelletOptions.USE_TRACING ? new DependencySet(ATermUtils.makeEqProp(s, r))
                    : DependencySet.INDEPENDENT;
    return addEquivalentRole(r, s, ds);
  }

  public boolean addEquivalentRole(ATerm s, ATerm r, DependencySet ds) {
    Role roleS = getRole(s);
    Role roleR = getRole(r);

    if (roleS == null || roleR == null) {
      return false;
    }

    roleR.addSubRole(roleS, ds);
    roleR.addSuperRole(roleS, ds);
    roleS.addSubRole(roleR, ds);
    roleS.addSuperRole(roleR, ds);

    if (roleR.getInverse() != null) {
      roleR.getInverse().addSubRole(roleS.getInverse(), ds);
      roleR.getInverse().addSuperRole(roleS.getInverse(), ds);
      roleS.getInverse().addSubRole(roleR.getInverse(), ds);
      roleS.getInverse().addSuperRole(roleR.getInverse(), ds);
    }

    return true;
  }

  public boolean addDisjointRole(ATerm s, ATerm r, DependencySet ds) {
    Role roleS = getRole(s);
    Role roleR = getRole(r);

    if (roleS == null || roleR == null) {
      return false;
    }

    roleR.addDisjointRole(roleS, ds);
    roleS.addDisjointRole(roleR, ds);

    return true;
  }

  /**
   * Add a non-asserted property domain axiom
   *
   * @param p
   *            The property
   * @param a
   *            A class expression for the domain
   * @param explain
   *            A set of {@link ATermAppl}s that explain the domain axiom.
   * @return <code>true</code> if domain add was successful, <code>false</code> else
   * @throws IllegalArgumentException
   *             if <code>p</code> is not a defined property.
   */
  public boolean addDomain(ATerm p, ATermAppl domain, Set<ATermAppl> explanation) {
    final Role r = getRole(p);
    if (r == null) {
      throw new IllegalArgumentException(p + " is not defined as a property");
    }
   
    Map<ATermAppl,Set<Set<ATermAppl>>> domains = domainAssertions.get(r);
    if( domains == null) {
      domains = new HashMap<ATermAppl, Set<Set<ATermAppl>>>();
      domainAssertions.put(r, domains);
    }
   
    Set<Set<ATermAppl>> allExplanations = domains.get(domain);   
    if (allExplanations == null ) {
      allExplanations = new HashSet<Set<ATermAppl>>();
      domains.put(domain, allExplanations);
    }
   
    return allExplanations.add(explanation)
  }

  /**
   * Add an asserted property domain axiom
   *
   * @param p
   *            The property
   * @param a
   *            A class expression for the domain
   * @return <code>true</code> if domain add was successful, <code>false</code> else
   * @throws IllegalArgumentException
   *             if <code>p</code> is not a defined property.
   */
  public boolean addDomain(ATerm p, ATermAppl a) {
    final Set<ATermAppl> explain = Collections.singleton(ATermUtils.makeDomain(p, a));

    return addDomain(p, a, explain);
  }

  public boolean addInverseRole(ATerm s, ATerm r, DependencySet ds) {
    Role roleS = getRole(s);
    Role roleR = getRole(r);

    if (roleS == null || roleR == null || !roleS.isObjectRole() || !roleR.isObjectRole()) {
      return false;
    }
    else {
      addEquivalentRole(roleS.getInverse().getName(), r, ds);
    }

    return true;
  }
 
  public Iterator<ATermAppl> getAssertedDomains(Role r) {
    final Map<ATermAppl, Set<Set<ATermAppl>>> domains = domainAssertions.get(r);
    return domains == null ? IteratorUtils.<ATermAppl> emptyIterator() : new ValueIterator(new DomainRangeIterator(
                    domains, r, true));
  }
 
  public Iterator<ATermAppl> getAssertedRanges(Role r) {
    final Map<ATermAppl, Set<Set<ATermAppl>>> ranges = rangeAssertions.get(r);
    return ranges == null ? IteratorUtils.<ATermAppl> emptyIterator() : new ValueIterator(new DomainRangeIterator(
                    ranges, r, false));
  }

  @Deprecated
  public boolean isDomainAsserted(ATerm p, ATermAppl domain) {
    final Role r = getRole(p);
    if (r == null) {
      throw new IllegalArgumentException(p + " is not defined as a property");
    }
     
    final Map<ATermAppl,Set<Set<ATermAppl>>> domains = domainAssertions.get(r);
    if( domains == null) {
      return false;
    }
   
    final Set<Set<ATermAppl>> allExplanations = domains.get(domain);   
    if (allExplanations == null ) {
      return false;
    }
   
    final Set<ATermAppl> explanation = Collections.singleton(ATermUtils.makeDomain(p, domain));
   
    return allExplanations.contains(explanation);
  }

  @Deprecated
  public boolean isRangeAsserted(ATerm p, ATermAppl range) {
    final Role r = getRole(p);
    if (r == null) {
      throw new IllegalArgumentException(p + " is not defined as a property");
    }
     
    final Map<ATermAppl,Set<Set<ATermAppl>>> ranges = rangeAssertions.get(r);
    if( ranges == null) {
      return false;
    }
   
    final Set<Set<ATermAppl>> allExplanations = ranges.get(range);   
    if (allExplanations == null ) {
      return false;
    }
   
    final Set<ATermAppl> explanation = Collections.singleton(ATermUtils.makeRange(p, range));
   
    return allExplanations.contains(explanation);
  }

  /**
   * check if the term is declared as a role
   */
  public boolean isRole(ATerm r) {
    return roles.containsKey(r);
  }

  public void prepare() {

    // first pass - compute sub roles
    Set<Role> complexRoles = new HashSet<Role>();
    for (Role role : roles.values()) {
      Map<ATerm, DependencySet> subExplain = new HashMap<ATerm, DependencySet>();
      Set<Role> subRoles = new HashSet<Role>();
      Set<ATermList> subRoleChains = new HashSet<ATermList>();

      computeSubRoles(role, subRoles, subRoleChains, subExplain, DependencySet.INDEPENDENT);

      role.setSubRolesAndChains(subRoles, subRoleChains, subExplain);

      for (Role s : subRoles) {
        DependencySet explainSub = role.getExplainSub(s.getName());
        s.addSuperRole(role, explainSub);
      }

      for (ATermList chain : subRoleChains) {
        if (chain.getLength() != 2
            || !chain.getFirst().equals(chain.getLast())
            || !subRoles.contains(getRole(chain.getFirst()))) {
          role.setHasComplexSubRole(true);
          complexRoles.add(role);
          break;
        }
      }
    }

    // iterate over complex roles to build DFAs - needs to be done after
    // all subRoles are propagated above
    for (Role s : complexRoles) {
      fsmBuilder.build(s);
    }

    // second pass - set super roles and propagate disjoint roles through inverses
    for (Role role : roles.values()) {
      Role invR = role.getInverse();
      if (invR != null) {
        if (invR.isTransitive() && !role.isTransitive()) {
          role.setTransitive(true, invR.getExplainTransitive());
        }
        else if (role.isTransitive() && !invR.isTransitive()) {
          invR.setTransitive(true, role.getExplainTransitive());
        }
        if (invR.isFunctional() && !role.isInverseFunctional()) {
          role.setInverseFunctional(true, invR.getExplainFunctional());
        }
        if (role.isFunctional() && !invR.isInverseFunctional()) {
          invR.setInverseFunctional(true, role.getExplainFunctional());
        }
        if (invR.isInverseFunctional() && !role.isFunctional()) {
          role.setFunctional(true, invR.getExplainInverseFunctional());
        }
        if (invR.isAsymmetric() && !role.isAsymmetric()) {
          role.setAsymmetric(true, invR.getExplainAsymmetric());
        }
        if (role.isAsymmetric() && !invR.isAsymmetric()) {
          invR.setAsymmetric(true, role.getExplainAsymmetric());
        }
        if (invR.isReflexive() && !role.isReflexive()) {
          role.setReflexive(true, invR.getExplainReflexive());
        }
        if (role.isReflexive() && !invR.isReflexive()) {
          invR.setReflexive(true, role.getExplainReflexive());
        }

        for (Role disjointR : role.getDisjointRoles()) {
          invR.addDisjointRole(disjointR.getInverse(), role.getExplainDisjointRole(disjointR));
        }
      }

      for (Role s : role.getSubRoles()) {
        if (role.isForceSimple()) {
          s.setForceSimple(true);
        }
        if (!s.isSimple()) {
          role.setSimple(false);
        }
      }
    }

    // third pass - set transitivity and functionality and propagate disjoint roles through subs
    for (Role r : roles.values()) {
      if (r.isForceSimple()) {
        if (!r.isSimple()) {
          ignoreTransitivity(r);
        }
      }
      else {
        boolean isTransitive = r.isTransitive();
        DependencySet transitiveDS = r.getExplainTransitive();
        for (Role s : r.getSubRoles()) {
          if (s.isTransitive()) {
            if (r.isSubRoleOf(s) && (r != s)) {
              isTransitive = true;
              transitiveDS = r.getExplainSub(s.getName()).union(s.getExplainTransitive(), true);
            }
            r.addTransitiveSubRole(s);
          }
        }
        if (isTransitive != r.isTransitive()) {
          r.setTransitive(isTransitive, transitiveDS);
        }
      }

      if (r.isFunctional()) {
        r.addFunctionalSuper(r);
      }

      for (Role s : r.getSuperRoles()) {
        if (s.equals(r)) {
          continue;
        }

        DependencySet supDS = PelletOptions.USE_TRACING ? r.getExplainSuper(s.getName())
                        : DependencySet.INDEPENDENT;

        if (s.isFunctional()) {
          DependencySet ds = PelletOptions.USE_TRACING ? supDS.union(s.getExplainFunctional(), true)
                          : DependencySet.INDEPENDENT;
          r.setFunctional(true, ds);
          r.addFunctionalSuper(s);
        }
        if (s.isIrreflexive() && !r.isIrreflexive()) {
          DependencySet ds = PelletOptions.USE_TRACING ? supDS.union(s.getExplainIrreflexive(), true)
                          : DependencySet.INDEPENDENT;
          r.setIrreflexive(true, ds);
        }
        if (s.isAsymmetric() && !r.isAsymmetric()) {
          DependencySet ds = PelletOptions.USE_TRACING ? supDS.union(s.getExplainAsymmetric(), true)
                          : DependencySet.INDEPENDENT;
          r.setAsymmetric(true, ds);
        }

        // create a duplicate array to avoid ConcurrentModificationException
        for (Role disjointR : s.getDisjointRoles().toArray(new Role[0])) {
          DependencySet ds = PelletOptions.USE_TRACING ? supDS.union(s.getExplainDisjointRole(disjointR),
                          true) : DependencySet.INDEPENDENT;
          r.addDisjointRole(disjointR, ds);
          disjointR.addDisjointRole(r, ds);
        }
      }

      if (r.isReflexive() && !r.isAnon()) {
        reflexiveRoles.add(r);
      }

      if (log.isLoggable(Level.FINE)) {
        log.fine(r.debugString());
      }
    }

    // we will compute the taxonomy when we need it
    objectTaxonomy = null;
    dataTaxonomy = null;
    annotationTaxonomy = null;
  }

  public void propagateDomainRange() {
    for (Role role : roles.values()) {
      role.resetDomainRange();
    }
   
    for (Role role : roles.values()) {     
      Role invRole = role.getInverse();
      if (invRole != null) {
        Map<ATermAppl,Set<Set<ATermAppl>>> invDomains = domainAssertions.get(invRole);
        Map<ATermAppl,Set<Set<ATermAppl>>> invRanges = rangeAssertions.get(invRole);
       
        propogateDomain(role, invRanges)
        propogateRange(role, invDomains);
      }
     
      Map<ATermAppl,Set<Set<ATermAppl>>> domains = domainAssertions.get(role);
      Map<ATermAppl,Set<Set<ATermAppl>>> ranges = rangeAssertions.get(role);
      propogateDomain(role, domains);
      propogateRange(role, ranges);   
    }
  }
 
  private void propogateDomain(Role role, Map<ATermAppl,Set<Set<ATermAppl>>> domains) {
    if (domains == null || domains.isEmpty())
      return;
    for (Map.Entry<ATermAppl,Set<Set<ATermAppl>>> e : domains.entrySet()) {
      Set<ATermAppl> explanation = e.getValue().iterator().next();
      ATermAppl domain = e.getKey();
      ATermAppl normalized = ATermUtils.normalize(domain);
     
      for (Role s : role.getSubRoles()) {
        DependencySet explainSub = role.getExplainSub(s.getName())
        DependencySet ds = explainSub.union(explanation, true);       
       
        s.addDomain(normalized, ds);
      }
        }
  }
 
  private void propogateRange(Role role, Map<ATermAppl,Set<Set<ATermAppl>>> ranges) {
    if (ranges == null || ranges.isEmpty())
      return;
    for (Map.Entry<ATermAppl,Set<Set<ATermAppl>>> e : ranges.entrySet()) {
      Set<ATermAppl> explanation = e.getValue().iterator().next();
      ATermAppl range = e.getKey();
      ATermAppl normalized = ATermUtils.normalize(range);
     
      for (Role s : role.getSubRoles()) {
        DependencySet explainSub = role.getExplainSub(s.getName())
        DependencySet ds = explainSub.union(explanation, true);
       
        s.addRange(normalized, ds);
      }
        }
  }

  public boolean removeDomain(ATerm p, ATermAppl domain) {
    if (!PelletOptions.USE_TRACING) {
      return false;
    }

    final Role r = getRole(p);
    if (r == null) {
      return false;
    }

    final Map<ATermAppl,Set<Set<ATermAppl>>> domains = domainAssertions.get(r);
    if( domains == null) {
      return false;
    }
   
    final Set<Set<ATermAppl>> allExplanations = domains.get(domain);   
    if (allExplanations == null ) {
      return false;
    }
   
    final Set<ATermAppl> explanation = Collections.singleton(ATermUtils.makeDomain(p, domain));
   
    if (!allExplanations.remove(explanation)) {
      return false;
    }
   
    if (allExplanations.isEmpty()) {
      domains.remove(domain);
    }
   
    return true;
  }

  public boolean removeRange(ATerm p, ATermAppl range) {
    if (!PelletOptions.USE_TRACING) {
      return false;
    }

    final Role r = getRole(p);
    if (r == null) {
      return false;
    }

    final Map<ATermAppl,Set<Set<ATermAppl>>> ranges = rangeAssertions.get(r);
    if( ranges == null) {
      return false;
    }
   
    final Set<Set<ATermAppl>> allExplanations = ranges.get(range);   
    if (allExplanations == null ) {
      return false;
    }
   
    final Set<ATermAppl> explanation = Collections.singleton(ATermUtils.makeRange(p, range));
   
    if (!allExplanations.remove(explanation)) {
      return false;
    }
   
    if (allExplanations.isEmpty()) {
      ranges.remove(range);
    }
   
    return true;
  }

  void ignoreTransitivity(Role role) {
    Role namedRole = role.isAnon() ? role.getInverse() : role;

    String msg = "Unsupported axiom: Ignoring transitivity and/or complex subproperty axioms for " + namedRole;

    if (!PelletOptions.IGNORE_UNSUPPORTED_AXIOMS) {
      throw new UnsupportedFeatureException(msg);
    }

    log.warning(msg);

    role.removeSubRoleChains();
    role.setHasComplexSubRole(false);
    role.setSimple(true);
    role.setFSM(null);

    role.getInverse().removeSubRoleChains();
    role.getInverse().setHasComplexSubRole(false);
    role.getInverse().setSimple(true);
    role.getInverse().setFSM(null);
  }

  private void computeImmediateSubRoles(Role r, Map<ATerm, DependencySet> subs) {

    Role invR = r.getInverse();
    if (invR != null && invR != r) {

      for (Role invSubR : invR.getSubRoles()) {
        Role subR = invSubR.getInverse();
        if (subR == null) {
          if (log.isLoggable(Level.FINE)) {
                      log.fine("Property " + invSubR + " was supposed to be an ObjectProperty but it is not!");
                    }
        }
        else if (subR != r) {
          // System.out.println("expsub:
          // "+invR.getExplainSub(invSubR.getName()));
          // System.out.println("expinv:
          // "+invSubR.getExplainInverse());
          DependencySet subDS = invR.getExplainSub(invSubR.getName());
          subs.put(subR.getName(), subDS);
        }
      }
      for (ATermList roleChain : invR.getSubRoleChains()) {
        DependencySet subDS = invR.getExplainSub(roleChain);

        ATermList subChain = inverse(roleChain);
        subs.put(subChain, subDS);
      }
    }

    for (Role sub : r.getSubRoles()) {
      DependencySet subDS = r.getExplainSub(sub.getName());

      subs.put(sub.getName(), subDS);
    }

    for (ATermList subChain : r.getSubRoleChains()) {
      DependencySet subDS = r.getExplainSub(subChain);

      subs.put(subChain, subDS);
    }

  }

  private void computeSubRoles(Role r, Set<Role> subRoles, Set<ATermList> subRoleChains,
                  Map<ATerm, DependencySet> dependencies, DependencySet ds) {
    // check for loops
    if (subRoles.contains(r)) {
      return;
    }

    // reflexive
    subRoles.add(r);
    dependencies.put(r.getName(), ds);

    // transitive closure
    Map<ATerm, DependencySet> immSubs = new HashMap<ATerm, DependencySet>();
    computeImmediateSubRoles(r, immSubs);
    for (Entry<ATerm, DependencySet> entry : immSubs.entrySet()) {
      ATerm sub = entry.getKey();
      DependencySet subDS = PelletOptions.USE_TRACING ? ds.union(entry.getValue(), true)
                      : DependencySet.INDEPENDENT;
      if (sub instanceof ATermAppl) {
        Role subRole = getRole(sub);

        computeSubRoles(subRole, subRoles, subRoleChains, dependencies, subDS);
      }
      else {
        subRoleChains.add((ATermList) sub);
        dependencies.put(sub, subDS);
      }
    }
  }

  /**
   * Returns a string representation of the RBox where for each role subroles, superroles, and isTransitive
   * information is given
   */
  @Override
  public String toString() {
    return "[RBox " + roles.values() + "]";
  }

  /**
   * for each role in the list finds an inverse role and returns the new list.
   */
  public ATermList inverse(ATermList roles) {
    ATermList invList = ATermUtils.EMPTY_LIST;

    for (ATermList list = roles; !list.isEmpty(); list = list.getNext()) {
      ATermAppl r = (ATermAppl) list.getFirst();
      Role role = getRole(r);
      Role invR = role.getInverse();
      if (invR == null) {
        System.err.println("Property " + r + " was supposed to be an ObjectProperty but it is not!");
      }
      else {
        invList = invList.insert(invR.getName());
      }
    }

    return invList;
  }

  /**
   * @return Returns the roles.
   */
  public Set<ATermAppl> getRoleNames() {
    return roles.keySet();
  }

  public Set<Role> getReflexiveRoles() {
    return reflexiveRoles;
  }

  /**
   * getRoles
   *
   * @return
   */
  public Collection<Role> getRoles() {
    return roles.values();
  }

  public Taxonomy<ATermAppl> getObjectTaxonomy() {
    if (objectTaxonomy == null) {
      RoleTaxonomyBuilder builder = new RoleTaxonomyBuilder(this, PropertyType.OBJECT);
      objectTaxonomy = builder.classify();
    }
    return objectTaxonomy;
  }

  public Taxonomy<ATermAppl> getDataTaxonomy() {
    if (dataTaxonomy == null) {
      RoleTaxonomyBuilder builder = new RoleTaxonomyBuilder(this, PropertyType.DATATYPE);
      dataTaxonomy = builder.classify();
    }
    return dataTaxonomy;
  }

  public Taxonomy<ATermAppl> getAnnotationTaxonomy() {
    if (annotationTaxonomy == null) {
      RoleTaxonomyBuilder builder = new RoleTaxonomyBuilder(this, PropertyType.ANNOTATION);
      if (PelletOptions.USE_ANNOTATION_SUPPORT) {
        annotationTaxonomy = builder.classify();
      }
    }
    return annotationTaxonomy;
  }
 
  public boolean isObjectTaxonomyPrepared() {
    return objectTaxonomy != null;
  }

  public boolean isDataTaxonomyPrepared() {
    return dataTaxonomy != null;
  }

  public boolean isAnnotationTaxonomyPrepared() {
    return annotationTaxonomy != null;
  }
}
TOP

Related Classes of org.mindswap.pellet.RBox$ValueIterator

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.