/*
(c) Copyright 2009 Hewlett-Packard Development Company, LP
All rights reserved.
*/
package com.hp.jena.ymris.deploy.reasoner;
import java.util.*;
import com.hp.hpl.jena.graph.*;
import com.hp.hpl.jena.graph.compose.Union;
import com.hp.hpl.jena.graph.impl.*;
import com.hp.hpl.jena.graph.query.*;
import com.hp.hpl.jena.reasoner.*;
import com.hp.hpl.jena.shared.*;
import com.hp.hpl.jena.util.iterator.*;
import com.hp.jena.ymris.deploy.local.BindingSink;
import com.hp.jena.ymris.yast.RuleSet;
public class DirectInferenceGraph implements InfGraph
{
protected final DirectReasoner reasoner;
protected final Graph base;
protected final Graph deductions;
protected final PrefixMapping prefixMapping = PrefixMapping.Factory.create();
protected final Reifier reifier;
protected DirectInferenceGraph.Prepared prepared = Prepared.Unprepared;
protected static enum Prepared { Unprepared, Preparing, Prepared }
protected boolean isClosed = false;
protected void needsPrepare()
{ prepared = Prepared.Unprepared; }
public DirectInferenceGraph( DirectReasoner reasoner, Graph base )
{
this.reasoner = reasoner;
this.base = base;
this.deductions = Factory.createDefaultGraph();
this.reifier = new DirectInferenceReifier();
}
class DirectInferenceReifier implements Reifier
{
@Override public ExtendedIterator<Node> allNodes()
{ return NullIterator.instance(); }
@Override public ExtendedIterator<Node> allNodes( Triple t )
{ return NullIterator.instance(); }
@Override public void close()
{}
@Override public ExtendedIterator<Triple> find( TripleMatch m )
{ return NullIterator.instance(); }
@Override public ExtendedIterator<Triple> findEither( TripleMatch m, boolean showHidden )
{ return NullIterator.instance(); }
@Override public ExtendedIterator<Triple> findExposed( TripleMatch m )
{ return NullIterator.instance(); }
@Override public Graph getParentGraph()
{ return DirectInferenceGraph.this; }
@Override public ReificationStyle getStyle()
{ throw new UnsupportedOperationException(); }
@Override public boolean handledAdd( Triple t )
{ return false; }
@Override public boolean handledRemove( Triple t )
{ return false; }
@Override public boolean hasTriple( Node n )
{ return false; }
@Override public boolean hasTriple( Triple t )
{ return false; }
@Override public Node reifyAs( Node n, Triple t )
{ throw new UnsupportedOperationException(); }
@Override public void remove( Triple t )
{}
@Override public void remove( Node n, Triple t )
{}
@Override public int size()
{ return 0; }
@Override public Triple getTriple( Node n )
{ return null; }
}
@Override public ExtendedIterator<Triple> find( Node S, Node P, Node O, Graph posit )
{ return reasoner.bind( new Union( this, posit ) ).find( S, P, O ); }
@Override public Graph getDeductionsGraph()
{ return deductions; }
@Override public Iterator<Derivation> getDerivation( Triple triple )
{ return null; }
@Override public Node getGlobalProperty( Node property )
{ throw new UnsupportedOperationException( "unimplemented" ); }
@Override public Graph getRawGraph()
{ return base; }
@Override public Reasoner getReasoner()
{ return reasoner; }
@Override public void prepare()
{
switch (prepared)
{
case Unprepared:
prepared = Prepared.Preparing;
rebind();
prepared = Prepared.Prepared;
break;
case Preparing:
// throw new UnsupportedOperationException( "OOPS: prepare() while preparing" );
case Prepared:
break;
}
}
@Override public void rebind()
{
RuleSet ruleSet = reasoner.ruleSet;
deductions.getBulkUpdateHandler().removeAll();
BindingSink output = new BindingSink()
{
@Override public void consume( Node[] item )
{ deductions.add( asTriple( item ) ); }
private Triple asTriple( Node[] item )
{ return Triple.create( item[1], item[2], item[3] ); }
};
BindingSink input = ruleSet.toCode( reasoner.getHowTo( this ), output );
input.start();
for (Iterator<Triple> it = base.find( Triple.ANY ); it.hasNext();)
input.consume( asBinding( it.next() ) );
}
private Node[] asBinding( Triple t )
{ return new Node[] {null, t.getSubject(), t.getPredicate(), t.getObject()}; }
@Override public void rebind( Graph data )
{ throw new UnsupportedOperationException( "we don't do that" ); }
@Override public void reset()
{}
@Override public void setDerivationLogging( boolean logOn )
{}
@Override public boolean testGlobalProperty( Node property )
{ return false; }
@Override public ValidityReport validate()
{ return null; }
@Override public void close()
{ isClosed = true; }
@Override public boolean isClosed()
{ return isClosed(); }
@Override public boolean contains( Triple t )
{
prepare();
return base.contains( t ) || deductions.contains( t );
}
@Override public boolean contains( Node s, Node p, Node o )
{
prepare();
return base.contains( s, p, o ) || deductions.contains( s, p, o );
}
@Override public void add( Triple t ) throws AddDeniedException
{
prepare();
base.add( t );
// throw new RuntimeException( "TBD" );
}
@Override public void delete( Triple t ) throws DeleteDeniedException
{
base.delete( t );
needsPrepare();
}
@Override public boolean dependsOn( Graph other )
{ return base.dependsOn( other ); }
@Override public ExtendedIterator<Triple> find( TripleMatch m )
{
prepare();
return base.find( m ).andThen( deductions.find( m ) ).filterDrop( hidden );
}
@Override public ExtendedIterator<Triple> find( Node s, Node p, Node o )
{
prepare();
return base.find( s, p, o ).andThen( deductions.find( s, p, o ) ).filterDrop( hidden );
}
protected final Filter<Triple> hidden = new Filter<Triple>()
{
@Override public boolean accept( Triple t )
{
return
hiddenNodes.contains( t.getSubject() )
|| hiddenNodes.contains( t.getPredicate() )
|| hiddenNodes.contains( t.getObject() )
;
}
};
protected final Set<Node> hiddenNodes = new HashSet<Node>();
@Override public BulkUpdateHandler getBulkUpdateHandler()
{
return new BulkUpdateHandler()
{
@Override public void add( Triple[] triples )
{ for (Triple t: triples) DirectInferenceGraph.this.add( t ); }
@Override public void add( List<Triple> triples )
{ for (Triple t: triples) DirectInferenceGraph.this.add( t ); }
@Override public void add( Iterator<Triple> it )
{ while (it.hasNext()) DirectInferenceGraph.this.add( it.next() ); }
@Override public void add( Graph g )
{ add( g.find( Triple.ANY ) ); }
@Override public void add( Graph g, boolean withReifications )
{ add( g ); }
@Override public void delete( Triple[] triples )
{
needsPrepare();
for (Triple t: triples) base.delete( t );
}
@Override public void delete( List<Triple> triples )
{
needsPrepare();
for (Triple t: triples) base.delete( t );
}
@Override public void delete( Iterator<Triple> it )
{
needsPrepare();
while (it.hasNext()) base.delete( it.next() );
}
@Override public void delete( Graph g )
{ delete( g.find( Triple.ANY ) ); }
@Override public void delete( Graph g, boolean withReifications )
{ delete( g ); }
@Override public void remove( Node s, Node p, Node o )
{
needsPrepare();
base.getBulkUpdateHandler().remove( s, p, o );
}
@Override public void removeAll()
{
needsPrepare();
base.getBulkUpdateHandler().removeAll();
}
};
}
@Override public Capabilities getCapabilities()
{ return new AllCapabilities(); }
@Override public GraphEventManager getEventManager()
{ return new SimpleEventManager( this ); }
@Override public PrefixMapping getPrefixMapping()
{ return prefixMapping; }
@Override public Reifier getReifier()
{ return reifier; }
@Override public GraphStatisticsHandler getStatisticsHandler()
{ return null; }
@Override public TransactionHandler getTransactionHandler()
{ return new SimpleTransactionHandler(); }
@Override public boolean isEmpty()
{
prepare();
return base.isEmpty() && deductions.isEmpty();
}
@Override public boolean isIsomorphicWith( Graph g )
{ return g != null && GraphMatcher.equals( this, g ); }
@Override public QueryHandler queryHandler()
{ return new SimpleQueryHandler( this ); }
@Override public int size()
{
prepare();
return base.size() + deductions.size();
}
public void hide( Node toHide )
{
if (toHide == null) throw new RuntimeException( "BOOM" );
hiddenNodes.add( toHide );
}
}
/*
(c) Copyright 2009 Hewlett-Packard Development Company, LP
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/