Package stanfordlogic.knowledge

Source Code of stanfordlogic.knowledge.BasicKB$FactsIterator

///////////////////////////////////////////////////////////////////////
//                        STANFORD LOGIC GROUP                       //
//                    General Game Playing Project                   //
//                                                                   //
// Sample Player Implementation                                      //
//                                                                   //
// (c) 2007. See LICENSE and CONTRIBUTORS.                           //
///////////////////////////////////////////////////////////////////////

/**
*
*/
package stanfordlogic.knowledge;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import stanfordlogic.gdl.SymbolTable;
import stanfordlogic.prover.GroundFact;
import stanfordlogic.prover.Substitution;
import stanfordlogic.prover.TermFunction;
import stanfordlogic.prover.VariableFact;


/**
* A basic knowledge base implementation. Uses a mapping of relation
* name to set of things true in that relation.
*
* <p>
* For example:
*
* <pre>
*   true
*    |- init(1,1,b) ; init(1,2;x) ; init(1,3,o) ; ...
*   succ
*    |- 1,2 ; 2,3 ; 3,4 ; ...
* </pre>
*
* @author Based on code by Team Camembert: David Haley, Pierre-Yves Laligand
*/
public class BasicKB extends KnowledgeBase
{
    private Map<Integer, Set<GroundFact>>         database_;
    private int                                   numFacts_;

    public BasicKB( )
    {
        database_ = new TreeMap<Integer, Set<GroundFact>>();
        numFacts_ = 0;
    }
   
    @Override
    public void clear()
    {
        numFacts_ = 0;
        database_.clear();
    }
   
    @Override
    public int getNumFacts()
    {
        return numFacts_;
    }
   
    @Override
    public boolean isTrue( GroundFact fact )
    {
        return getFacts( fact.getRelationName() ).contains(fact);
    }

    @Override
    public void setTrue( GroundFact fact )
    {
        Set<GroundFact> facts = getFacts( fact.getRelationName() );

        // increment numFacts if the element was actually added
        if ( facts.add( fact ) )
            numFacts_ ++;
    }
   
    @Override
    public void setFalse( GroundFact fact )
    {
        Set<GroundFact> facts = getFacts( fact.getRelationName() );
       
        // decrement numFacts if the element was actually removed
        if ( facts.remove( fact ) )
            numFacts_ --;
    }

    /**
     * Get the facts for a given token of a given arity.
     *
     * Note that a fact is really just a row in a table. For a relation of arity
     * 3 named 'cell', we could have as a fact (cell 1 2 x) which would mean
     * that the fact as represented here in the code would be [1,2,x].
     *
     * @param token
     *            The token whose facts to get.
     *
     * @return A list of facts for the token/arity.
     */
    private Set<GroundFact> getFacts( int token )
    {
        Set<GroundFact> facts;

        facts = database_.get( token );

        // Make sure that this entry in the database exists
        if ( facts == null )
        {
            facts = new TreeSet<GroundFact>();
            database_.put( token, facts );
        }

        return facts;
    }
   
    private class FactsIterator implements Iterator<GroundFact>
    {
        private Iterator<Integer> relationIterator_;

        private Iterator<GroundFact> currentIterator_ = null;

        private FactsIterator()
        {
            relationIterator_ = database_.keySet().iterator();
            advanceIterator();
        }
       
        private void advanceIterator()
        {
            if ( relationIterator_.hasNext() )
                currentIterator_ = database_.get(relationIterator_.next()).iterator();
            else
                currentIterator_ = null;
        }

        public boolean hasNext()
        {
            if ( currentIterator_ == null )
                return false;
            else
            {
                if ( currentIterator_.hasNext() )
                    return true;
                else
                {
                    advanceIterator();
                    return hasNext();
                }
            }
        }

        public GroundFact next()
        {
            // Get the current element
            return currentIterator_.next();
        }

        public void remove()
        {
            throw new UnsupportedOperationException("Can't remove from NaiveKB iteration");
        }
    }

    @Override
    public Iterator<GroundFact> getIterator()
    {
        return new FactsIterator();
    }

    @Override
    public void stateToGdl( PrintStream target, SymbolTable symtab )
    {
        // iterate over all facts, printing them out
        for ( Set<GroundFact> facts : database_.values() )
        {
            for ( GroundFact f : facts )
                f.printToStream( target, symtab );
        }
       
    }

    @Override
    public List<GroundFact> getFacts(boolean sorted)
    {
        List<GroundFact> c = new ArrayList<GroundFact>();
       
        // iterate through all facts, adding them to the collection
        for ( Set<GroundFact> facts : database_.values() )
        {
            for ( GroundFact f : facts )
                c.add( f );
        }
       
        if ( sorted )
            Collections.sort(c);
       
        return c;
    }
   
    @Override
    public List<Substitution> getUnifiable(VariableFact fact)
    {
        List<Substitution> result = new ArrayList<Substitution>();
       
        Set<GroundFact> facts = database_.get(fact.getRelationName());
        if( facts == null )
            return result;
       
        if(fact.getArity() > 0 && fact.getTerm(0) instanceof TermFunction)
        {
            for(GroundFact nFact : facts)
            {
                // THINK: do we really want to get getArity() > 0 here?
                // maybe the variable fact should bind to a 0-arity function.
                // THINK: write a junit test case for this.
               
                if(nFact.getArity() > 0 && nFact.getTerm(0) instanceof TermFunction)
                {
                    if(((TermFunction) nFact.getTerm(0)).functionName_ == ((TermFunction) fact.getTerm(0)).functionName_)
                    {
                        Substitution s = fact.unify(nFact);
                        if ( s != null )
                            result.add(s);
                    }
                }
            }
        }
        else
        {
            for(GroundFact nFact : facts)
            {
                Substitution s = fact.unify(nFact);
                if ( s != null )
                    result.add( s );
            }
        }
        return result;
    }
   
    @Override
    public boolean equals(Object other)
    {
        if(! (other instanceof BasicKB))
            return false;
        List<GroundFact> mine = getFacts();
        List<GroundFact> his = ((BasicKB) other).getFacts();
        if(mine.size() != his.size())
            return false;
        for(int i=0; i<mine.size(); i++ )
        {
            if(!mine.get(i).equals(his.get(i)))
                return false;
        }
        return true;
    }
}
TOP

Related Classes of stanfordlogic.knowledge.BasicKB$FactsIterator

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.