///////////////////////////////////////////////////////////////////////
// STANFORD LOGIC GROUP //
// General Game Playing Project //
// //
// Sample Player Implementation //
// //
// (c) 2007. See LICENSE and CONTRIBUTORS. //
///////////////////////////////////////////////////////////////////////
/**
*
*/
package stanfordlogic.prover;
import java.util.logging.Level;
import java.util.logging.Logger;
import stanfordlogic.game.GameManager;
import stanfordlogic.util.Util;
/**
* Functions for unifications.
*
* <b>WARNING</b>: the debugging is not thread-safe.
*
* @author Based on code by Team Camembert: David Haley, Pierre-Yves Laligand
*/
public class Unifier
{
private static int unificationLevel_ = 0;
private static final Logger logger_ = Logger.getLogger("stanfordlogic.prover.unify");
private static void enterUnificationLevel(Fact f1, Fact f2)
{
if (logger_.isLoggable(Level.FINER))
{
logger_.finer( Util.makeIndent( unificationLevel_ )
+ "Unifier: attempting to unify " + f1.toString(GameManager.getSymbolTable()) + " and " + f2.toString(GameManager.getSymbolTable()) );
unificationLevel_++;
}
}
private static void exitUnificationLevel(Substitution subs)
{
if (logger_.isLoggable(Level.FINER))
{
unificationLevel_--;
if ( unificationLevel_ < 0 )
throw new RuntimeException("Unification level < 0!!");
if ( subs == null )
logger_.finer( Util.makeIndent( unificationLevel_ )
+ "Unifier: failed to unify." );
else
logger_.finer( Util.makeIndent( unificationLevel_ )
+ "Unifier: mgu = " + subs );
}
}
public static Substitution mgu(Fact f1, Fact f2)
{
// Make sure this is even worth our time to check
if ( f1.relationName_ != f2.relationName_ )
return null;
if ( f1.getArity() != f2.getArity() )
return null;
enterUnificationLevel(f1, f2);
Substitution subs = new Substitution();
if ( mgu(f1, f2, subs) )
{
exitUnificationLevel(subs);
return subs;
}
else
{
exitUnificationLevel(null);
return null;
}
}
private static boolean mgu(Fact f1, Fact f2, Substitution subsSoFar)
{
// Make sure this is even worth our time to check
if ( f1.relationName_ != f2.relationName_ )
return false;
if ( f1.getArity() != f2.getArity() )
return false;
// Find the mgu for each column of the facts
for ( int i = 0; i < f1.getArity(); i++ )
{
// If there is no mgu, just die
if ( mgu( f1.getTerm(i), f2.getTerm(i), subsSoFar ) == false )
return false;
}
return true;
}
private static boolean mgu(Term t1, Term t2, Substitution subsSoFar)
{
return t1.mgu(t2, subsSoFar);
}
}