org.mindswap.pellet.tbox.impl.TgBox Maven / Gradle / Ivy
// Portions Copyright (c) 2006 - 2008, Clark & Parsia, LLC.
// 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: [email protected]
//
// ---
// 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.tbox.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.mindswap.pellet.DependencySet;
import org.mindswap.pellet.PelletOptions;
import org.mindswap.pellet.utils.ATermUtils;
import aterm.ATermAppl;
import aterm.ATermInt;
import aterm.ATermList;
public class TgBox extends TBoxBase {
public static final Logger log = Logger.getLogger(TgBox.class.getName() );
private Set explanation;
// universal concept
private List UC = null;
/*
* Constructors
*/
public TgBox(TBoxExpImpl tbox) {
super( tbox );
}
/*
* Utility Functions
*/
public void internalize() {
UC = new ArrayList();
for( TermDefinition termDef : termhash.values() ) {
for( ATermAppl subClassAxiom : termDef.getSubClassAxioms() ) {
ATermAppl c1 = (ATermAppl) subClassAxiom.getArgument( 0 );
ATermAppl c2 = (ATermAppl) subClassAxiom.getArgument( 1 );
ATermAppl notC1 = ATermUtils.makeNot( c1 );
ATermAppl notC1orC2 = ATermUtils.makeOr( notC1, c2 );
ATermAppl norm = ATermUtils.normalize( notC1orC2 );
Set explanation;
if( PelletOptions.USE_TRACING )
explanation = tbox.getAxiomExplanation( subClassAxiom );
else
explanation = Collections.emptySet();
UC.add( Unfolding.create( norm, explanation ) );
}
for( ATermAppl eqClassAxiom : termDef.getEqClassAxioms() ) {
ATermAppl c1 = (ATermAppl) eqClassAxiom.getArgument( 0 );
ATermAppl c2 = (ATermAppl) eqClassAxiom.getArgument( 1 );
ATermAppl notC1 = ATermUtils.makeNot( c1 );
ATermAppl notC2 = ATermUtils.makeNot( c2 );
ATermAppl notC1orC2 = ATermUtils.makeOr( notC1, c2 );
ATermAppl notC2orC1 = ATermUtils.makeOr( notC2, c1 );
Set explanation;
if( PelletOptions.USE_TRACING )
explanation = tbox.getAxiomExplanation( eqClassAxiom );
else
explanation = Collections.emptySet();
UC.add( Unfolding.create( ATermUtils.normalize( notC1orC2 ),
explanation ) );
UC.add( Unfolding.create( ATermUtils.normalize( notC2orC1 ),
explanation ) );
}
}
}
public void absorb() {
log.fine( "Absorption started" );
if( log.isLoggable( Level.FINE ) ) {
log.fine( "Tg.size was " + termhash.size() + " Tu.size was " + tbox.Tu.size() );
}
Collection terms = termhash.values();
termhash = new HashMap();
for( TermDefinition def : terms ) {
kb.timers.checkTimer( "preprocessing" );
for( ATermAppl subClassAxiom : def.getSubClassAxioms() ) {
ATermAppl c1 = (ATermAppl) subClassAxiom.getArgument( 0 );
ATermAppl c2 = (ATermAppl) subClassAxiom.getArgument( 1 );
absorbSubClass( c1, c2, tbox.getAxiomExplanation( subClassAxiom ) );
}
for( ATermAppl eqClassAxiom : def.getEqClassAxioms() ) {
ATermAppl c1 = (ATermAppl) eqClassAxiom.getArgument( 0 );
ATermAppl c2 = (ATermAppl) eqClassAxiom.getArgument( 1 );
absorbSubClass( c1, c2, tbox.getAxiomExplanation( eqClassAxiom ) );
absorbSubClass( c2, c1, tbox.getAxiomExplanation( eqClassAxiom ) );
}
}
if( log.isLoggable( Level.FINE ) ) {
log.fine( "Tg.size is " + termhash.size() + " Tu.size is " + tbox.Tu.size() );
}
log.fine( "Absorption finished" );
}
private void absorbSubClass(ATermAppl sub, ATermAppl sup, Set axiomExplanation) {
if( log.isLoggable( Level.FINE ) )
log.fine( "Absorb: subClassOf(" + ATermUtils.toString(sub) + ", " + ATermUtils.toString(sup) + ")");
HashSet set = new HashSet();
set.add( ATermUtils.nnf( sub ) );
set.add( ATermUtils.nnf( ATermUtils.makeNot( sup ) ) );
// ***********************************
// Explanation-related axiom tracking:
// This is used in absorbII() where actual absorption takes place
// with primitive definition
explanation = new HashSet();
explanation.addAll( axiomExplanation );
// ***********************************
absorbTerm( set );
}
private boolean absorbTerm(Set set) {
RuleAbsorber ruleAbsorber = new RuleAbsorber( tbox );
if( log.isLoggable( Level.FINER ) )
log.finer( "Absorbing term " + set );
while( true ) {
log.finer( "Absorb rule" );
if( PelletOptions.USE_RULE_ABSORPTION && ruleAbsorber.absorbRule( set, explanation ) ) {
return true;
}
log.finer( "Absorb nominal" );
if( !PelletOptions.USE_PSEUDO_NOMINALS
&& (PelletOptions.USE_NOMINAL_ABSORPTION || PelletOptions.USE_HASVALUE_ABSORPTION)
&& absorbNominal( set ) ) {
return true;
}
log.finer( "Absorb II" );
if( absorbII( set ) ) {
log.finer( "Absorbed" );
return true;
}
log.finer( "Absorb III" );
if( absorbIII( set ) ) {
log.finer( "Absorb III" );
continue;
}
// log.finer("Absorb IV");
// if (absorbIV(set)) {
// log.finer("Absorb IV");
// continue;
// }
log.finer( "Absorb V" );
if( absorbV( set ) ) {
log.finer( "Absorb V" );
continue;
}
log.finer( "Absorb VI" );
if( absorbVI( set ) ) {
log.finer( "Recursed on OR" );
return true;
}
log.finer( "Absorb role" );
if( PelletOptions.USE_ROLE_ABSORPTION && absorbRole( set ) ) {
log.finer( "Absorbed w/ Role" );
return true;
}
log.finer( "Absorb VII" );
absorbVII( set );
log.finer( "Finished absorbTerm" );
return false;
}
}
private boolean absorbNominal(Set set) {
for( Iterator i = set.iterator(); i.hasNext(); ) {
ATermAppl name = i.next();
if( PelletOptions.USE_NOMINAL_ABSORPTION
&& (ATermUtils.isOneOf( name ) || ATermUtils.isNominal( name )) ) {
i.remove();
ATermList list = null;
if( ATermUtils.isNominal( name ) )
list = ATermUtils.makeList( name );
else
list = (ATermList) name.getArgument( 0 );
ATermAppl c = ATermUtils.makeNot( ATermUtils.makeAnd( ATermUtils.makeList( set ) ) );
absorbOneOf( list, c, explanation );
return true;
}
else if( PelletOptions.USE_HASVALUE_ABSORPTION && ATermUtils.isHasValue( name ) ) {
ATermAppl p = (ATermAppl) name.getArgument( 0 );
if( !kb.isObjectProperty( p ) )
continue;
i.remove();
ATermAppl c = ATermUtils.makeNot( ATermUtils.makeAnd( ATermUtils.makeList( set ) ) );
ATermAppl nominal = (ATermAppl) name.getArgument( 1 );
ATermAppl ind = (ATermAppl) nominal.getArgument( 0 );
ATermAppl invP = kb.getProperty( p ).getInverse().getName();
ATermAppl allInvPC = ATermUtils.makeAllValues( invP, c );
if( log.isLoggable( Level.FINER ) )
log.finer( "Absorb into " + ind + " with inverse of " + p + " for " + c );
tbox.getAbsorbedAxioms().addAll( explanation );
kb.addIndividual( ind );
kb.addType( ind, allInvPC, new DependencySet( explanation ) );
return true;
}
}
return false;
}
void absorbOneOf(ATermAppl oneOf, ATermAppl c, Set explain) {
absorbOneOf( (ATermList) oneOf.getArgument( 0 ), c, explain );
}
private void absorbOneOf(ATermList list, ATermAppl c, Set explain) {
if( PelletOptions.USE_PSEUDO_NOMINALS ) {
if( log.isLoggable( Level.WARNING ) )
log.warning( "Ignoring axiom involving nominals: " + explain );
return;
}
if( log.isLoggable( Level.FINE ) )
log.fine( "Absorb nominals: " + ATermUtils.toString( c ) + " " + list );
tbox.getAbsorbedAxioms().addAll( explain );
DependencySet ds = new DependencySet( explain );
while( !list.isEmpty() ) {
ATermAppl nominal = (ATermAppl) list.getFirst();
ATermAppl ind = (ATermAppl) nominal.getArgument( 0 );
kb.addIndividual( ind );
kb.addType( ind, c, ds );
list = list.getNext();
}
}
private boolean absorbRole(Set set) {
for( Iterator i = set.iterator(); i.hasNext(); ) {
ATermAppl name = i.next();
if( ATermUtils.isSomeValues( name ) ) {
ATermAppl r = (ATermAppl) name.getArgument( 0 );
if( kb.getRole( r ).hasComplexSubRole() )
continue;
ATermAppl domain = ATermUtils.makeNot( ATermUtils.makeAnd( ATermUtils
.makeList( set ) ) );
kb.addDomain( r, domain, explanation );
if( log.isLoggable( Level.FINE ) )
log.fine( "Absorb domain: " + ATermUtils.toString( r ) + " " + ATermUtils.toString( domain ) );
tbox.getAbsorbedAxioms().addAll( explanation );
return true;
}
else if( ATermUtils.isMin( name ) ) {
ATermAppl r = (ATermAppl) name.getArgument( 0 );
ATermAppl q = (ATermAppl) name.getArgument( 2 );
if( kb.getRole( r ).hasComplexSubRole() || !ATermUtils.isTop( q ) )
continue;
int n = ((ATermInt) name.getArgument( 1 )).getInt();
// if we have min(r,1) sub ... this is also equal to a domain
// restriction
if( n == 1 ) {
i.remove();
ATermAppl domain = ATermUtils.makeNot( ATermUtils.makeAnd( ATermUtils
.makeList( set ) ) );
kb.addDomain( r, domain, explanation );
if( log.isLoggable( Level.FINE ) )
log.fine( "Absorb domain: " + ATermUtils.toString( r ) + " " + ATermUtils.toString( domain ) );
tbox.getAbsorbedAxioms().addAll( explanation );
return true;
}
}
}
return false;
}
private boolean absorbII(Set set) {
for( ATermAppl term : set ) {
TermDefinition td = tbox.Tu.getTD( term );
boolean canAbsorb;
if( td != null )
canAbsorb = td.getEqClassAxioms().isEmpty();
else
canAbsorb = term.getArity() == 0 && set.size() > 1;
if( canAbsorb ) {
set.remove( term );
ATermList setlist = ATermUtils.makeList( set );
ATermAppl conjunct = ATermUtils.makeAnd( setlist );
conjunct = ATermUtils.makeNot( conjunct );
ATermAppl sub = ATermUtils.makeSub( term, ATermUtils.nnf( conjunct ) );
tbox.Tu.addDef( sub );
if( log.isLoggable( Level.FINE ) )
log.fine( "Absorb named: " + ATermUtils.toString( sub ) );
// System.out.println(System.currentTimeMillis() + " " + sub.toString() + " " + sub.getName() + " " + sub.getClass().getName());
// System.out.println(System.currentTimeMillis() + " " + explanation.toString() + " " + explanation.size() + " "
// + explanation.getClass().getName());
// log.severe(System.currentTimeMillis() + " " + sub.toString() + " " + sub.getName() + " " + sub.getClass().getName());
// log.severe(System.currentTimeMillis() + " " + explanation.toString() + " " + explanation.size() + " "
// + explanation.getClass().getName());
// System.err.println(System.currentTimeMillis() + " " + sub.toString() + " " + sub.getName() + " " + sub.getClass().getName());
// System.err.println(System.currentTimeMillis() + " " + explanation.toString() + " " + explanation.size() + " "
// + explanation.getClass().getName());*/
tbox.addAxiomExplanation( sub, explanation );
return true;
}
}
return false;
}
private boolean absorbIII(Set set) {
for( ATermAppl term : set ) {
ATermAppl negatedTerm = null;
TermDefinition td = tbox.Tu.getTD( term );
if( td == null && ATermUtils.isNegatedPrimitive( term ) ) {
negatedTerm = (ATermAppl) term.getArgument( 0 );
td = tbox.Tu.getTD( negatedTerm );
}
// EDIT Riccardo Zese: there are problems if the
// second condition is checked
if( td == null || ATermUtils.isTop( td.getName() ) )
continue;
List eqClassAxioms = td.getEqClassAxioms();
if( !eqClassAxioms.isEmpty() ) {
ATermAppl eqClassAxiom = eqClassAxioms.get( 0 );
ATermAppl eqClass = (ATermAppl) eqClassAxiom.getArgument( 1 );
set.remove( term );
if( negatedTerm == null )
set.add( eqClass );
else
set.add( ATermUtils.negate( eqClass ) );
// *******************************
// Explanation-related tracking of axioms
explanation.addAll( tbox.getAxiomExplanation( eqClassAxiom ) );
// *******************************
return true;
}
}
return false;
}
private boolean absorbV(Set set) {
for( ATermAppl term : set ) {
ATermAppl nnfterm = ATermUtils.nnf( term );
// System.out.println(term);
if( nnfterm.getAFun().equals( ATermUtils.ANDFUN ) ) {
set.remove( term );
ATermList andlist = (ATermList) nnfterm.getArgument( 0 );
while( !andlist.isEmpty() ) {
set.add( (ATermAppl) andlist.getFirst() );
andlist = andlist.getNext();
}
return true;
}
}
return false;
}
private boolean absorbVI(Set set) {
for( ATermAppl term : set ) {
ATermAppl nnfterm = ATermUtils.nnf( term );
if( nnfterm.getAFun().equals( ATermUtils.ORFUN ) ) {
set.remove( term );
for( ATermList orlist = (ATermList) nnfterm.getArgument( 0 ); !orlist.isEmpty(); orlist = orlist
.getNext() ) {
Set cloned = new HashSet( set );
cloned.add( (ATermAppl) orlist.getFirst() );
// System.out.println("Term: "+term);
// System.out.println("Recursing on "+cloned);
// System.out.println("--");
absorbTerm( cloned );
}
return true;
}
}
return false;
}
private boolean absorbVII(Set set) {
ATermList list = ATermUtils.makeList( set );
ATermAppl sub = ATermUtils.nnf( (ATermAppl) list.getFirst() );
list = list.getNext();
ATermAppl sup = list.isEmpty()
? ATermUtils.makeNot( sub )
: ATermUtils.makeNot( ATermUtils.makeAnd( list ) );
sup = ATermUtils.nnf( sup );
ATermAppl subClassAxiom = ATermUtils.makeSub( sub, sup );
if( log.isLoggable( Level.FINE ) )
log.fine( "GCI: " + subClassAxiom + "\nexplanation: " + explanation );
addDef( subClassAxiom );
tbox.addAxiomExplanation( subClassAxiom, explanation );
return true;
}
/**
* @return Returns the UC.
*/
public List getUC() {
return UC;
}
public int size() {
return UC == null
? 0
: UC.size();
}
public void print(Appendable out) {
try {
out.append( "Tg: [\n" );
if( UC != null ) {
for( Unfolding unf : UC ) {
out.append( ATermUtils.toString( unf.getResult() ) );
out.append( ", " );
}
out.append( "\n" );
}
out.append( "]" );
} catch( IOException e ) {
e.printStackTrace();
}
}
public void print() {
print( System.out );
}
public String toString() {
StringBuilder sb = new StringBuilder();
print( sb );
return sb.toString();
}
} © 2015 - 2025 Weber Informatics LLC | Privacy Policy