package org.mandarax.kernel;

import java.util.Collection;
import java.util.Map;

/*
 * Copyright (C) 1999-2004 <a href="mailto:mandarax@jbdietrich.com">Jens Dietrich</a>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
/**
 * Interface representing facts. Instances are usually created using
 * a factory. Note that we use facts also as prerequisites and conclusion(s)
 * in rules.
 * @see org.mandarax.kernel.Rule
 * @see org.mandarax.kernel.LogicFactory
 * @author <A HREF="mailto:mandarax@jbdietrich.com">Jens Dietrich</A>
 * @version 3.3.1 <9 August 2004>
 * @since 1.0
 */
public interface Fact extends Clause, TermContainer {

    /**
     * Apply a set of replacements to a fact. Returns a new fact!
     * @see org.mandarax.kernel.Replacement
     * @return the fact that is the result of the application of replacements
     * @param r the collection of replacements
     */
    public Fact applyToFact(java.util.Collection r);

    /**
     * Apply a single replacement to a fact. Return a new fact!
     * @return the fact that is the result of the application of the replacement
     * @param r the replacement applied
     */
    public Fact applyToFact(Replacement r);

    public Fact applyToFactMinimally(Collection r, Map complexReplacements);

    /**
     * Get a key for fast access. The key is usually the predicate, but subclasses
     * might want to use different keys. Note that keys are mainly used by inference engines and
     * knowledge bases to improve performance and inference engine and knowledge bases
     * must know about the semantics of keys to use them correctly!
     * @see org.mandarax.kernel.KnowledgeBase
     * @see org.mandarax.kernel.Clause#getKey
     * @return the key object
     */
    public Object getKey();

    /**
     * Get the predicate.
     * @return the predicate
     */
    public org.mandarax.kernel.Predicate getPredicate();

    /**
     * Resolve a fact: if supported, the predicate
     * should be performed using its semantic. E.g., for a fact
     * like <i>isFather(Max,Jens)</i> the function <i>isFather</i> is performed
     * for the objects (constant terms) <i>Max</i> and <i>Jens</i> and the result (e.g., <i>true</i>) is returned.
     * Note that not all predicates support this (since not all predicates
     * have a semantic), and the operation can also fail
     * in case one term is variable. In these cases we throw appropriate exceptions.
     * @see org.mandarax.kernel.Constructor#perform
     * @param session a session object
     * @return the resulting object, usually true or false
     * @throws java.lang.UnsupportedOperationException - thrown if not supported
     * @throws java.lang.IllegalArgumentException
     */
    public Object resolve(Session session) throws UnsupportedOperationException, IllegalArgumentException;

    /**
     * Set a new predicate.
     * @param p the new predicate
     */
    public void setPredicate(org.mandarax.kernel.Predicate p);
    /**
	 * Indicates whether the fact is negated (negation as failure)
	 * @return true if the fact is negated, false otherwise
	 */
	boolean isNegatedAF();
}
